Platform SDK: TAPI |
The following are points to consider when writing a TAPI 3.0 application.
In apartment threading you must have a message pump regardless of whether you wait for synchronization objects. This is particularly important if you have a console application or you write a COM local/remote server object that is apartment threaded (where you don't have a console or a GUI, but the control just "runs" in the system).
Use caution when calling the wait and synchronization functions, such as Sleep(), WaitForMultipleObjects, WaitForMultipleObjectsEx, WaitForSingleObject, WaitForSingleObjectEx, and so on. Instead, use MsgWaitForMultipleObjects and process the messages, or use CoWaitForMultipleHandles(), which will automatically detect what type of apartment the thread is in (STA or MTA) and will wait either in COM's modal loop (if STA) or block on WaitForMultipleObjects (if MTA). MsgWaitForMultipleObjects and CoWaitForMultipleHandles() also process windows messages according to the COM rules.
For example, instead of:
Sleep (5000);
Use:
{ DWORD dwSignalled; HANDLE heventDone = CreateEvent(0, FALSE, FALSE, 0); CoWaitForMultipleHandles (COWAIT_ALERTABLE, 5000, 1, &heventDone, &dwSignalled); CloseHandle(heventDone); }
Do the minimum in the Event routine; instead, use one of your own threads where possible.
HRESULT STDMETHODCALLTYPE CTAPIEventNotification::Event( TAPI_EVENT TapiEvent, IDispatch * pEvent ) { // // addref the event so it doesn't go away // pEvent->AddRef(); // // post a message to ourself // PostMessage( ghDlg, WM_PRIVATETAPIEVENT, (WPARAM) TapiEvent, (LPARAM) pEvent ); return S_OK; }