5

Win32 API を使用して非常に基本的なウィンドウを作成しようとしていますが、これを行ってから長い時間が経ちました。

メッセージ ループは問題ないと思いますが、開いているウィンドウを閉じると、アプリケーションがまだ実行されています。メッセージループがWM_QUITメッセージを取得しないようです。しかし、私は電話をかけPostQuitMessageており、メッセージ ボックスで電話をかけたことを確認します。

このミニマリスト コードの何が問題なのですか?

#include <Windows.h>

LRESULT CALLBACK window_proc(HWND hwnd, UINT msg,
        WPARAM w_param, LPARAM l_param) {
    switch (msg) {
    case WM_DESTROY:
        MessageBox(NULL, L"destroy", L"info", MB_OK);
        PostQuitMessage(0);
        break;

    default:
        return DefWindowProc(hwnd, msg, w_param, l_param);
    }

    return 0;
}

int CALLBACK WinMain(HINSTANCE h_instance, HINSTANCE h_prev_instance,
        LPSTR cmd_line, int n_cmd_show) {
    WNDCLASS wnd_class;
    HWND hwnd;
    MSG msg;
    BOOL ret;

    wnd_class.cbClsExtra = 0;
    wnd_class.cbWndExtra = 0;
    wnd_class.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);
    wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
    wnd_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wnd_class.hInstance = h_instance;
    wnd_class.lpfnWndProc = window_proc;
    wnd_class.lpszClassName = L"MyWindowClass";
    wnd_class.lpszMenuName = NULL;
    wnd_class.style = 0;
    if (!RegisterClass(&wnd_class)) {
        MessageBox(NULL, L"cannot register window class",
            L"error", MB_OK | MB_ICONERROR);
    }

    hwnd = CreateWindow(
        L"MyWindowClass",
        L"",
        WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        h_instance,
        NULL
    );

    while ((ret = GetMessage(&msg, hwnd, 0, 0)) != 0) {
        if (ret == -1) {
            MessageBox(NULL, L"error", L"", MB_OK);
        } else {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    MessageBox(NULL, L"quitting now", L"info", MB_OK);

    return msg.wParam;
}

ドキュメントは、メッセージGetMessageを読み取るときに関数が0を返すと言います。WM_QUITHowcomPostQuitMessageが呼び出され、GetMessage0 が返されない?

ありがとう、Win32の達人。

4

1 に答える 1

8

そのあなたのGetMessage()ループ。

ウィンドウ ハンドルをそのループに渡しているため、すべてのアプリケーション スレッド メッセージが除外され、そのウィンドウへのメッセージのみが受信されます。.

これを変える:

while ((ret = GetMessage(&msg, hwnd, 0, 0)) != 0) 
//  Note window handle =========^

これに:

while ((ret = GetMessage(&msg, NULL, 0, 0)) != 0) 
//  Note no handle =============^

そして、アプリケーション スレッド キューがGetMessage()ループによって監視されるようになりました。

理由: GetMessage()特定のウィンドウ ハンドルのメッセージ キューを監視するように呼び出しを調整できます。アプリケーション WM_QUIT は、ウィンドウ ハンドル キューにポストされません。これは、特に監視するターゲット ウィンドウ ハンドルを使用せずにGetMessage()(おそらくPeekMessage()同様ですが、長すぎて覚えていません) を使用して、キューからメッセージをプルすることしかできません。

于 2013-01-26T04:04:26.533 に答える