刚刚学习了一个如何实现带下拉菜单的工具栏按钮(DropDownList Button),发现并不难,但是要设置风格,定义消息处理函数等,使用起来有点繁琐,我将其封装起来,用起来就方便多了!其中一个关键是消息反射!
使用方法:
建立SDI(或MDI)项目,添加CToolBarEx类的头文件与现实文件到项目中,主窗口原有的工具栏是CToolBar对象m_wndToolBar,将CToolBar改为CToolBarEx.
在CMainFrame的OnCreate(...)函数尾添加
m_wndToolBar.AddDropDownBtn(ID_BUTTON,ID_MENU);
ID_BUTTON:工具栏要有下拉菜单的按钮ID,如ID_FILE_NEW,
ID_MENU:下拉菜单ID,如IDR_MAINFRAME
然后运行即可实现目标!
特别说明:这是新手级文章
ToolBarEx.h文件#include <afxtempl.h>
typedef struct tagDROPDOWNLIST
{
UINT nIDButton;
UINT nIDMenu;
}DROPDOWNLIST;
class CToolBarEx : public CToolBar
{
DECLARE_DYNAMIC(CToolBarEx)public:
CToolBarEx();
virtual ~CToolBarEx();
protected:
afx_msg void OnDropDownBtn( NMHDR * pNotifyStruct, LRESULT * result );
DECLARE_MESSAGE_MAP()
protected:
BOOL m_bDropDownStyle;
//下拉菜单列表
CArray<DROPDOWNLIST,DROPDOWNLIST> m_DDBtnArray;
public:
void AddDropDownBtn(UINT nIDBUTTON, UINT nIDMENU);
void RemoveDropDownBtn(UINT nIDBUTTON);
};
ToolBarEx.cpp : 实现文件#include "stdafx.h"
#include "ToolBarEx.h"// CToolBarEx
IMPLEMENT_DYNAMIC(CToolBarEx, CToolBar)
CToolBarEx::CToolBarEx()
{
m_bDropDownStyle=FALSE;
}
CToolBarEx::~CToolBarEx()
{
m_DDBtnArray.RemoveAll();
}
BEGIN_MESSAGE_MAP(CToolBarEx, CToolBar)
//消息反射
ON_NOTIFY_REFLECT(TBN_DROPDOWN,OnDropDownBtn)
END_MESSAGE_MAP()
// CToolBarEx 消息处理程序
void CToolBarEx::OnDropDownBtn( NMHDR * pNotifyStruct, LRESULT * result )
{
LPNMTOOLBAR pnmtb=(LPNMTOOLBAR)pNotifyStruct;
UINT nIDMenu=NULL;
//
for(int i=0;i<m_DDBtnArray.GetCount();i++)
if(((DROPDOWNLIST)m_DDBtnArray[i]).nIDButton==pnmtb->iItem)
nIDMenu=((DROPDOWNLIST)m_DDBtnArray[i]).nIDMenu;
if(!nIDMenu)
return;
CMenu menu;
menu.LoadMenu(nIDMenu);
CMenu* pPopup = menu.GetSubMenu(0);
ASSERT(pPopup);
CRect rc;
SendMessage(TB_GETRECT, pnmtb->iItem, (LPARAM)&rc);
ClientToScreen(&rc);
pPopup->TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_VERTICAL,
rc.left, rc.bottom, this, &rc);
}
void CToolBarEx::AddDropDownBtn(UINT nIDBUTTON, UINT nIDMENU)
{
if(!m_bDropDownStyle)
{
DWORD dwExStyle = TBSTYLE_EX_DRAWDDARROWS;
GetToolBarCtrl().SendMessage(TB_SETEXTENDEDSTYLE, 0, (LPARAM)dwExStyle);
m_bDropDownStyle=TRUE;
}
DROPDOWNLIST DropdownBtn={nIDBUTTON,nIDMENU};
DWORD dwStyle =GetButtonStyle(CommandToIndex(nIDBUTTON));
dwStyle |= TBSTYLE_DROPDOWN;
SetButtonStyle(CommandToIndex(nIDBUTTON), dwStyle);
m_DDBtnArray.Add(DropdownBtn);
}
void CToolBarEx::RemoveDropDownBtn(UINT nIDBUTTON)
{
for(int i=0;i<m_DDBtnArray.GetCount();i++)
if(((DROPDOWNLIST)m_DDBtnArray[i]).nIDButton==nIDBUTTON)
{
DWORD dwStyle =GetButtonStyle(CommandToIndex(nIDBUTTON));
dwStyle &=~TBSTYLE_DROPDOWN;
SetButtonStyle(CommandToIndex(nIDBUTTON), dwStyle);
m_DDBtnArray.RemoveAt(i);
}
if(m_DDBtnArray.IsEmpty())
{
DWORD dwExStyle =NULL;
GetToolBarCtrl().SendMessage(TB_SETEXTENDEDSTYLE, 0, (LPARAM)dwExStyle);
m_bDropDownStyle=FALSE;
}
}