|
刚刚学习了一个如何实现带下拉菜单的工具栏按钮(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; } } | |