读书人

《急》怎么动态添加工具栏下拉菜单的菜

发布时间: 2011-12-30 23:30:45 作者: rapoo

《急!在线等!》如何动态添加工具栏下拉菜单的菜单项?
我先在资源中创建了个新的菜单资源,IDR_MENU1,添加第一个POP_UP子菜单,caption为TEST,不添加任何菜单项(菜单项打算动态添加)。
然后代码如下:CMenu menu;
menu.LoadMenu( IDR_MENU1 );
menu.AppendMenu( MF_STRING, 10000, "1111" );

但是这样做CMenu *pm;
pm = menu.GetSubMenu(0);
pm为空。

应该动态添加这个菜单项呢?郁闷。

[解决办法]
CMenu* menu_bar = AfxGetMainWnd()->GetMenu();
CMenu* file_menu = menu_bar->GetSubMenu(0);
[解决办法]
一个顶层菜单中必须要有弹出式子菜单,而且这个子菜单中必须要有菜单项,如果你不在子菜单中添加项目,那么所获取的子菜单对象就是空的。以下是为工具栏添加下拉菜单的步骤:
可以分为几下几步:
1为工具栏显示出下拉按钮,必须设置它扩展属性TBSTYLE_EX_DRAWDDARROWS
2为了让某个按钮能够悬挂菜单,必须添加此按钮的TBSTYLE_DROPDOWN,表示此按钮是一个下拉式按钮
3在工具栏的TTN_DROPDOWN消息中添加下拉菜单的代码,关于工具栏的通知消息是一个OnNotify消息,它的LPARAM是一个指向NMTOOLBARX结构的指针

首先在OnInitDialog语句的最后添加:
m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
UINT btnstyle=m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_FILE_SAVE));
btnstyle|=TBSTYLE_DROPDOWN;
m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_FILE_SAVE),btnstyle);
这几句是为了设置工具栏和按钮的属性

然后添加OnNotify消息映射,加入如下消息注册语句:
ON_NOTIFY(TBN_DROPDOWN,AFX_IDW_TOOLBAR,&CMainFrame::OnToolbarDropDown)
其中第一参数表示此消息此负责TBN_DROPDOWN消息的处理,第二个参数表示工具栏默认的ID号.

最后添加消息体:

C/C++ code
void CMainFrame::OnToolbarDropDown(NMHDR *pnmhdr, LRESULT *result){    UINT nID;    NMTOOLBAR* pToolBar=(NMTOOLBAR*)pnmhdr;    CRect rect;    switch(pToolBar->iItem)    {    case ID_FILE_SAVE:            {                CMenu menu;    menu.LoadMenu(IDR_MAINFRAME);    CMenu* sub=menu.GetSubMenu(0);    ClientToScreen(&rect);//将按钮的区域转化成屏幕区域    rect.OffsetRect(0,rect.bottom-rect.top);//将按钮区域下移一个按钮高度,确保下拉菜单下按钮下方展开.    sub->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_LEFTALIGN,rect.left,rect.top,this);//在屏幕坐标处展开菜单        nID=pToolBar->iItem;        rect=pToolBar->rcButton;            }        break;    default:        break;    }    }
[解决办法]
一旦资源浏览器的顶层菜单中添加弹出式菜单,你就必须为子菜单添加菜单项. 一个空的弹出式菜单的句柄是空值。
要么你从头开始创建整个菜单,以下是示例代码:
C/C++ code
CMenu memu;memu.CreateMenu();HMENU hmenu=CreatePopupMenu();    memu.AppendMenu(MF_POPUP,(UINT_PTR)hmenu,_T("文件"));CMenu* psubmenu=memu.GetSubMenu(memu.GetMenuItemCount()-1);    psubmenu->AppendMenu(MF_BYCOMMAND,123,_T("打开"));
[解决办法]
第2楼的那段代码写错了,改成:
C/C++ code
void CMainFrame::OnToolbarDropDown(NMHDR *pnmhdr, LRESULT *result){    UINT nID;    NMTOOLBAR* pToolBar=(NMTOOLBAR*)pnmhdr;    CRect rect;    switch(pToolBar->iItem)    {    case ID_FILE_SAVE:            {                        nID=pToolBar->iItem;       rect=pToolBar->rcButton;       CMenu menu;       menu.LoadMenu(IDR_MAINFRAME);       CMenu* sub=menu.GetSubMenu(0);       ClientToScreen(&rect);//将按钮的区域转化成屏幕区域        rect.OffsetRect(0,rect.bottom-rect.top);//将按钮区域下移一个按钮高度,确保下拉菜单下按钮下方展开.       sub->TrackPopupMenu(TPM_RIGHTBUTTON|TPM_LEFTALIGN,rect.left,rect.top,this);//在屏幕坐标处展开菜单            }        break;    default:        break;    }    } 

读书人网 >VC/MFC

热点推荐