マルチスレッド アプリケーションがあり、特定のスレッドで、ATL を使用してウィンドウを作成していますCWindowImpl<>
。スレッド プロシージャとして使用している静的メソッドがあります。スレッドとの通信の一部をsynchronousにする必要があり、PostThreadMessage()
明示的に非同期であるため、スレッドにウィンドウを作成する必要があります。ウィンドウがメッセージ (マクロでWM_DESTROY
定義されたハンドラー)を受け取ると、次のメソッドに示すように、 を呼び出します。MESSAGE_HANDLER
PostQuitMessage()
LRESULT MyATLWindowClass::OnDestroy(UINT uMsg,
WPARAM wParam,
LPARAM lParam,
BOOL& bHandled) {
::PostQuitMessage(0);
return 0;
}
私はスレッドにカスタムメッセージを使用してPostThreadMessage()
、それ自体を終了する時が来たことをスレッドに示しています。そのカスタム メッセージを処理して、メソッドを呼び出します。メッセージ ハンドラーが呼び出されるとCWindowImpl::DestroyWindow()
、ウィンドウが適切に破棄されるように見えます。ただし、所有スレッドが処理用のメッセージをOnDestroy
受信したことはないようです。WM_QUIT
以下に含まれるのは、私のスレッド手順の簡略化されたバージョンです。
unsigned int WINAPI MyATLWindowClass::ThreadProc(LPVOID lpParameter) {
// Initialize COM on the thread
::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// Create the window using ATL
MyATLWindowClass new_window;
HWND session_window_handle = new_window.Create(
/* HWND hWndParent */ HWND_MESSAGE,
/* _U_RECT rect */ CWindow::rcDefault,
/* LPCTSTR szWindowName */ NULL,
/* DWORD dwStyle */ NULL,
/* DWORD dwExStyle */ NULL,
/* _U_MENUorID MenuOrID */ 0U,
/* LPVOID lpCreateParam */ NULL);
// Initialize the message pump on the thread.
MSG msg;
::PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
// Run the message loop
BOOL get_message_return_value;
while ((get_message_return_value = ::GetMessage(&msg, NULL, 0, 0)) != 0) {
if (get_message_return_value == -1) {
// GetMessage handling logic taken from MSDN documentation
break;
} else {
if (msg.message == WD_SIGNAL_THREAD_SHUTDOWN) {
// Requested thread shutdown, so destroy the window
new_window.DestroyWindow();
} else if (msg.message == WM_QUIT) {
// Process the quit message and exit the message loop
// to terminate the thread
break;
} else {
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
}
// Uninitialize COM on the thread before exiting
::CoUninitialize();
return 0;
}
DestroyWindow()
私が電話をかけるかWM_CLOSE
、ウィンドウにメッセージを送信するかは問題ではないように思われることに注意してください。いずれの場合も、スレッドのメッセージ ポンプは WM_QUIT を受信していません。所有スレッドのメッセージ ポンプは、そのようなメッセージを受信する必要がありますか? スレッドのメッセージ ポンプとウィンドウのメッセージ ポンプがどのように相互作用するかについての私の誤解はどこにありますか? または、ATL のウィンドウ クラスがウィンドウを作成および管理する方法について何が欠けているのでしょうか?