以下のようなコードを実装したところ、
PostThreadMessage()で送信したメッセージは受信できているのに
DispatchMessage()を実行してもウィンドウプロシージャ(MyWindowProc)が実行されないという現象が発生しました。
RegisterWindow()、CreateWindow()は共に成功していますし
原因が分からない状況です。
RegisterWindow()やCreateWindow()のパラメータを間違えているのでしょうか?
#include <windows.h>
#include <stdio.h>
#include <process.h>
#define EVENT_NAME "EVENT_NAME"
#define MY_MESSAGE (WM_APP + 1)
// _beginthreadex()から実行されるAPI
unsigned int WINAPI func(void *vp);
// ウィンドウプロシージャ
LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
// Windowを作成
BOOL MyCreateWindow(LPTSTR lpszAppName, HINSTANCE hinst);
int main(void)
{
char buf[64];
HANDLE hEvent;
HANDLE hThread;
printf("【0x%08X】main thread\n", GetCurrentThreadId());
// サスペンド状態でスレッドを作成
hThread = (HANDLE)_beginthreadex(NULL, 0, func, NULL, CREATE_SUSPENDED, NULL);
// EVENT名にスレッドIDを使用し、EVENT作成後にスレッドを開始する
sprintf_s(buf, sizeof(buf), "%s-0x%08X", EVENT_NAME, GetThreadId(hThread));
hEvent = CreateEvent(NULL, FALSE, FALSE, buf);
ResumeThread(hThread);
// GUIスレッドになるまで待つ
WaitForSingleObject(hEvent, INFINITE);
printf("【0x%08X】GUIスレッドになったため、スレッドに対してメッセージを送信\n", GetCurrentThreadId());
// 作成したスレッドにメッセージを送る
if(PostThreadMessage(GetThreadId(hThread), MY_MESSAGE, 0, 0) == FALSE)
{
printf("【0x%08X】PostThreadMessage() == FALSE、GetLastError() = 0x%08X\n", GetCurrentThreadId(), GetLastError());
return 0;
}
// 作成したスレッドが終了するまで待つ
WaitForSingleObject(hThread, INFINITE);
return 0;
}
unsigned int WINAPI func(void *vp)
{
char buf[64];
HANDLE hEvent;
MSG msg;
printf("【0x%08X】sub thread", GetCurrentThreadId());
// GUIスレッドにする
if(IsGUIThread(TRUE) == FALSE)
{
printf("ERROR");
}
// Windowを作成
if(MyCreateWindow("WinProc", GetModuleHandle(NULL)) == FALSE)
{
printf("FALSE\n");
}
// EVENT名を作成し、EVENTをシグナル状態にする
sprintf_s(buf, sizeof(buf), "%s-0x%08X", EVENT_NAME, GetCurrentThreadId());
hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, buf);
SetEvent(hEvent);
// メッセージループ開始
while (GetMessage(&msg, NULL, 0, 0) > 0) {
printf("【0x%08X】msg.message = 0x%08X, msg.lParam = 0x%08X, msg.wParam = 0x%08X\n", GetCurrentThreadId(), msg.message, msg.lParam, msg.wParam);
printf("【0x%08X】DispatchMessage()開始\n", GetCurrentThreadId());
DispatchMessage(&msg);
printf("【0x%08X】DispatchMessage()終了\n", GetCurrentThreadId());
}
return 0;
}
// Windowの作成
BOOL MyCreateWindow(LPTSTR lpszAppName, HINSTANCE hinst)
{
HWND hwnd;
WNDCLASSEX wc;
memset(&wc, 0, sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = MyWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hinst;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = lpszAppName;
wc.hIconSm = NULL;
if (RegisterClassEx(&wc) == 0)
return FALSE;
hwnd = CreateWindowEx(0, lpszAppName, lpszAppName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hinst, NULL);
if (hwnd == NULL)
return FALSE;
return TRUE;
}
LRESULT CALLBACK MyWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
printf("【0x%08X】MyWindowsProc thread、Msg = 0x%08X\n", GetCurrentThreadId(), uMsg);
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
break;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}