Hinweise und Tipps
Im Folgenden sind Hinweise und Tipps zu beachten, wenn Sie eine Anwendung für TAPI 3 schreiben:
COM CoInitialize erstellt indirekt Fenster; dies ist besonders wichtig für Apartmentthreading. Wenn ein Thread Fenster erstellt, muss er Nachrichten verarbeiten. Wenn Ihre Threads CoInitialize aufrufen, führen Sie eine Nachrichtenpump aus, um Probleme zu vermeiden. Beispielsweise kann COM das Marshalling ordnungsgemäß beenden, oder Methoden in COM-Schnittstellen, z. B. IGlobalInterfaceTable, können hängen bleiben.
Beim Apartmentthreading muss eine Nachrichtenpumpe vorhanden sein, unabhängig davon, ob Sie auf Synchronisierungsobjekte warten. Dies ist besonders wichtig, wenn Sie über eine Konsolenanwendung verfügen oder ein lokales COM-/Remoteserverobjekt schreiben, das im Apartmentthread ausgeführt wird (wenn Sie keine Konsole oder GUI haben, das Steuerelement jedoch nur im System ausgeführt wird).
Achtung
Beim Aufrufen der Warte- und Synchronisierungsfunktionen wie Sleep, WaitForMultipleObjects, WaitForMultipleObjectsEx, WaitForSingleObject, WaitForSingleObjectExusw. Verwenden Sie stattdessen MsgWaitForMultipleObjects, und verarbeiten Sie die Nachrichten, oder verwenden Sie CoWaitForMultipleHandles, das automatisch erkennt, in welchem Apartmenttyp sich der Thread befindet (STA oder MTA) und entweder in einer modalen COM-Schleife (bei STA) oder auf WaitForMultipleObjects (bei MTA) wartet. MsgWaitForMultipleObjects und CoWaitForMultipleHandles verarbeiten auch Windows-Nachrichten gemäß den COM-Regeln.
Verwenden Sie anstelle von
Sleep (5000);Verwendung:
{ DWORD dwSignalled; HANDLE heventDone = CreateEvent(0, FALSE, FALSE, 0); CoWaitForMultipleHandles (COWAIT_ALERTABLE, 5000, 1, &heventDone, &dwSignalled); CloseHandle(heventDone); }ITTAPIEventNotification::Event ist die Ereignisfunktion der Apps, die in einem TAPI 3-Rückrufthread aufgerufen wird.
Gehen Sie in der Ereignisroutine so gering wie nötig vor. Verwenden Sie stattdessen nach Möglichkeit Ihren eigenen Thread.
Beachten Sie, dass das folgende Codebeispiel bereitgestellt wird, aber keine Anforderung ist.
#include <windows.h> HRESULT STDMETHODCALLTYPE CTAPIEventNotification::Event( TAPI_EVENT TapiEvent, IDispatch *pEvent) { // // Addref the event so that it does not go away. // pEvent->AddRef(); // // Post a message for reference. // BOOL RetVal = PostMessage( ghDlg, WM_PRIVATETAPIEVENT, (WPARAM) TapiEvent, (LPARAM) pEvent ); // If (RetVal == 0 ) process error here. return S_OK; }Bearbeiten Sie COM-Objekte nicht, nachdem Sie CoUninitializeaufgerufen haben. Die Ergebnisse sind unvorhersehbar und schädlich für eine fehlerfreie Anwendung. Beispiele dafür sind Arbeitsthreads und C++-Destruktoren, die ausgeführt werden können, nachdem eine Anwendung CoUninitialize aufruft.