2013-03-04 4 views
1

Я использую следующий код для создания кнопки и изменить его прок:Обработка нажатия кнопки в процедуре кнопки

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

Вы не видите свое сообщение, потому что 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); 
+0

1. опечатка, извините 2. Вы могли бы предоставить пример использования SetWindowsHookEx? – user1233963

+0

Я добавил пример. –

Смежные вопросы