win32api函数的顺序导致回调函数接收相同的消息

时间:2016-03-27 20:50:55

标签: c winapi callback messagebox sendmessage

我有一个资源文件(.rc),其中包含以下内容

#include <windows.h>
#include "resource.h"

IDD_ABOUT DIALOG DISCARDABLE  0, 0, 500, 106
BEGIN

    DEFPUSHBUTTON   "&OK", IDOK,            174, 18, 50, 14

    RADIOBUTTON     "Radio 1", ID_RADIOBUTTON1, 226, 18, 55, 14
END

我的C档包含以下内容

#include <windows.h>
#include "resource.h"

BOOL CALLBACK AboutDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch(Message)
    {
        case WM_COMMAND:
        switch(LOWORD(wParam))
        {
            case ID_RADIOBUTTON1:
            {
                MessageBox(hwnd, "RadioButton 1", "111", MB_OK);
                SendMessage((HWND)lParam, (UINT) BM_SETCHECK, (WPARAM) BST_CHECKED,(LPARAM)NULL);
            }
        return TRUE;
        break;

        }
    break;
        default:
            return FALSE;
    }
        return TRUE;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_ABOUT), NULL, AboutDlgProc);
}

在对话框打开后单击单选按钮一次,回调函数重复接收相同的消息,即带有LOWORD(wParam)== ID_RADIOBUTTON1的WM_COMMAND。但是如果在MessageBox之前调用SendMessage,那么错误就不会发生。这是否有特定的原因?

修改

但是如果我用printf替换对MessageBox的调用,那么错误就不会发生,行为就像预期的那样,只产生一个输出实例。

我正在使用gcc和windres制作程序。

我的操作系统是Windows Vista(tm)Home Premium 32位Service Pack 2

1 个答案:

答案 0 :(得分:0)

使用AUTORADIOBUTTON(而不是RADIOBUTTON)这将自动设置选择标记。例如:

IDD_ABOUT DIALOGEX 0, 0, 222, 257
STYLE DS_ABSALIGN | DS_SETFONT | WS_POPUP | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 9, "Segoe UI", 400, 0, 0x0
BEGIN
    DEFPUSHBUTTON   "&OK", IDOK,  174, 18, 50, 14
    AUTORADIOBUTTON "Radio 1", ID_RADIOBUTTON1, 226, 18, 55, 14
END

您可以使用MessageBox或其他模态窗口:

...
case ID_RADIOBUTTON1:
{
    MessageBox...
}

对于RADIOBUTTON,您必须自己设置选择标记。尽快执行此操作并立即返回TRUE。不要在之前或之后致电MessageBox

case ID_RADIOBUTTON1:
    SendMessage((HWND)lParam, BM_SETCHECK, !IsDlgButtonChecked(hwnd, ID_RADIOBUTTON1), 0);
    return TRUE;