用MFC创建菜单按钮 现在有不少的软件都有这样的一种界面效果:当用户单击某一个按钮之后,并不是简单地执行某种功能或弹出一个对话框,而是在按钮旁边弹出一个菜单,让用户作更详细地选择,这在某种程度上就代替了简单的对话框,而且较对话框更为“用户友好”。这样的按钮基本上有两种类型:在按钮上显示文字的和在按钮上显示箭头的,显示箭头常见的有向右的和向下的两种,还有向上的和向左的。图示为常见的风格,即向下的箭头和在按钮左下角弹出菜单。那么,我们在编程时如何实现这一功能呢? 我们知道,MFC中的CButton类有一个虚函数名叫DrawItem(),若在对话框模板中为控件指定了BS_OWNERDRAW风格,则在运行时将调用这个函数来画按钮,而CMenu类的成员函数TrackPopupMenu()则可以在屏幕的任何位置弹出菜单。由上得到启发,只要我们合理地使用这两个函数,就能创建出“菜单按钮”来。 下面的CMenuButton类封装了全部的这些功能,让我们先来看一下它的制作原理。 在取得了按钮的矩形区域之后,取其一个角落的值传递给TrackPopupMenu()函数即可实现弹出菜单,在TrackPopupMenu内部使用TPM_RETURNCMD标志可以得到用户选择的菜单的命令ID,以供进一步的处理;在重载了DrawItem()函数之后,我们可以在函数的内部使用CDC::DrawFrameControl()函数来画出基本的按钮外观,再在中间部位画一个箭头即可。箭头可以用Marlett字体来画。也许有人会担心,若果其他人的机器没装Marlett字体怎么办?其实,任何一台安装Windows的机器离开了Marlett字体都无法正常工作,先请看下图,这是Windows“系统工具”中自带的“字符映射表”。 看到最上面一行中的那几个箭头了吗?就是要把它们画在按钮上。等一等,另外的几个符号怎么也那么熟悉?这不就是几乎每个窗口上都有的“最小化”、“还原”、“关闭”和“最大化”按钮吗?不错,Windows正是使用这几个字符在标题栏上绘图的。其实,Windows中的最“标准”的画箭头的方法就是使用Marlett字体,无论是工具栏上的箭头还是组合框中的箭头,都是这样画出的。有时,在乱删了字体之后,组合框或工具栏的下拉箭头会变成数字6或者9,为什么?看到状态栏上的“击键值”了吗?——“6”,往右数,那个小一点的下箭头正好是——“9”。 下面是具体的制作过程。 首先,生成一个MFC AppWizard EXE 工程,最好是基于对话框的工程,当然,利用现有的工程也可以。 生成一个以CButton为基类的新类,名为CMenuButton,然后用ClassWizard为其添加两个成员函数:DrawItem()和PreSubclassWidnow();手工为CMenuButton类添加BOOL类型m_bDrawFocusRect成员变量,用于决定是否在按钮上画焦点矩形,添加SetDrawFocusRect()函数用于设置这个标志,默认为画焦点矩形;添加两个枚举类型的变量m_ArrowType和m_PopupPos,用于决定所画的箭头的类型和菜单弹出的位置。箭头可为右箭头、下箭头、小右箭头、小下箭头、上箭头和左箭头(参见本文开始处的图);菜单的弹出位置可以为按钮的左上角、右上角、左下角和右下角。最后手工添加两个函数,SetArrowType()和SetMenuPopupPos(),用于设置以上各种风格,其默值分别为画右箭头和在左下角弹出。 如果只需要菜单而不需要画箭头,只需置空BS_OWNERDRAW标志位即可,添加一个SetStyle()函数,用于设置是画箭头还是显示文本,其默认值是画箭头。 为方便处理按钮的BN_CLICKED通知消息,为CMenuButton类创建一个公有的成员函数On 下面是程序代码。 头文件: #if !defined(_EWAY_MEMUBUTTON_H__INCLUDED_) #define _EWAY_MEMUBUTTON_H__INCLUDED_ #if _MSC_VER >= 1000 #pragma on #endif // _MSC_VER >= 1000 // MenuButton.h : header file // class CMenuButton : public CButton { public: CMenuButton(); virtual ~CMenuButton(); DECLARE_DYNAMIC( CMenuButton ) enum ArrowType { arrowRight,//向右的箭头; arrowDown, //向下的箭头; arrowSmallRight, //向右的小箭头; arrowSmallDown, //向下的小箭头; arrowUp, //向上的箭头; arrowLeft//向左的箭头; }m_ArrowType; enum PopupPos { //名称为TopLeft等等,遵守英文习惯; posTopLeft, //左上角; posBottomLeft, //左下角; posTopRight, //右上角; posBottomRight, //右下角; }m_PopupPos; virtual UINT On void SetArrowType(CMenuButton::ArrowType type=CMenuButton::arrowRight); void SetDrawFocusRect(BOOL bDrawFocusRect=TRUE); void SetMenuPopupPos(CMenuButton::PopupPos pos=CMenuButton::posBottomLeft); void SetStyle(BOOL bDrawArrow=TRUE); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMenuButton) public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); protected: virtual void PreSubclassWindow(); //}}AFX_VIRTUAL protected: BOOL m_bDrawFocusRect; //{{AFX_MSG(CMenuButton) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(_EWAY_MEMUBUTTON_H__INCLUDED_) 实现文件: // MenuButton.cpp : implementation file // #include "stdafx.h" #include "MenuButtonTest.h" #include "MenuButton.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMenuButton IMPLEMENT_DYNAMIC( CMenuButton, CButton ) CMenuButton::CMenuButton() { SetArrowType(); SetDrawFocusRect(); SetMenuPopupPos(); } CMenuButton::~CMenuButton() { }
BEGIN_MESSAGE_MAP(CMenuButton, CButton) //{{AFX_MSG_MAP(CMenuButton) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMenuButton message handlers void CMenuButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { //使用FromeHandle()创建临时的对象,若使用Attach()则必需在最后使用Detach() CDC *pDC= CDC::FromHandle(lpDrawItemStruct->hDC); //得到画笔的颜色; CPen pen; if( (lpDrawItemStruct->itemState&ODS_DISABLED) ) { pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_GRAYTEXT) ); } else { pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT) ); } CPen * pOldPen = pDC->SelectObject(&pen); CFont font; font.CreateFont(12, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_SWISS, "Marlett"); CFont * pOldFont=pDC->SelectObject(&font); CSize size=pDC->GetTextExtent("4",1); //决定箭头的样子,具体的值可在“字符映射表”中查得; CString strArrow; switch (m_ArrowType) { case CMenuButton::arrowRight: strArrow="4"; break; case CMenuButton::arrowDown: strArrow="6"; break; case CMenuButton::arrowSmallRight: strArrow="8"; break; case CMenuButton::arrowSmallDown: strArrow="9"; break; case CMenuButton::arrowUp: strArrow="5"; break; case CMenuButton::arrowLeft: strArrow="3"; break; default: ASSERT(FALSE); } //计算座标值,用于绘制箭头; int x=(lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left-size.cx)/2; int y=(lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top-size.cy)/2; //画按钮与箭头; if( (lpDrawItemStruct->itemState&ODS_SELECTED) ) { pDC->DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH|DFCS_PUSHED); //在按钮被按下时,上面的字符要有一个向右和向下的偏移; pDC->TextOut(++x,++y,strArrow); } else { pDC->DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH); pDC->TextOut(x,y,strArrow); } //如果需要,画焦点矩形; if( (lpDrawItemStruct->itemState&ODS_FOCUS) && m_bDrawFocusRect) { CRect rectFocus(lpDrawItemStruct->rcItem); rectFocus.DeflateRect(3,3); //看起来比较接近的值; pDC->DrawFocusRect(rectFocus); } //仅将对象选回即可,不必调用DeleteTempMap(); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldFont); } UINT CMenuButton::On { CMenu menu; //装载菜单; VERIFY(menu.LoadMenu(nIDMenuResource) ); //得到子菜单; CMenu *pPopup = menu.GetSubMenu(nSubMenu);//默认为第一组子菜单; ASSERT(pPopup != NULL); CRect rect; GetWindowRect(rect); POINT point; //决定弹出菜单的位置; switch (m_PopupPos) { case CMenuButton::posTopLeft://左上角; point.x=rect.left; point.y=rect.top; break; case CMenuButton::posBottomLeft://左下角; point.x=rect.left; point.y=rect.bottom; break; case CMenuButton::posTopRight://右上角; point.x=rect.right; point.y=rect.top; break; case CMenuButton::posBottomRight://右下角; point.x=rect.right; point.y=rect.bottom; break; default: ASSERT(FALSE); } //弹出菜单; UINT nMenuSel = pPopup->TrackPopupMenu((TPM_LEFTALIGN|TPM_LEFTBUTTON |TPM_NONOTIFY |TPM_RETURNCMD),point.x, point.y, this); pPopup->DestroyMenu(); //返回被选择的菜单的ID,如果无任何有效的选择,将返回0; return nMenuSel; } void CMenuButton::PreSubclassWindow() { CButton::PreSubclassWindow(); //默认值:加入BS_OWNERDRAW风格; ModifyStyle(0,BS_OWNERDRAW); } void CMenuButton::SetArrowType(CMenuButton::ArrowType type) { m_ArrowType=type; } void CMenuButton::SetDrawFocusRect(BOOL bDrawFocusRect) { m_bDrawFocusRect=bDrawFocusRect; } void CMenuButton::SetMenuPopupPos(CMenuButton::PopupPos pos) { m_PopupPos=pos; } void CMenuButton::SetStyle(BOOL bDrawArrow) { if(bDrawArrow) { ModifyStyle(0,BS_OWNERDRAW,SWP_NOMOVE|SWP_NOZORDER| SWP_NOSIZE); } else { ModifyStyle(BS_OWNERDRAW,0,SWP_NOMOVE|SWP_NOZORDER| SWP_NOSIZE); } } 要使用这个类,为对话框添加CMenuButton类型的按钮成员变量,若需改变默认风格,则可在On void CMenuButtonTestDlg::On { UINT nSel=m_btnTest.On switch(nSel) { case ID_APP_EXIT: SendMessage(WM_CLOSE,0,0); break; case ID_POPUP_ITEM1: AfxMessageBox("您选择了第一项!"); break; case ID_POPUP_ITEM2: AfxMessageBox("您选择了第二项!"); break; case ID_POPUP_ITEM3: AfxMessageBox("您选择了第三项!"); break; default: //Do nothing; ; } } 所用菜单的资源描述如下,外观可参见文首的图。 IDR_POPUP MENU DISCARDABLE BEGIN POPUP "_POPUP_" BEGIN MENUITEM "第一项", ID_POPUP_ITEM1 MENUITEM "第二项", ID_POPUP_ITEM2 MENUITEM "第三项", ID_POPUP_ITEM3 MENUITEM SEPARATOR MENUITEM "退出(&X)", ID_APP_EXIT END END BOOL CMenuButtonTestDlg::On { CDialog::On //因为这几个值都是默认值,所以注释掉,仅为了演示用法; //m_btnTest.SetDrawFocusRect(TRUE); //m_btnTest.ArrowType (CMenuButton::arrowRight); //m_btnTest.SetStyle(TRUE); //m_btnTest.SetMenuPopupPos(CMenuButton::posBottomLeft); return TRUE; } 值得补充说明的是,使用CMenuButton类的时候,并不一定需要在对话框模板中为按钮指定BS_OWNERDRAW风格,因为在缺省情况下,CMenuButton类的PreSubclassWindow()函数中已经自动加入了这一风格。
阅读(283)|
评论(0)
|
喜欢
推荐
转载
最近读者
用MFC创建菜单按钮 现在有不少的软件都有这样的一种界面效果:当用户单击某一个按钮之后,并不是简单地执行某种功能或弹出一个对话框,而是在按钮旁边弹出一个菜单,让用户作更详细地选择,这在某种程度上就代替了简单的对话框,而且较对话框更为“用户友好”。这样的按钮基本上有两种类型:在按钮上显示文字的和在按钮上显示箭头的,显示箭头常见的有向右的和向下的两种,还有向上的和向左的。图示为常见的风格,即向下的箭头和在按钮左下角弹出菜单。那么,我们在编程时如何实现这一功能呢? 我们知道,MFC中的CButton类有一个虚函数名叫DrawItem(),若在对话框模板中为控件指定了BS_OWNERDRAW风格,则在运行时将调用这个函数来画按钮,而CMenu类的成员函数TrackPopupMenu()则可以在屏幕的任何位置弹出菜单。由上得到启发,只要我们合理地使用这两个函数,就能创建出“菜单按钮”来。 下面的CMenuButton类封装了全部的这些功能,让我们先来看一下它的制作原理。 在取得了按钮的矩形区域之后,取其一个角落的值传递给TrackPopupMenu()函数即可实现弹出菜单,在TrackPopupMenu内部使用TPM_RETURNCMD标志可以得到用户选择的菜单的命令ID,以供进一步的处理;在重载了DrawItem()函数之后,我们可以在函数的内部使用CDC::DrawFrameControl()函数来画出基本的按钮外观,再在中间部位画一个箭头即可。箭头可以用Marlett字体来画。也许有人会担心,若果其他人的机器没装Marlett字体怎么办?其实,任何一台安装Windows的机器离开了Marlett字体都无法正常工作,先请看下图,这是Windows“系统工具”中自带的“字符映射表”。 看到最上面一行中的那几个箭头了吗?就是要把它们画在按钮上。等一等,另外的几个符号怎么也那么熟悉?这不就是几乎每个窗口上都有的“最小化”、“还原”、“关闭”和“最大化”按钮吗?不错,Windows正是使用这几个字符在标题栏上绘图的。其实,Windows中的最“标准”的画箭头的方法就是使用Marlett字体,无论是工具栏上的箭头还是组合框中的箭头,都是这样画出的。有时,在乱删了字体之后,组合框或工具栏的下拉箭头会变成数字6或者9,为什么?看到状态栏上的“击键值”了吗?——“6”,往右数,那个小一点的下箭头正好是——“9”。 下面是具体的制作过程。 首先,生成一个MFC AppWizard EXE 工程,最好是基于对话框的工程,当然,利用现有的工程也可以。 生成一个以CButton为基类的新类,名为CMenuButton,然后用ClassWizard为其添加两个成员函数:DrawItem()和PreSubclassWidnow();手工为CMenuButton类添加BOOL类型m_bDrawFocusRect成员变量,用于决定是否在按钮上画焦点矩形,添加SetDrawFocusRect()函数用于设置这个标志,默认为画焦点矩形;添加两个枚举类型的变量m_ArrowType和m_PopupPos,用于决定所画的箭头的类型和菜单弹出的位置。箭头可为右箭头、下箭头、小右箭头、小下箭头、上箭头和左箭头(参见本文开始处的图);菜单的弹出位置可以为按钮的左上角、右上角、左下角和右下角。最后手工添加两个函数,SetArrowType()和SetMenuPopupPos(),用于设置以上各种风格,其默值分别为画右箭头和在左下角弹出。 如果只需要菜单而不需要画箭头,只需置空BS_OWNERDRAW标志位即可,添加一个SetStyle()函数,用于设置是画箭头还是显示文本,其默认值是画箭头。 为方便处理按钮的BN_CLICKED通知消息,为CMenuButton类创建一个公有的成员函数On 下面是程序代码。 头文件: #if !defined(_EWAY_MEMUBUTTON_H__INCLUDED_) #define _EWAY_MEMUBUTTON_H__INCLUDED_ #if _MSC_VER >= 1000 #pragma on #endif // _MSC_VER >= 1000 // MenuButton.h : header file // class CMenuButton : public CButton { public: CMenuButton(); virtual ~CMenuButton(); DECLARE_DYNAMIC( CMenuButton ) enum ArrowType { arrowRight,//向右的箭头; arrowDown, //向下的箭头; arrowSmallRight, //向右的小箭头; arrowSmallDown, //向下的小箭头; arrowUp, //向上的箭头; arrowLeft//向左的箭头; }m_ArrowType; enum PopupPos { //名称为TopLeft等等,遵守英文习惯; posTopLeft, //左上角; posBottomLeft, //左下角; posTopRight, //右上角; posBottomRight, //右下角; }m_PopupPos; virtual UINT On void SetArrowType(CMenuButton::ArrowType type=CMenuButton::arrowRight); void SetDrawFocusRect(BOOL bDrawFocusRect=TRUE); void SetMenuPopupPos(CMenuButton::PopupPos pos=CMenuButton::posBottomLeft); void SetStyle(BOOL bDrawArrow=TRUE); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CMenuButton) public: virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct); protected: virtual void PreSubclassWindow(); //}}AFX_VIRTUAL protected: BOOL m_bDrawFocusRect; //{{AFX_MSG(CMenuButton) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; //{{AFX_INSERT_LOCATION}} // Microsoft Developer Studio will insert additional declarations immediately before the previous line. #endif // !defined(_EWAY_MEMUBUTTON_H__INCLUDED_) 实现文件: // MenuButton.cpp : implementation file // #include "stdafx.h" #include "MenuButtonTest.h" #include "MenuButton.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CMenuButton IMPLEMENT_DYNAMIC( CMenuButton, CButton ) CMenuButton::CMenuButton() { SetArrowType(); SetDrawFocusRect(); SetMenuPopupPos(); } CMenuButton::~CMenuButton() { }
BEGIN_MESSAGE_MAP(CMenuButton, CButton) //{{AFX_MSG_MAP(CMenuButton) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMenuButton message handlers void CMenuButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { //使用FromeHandle()创建临时的对象,若使用Attach()则必需在最后使用Detach() CDC *pDC= CDC::FromHandle(lpDrawItemStruct->hDC); //得到画笔的颜色; CPen pen; if( (lpDrawItemStruct->itemState&ODS_DISABLED) ) { pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_GRAYTEXT) ); } else { pen.CreatePen(PS_SOLID, 0, ::GetSysColor(COLOR_BTNTEXT) ); } CPen * pOldPen = pDC->SelectObject(&pen); CFont font; font.CreateFont(12, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH|FF_SWISS, "Marlett"); CFont * pOldFont=pDC->SelectObject(&font); CSize size=pDC->GetTextExtent("4",1); //决定箭头的样子,具体的值可在“字符映射表”中查得; CString strArrow; switch (m_ArrowType) { case CMenuButton::arrowRight: strArrow="4"; break; case CMenuButton::arrowDown: strArrow="6"; break; case CMenuButton::arrowSmallRight: strArrow="8"; break; case CMenuButton::arrowSmallDown: strArrow="9"; break; case CMenuButton::arrowUp: strArrow="5"; break; case CMenuButton::arrowLeft: strArrow="3"; break; default: ASSERT(FALSE); } //计算座标值,用于绘制箭头; int x=(lpDrawItemStruct->rcItem.right-lpDrawItemStruct->rcItem.left-size.cx)/2; int y=(lpDrawItemStruct->rcItem.bottom-lpDrawItemStruct->rcItem.top-size.cy)/2; //画按钮与箭头; if( (lpDrawItemStruct->itemState&ODS_SELECTED) ) { pDC->DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH|DFCS_PUSHED); //在按钮被按下时,上面的字符要有一个向右和向下的偏移; pDC->TextOut(++x,++y,strArrow); } else { pDC->DrawFrameControl(&lpDrawItemStruct->rcItem, DFC_BUTTON, DFCS_BUTTONPUSH); pDC->TextOut(x,y,strArrow); } //如果需要,画焦点矩形; if( (lpDrawItemStruct->itemState&ODS_FOCUS) && m_bDrawFocusRect) { CRect rectFocus(lpDrawItemStruct->rcItem); rectFocus.DeflateRect(3,3); //看起来比较接近的值; pDC->DrawFocusRect(rectFocus); } //仅将对象选回即可,不必调用DeleteTempMap(); pDC->SelectObject(pOldPen); pDC->SelectObject(pOldFont); } UINT CMenuButton::On { CMenu menu; //装载菜单; VERIFY(menu.LoadMenu(nIDMenuResource) ); //得到子菜单; CMenu *pPopup = menu.GetSubMenu(nSubMenu);//默认为第一组子菜单; ASSERT(pPopup != NULL); CRect rect; GetWindowRect(rect); POINT point; //决定弹出菜单的位置; switch (m_PopupPos) { case CMenuButton::posTopLeft://左上角; point.x=rect.left; point.y=rect.top; break; case CMenuButton::posBottomLeft://左下角; point.x=rect.left; point.y=rect.bottom; break; case CMenuButton::posTopRight://右上角; point.x=rect.right; point.y=rect.top; break; case CMenuButton::posBottomRight://右下角; point.x=rect.right; point.y=rect.bottom; break; default: ASSERT(FALSE); } //弹出菜单; UINT nMenuSel = pPopup->TrackPopupMenu((TPM_LEFTALIGN|TPM_LEFTBUTTON |TPM_NONOTIFY |TPM_RETURNCMD),point.x, point.y, this); pPopup->DestroyMenu(); //返回被选择的菜单的ID,如果无任何有效的选择,将返回0; return nMenuSel; } void CMenuButton::PreSubclassWindow() { CButton::PreSubclassWindow(); //默认值:加入BS_OWNERDRAW风格; ModifyStyle(0,BS_OWNERDRAW); } void CMenuButton::SetArrowType(CMenuButton::ArrowType type) { m_ArrowType=type; } void CMenuButton::SetDrawFocusRect(BOOL bDrawFocusRect) { m_bDrawFocusRect=bDrawFocusRect; } void CMenuButton::SetMenuPopupPos(CMenuButton::PopupPos pos) { m_PopupPos=pos; } void CMenuButton::SetStyle(BOOL bDrawArrow) { if(bDrawArrow) { ModifyStyle(0,BS_OWNERDRAW,SWP_NOMOVE|SWP_NOZORDER| SWP_NOSIZE); } else { ModifyStyle(BS_OWNERDRAW,0,SWP_NOMOVE|SWP_NOZORDER| SWP_NOSIZE); } } 要使用这个类,为对话框添加CMenuButton类型的按钮成员变量,若需改变默认风格,则可在On void CMenuButtonTestDlg::On { UINT nSel=m_btnTest.On switch(nSel) { case ID_APP_EXIT: SendMessage(WM_CLOSE,0,0); break; case ID_POPUP_ITEM1: AfxMessageBox("您选择了第一项!"); break; case ID_POPUP_ITEM2: AfxMessageBox("您选择了第二项!"); break; case ID_POPUP_ITEM3: AfxMessageBox("您选择了第三项!"); break; default: //Do nothing; ; } } 所用菜单的资源描述如下,外观可参见文首的图。 IDR_POPUP MENU DISCARDABLE BEGIN POPUP "_POPUP_" BEGIN MENUITEM "第一项", ID_POPUP_ITEM1 MENUITEM "第二项", ID_POPUP_ITEM2 MENUITEM "第三项", ID_POPUP_ITEM3 MENUITEM SEPARATOR MENUITEM "退出(&X)", ID_APP_EXIT END END BOOL CMenuButtonTestDlg::On { CDialog::On //因为这几个值都是默认值,所以注释掉,仅为了演示用法; //m_btnTest.SetDrawFocusRect(TRUE); //m_btnTest.ArrowType (CMenuButton::arrowRight); //m_btnTest.SetStyle(TRUE); //m_btnTest.SetMenuPopupPos(CMenuButton::posBottomLeft); return TRUE; } 值得补充说明的是,使用CMenuButton类的时候,并不一定需要在对话框模板中为按钮指定BS_OWNERDRAW风格,因为在缺省情况下,CMenuButton类的PreSubclassWindow()函数中已经自动加入了这一风格。
阅读(283)|
评论(0)
|
喜欢
推荐
转载
|
|