WinAPI 中的菜单:我对 WM_COMMAND 使用 LPARAM 还是 WPARAM?

Posted

技术标签:

【中文标题】WinAPI 中的菜单:我对 WM_COMMAND 使用 LPARAM 还是 WPARAM?【英文标题】:Menus in WinAPI: Do I use LPARAM or WPARAM for WM_COMMAND? 【发布时间】:2015-07-23 23:27:23 【问题描述】:

我最近开始自学 WinAPI,所以请耐心等待。

编译器:TDM-GCC 4.9.2 操作系统:Windows 8.1 64 位

我最近学会了如何使用资源创建菜单。关于这一点,我注意到处理菜单的 WM_COMMAND 消息有些奇怪。 MSDN documentation 告诉我,如果我想处理从菜单发送的消息,命令项 ID 可以在 WPARAM 的低位字中找到;所以我假设我的窗口过程中的代码如下所示:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, LPARAM lParam, WPARAM wParam)

    switch (msg)
    
    case WM_COMMAND:
        switch (LOWORD(wParam))  //<--
        
        case /*IDs go here*/:

            break;
        
        break;

    //...
    

    return 0;

但是,我注意到菜单中的命令项不起作用。经过一些调试,我发现 wParam 始终为 0,而我的 ID 实际上在 lParam 中!我对以下代码进行了快速更改:

switch (lParam)

case /*IDs go here*/:

    break;

它有效!

我的问题:为什么? 为什么文档说它在 wParam 中,而对我来说它在 lParam 中?

另外,这里是我的 resource.rc 和 resource.h 文件,以防万一:

“资源.h”:

#define IDR_MYMENU 101

//These are appearing in LPARAM instead of WPARAM
#define ID_FILE_EXIT 9001
#define ID_STUFF_GO  9002

“资源.rc”:

#include "resource.h"

IDR_MYMENU MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit", ID_FILE_EXIT
    END

    POPUP "&Stuff"
    BEGIN
        MENUITEM "&Go", ID_STUFF_GO
        MENUITEM "G&o somewhere else", 0, GRAYED
    END
END


2015 年 7 月 23 日编辑: 解决了。我的窗口程序有错误的签名。不敢相信这是如此微不足道的事情!谢谢,克雷姆诺!

【问题讨论】:

【参考方案1】:

WPARAM 和 LPARAM 参数在您的代码中的顺序不正确:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, LPARAM lParam, WPARAM wParam)

来自WindowProc callback function MSDN 文档:

LRESULT CALLBACK WindowProc(
  _In_ HWND   hwnd,
  _In_ UINT   uMsg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);

只需交换它们即可修复您的代码:

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)

【讨论】:

【参考方案2】:

您的 WM_COMMAND 消息处理应首先检查 wParam 的高位 WORD。因为这个值告诉你发送消息的是菜单、加速器还是子控件。

swtich(msg)

case WM_COMMAND:

    switch(HIWORD(wParam))
    
        case 0: // Menu
        
            // Check LOWORD(wParam) here
            break;
        
    
    return 0;

请参阅 MSDN 文档中的表格:WM_COMMAND message

【讨论】:

以上是关于WinAPI 中的菜单:我对 WM_COMMAND 使用 LPARAM 还是 WPARAM?的主要内容,如果未能解决你的问题,请参考以下文章

WM_COMMAND 和 WM_NOTIFY 的区别

winapi - 防止上下文菜单关闭

WINAPI - 设置组合框下拉菜单的背景和文本颜色

win32 WM_NOTIFY 与 WM_COMMAND

《深入浅出MFC》第九章 消息映射与命令传递

菜单栏