【问题标题】:WM_COMMAND not being received by Dialog Procedure对话过程未收到 WM_COMMAND
【发布时间】:2012-03-11 18:14:45
【问题描述】:

我正在尝试使用为对话框创建的上下文菜单,但是当我单击菜单项时应该发送的 WM_COMMAND 消息没有到达对话框过程。

我在消息循环中放置了一条 if 语句来检查 WM_COMMAND,它正在注册但未发送到我的对话过程。

是的,我正在使用if( !IsDialogMessage( hwndListDialog, &msg ) ) 呼叫TranslateMessageDispatchMessage

这就是我初始化上下文菜单的方式:

listitemmenu = CreatePopupMenu();

listmenuitem1.cbSize = sizeof( menuitem1 );
listmenuitem1.fMask = MIIM_TYPE;
listmenuitem1.fType = MFT_STRING;
listmenuitem1.hSubMenu = NULL;
listmenuitem1.dwTypeData = "Copy Imgur Link";
InsertMenuItem( listitemmenu, 0, true, &listmenuitem1 ); //insert menu item

listmenuitem2.cbSize = sizeof( menuitem1 );
listmenuitem2.fMask = MIIM_TYPE;
listmenuitem2.fType = MFT_STRING;
listmenuitem2.hSubMenu = NULL;
listmenuitem2.dwTypeData = "Copy Imgur Delete Link";
InsertMenuItem( listitemmenu, 1, true, &listmenuitem2 ); //insert menu item

listmenuitem3.cbSize = sizeof( menuitem1 );
listmenuitem3.fMask = MIIM_TYPE;
listmenuitem3.fType = MFT_STRING;
listmenuitem3.hSubMenu = NULL;
listmenuitem3.dwTypeData = "Rename";
InsertMenuItem( listitemmenu, 2, true, &listmenuitem3 ); //insert menu item

listmenuitem4.cbSize = sizeof( menuitem1 );
listmenuitem4.fMask = MIIM_TYPE;
listmenuitem4.fType = MFT_STRING;
listmenuitem4.hSubMenu = NULL;
listmenuitem4.dwTypeData = "Remove from list";
InsertMenuItem( listitemmenu, 3, true, &listmenuitem4 ); //insert menu item

这就是我跟踪菜单的方式:

TrackPopupMenuEx( listitemmenu, TPM_LEFTBUTTON | TPM_NOANIMATION | TPM_HORIZONTAL | TPM_VERTICAL, cpos.x, cpos.y, ListControl, NULL );

这是我尝试用来与我的菜单交互的开关盒:

case WM_COMMAND:
        switch( LOWORD(lParam) )
        {
        case 0:
            printf("copy link");
            break;
        case 1:
            printf("copy deletion link");
            break;
        case 2:
            printf("Rename");
            break;
        case 3:
            printf("Remove");
            break;
        }
        break;

【问题讨论】:

  • WM_COMMAND 消息被发送到 ListControl。这是故意的吗?

标签: c++ winapi user-interface dialog contextmenu


【解决方案1】:

来自the documentation for TrackPopupMenuEx

hwnd [输入]

类型:HWND

拥有快捷菜单的窗口句柄。 此窗口接收来自菜单的所有消息。

您将ListControl 作为hwnd 参数传递,因此WM_COMMAND 将转到该窗口,而不是您的对话框。如果您希望WM_COMMAND 转到您的对话框,则将您的对话框作为hwnd 传递。

【讨论】:

    【解决方案2】:

    我相信(虽然不记得确切,这是很久以前的事了......)问题是您没有为菜单项指定 ID。预计将到达您的窗口过程的WM_COMMAND 应该带有等于所选项目ID 的lParam。但是,如果您不指定项目 ID,则默认情况下会得到 IDC_STATIC,这是一个无效值。

    尝试以下方法:

    listmenuitem1.cbSize = sizeof( menuitem1 );
    listmenuitem1.fMask = MIIM_TYPE | MIIM_ID;
    // ...
    listmenuitem1.wID = /* the ID you want to see in processing WM_COMMAND */;
    // ...
    InsertMenuItem( listitemmenu, 0, true, &listmenuitem1 ); //insert menu item
    

    附:你也可以在TrackPopupMenuEx中指定TPM_RETURNCMD,这样返回值就是被选中的item ID

    【讨论】:

    • TPM_RETURNCMD 标志使 WM_COMMAND 绕过我的对话过程...我以前在 Windows 过程中尝试过这个,并且对为什么 WM_COMMAND 不起作用而摸不着头脑。我只是尝试添加一个 ID ......不幸的是没有工作。 WM_COMMAND 仍未到达对话过程。
    • @Joshua:对不起。我几年前做过这样的事情,不记得所有细节。我可以建议使用 winspy 来查看窗口实际接收到哪些消息。此外,您谈论的是对话框过程,而不是实际的窗口过程 (DlgProc)。也许它决定不为WM_COMMAND 调用您的对话过程(尽管这不太可能)。无论如何,使用 winspy 通常会有所帮助。祝你好运
    • 感谢您的帮助。我会考虑使用 Spy++。
    • Wow Spy++ 非常强大,但它并没有真正帮助我。我看到 WM_COMMAND 消息从我的 ListControl HWND 发布,但我看不到它被发布到哪里...
    【解决方案3】:

    我想出了一个解决方案,但它有点像贫民窟的解决方法。

    我在消息循环中处理它,而不是在无法接收的对话过程中处理WM_COMMAND

    if( !IsDialogMessage( hwndListDialog, &msg ) )
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    } else {
        if( WM_COMMAND == msg.message )
        {
            switch( LOWORD( msg.wParam ) )
            {
            case 200:
                break;
            case 201:
                break;
            case 202:
                break;
            case 203:
                break;
            }
        }
    }
    

    我仍然希望有人可以帮助我在我的对话过程中获得WM_COMMAND(特别是因为来自其他对话控件的WM_COMMAND 正在到达对话过程),但这有助于我暂时前进。

    【讨论】:

      【解决方案4】:

      在处理 WM_COMMAND 时,您的开关不应该使用 wParam 而不是 lParam 吗?对于菜单,wParm 的高位字为 0,菜单 ID 在 wParam 的低位字中。正如其他人所说,您还应该将 ListControl 替换为对话框的句柄,以便在 TrackPopupMenu 中接收消息。

      【讨论】:

      • 我在发布这个问题后不久就修复了 wParam 问题。不过谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-31
      • 2012-09-30
      • 1970-01-01
      • 2012-09-07
      相关资源
      最近更新 更多