对话程序未收到WM_COMMAND

时间:2012-03-11 18:14:46

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

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

我在消息循环中放了一个if语句来检查WM_COMMAND,它正在注册但没有被发送到我的Dialog过程。

是的,我正在使用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;

4 个答案:

答案 0 :(得分:1)

我相信(虽然不记得确切,这是很久以前......)问题是你没有为菜单项指定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

P.S。您也可以在TPM_RETURNCMD中指定TrackPopupMenuEx,以便返回值为所选的商品ID

答案 1 :(得分:1)

来自the documentation for TrackPopupMenuEx

  

hwnd [in]

     

类型:HWND

     

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

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

答案 2 :(得分:0)

我想出了一个解决方案,但这是一种解决方法。

我没有在Dialog Proc中处理无法接收的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到达Dialog Proc),但这有助于我暂时前进。 / p>

答案 3 :(得分:0)

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