【问题标题】:Why are my WINAPI messages not reaching my window procedure?为什么我的 WINAPI 消息没有到达我的窗口过程?
【发布时间】:2021-08-01 08:36:06
【问题描述】:

我使用 winapi 对话框作为窗口类的根 HWND。该程序编译并显示完美,但是当我单击按钮时,没有任何响应,几乎就像消息没有到达我的窗口过程,或者说过程从未被调用。如何确保消息正常工作并且我正在正确处理它们以完成我想要做的事情?

main.c 中的简化 WinMain:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
    LPSTR lpCmdLine, int nCmdShow)
{
    static char szAppName[] = TEXT ("AppName"); // Does not display, remove later
    HWND hwnd;
    MSG msg;

    WNDCLASS wndclass;
    wndclass.style = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc = DlgProc;
    wndclass.cbClsExtra = 0;
    wndclass.cbWndExtra = DLGWINDOWEXTRA;
    wndclass.hInstance = hInstance;
    wndclass.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MAIN));
    wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
    wndclass.lpszMenuName  = MAKEINTRESOURCE(IDC_MAINMENU);
    wndclass.lpszClassName = szAppName;
    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL,
                   TEXT("This program requires Windows NT!"),
                   szAppName,
                   MB_ICONERROR);
        return 0;
    }

    hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MAIN), 0, NULL);
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

简化的DlgProc(用 C++ 编写并在 C 中注册使用):

LRESULT CALLBACK DlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
{
    switch(Message)
    {
        case WM_INITDIALOG:
            MessageBeep(0); // Does not sound, even if I change the case to WM_CREATE
        break;
        case WM_COMMAND:
            switch(LOWORD(wParam))
            {
                // Handle buttons/statics inside the dialog, they do nothing
            }
        case WM_CLOSE:
            EndDialog(hwnd, 0);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return FALSE;
    }
    return TRUE;
}

资源文件中的对话:

IDD_MAIN DIALOG DISCARDABLE  0, 0, 207, 156
STYLE WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX
CAPTION "AppTitle"
FONT 8, "MS Sans Serif"
BEGIN
    // Internal statics and buttons
END

感谢任何帮助。谢谢!

【问题讨论】:

  • hwnd = CreateDialog(hInstance, MAKEINTRESOURCE(IDD_MAIN), 0, NULL); - 您忘记将 DlgProc 作为最后一个参数传递。 (另外,你的 RegisterClass 是没有意义的。系统提供了对话框类,而不是你。)
  • 可以继承它
  • @RaymondChen 我现在正在测试您的CreateDialog 提示,但我正在遵循 Programming Windows (Petzold) 中的一个示例,他没有解释他注册窗口类的理由,但我'假设它的存在是有原因的?
  • @Swift-FridayPie 你能举个例子吗?这大概就是我想走的路线。
  • @OCDkirby 子类化正在改变现有窗口的类,此时无需考虑。问题是您正在使用CreateDialog 从此处的资源创建一个无模式对话框,并且它不使用您的窗口类!它在调用CreateWindow 之前在内部创建自己的。消耗寡妇阶级的是CreateWindow。我唯一使用那本书(早期版)是在 90 年代,所以我不能肯定地说,那是使用 CreateWindow 的不同代码吗?

标签: c winapi


【解决方案1】:

按照 Microsoft GitHub 存储库中的Using the code 步骤完成您的程序。您应该在资源文件中设置您的对话框Class Name = AppName,并在您调用DlgProc 的WndProc 中将WM_INITDIALOG 更改回WM_CREATE

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-16
    • 2012-11-06
    • 2014-11-12
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    相关资源
    最近更新 更多