9

私のC++アプリケーションのGUIオブジェクトでは、メインウィンドウの手順に次のものがあります。

case WM_SIZE:
    {
        OutputDebugString(L"WM_SIZE received.\n");
        RECT rect = {0};
        GetWindowRect(hwnd, &rect);
        if (!PostMessage(0, GUI_MSG_SIZECHANGED, w, MAKELONG(rect.bottom - rect.top, rect.right - rect.left))) {
            OutputDebugString(L"PostMessage failed.\n"); // <--- never called
        }
    }

    return 0; // break;

GUIオブジェクトには、次のgetMessage()メソッドもあります。

int GUI::getMessage(MSG & msg) {
    BOOL result = 0;

    while ((result = GetMessage(&msg, 0, 0, 0)) > 0) {
        if (msg.message > (GUI_MSG_BASE-1) && msg.message < (GUI_MSG_LAST+1)) {
            OutputDebugString(L"GUI message received.\n");
            break;
        }
        else {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return result;
}

アプリケーションオブジェクトは、次の方法でこのメソッドを呼び出します。

while ((result = _gui.getMessage(msg)) > 0) {
    switch (msg.message) {
        // TODO: Add gui message handlers
        case GUI_MSG_SIZECHANGED:
            OutputDebugString(L"GUI_MSG_SIZECHANGED received.\n");
            _cfg.setWndWidth(HIWORD(msg.lParam));
            _cfg.setWndHeight(LOWORD(msg.lParam));
            if (msg.wParam == SIZE_MAXIMIZED)
                _cfg.setWndShow(SW_MAXIMIZE);
            else if (msg.wParam == SIZE_MINIMIZED)
                _cfg.setWndShow(SW_MINIMIZE);
            else if (msg.wParam == SIZE_RESTORED)
                _cfg.setWndShow(SW_SHOWNORMAL);
            break;
    }
}

アプリケーションオブジェクトは、この情報を構成ファイルに格納するため、ウィンドウサイズに関心があります。

Visual Studioのデバッガーでこれを実行すると、ウィンドウのサイズを変更した後の出力ウィンドウは次のようになります。

WM_SIZE received.
GUI message received.
GUI_MSG_SIZECHANGED received.
WM_SIZE received.
WM_SIZE received.
WM_SIZE received.
WM_SIZE received.
...etc...

PostMessage()関数は失敗することはありませんが、WM_CREATEを処理した直後のWM_SIZEが最初に処理されるときに、GUI_MSG_SIZECHANGED(#defined as WM_APP + 0x000d)のみを送信するようです。

何が原因なのかわかりません。SendMessageとPostThreadMessageを使用してみましたが、結果は同じです。また、MSDNのメッセージ処理ドキュメントを読みましたが、コードの何が問題になっているのかわかりませんでした。

誰か助けてもらえますか?

4

1 に答える 1

6

カスタムメッセージループをハッキングすることは、いつか後悔することになるでしょう。あなたは早くそれを打ちました。

NULLウィンドウハンドルを使用してメッセージを投稿しないでください。プログラムがカスタムメッセージループのみをポンプすることを保証できる場合にのみ機能します。そのような保証はできません。これらのメッセージは、ダイアログを開始するか、Windowsがメッセージループ自体をポンプすることを決定するとすぐにビットバケットに分類されます。これは、ユーザーがウィンドウのサイズを変更する場合、サイズ変更ロジックはモーダルです。Windowsは独自のメッセージループをポンプし、WM_ENTERSIZEMOVEがそれをアナウンスします。これは、スレッドが任意のウィンドウを表示できる場合にPostThreadMessageが悪である理由でもあります。MessageBoxでさえ致命的です。DispatchMessageはメッセージを配信できません。

コントローラとして機能する非表示のウィンドウを作成します。これで、ウィンドウプロシージャでGUI_MSG_SIZECHANGEDを​​検出でき、メッセージループをハックする必要はありません。そのコントローラーは、アプリのメインウィンドウになることはめったにありません。

于 2011-06-26T19:10:52.093 に答える