1

次のコードを使用してボタンを作成し、その proc を変更しています。

INT_PTR CALLBACK Proc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    //switch( LOWORD(wParam) )
    //switch( HIWORD(wParam) )
    switch (message)
    {
    case 200:
    case BN_CLICKED:
        MessageBox(NULL,NULL,NULL,NULL);
        break;

    default: return oldproc(hDlg, message, wParam, lParam);
    }
    return (INT_PTR)FALSE;
}

HWND handle = CreateWindowEx( NULL,
        L"button",
        L"TEXT",
        WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,
        50,
        50,
        500,
        500,
        hWnd,
        (HMENU)200,
        hInstance,
        nullptr);

    oldproc = (WNDPROC)SetWindowLong(handle, GWL_WNDPROC, (LONG)Proc);

問題は、Proc でメッセージをどのように処理しても、メッセージボックスが作成されないことです。

注: 最後の行にコメントを付けて、ウィンドウ プロシージャで次のように処理します。

case WM_COMMAND:
    wmId    = LOWORD(wParam);
    wmEvent = HIWORD(wParam);
    switch (wmId)
    {
    case 200:
         if(wmEvent == BN_CLICKED)
            MessageBox(NULL,NULL,NULL,NULL);
... }

正常に動作しますが、私がどのように設計したかにより、これを使用できません。

これを機能させる方法はありますか?

4

2 に答える 2

4

BM_CLICKボタンが受信するメッセージではないため、メッセージ ボックスは表示されません。クリック アクションをシミュレートするときにボタンに送信するメッセージです。

あなたが探しているのは、BN_CLICKED代わりに通知です。ただし、ボタン自体ではなく、ボタンの親ウィンドウに送信されるメッセージBN_CLICKED内にラップされます。WM_COMMANDしたがって、親ウィンドウを受け取るには、親ウィンドウをサブクラス化する必要があります。

それができない場合は、SetWindowsHookEx()代わりにスレッド固有のメッセージ フックを使用して、そのコールバックでボタンの親ウィンドウに送信されるメッセージを探すことができます。例えば:

HWND hBtn, hBtnParent;
HHOOK hHook;

LRESULT CALLBACK BtnMsgProc(int iCode, WPARAM wParam, LPARAM lParam)
{
    if ((iCode == HC_ACTION) && (wParam == PM_REMOVE))
    {
        MSG *msg = reinterpret_cast<MSG*>(lParam);
        if ((msg->hwnd == hBtnParent) &&
            (msg->message == WM_COMMAND) &&
            (HIWORD(msg->wParam) == BN_CLICKED) &&
            (reinterpret_cast<HWND>(msg->lParam) == hBtn))
        {
            // button has been clicked...
        }
    }

    return CallNextHookEx(hHook, iCode, wParam, lParam);
}

.

hBtnParent = hWnd;
hBtn = CreateWindowEx(
    NULL,
    L"button",
    L"TEXT",
    WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_DEFPUSHBUTTON,
    50,
    50,
    500,
    500,
    hWnd,
    (HMENU)200,
    hInstance,
    NULL);

hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)BtnMsgProc, NULL, GetCurrentThreadId());
...
UnhookWindowsHookEx(hHook);
DestroyWindow(hBtn);
于 2013-03-04T17:58:43.957 に答える
2

SetWindowsHookEx の例についての質問: MSDN

于 2013-03-04T18:08:44.930 に答える