使用命令范围进行动态菜单 [英] use command range for dynamic menu

查看:65
本文介绍了使用命令范围进行动态菜单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个非常基本的问题,但是由于新手不了解原因,基本上我想在树形控件上弹出菜单,在树形控件上单击鼠标右键,将弹出一个菜单,而在此菜单的基础上,其他功能将继续进行.为此,我使用了以下代码,

This may be very basic question but as newbie don't understand the reason,Basically i want popup menu on tree control like,On right click of tree control one menu will pop up and on basic of this menu other functionality proceed.For that purpose i used following code,

在.h文件中,

#define NEW_RELAY_MENU_START                    WM_USER + 1
#define NEW_RELAY_MENU_END                  WM_USER + 256

.cpp文件中的

BEGIN_MESSAGE_MAP(CCtrlModDefDlgTree, CTreeCtrl)
    ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelChangedTreeCtrl)
    ON_NOTIFY_REFLECT(NM_RCLICK, &CCtrlModDefDlgTree::OnNMRClick)
    ON_COMMAND_RANGE(NEW_RELAY_MENU_START,NEW_RELAY_MENU_END,CCtrlModDefDlgTree::OnNewMenu)
END_MESSAGE_MAP()

CCtrlModDefDlgTree::CCtrlModDefDlgTree()
{
    NumberOfRelays.RemoveAll();
    NumberOfRelays.Add(L"MENU1");
    NumberOfRelays.Add(L"MENU2");
    NumberOfRelays.Add(L"MENU3");
    NumberOfRelays.Add(L"MENU4");
    NumberOfRelays.Add(L"MENU5);
    NumberOfRelays.Add(L"MENU6");   
}
void CCtrlModDefDlgTree::OnNMRClick(NMHDR *pNMHDR, LRESULT *pResult)
{
    // TODO: Add your control notification handler code here
     /* Get the cursor position for this message */ 
    DWORD dwPos = GetMessagePos(); 
    /* Convert the co-ords into a CPoint structure */ 
    CPoint pt( GET_X_LPARAM( dwPos ), GET_Y_LPARAM ( dwPos ) ); 
    CPoint spt; 
    spt = pt; 
    /* convert to screen co-ords for the hittesting to work */ 
    ScreenToClient( &spt ); 
    UINT test; 
    HTREEITEM hti = HitTest( spt, &test ); 
    if ( hti != NULL  ) 
    { 
            /* Is the click atcually *on* the item? */ 
            if ( test & TVHT_ONITEM ) 
            { 
                    /* Do the normal context menu stuff */ 
                    ShowPopupMenu(  pt ); 
            } 
    } 
    *pResult = 0; 
}
void CCtrlModDefDlgTree::ShowPopupMenu( CPoint& point )
{
        if (point.x == -1 && point.y == -1)
        {
            //keystroke invocation
            CRect rect;
            GetClientRect(rect);
            ClientToScreen(rect);
            point = rect.TopLeft();
            point.Offset(5, 5);
        }

        //create a menu object for main menu
        CMenu *menu    = new CMenu();
        menu->CreatePopupMenu();

        //another menu object for submenu
        CMenu *subMenu = new CMenu();
        subMenu->CreatePopupMenu();
        for(int __index = 0;__index<NumberOfRelays.GetCount();__index++)
        {
            subMenu->AppendMenu(MF_STRING, NEW_RELAY_MENU_START+__index, NumberOfRelays.ElementAt(__index));
        }
        //append submenu to menu
        menu->AppendMenu(MF_POPUP|MF_STRING, (UINT)subMenu->m_hMenu,  _T("New Menu") );
        ASSERT(menu != NULL);
        CWnd* pWndPopupOwner = this;
        while (pWndPopupOwner->GetStyle() & WS_CHILD)
            pWndPopupOwner = pWndPopupOwner->GetParent();
        menu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
            pWndPopupOwner);
}

void CCtrlModDefDlgTree::OnNewMenu(UINT nID)
{
}

但是我的OnNewMenu()函数没有在菜单单击时调用.即使默认情况下所有菜单都处于启用状态,我在做什么错呢?

But my OnNewMenu() function is not called on menu click.Even all menus are by default enable.What i am doing wrong?

推荐答案

您已经将命令范围添加到树控件的消息映射中,但是没有将树控件用作菜单的所有者窗口.

You've added the command range to the message map for the tree control, but you're not using the tree control as the owner window for the menu.

CWnd* pWndPopupOwner = this;
while (pWndPopupOwner->GetStyle() & WS_CHILD)
    pWndPopupOwner = pWndPopupOwner->GetParent();

这将找到顶层窗口并将其用作弹出窗口的所有者,这意味着来自弹出窗口的WM_COMMAND消息将转到顶层窗口,而不是树.您需要将命令范围添加到该窗口的消息映射中.

This will find the top-level window and use it as the popup's owner, which means the WM_COMMAND messages from the popup will go to the top-level window rather than the tree. You need to add the command range to that window's message map.

或者,您可以将TPM_RETURNCMD标志与TrackPopupMenu一起使用,这将返回选定的命令ID,然后自己调用OnNewMenu()函数:

Alternatively, you can use the TPM_RETURNCMD flag with TrackPopupMenu which will return the selected command ID, and then invoke your OnNewMenu() function yourself:

int iID = menu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON | TPM_RETURNCMD, 
            point.x, point.y, pWndPopupOwner);
if (iID) OnNewMenu(iID);

这篇关于使用命令范围进行动态菜单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆