メッセージ ハンドラ内からメッセージ ループを正しく実行できません。実際には、DialogBox() がメッセージを処理する方法を複製し、すべてのウィンドウ処理を差し引いています。
システム メニューを開く WM_SYSKEYDOWN イベントがサブループへのエントリもトリガーする場合を除いて、メッセージ ハンドラー内から GetMessage() を呼び出すだけでほとんど機能します。この奇妙なことが起こった後、キーの押下が飲み込まれ、システム メニューに関連する WM_MOUSEMOVE メッセージがメイン ウィンドウに送信されます。
記録として、これは Windows 8 と XP の両方で発生します。
いくつかのコンテキストを提供するために、(ウィンドウのない) ワーカー スレッドがサーバーとして機能するメイン ウィンドウへの SendMessage 呼び出しをブロックすることで通信するスレッド モデルを試みています。これらのアクションにはさらに入力が必要な場合や、他の I/O に依存する場合があるため、通常のメッセージは、応答の準備ができるまで処理する必要があります。
前回ここに投稿したときと同じように、これが私の側の基本的な間違いまたは誤解であることはかなり確信していますが、自分で何が間違っているのかをうまく理解できないようです.
これが私の再現ケースです。ALT+SPACE を押してシステムメニューを開いてからナビゲートしてみてください。
#include <windows.h>
BOOL update;
LRESULT WINAPI WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
MSG msg;
char text[256];
switch(uMsg) {
case WM_DESTROY:
ExitProcess(0);
// Trigger an update on input
case WM_SYSKEYDOWN:
update = TRUE;
break;
// Display the update from the worker thread, returning once it is time to
// ask for the next one
case WM_USER:
wsprintf(text, TEXT("%u"), (unsigned int) lParam);
SetWindowText(hwnd, text);
while(!update && GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
update = FALSE;
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
DWORD WINAPI ThreadProc(void *hwnd) {
// Submit updates as quickly as possible
LONG sequence = 1;
for(;;)
SendMessage(hwnd, WM_USER, 0, sequence++);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCommandLine, int nCmdShow) {
HWND hwnd;
MSG msg;
// Create our window
WNDCLASS windowClass = { 0 };
windowClass.lpfnWndProc = WindowProc;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = NULL;
windowClass.lpszClassName = TEXT("Repro");
RegisterClass(&windowClass);
hwnd = CreateWindow(TEXT("Repro"), TEXT("Repro"),
WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL,
hInstance, 0);
// Launch the worker thread
CreateThread(NULL, 0, ThreadProc, hwnd, 0, NULL);
// And run the primary message loop
while(GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}