00. 目录
01. 案例概述
本实例是对工具栏功能的扩充,可以将工具栏上按钮的并列项以菜单的形式显示,方便用户操作。运行程序,单击工具栏按钮旁边的下三角按钮,将弹出一个下拉菜单,如下图所示。
02. 开发环境
系统环境:Windows 10
开发环境:Visual Studio 2019
03. 关键技术
下三角按钮是通过CToolBar类的SetButtonStyle方法和CToolBarCtrl类的SetExtendedStyle方法实现的。
SetButtonStyle方法主要用来设置工具栏按钮的风格,语法如下:
void SetButtonStyle( int nIndex, UINT nStyle );
参数说明
nIndex:按钮的索引。
nStyle:按钮的风格。可以有以下取值。
TBBS_BUTTON:标准按钮。
TBBS_SEPARATOR:分隔线。
TBBS_CHECKBOX:复选风格。
TBBS_GROUP:按钮组。
TBBS_CHECKGROUP:复选按钮组。
SetExtendedStyle方法用于设置工具栏控件的扩展风格,语法如下:
DWORD SetExtendedStyle( DWORD dwExStyle ) const;
参数说明
dwExStyle:系统定义的工具栏控件风格,取值TBSTYLE_EX_DRAWDDARROWS,可以实现下三角按钮功能。
04. 程序设计
4.1 在OnCreate函数中针对创建的Toolbar获取到对应的按钮属性,并设置为具有下拉风格
//设置工具栏有下拉按钮
m_wndToolBar.GetToolBarCtrl().SetExtendedStyle(TBSTYLE_EX_DRAWDDARROWS);
//获得添加下拉按钮的工具栏打开按钮风格
DWORD dwStyle = m_wndToolBar.GetButtonStyle(m_wndToolBar.CommandToIndex(ID_FILE_OPEN));
//添加下拉按钮风格
dwStyle |= TBSTYLE_DROPDOWN;
m_wndToolBar.SetButtonStyle(m_wndToolBar.CommandToIndex(ID_FILE_OPEN), dwStyle);
4.2 创建你点击Toolbar上对应的按钮后需要下拉的菜单栏,插入新的Resouse:Menu,在这里我新建的Menu它的ID是ID_DRAW_LINE
4.3 在CMainFrame类的消息映射中(即MainFrm.cpp )加入下拉箭头的ID_DRAW_LINE消息映射
此消息映射需要手动添加,添加步骤
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_WM_CREATE()
ON_NOTIFY(TBN_DROPDOWN, AFX_IDW_TOOLBAR, OnToolbarDropDown)//此行即为新增的ON_NOTIFY消息映射
ON_COMMAND(ID_TEST_32771, &CMainFrame::OnTest32771)
ON_COMMAND(ID_TEST_32772, &CMainFrame::OnTest32772)
END_MESSAGE_MAP()
4.4 在MainFrame.h头文件中加入消息处理函数的声明:
afx_msg void OnToolbarDropDown(NMHDR* pnmhdr, LRESULT* plRes);
4.5 在MainFrame.cpp中实现消息处理函数和添加响应处理函数
// CMainFrame 消息处理程序
void CMainFrame::OnToolbarDropDown(NMHDR* pnmhdr, LRESULT* plRes)
{
LPNMTOOLBAR pnmh = reinterpret_cast<LPNMTOOLBAR>(pnmhdr);
CWnd* pWnd;
switch (pnmh->iItem)
{
case ID_FILE_OPEN:
pWnd = &m_wndToolBar;
break;
default:
//此处必须写return 否则在vs2019中会报错
return;
}
//pWnd = &m_wndToolBar;
CMenu menu;
//加载菜单资源
menu.LoadMenuW(ID_DRAW_LINE);
//获得子菜单
CMenu* pPopub = menu.GetSubMenu(0);
ASSERT(pPopub);
CRect rect;
//获得区域
pWnd->SendMessage(TB_GETRECT, pnmh->iItem, (LPARAM)&rect);
pWnd->ClientToScreen(&rect);
pPopub->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
rect.left, rect.bottom, this, &rect);
}
void CMainFrame::OnTest32771()
{
// TODO: 在此添加命令处理程序代码
MessageBox(TEXT("Release"));
}
void CMainFrame::OnTest32772()
{
// TODO: 在此添加命令处理程序代码
MessageBox(TEXT("Debug"));
}
05. 秘笈心法