MFC提供的工具栏具有拖放功能,可以把工具栏改造成一个菜单栏,这样菜单栏就具有拖放功能了。
把工具栏按钮的标题设置成顶级菜单项的标题,然后在点击工具栏按钮的消息响应中弹出子菜单即可。
在CMainFrame中添加 CToolBar m_menu,用来保存菜单。
在OnCreate中创造这个菜单栏
m_menu.CreateEx(this);
m_menu.EnableDocking(CBRS_ALIGN_ANY);
m_menu.EnableDocking(CBRS_ALIGN_ANY);
CMenu menu;
menu.LoadMenu(IDR_MAINFRAME);
int nCount = menu.GetMenuItemCount();
UINT * array = new UINT[nCount];
menu.LoadMenu(IDR_MAINFRAME);
int nCount = menu.GetMenuItemCount();
UINT * array = new UINT[nCount];
CString text;
for (int n = 0; n<nCount;n++)
{
array[n]=ID_BUTTON1 +n;
}
m_menu.SetButtons(array,nCount); //设置工具栏按钮
for (int i=0;i<nCount;i++)
{
menu.GetMenuString(i,text,MF_BYPOSITION);
m_menu.SetButtonText(i,text); //设置标题为菜单项标题
m_menu.SetButtonStyle(i,TBSTYLE_DROPDOWN); //设置按钮模式为下拉模式
}
for (int n = 0; n<nCount;n++)
{
array[n]=ID_BUTTON1 +n;
}
m_menu.SetButtons(array,nCount); //设置工具栏按钮
for (int i=0;i<nCount;i++)
{
menu.GetMenuString(i,text,MF_BYPOSITION);
m_menu.SetButtonText(i,text); //设置标题为菜单项标题
m_menu.SetButtonStyle(i,TBSTYLE_DROPDOWN); //设置按钮模式为下拉模式
}
delete array;
menu.DestroyMenu();
menu.DestroyMenu();
m_menu.GetToolBarCtrl().SetBitmapSize(CSize(0,0));
m_menu.GetToolBarCtrl().SetButtonSize(CSize(70,22));
SetMenu(NULL); //取消原来的菜单
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_menu);//停靠菜单栏
m_menu.GetToolBarCtrl().SetButtonSize(CSize(70,22));
SetMenu(NULL); //取消原来的菜单
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_menu);//停靠菜单栏
重写响应下拉消息的函数,在按钮下方弹出子菜单
类声明中: afx_msg void OnToolbarDropDown(NMTOOLBAR* pnmh, LRESULT* plRes);
消息映射中: ON_NOTIFY(TBN_DROPDOWN,AFX_IDW_TOOLBAR,OnToolbarDropDown)
类实现中:
void CMainFrame::OnToolbarDropDown(NMTOOLBAR* pnmtb, LRESULT* plRes)
{
CWnd* pWnd = &m_menu;
UINT nID = IDR_MAINFRAME;
{
CWnd* pWnd = &m_menu;
UINT nID = IDR_MAINFRAME;
CMenu menu;
menu.LoadMenu(nID);
CMenu* pPop = menu.GetSubMenu(pnmtb->iItem-ID_BUTTON1); //获得子菜单
CRect rc;
m_menu.GetToolBarCtrl().GetItemRect(pnmtb->iItem-ID_BUTTON1,rc); //获得按钮位置
pWnd->ClientToScreen(&rc);
pPop->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON
menu.LoadMenu(nID);
CMenu* pPop = menu.GetSubMenu(pnmtb->iItem-ID_BUTTON1); //获得子菜单
CRect rc;
m_menu.GetToolBarCtrl().GetItemRect(pnmtb->iItem-ID_BUTTON1,rc); //获得按钮位置
pWnd->ClientToScreen(&rc);
pPop->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON
|TPM_VERTICAL,rc.left,rc.bottom,this,&rc); //弹出子菜单
}
}
此时的菜单栏上的按钮还是灰色不可用状态,给他们编写一个空的点击消息函数,使其变为可用状态
类声明中: afx_msg void OnNull();
消息映射中: ON_COMMAND_RANGE(ID_BUTTON1,ID_BUTTON1+4,OnNull)
类实现中: void CMainFrame::OnNull() {}
此时就完成了一个可以拖放的菜单栏了。