Article ID: 136885
Article Last Modified on 3/16/2005
150777 Descriptions and Workings of OLE Threading Models
OleInitialize(NULL);
CoCreateInstance(CLSID_Hello, NULL, CLSCTX_SERVER,
IID_IUnknown, (void **)&punk);
punk->QueryInterface(IID_IHello, (void **)&phello);
WaitForSingleObject(hSomeObjectThatTakesALongTime);
phello->put_Visible(TRUE);
phello->SayHello();
OleUninitialize();
You can fix this code by replacing WaitForSingleObject with a message loop
function as in this example:
BOOL WaitWithMessageLoop(HANDLE hEvent)
{
DWORD dwRet;
MSG msg;
while(1)
{
dwRet = MsgWaitForMultipleObjects( 1, // One event to wait for
&hEvent, // The array of events
FALSE, // Wait for 1 event
INFINITE, // Timeout value
QS_ALLINPUT); // Any message wakes up
if(dwRet == WAIT_OBJECT_0)
{
// The event was signaled, return
return TRUE;
} else if(dwRet == WAIT_OBJECT_0 + 1)
{
// There is a window message available. Dispatch it.
while(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} else
{
// Something else happened. Return.
return FALSE;
}
}
}
Any STA thread that does not block but makes OLE calls, needs to dispatch
messages as follows.
MSG msg;
CoInitialize(); // or OleInitialize()
// force msg-q to be created just in case, NOP otherwise
PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
// msg to myself to do work
PostThreadMessage(GetCurrentThreadId(), WM_USER+1, 0, 0);
// msg-pump
while (GetMessage(&msg, NULL, 0, 0))
{
// this was my message -- time to do my work
if (msg.hwnd == NULL && msg.message == WM_USER+1)
{
// do my work here, CCI, work, work, release, etc
// if this thread is doing long process, you need to break
that into smaller chunks,
// and post another user message to process further, that
way you don't block the
// messages which need to be processed.
// when done,
PostQuitMessage(0);
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
CoUninitialize();
Additional query words: Windows 95 threading GetMessage
Keywords: kbcode kbinfo KB136885