|
That worked perfectly. Thanks a lot for that, it was giving me a real headache!
|
|
|
|
|
HI All,
My problem is related to the COM out-proc exe.
I have a COM server(EXE) which has 2 interfaces:-
ISingletonTest - This inteface acts like an entry point for the server.The component class is made singleteon by using the DECLARE_CLASSFACTORY_SINGLETON().This will be created only once.There is function getTest() in this interface which returns the pointer to second interface(ITest). Now as cllient only passes the uninitialized pointer of ITest , i make a call to CoCreateInstance() for intiliaizing the CTest component class.
The problem is when i call the function getTest(ITest *pVal) and i do some work and set this pointer to null it calls its destructor but it doesn't fress the main interface i.e ISingletonTest pointer.
As a result my out-proc exe never gets unloaded.
Ina nutshell could you explan why the module gets locked when i create a COM object in the process of my COM server.Is there any specific care to be taken care of while doing such programming.
Please provide your suggestions as soon as possible.I have strucked badly on this problem.
Thanks in advance.
Deepak
|
|
|
|
|
Having recently discovered the joys of STL, I have set about using it in my projects with gusto. I particularly like auto_ptr, but I have a newbie query. When I try and assign a new value to an auto_ptr, I am getting the following VC7 warning (I am using level 4):
warning C4239: nonstandard extension used : 'argument' : conversion from 'std::auto_ptr<_Ty>' to 'std::auto_ptr<_Ty> &'
For example:
std::auto_ptr<CMyClass> ap;
...
ap = std::auto_ptr<CMyClass>(new CMyClass);
However, the following code doesn't generate the warning:
std::auto_ptr<CMyClass> ap;
...
std::auto_ptr<CMyClass> new_ap(new CMyClass);
ap = new_ap;
Any clues how I can avoid this warning? Note that CMyClass might look something like:
class CMyClass
{
public:
...
CMyClass(void) { ... }
CMyClass(const CMyClass& o) { ... }
};
The Rob Blog
|
|
|
|
|
Welcome to the wonderful world of STL
As for std::auto_ptr , be sure to read this article[^] before using it - its copy semantic is "unusual" and it can cause problems. In fact, I prefer Boost smart pointers in my code - they are safer.
To try to answer your question, I believe you get the warning because the way assigment operator is declared in auto_ptr :
auto_ptr<_Ty>& operator=(auto_ptr<_Ty>& _Right) _THROW0()
{
reset(_Right.release());
return (*this);
}
As you can see, it takes a reference as the argument, not a const reference.
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
I keep hearing about Boost - and I must admit, not being able to use auto_ptrs in STL containers is a real shame.
So now's your chance to sell me Boost - what else am I missing out on apart from a better auto_ptr?
Any suggested hacks for my auto_ptr assignment issue?
The Rob Blog
|
|
|
|
|
Just found a solution thanks to your link - 'reset' does the trick - reset(new CMyClass).
The Rob Blog
|
|
|
|
|
|
Hi All,
I have been trying to create a toolbar for Windows Explorer, I used the Wizard provided by Eric and the basic thing was there. I have got a button on the toolbar I need to know which file or files were selected int the explorer view when the button was clicked.
for more calrification it is just like the standard buttons of copy and paste, when we select some file and press copy it gets the name of the file, same is the thing I want to perform.
I have tried using IWebBrowser2 and the use the get_Document method of it but I dont know what I would be doing further
regards
Muhammad Aftab Alam.
|
|
|
|
|
Hi
I have the following...
<br />
vector<HANDLE> handles;<br />
handles.push_back(CreateMutex(NULL , FALSE , "A"));<br />
handles.push_back(CreateMutex(NULL , FALSE , "B"));<br />
<br />
WaitForMultipleObjects(handles.size() , (const HANDLE*)(&handles) , TRUE , INFINITE);<br />
Basically, the Wait doesn't. I replaced the vectors with an array of handles
<br />
HANDLE handles[2];<br />
handles[0] = CreateMutex(NULL , FALSE , "A");<br />
handles[1] = CreateMutex(NULL , FALSE , "B");<br />
<br />
WaitForMultipleObjects(2 , handles , TRUE , INFINITE);<br />
and it works a treat. It's obviously me, I'm new to STL - I reckon it's the cast to the second param of WaitForMultipleObjects.
Thanks for any input...
Cheers
Angel1058
*********************************************
The sooner you fall behind, the longer you have to catch up.
|
|
|
|
|
Try:
WaitForMultipleObjects(handles.size() , &handles[0], TRUE , INFINITE);
My programming blahblahblah blog. If you ever find anything useful here, please let me know to remove it.
|
|
|
|
|
Many thanks. Easy when you know how....and now I do.
Angel1058
*********************************************
The sooner you fall behind, the longer you have to catch up.
|
|
|
|
|
I have been tasked to update a WTL program. The program creates many modeless windows, the windows are created with style pop-up and the parent for the window is set to NULL in the create call. The main problem is the tabbing order on the modeless windows is not working. I have verified the VK_TAB message arrives in the main dialog(pretranslate message function) that created the modeless dialogs. How do I go about forwarding the message to the appropriate dialog, or is there a simpler solution to make the tabbing work? I have never had to work with the tabbing msgs before and it all seems a bit mysterious what is really going on.
TIA
|
|
|
|
|
Try something like this:
virtual BOOL PreTranslateMessage(MSG* pMsg)
{
if (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB)
return m_dlgChild.PreTranslateMessage(pMsg);
}
Then in your child dialog message handler you handle it.
Igor.
|
|
|
|
|
Each modeless window (I assume they're all dialogs?) should derive from CMessageFilter and override the PreTranslateMessage() method. The PreTranslateMessage() would do:
BOOL CYourWindow::PreTranslateMessage ( MSG* pMsg )
{
return IsDialogMessage ( pMsg );
} In each window's OnInitDialog() , register for pre-translate calls with:
CMessageLoop* pLoop = _Module.GetMessageLoop();
ATLASSERT(pLoop != NULL);
pLoop->AddMessageFilter ( this ); Look at the wizard-generated CMainFrame::OnCreate() if this part is still unclear.
--
I'm Michael Dunn and I approve this post.
Vote Trogdor in oh-four!
|
|
|
|
|
|
This is more of a visual studio problem than ATL/WTL, I suspect. I have a project that builds a COM client. When I try to open the .rc file, it tells me it can't open atlres.h, one of the include files. However, I can compile and build without any problem (the proper include directory is in the build path). Furthermore, if I edit the .rc file in the text editor and right-click atlres.h at the location of the include statement to try and open it, i get a error messagebox telling my it can't find the file and open it... BUT, it also displays the entire build path and that path includes the directory with atlres.h!!!!
Arg! What's going on? Why can't if find that file during editing, but it can during the compile?
Thanks for any thoughts,
Matt
|
|
|
|
|
do u hav WTL installed and its path configured properly with VC++ IDE
-------------------------
Have a great day ahead!
Regards,
Sohail Kadiwala
(My COM Blog - http://lovecom.blogspot.com)
modified 21-Apr-21 21:01pm.
|
|
|
|
|
Figured it out. I had all proper paths specified under the Project Properties, but not in the Options sections (Tools -> Options). Seems like it shouldn't matter and VS should have been able to find the file, but obviously is couldn't.
Matt
|
|
|
|
|
Good
I was talking about the same "Options sections" settings for WTL.
-------------------------
Have a great day ahead!
Regards,
Sohail Kadiwala
(My COM Blog - http://lovecom.blogspot.com)
modified 21-Apr-21 21:01pm.
|
|
|
|
|
Is it possible to make a list view single selection at runtime or does LVS_SINGLESEL have to be set when you create the control?
|
|
|
|
|
Use CWindow::ModifyStyle() :
CWindow wndList = GetDlgItem ( IDC_YOUR_LIST );
wndList.ModifyStyle ( LVS_SINGLESEL, 0 );
--
I'm Michael Dunn and I approve this post.
Vote Trogdor in oh-four!
|
|
|
|
|
Hi,
I am writing a very simple ATL in-proc server to experience the STA mechanism.
My code is like that:
1) I defined an interface called IEcho, which has only one function called Echo(DWORD).
2) I implemeted this interface in coclass CoEcho,
which has a data member named "m_nNumber" with type "long" and which implements Echo(DWORD) as the following:
///------------------------------------------
ATLTRACE("%ld enter\n", GetCurrentThreadId());
this->m_nNumber = number;
Sleep(1000);
//!!!!! NOTICE THIS STAEMENT
//MessageBox(NULL, _T("WAIT"), _T("WAIT"), 0);
//!!!!!
ATLTRACE("the number passed in: %ld\n",
this->m_nNumber);
ATLTRACE("%ld leave\n", GetCurrentThreadId());
return S_OK;
///----------------------------------------------
3) Then, I create a STA Client, which creates a IEcho instance, marshals it and passes it to two threads sharing the same thread function.
the STA Client is like:
//------------------THREAD FUNCTION-----
//it is very simple
DWORD WINAPI ThreadFunc(LPVOID lpara){
CoInitialize(NULL);
IStream * pStream =(IStream*)lpara;
IEcho *pEcho;
CoGetInterfaceAndReleaseStream(pStream,
IID_IEcho,
(LPVOID*)&pEcho);
pEcho->Echo(GetCurrentThreadId());
pEcho->Release();
CoUninitialize();
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IEcho * pEcho = NULL;
CoCreateInstance(CLSID_CoEcho, NULL,
CLSCTX_ALL, IID_IEcho,
(void **)&pEcho);
IStream * t1stream;
IStream * t2stream;
CoMarshalInterThreadInterfaceInStream(IID_IEcho,
pEcho, &t1stream);
HANDLE hThread1 = CreateThread(NULL, 0,
ThreadFunc, t1stream, 0, NULL);
CoMarshalInterThreadInterfaceInStream(IID_IEcho,
pEcho, &t2stream);
HANDLE hThread2 = CreateThread(NULL, 0,
ThreadFunc, t2stream, 0, NULL);
//message pump
MSG ms;
while(GetMessage(&ms, 0, 0, 0)){
TranslateMessage(&ms);
DispatchMessage(&ms);
}
WaitForSingleObject(hThread1, INFINITE);
WaitForSingleObject(hThread2, INFINITE);
CloseHandle(hThread1);
CloseHandle(hThread2);
pEcho->Release();
CoUninitialize();
return 0;
}
///
What I am expecting is that though two threads may call IEcho simultaneously with different thread ids, the data member "m_nNumber" of CoEcho should be well protected by COM STA since only one thread can enter IEcho::Echo function.
for examle, if main thread id is 3, the first thread's id is 1 and the second 2, the ECHO should output:
3 enter
the number passed in 1
3 leave
3 enter
the number passed in 2
3 leave
It works well
But if I have the statement
MessageBox(NULL, _T("WAIT"), _T("WAIT"), 0);
added, m_nNumber is damaged.
the output is something like:
//thread 1 in
3 enter
//thread 2 in?
3 enter <--- it should not be that, only one
thread can be here!!!
the number passed in 2 // thread 1's id is lost
....
I am very confused by that.
Any explaination?
Thanks a lot in advanced!
|
|
|
|
|
duckpond wrote:
Any explaination?
COM uses a hidden window's message queue to synchronize the calls towards the objects of an STA. It seems that when it hits MessageBox (NULL , ...), the hidden window's procedure must retreive and dispatch messages by itself; this makes it reentrant and thus the main apartment - which holds pEcho - unblocks, allowing the second call of Echo to execute.
It is, in essence, equivalent with a cross-apartment call.
"though nothing
will keep us together
we can beat them
for ever and ever"
rechi
|
|
|
|
|
Thanks Rechi I got it.
|
|
|
|
|
May I recommend the book Essential COM by Don Box? IIRC, this reentrancy behaviour is described in it. To summarize: objects living in an STA need not prepare itself for concurrency, but it should prepare itself for reentrancy, as your example shows.
Essential COM is a really good read, and a must for COM developers IMHO.
--
Weiter, weiter, ins verderben.
Wir müssen leben bis wir sterben.
|
|
|
|
|