微信那个91团淘宝做任务,5元一单刷单是真的吗

& VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
&&&&&& 鸡啄米在上一节中讲的是,本节主要讲菜单及CMenu类的使用。&&&&&& CMenu类的主要成员函数&&&&&& 为菜单的操作提供了CMenu类,下面鸡啄米就常用的几个成员函数进行简单的介绍。&&&&&& BOOL LoadMenu(UINT nIDResource);&&&&&& 加载菜单资源,并将其附加到CMenu对象上。参数nIDResource指定了要加载的菜单资源的ID。如果菜单加载成功则返回TRUE,否则返回FALSE。&&&&&& BOOL DeleteMenu(UINT nPosition,UINT nFlags);&&&&&& 在菜单中删除一个菜单项。参数nPosition指定要删除的菜单项。参数nFlags就用来解释nPosition的意义,为MF_BYCOMMAND时说明nPosition表示菜单项的ID,为MF_BYPOSITION时说明nPosition表示菜单项的位置,第一个菜单项的位置为0。如果删除菜单项成功则返回TRUE,否则返回FALSE。&&&&&& BOOL TrackPopupMenu(UINT nFlags,int x,int y,CWnd* pWnd,LPCRECT lpRect = 0);&&&&&& 用来在指定位置显示一个浮动的弹出式菜单。参数nFlags指定屏幕坐标和鼠标位置的标志,可以是以下取值:&&&&&& TPM_CENTERALIGN:菜单在水平方向上相对于参数x指定的坐标值居中显示&&&&&& TPM_LEFTALIGN:菜单的左侧与参数x指定的坐标值对齐&&&&&&&TPM_RIGHTALIGN:菜单的右侧与参数x指定的坐标值对齐&&&&&& TPM_BOTTOMALIGN:菜单的底部与参数y指定的坐标值对齐&&&&&& TPM_TOPALIGN:菜单项的顶部与参数y指定的坐标值对齐&&&&&& TPM_VCENTERALIGN:菜单在垂直方向上相对于参数y指定的坐标值居中显示&&&&&& 这里先介绍这几个比较常用的,其他可参见MSDN。参数x指定弹出式菜单的水平方向的屏幕坐标,参数y指定菜单顶部垂直方向上的屏幕坐标,参数pWnd指明哪个窗口拥有此弹出式菜单,不能为NULL,参数lpRect忽略。&&&&&& UINT CheckMenuItem(UINT nIDCheckItem,UINT nCheck);&&&&&& 在弹出菜单中为菜单项增加选中标记或移除选中标记。参数nIDCheckItem指定要选中或取消选中的菜单项。参数nCheck指定菜单项的选中状态和如何根据nIDCheckItem确定菜单项的位置,可以是MF_CHECKED或MF_UNCHECKED与MF_BYPOSITION或MF_BYCOMMAND的组合,这几个标志的含义如下:&&&&&& MF_BYCOMMAND:为默认值。说明参数nIDCheckItem表示菜单项的ID&&&&&&&MF_BYPOSITION:说明参数nIDCheckItem表示菜单项的位置,第一个菜单项的位置是0&&&&&& MF_CHECKED:为菜单项添加选中标记&&&&&& MF_UNCHECKED:为菜单项移除选中标记&&&&&& 该函数返回菜单项之前的状态:MF_CHECKED或MF_UNCHECKED, 如果菜单项不存在则返回0xFFFFFFFF。&&&&&& UINT EnableMenuItem(UINT nIDEnableItem,UINT nEnable);&&&&&& 激活、禁用菜单项或使其变灰。参数nIDEnableItem指定要激活、禁用或变灰的菜单项。参数nEnable指定操作的类型,可以是MF_DISABLED、MF_ENABLED或MF_GRAYED与MF_BYCOMMAND或MF_BYPOSITION的组合,这些值的含义如下:&&&&&& MF_BYCOMMAND:同CheckMenuItem&&&&&& MF_BYPOSITION:同CheckMenuItem&&&&&& MF_DISABLED:禁用菜单项,使其不能被选择但不变灰&&&&&& MF_ENABLED:激活菜单项,使其能够被选择并由变灰状态恢复&&&&&& MF_GRAYED:禁用菜单项,使其不能被选择并变灰&&&&&& 该函数返回菜单项之前的状态:MF_DISABLED、MF_ENABLED或MF_GRAYED&&&&&& CMenu* GetSubMenu(int nPos)&&&&&& 获取弹出菜单的CMenu对象。参数nPos指定弹出菜单在菜单中的位置,不能使用ID。返回值是CMenu对象的指针,该CMenu对象的m_hMenu成员为由nPos指定的弹出菜单的句柄,如果不存在这样的CMenu对象则返回NULL,然后创建一个临时弹出菜单。&&&&&& CMenu类的成员函数先讲这些,如果大家需要用其他的函数可以到MSDN中查看,解释的很清楚。&&&&&& 菜单消息&&&&&& 菜单主要能发送两种消息:COMMAND消息和UPDATE_COMMAND_UI消息。下面分别讲解:&&&&&& COMMAND消息:在菜单项被点击时发送该消息。&&&&&& UPDATE_COMMAND_UI消息:用来维护菜单项的各项状态,包括激活、禁用、变灰、选中、未选中等。在下拉菜单每次打开的时候,所有菜单项的此消息都会被发送出去。如果所属类中为菜单项的该消息添加了处理函数,则执行相应函数更新菜单状态,如果菜单项没有此消息处理函数,也没有COMMAND消息的处理函数,那么它就会变灰。&&&&&& 菜单的应用实例&&&&&& 鸡啄米先讲一下本实例要实现的功能,此实例是在上一节创建的单文档工程Example34的基础上完成的,上一节中为主菜单栏添加了&Tools&菜单项,并设置它的第一个子菜单项为&Draw&,另外我们还要为主菜单栏添加&Settings&项,然后为其添加一个子菜单项&Draw Enable&,我们通过&Draw Enable&菜单项的选中状态控制菜单项&Draw&的激活状态,如果&Draw Enable&菜单项选中,则&Draw&菜单项激活,点击它弹出一个MessageBox,否则&Draw&菜单项禁用。程序中已经在Example34View类中自动生成了OnRButtonUp(UINT /* nFlags */, CPoint point)函数,并在其中实现了弹出右键菜单的功能,这里鸡啄米用CMenu类的TrackPopupMenu成员函数重新做一遍。&&&&&& 注意:Example34的CMainFrame类中定义的菜单并没有使用常用的CMenu类,而是用的CMFCMenuBar类(自VS2008起提供),但菜单的消息处理函数的添加是相同的。&&&&&& 下面是具体步骤:&&&&&& 1. 打开Example34工程的IDR_MAINFRAME菜单资源,在&Help&菜单项前通过&Insert New&操作插入一个菜单项,Caption设为&Settings&,在新菜单项的子菜单中再添加一个菜单项,Caption设为&Draw Enable&,ID默认为ID_SETTINGS_DRAWENABLE。&&&&&& 2. 因为此菜单为CMainFrame所拥有,所以我们在CMainFrame类中对菜单进行操作。在&MainFrm.h&中为CMainFrame类添加成员变量bool m_bDraw,以标识当前是否可以点击Tools-&Draw菜单项,并在CMainFrame类的中为m_bDraw初始化:m_bDraw = TRUE。&&&&&& 3. 为菜单项Tools-&Draw的COMMAND消息和UPDATE_COMMAND_UI消息分别添加处理函数CMainFrame::OnToolsDraw()和OnUpdateToolsDraw(CCmdUI *pCmdUI),这里要注意,添加处理函数时class list中应选择CMainFrame,修改两个函数的实现为:
void&CMainFrame::OnToolsDraw() &&
&&&&MessageBox(_T(&Draw&)); &&
void&CMainFrame::OnUpdateToolsDraw(CCmdUI&*pCmdUI) &&
&&&&pCmdUI-&Enable(m_bDraw); &&
}&&&&&&&& 4. 为菜单项Settings-&Draw Enable的COMMAND消息和UPDATE_COMMAND_UI消息分别添加处理函数CMainFrame::OnSettingsDrawenable()和OnUpdateSettingsDrawenable(CCmdUI *pCmdUI),并将它们的实现修改为:
void&CMainFrame::OnSettingsDrawenable() &&
&&&&m_bDraw&=&!m_bD &&
void&CMainFrame::OnUpdateSettingsDrawenable(CCmdUI&*pCmdUI) &&
&&&&pCmdUI-&SetCheck(m_bDraw); &&
}&&&&&&&& 5. 运行程序,效果图如下:&&&&&& 6. 接下来我们要重新实现右键菜单。大家以后可以仿照自动生成的代码实现右键菜单,也可以用鸡啄米下面讲到的方法。首先将CExample34View::OnRButtonUp(UINT /* nFlags */, CPoint point)函数内的代码都注释掉,保证原来的弹出方法失效。&&&&&& 7. 自动生成代码是在鼠标弹起时实现的右键菜单,我们这里改为在鼠标按下时就弹出右键菜单。在class view类视图中点击CExample34View,然后在属性页的messages列表中找到WM_RBUTTONDOWN,添加其消息响应函数CExample34View::OnRButtonDown(UINT nFlags,CPoint point),修改其实现为:
void&CExample34View::OnRButtonDown(UINT&nFlags,&CPoint&point) &&
&&&&CMenu&&&&&&&&&&
&&&&CMenu&*pSubM&&&&
&&&&menu.LoadMenu(IDR_POPUP_EDIT); &&
&&&&pSubMenu&=&menu.GetSubMenu(0); &&
&&&&ClientToScreen(&point); &&
&&&&pSubMenu-&TrackPopupMenu(TPM_LEFTALIGN,&point.x,&point.y,&this); &&
&&&&CView::OnRButtonDown(nFlags,&point); &&
}&&&&&&&& 8. 最终的右键菜单效果:&&&&&&&&本节内容不少,大家可以慢慢消化。菜单的讲解就到这里了。鸡啄米谢谢大家的关注和支持。
除非特别注明,文章均为原创
转载请标明本文地址:
作者:鸡啄米
&&( 21:53:4)&&( 22:4:25)&&( 21:43:59)&&( 0:11:32)&&( 20:22:53)&&( 20:35:57)&&( 21:47:5)&&( 22:36:38)&&( 21:53:33)&&( 0:49:15)
不错,多谢分享。
过来看看了。
写的很详实,学习了。
学习力,太感谢了,鸡啄米 于
22:38:32 回复不用谢,常来看看啊
函数太难学了,分享了。
现在的博客也不如往日那般兴盛了,不知最后会不会被微博、轻微博以及新的事物所取代,想来博主们也在纠结,是否要坚持更新。鸡啄米 于
16:36:38 回复坚持,没说的秦风 于
11:19:58 回复支持楼主!
博主你好,在完成这个帖子的训练时遇到了一点麻烦,求助:不了解其中为“菜单项Tools-&Draw的COMMAND消息和UPDATE_COMMAND_UI消息分别添加处理函数CMainFrame::OnToolsDraw()和OnUpdateToolsDraw(CCmdUI *pCmdUI)”的具体操作是什么样。。我打开Class Wizard,将Class name选为CMainFrame,然后在Commands Tab里面搜索ID_TOOLS_DRAW,然后双击Message中的COMMAND,按OK得到了那个函数。可是在运行程序时并没有看到任何效果,调试时也不会进入那个函数,不知道为什么。。Shuang 于
20:00:35 回复你好,问题已经解决了,上面的方法是正确的,但是我的菜单的Popup错误的设成了True,如果是False则一切顺利~鸡啄米 于
22:52:17 回复能够自己解决问题,相信能学到更多
在哪里动态添加子菜单呢?
右键弹出的菜单怎么打勾呢?
那带图标的菜单怎么弄呢
vs2010快捷菜单在那添呢
鸡啄米大神好。首先感谢你的这一系列教程,给了我诸多帮助。下面是我的一点小疑惑。我自己建立了菜单栏并且添加消息处理函数以后,我发现OnupdateXXX这个消息函数里面的那个参数句柄pCmdUI是CCmdUI类的,并且我从MSDN上得知CCmdUI是一个单独的类,并没有继承任何关系。所以我一开始试图用GetDlgItm这个常用办法调取控件句柄的时候就出错了(因为我粗略的查了一下,CMenu类是从Cwnd类继承过来的,所以我就想当然的调用了一下GetDlgItm这个函数)。我发现似乎控制菜单只能通过这个pCmdUI来进行。不知道事实是不是这样。还希望大神能给解答下。简而言之,就是这个菜单是不是不像那些按钮啊之类的有一个单独的变量可以控制,纯粹只是一个消息的载体。而不像按钮那些可以比如变量-&Create,变量-&ShowWindow这样。
我记得之前用cmenu类 vs2010已经把这个变成cmenebar
楼主能单独讲讲基于对话框下如何进行菜单操作么。
谢谢鸡啄米的分享~学习了
楼主,你好!我照你上面的步骤2、3、4编译运行后,有1个报错:visual studio 2008\projects\example34\example34\example34.cpp(156) : error C2065: “m_bDraw”: 未声明的标识符我感觉是我是步骤2“在“MainFrm.h”中为CMainFrame类添加成员变量bool m_bDraw”没有添加好,因为显示的是另一个.cpp文件Example34.cpp中引用了“m_bDraw”未声明的标示符,,但是不知道怎么修改?我在MainFrm.h”中是按如下格式添加的CMainFrame类添加成员变量bool m_bDraw:class CMainFrame : public CFrameWnd{ (.....省略)public: bool m_bD};小飞 于
16:14:37 回复我已经找到问题了,因为疏忽添加处理函数时class list没有选中CMainFrame,选成Example34View了。 physu 于
11:45:37 回复我也是出现了这个问题,如果在设置处理函数时在class list没有选中CMainFrame,则默认选择CAboutDlg类,然后处理函数会出现在Example34.cpp中,这样运行时会报错m_bDraw未声明。正确的应该是在MainFrm.cpp中出现处理函数,这样就不会报错了。供大家参考
在“MainFrm.h”中为CMainFrame类添加成员变量bool m_bDraw,以标识当前是否可以点击Tools-&Draw菜单项
这个成员变量是要添加在哪儿?
为什么我的vs2012不能自动生成OnRButtonUp(UINT /* nFlags */, CPoint point)函数呢?menu.LoadMenu(IDR_POPUP_EDIT)括号中的IDR_POPUP_EDIT是哪里来的哇。。wegen 于
11:53:47 回复这应该是系统本身有的模块
非常感谢博主
应该填的是资源视图中Menu下的,IDR_...。我的是IDR_MAINFRAME.
完全随机文章最新公告:
本站所有期刊杂志信息均包含杂志社真实投稿电话,以及投稿邮箱,投稿请点击以上期刊栏目选择相应期刊直接联系杂志社。
论如何用VC++6.0为对话框添加最小化按钮和提示条
  摘 要 我们在使用对话框窗体时,会有这样一种感受:当对话框窗体位于其它程序窗口界面上时,单击对话框外区域时,可使对话框窗体最小化;而当对话框窗体位于桌面上时,无论怎样单击对话框外区域,对话框均不能最小化,只能选择关闭。但有时我们在使用对话框时,还希望能根据需要使对话框具有最小化功能。本文的设计思想就是据此提出来的。
  关键词:对话框,最小化按钮,提示条
  1 实例程序设计要点
  ⑴ 取得对话框标题栏位置和大小,在标题栏的适当位置绘制最小化按钮,并记住按钮的位置。
  ⑵ 在最小化按钮所在区域检测鼠标是否在该区域内、是否按下,是否发送最小化消息使对话框最小化,否则不变。
  ⑶ 将最小化按钮矩形区域向工具提示条控件注册,这样当鼠标在最小化按钮矩形区域时,显示提示文本。
  2 实例程序实现的步骤及说明
  ⑴ 准备二个位图,一个位图表示最小化按钮正常显示状态,另一个位图表示最小化按钮被按下时的状态。
  ⑵ 使用MFC AppWizard(exe)创建工程名为MinButton的对话框窗体,如图所示,将二个按钮位图导入对话框的资源里。
  ⑶ 在CMinButtonDlg对话框类中进行变量定义和函数声明。
  ⑷ 利用ClassWizard为对话框类添加消息WM_NCPAINT,WM_ACTIVATE和WM_NCMOUSEMOVE的消息处理函数,在这三个函数中调用成员函数DrawButton()来绘制按钮。
  ⑸ 利用ClassWizard为最小化按钮关联对应的消息WM_NCLBUTTONDOWN和消息处理函数OnNcLButtonDown(UINT nHitTest, CPoint point)。
  ⑹ 函数DrawButton()用于绘制按钮。由于最小化按钮并不是一个真实的按钮控件,而是一个画在标题栏上的位图。因此,为了在对话框窗体标题上绘画,必须创建一个窗口设备环境类(相当于创建一个画布,有了这个画布,才能在画布上绘画,也就是才能在标题栏上绘画。)
  ① 调用函数GetWindowDC()取得指向CDC的指针 CDC* pDC;
  ② 调用函数 CreateCompatibleDC(CDC* pDC)创建一个内存设备环境,以便在内存中保存位图,并与指定的窗口设备环境相兼容;
  ③ 调用函数SelectObject(CBitmap *pBitmap),将位图选入内存设备环境中;
  ④ 调用函数 BitBlt(int x, int y, int nWidth, int nHeight, CDC *pSrc, int xSrc, int ySrc, DWORD dwRop)将位图复制到实际设备环境中。其中,参数x, y 表示位图目标矩形左上角的x, y 逻辑坐标值;nWidth, nHeight 表示位图目标矩形的逻辑宽度和高度;pSrc 表示源设备环境CDC指针;xSrc, ySrc 表示位图源矩形的左上角的x, y 逻辑坐标值;dwRop 表示显示位图的光栅操作方式。光栅操作方式有多种,这里使用的是SRCCOPY,表示将位图直接复制到目标内存设备环境中。这里要说明一点:函数BitBlt()只能&一比一&的显示位图,如要任意缩放显示位图须使用函数StretchBlt(),该函数的使用方法,请参考相关书籍。
  ⑤ 位图选入内存环境中显示后,应调用函数SelectObject(CBitmap *pOldBitmap)恢复原来的内存设备环境。
  ⑺ 提示条实质上是一个小的弹出窗口,在窗口中显示一行文本,用来描述工具(或区域)的用途或其它信息。在MFC中提供了工具提示条控件类CToolTipCtrl,由它来管理提示条。在这里,我们从CToolTipCtrl类派生子类CToolTips。在子类的定义中添加函数BOOL AddToolTip( UINT nID, LPRECT lpRect, LPCTSTR lpszText),该函数用于向工具提示条控件注册按钮区域和提示文本,当鼠标在最小化按钮区域时,显示提示文本。
  3 主要的程序代码
  ⑴ 在对话框类中定义相应的变量和函数声明
  class CMinButtonDlg : public CDialog
  public:
  CRect m_rtButtM //记录最小化按钮位置
  void DrawButton(); //绘制最小化按钮
  BOOL m_BMPP//最小化按钮状态标志
  CRect m_ButtMinT//记录最小化按钮区域
  protected:
  CToolTips m_ToolT//定义工具提示条控件变量
  void GetMinButRect();//获取最小化按钮所在区域
  //消息处理函数
  afx_msg void OnNcLButtonDown(UINT nHitTest, CPoint point);
  afx_msg void OnNcPaint();
  afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
  afx_msg void OnNcMouseMove(UINT nHitTest, CPoint point);
  ⑵ 对话框类中三个消息处理函数定义如下:
  //对应消息WM_NCPAINT的消息处理函数
  void CMinButtonDlg::OnNcPaint()
  CDialog::OnNcPaint();
  DrawButton(); //绘制最小化按钮
  //对应消息WM_ACTIVATE的消息处理函数
  void CMinButtonDlg::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
  CDialog::OnActivate(nState, pWndOther, bMinimized);
  DrawButton(); //绘制最小化按钮
  //对应消息WM_NCMOUSEMOVE的消息处理函数
  void CMinButtonDlg::OnNcMouseMove(UINT nHitTest, CPoint point)
  DrawButton(); //绘制最小化按
  CDialog::OnNcMouseMove(nHitTest, point);
  ⑶ 绘制最小化按钮的函数
  void CMinButtonDlg::DrawButton()
  CDC* pDC = GetWindowDC();
  CDC* pMemDC=new CDC;
  CBitmap *pBitmap1=new CB
  CBitmap *pBitmap2=new CB
  CBitmap *pOldB
  CRect rtWnd, rtButtons, rtT
  //创建一个内存设备环境
  pMemDC-&CreateCompatibleDC(pDC);
  if(!pDC)
  GetWindowRect(&rtWnd);
  //取得标题栏的矩形
  rtTitle.left = GetSystemMetrics(SM_CXFRAME);
  rtTitle.top = GetSystemMetrics(SM_CYFRAME);
  rtTitle.right = rtWnd.right - rtWnd.left - GetSystemMetrics(SM_CXFRAME);
  rtTitle.bottom = rtTitle.top + GetSystemMetrics(SM_CYSIZE);
  //计算最小化按钮的位置,位图大小为15X15
  rtButtons.top=rtTitle.top+1;
  rtButtons.bottom=rtButtons.top+15;
  rtButtons.right = rtTitle.right-20;
  rtButtons.left = rtButtons.right-15;
  m_rtButtMin = rtB
  pBitmap1-&LoadBitmap(IDB_BITMAP1); //调入正常状态按钮的位图
  pBitmap2-&LoadBitmap(IDB_BITMAP2); //调入按钮按下状态的位图
  m_rtButtMin.OffsetRect(rtWnd.TopLeft());//记录最小化按钮的位置
  //将按钮位图调入内存设备环境中,m_BMPPressed为TRUE
  //调入正常状态按钮的位图
  pOldBitmap=pMemDC-&SelectObject(m_BMPPressed ? pBitmap1: pBitmap2);
  //将按钮位图复制到实际的内存设备环境中
  pDC-&BitBlt(rtButtons.left, rtButtons.top, rtButtons.Width(),
  rtButtons.Height(), pMemDC, 0, 0, SRCCOPY);
  pMemDC-&SelectObject(pOldBitmap);//恢复原来的内存设备环境
  //释放资源
  ReleaseDC(pMemDC);
  ReleaseDC(pDC);
  delete pMemDC;
  delete pBitmap1;
  delete pBitmap2;
  ⑷ 对应鼠标左键的WM_NCLBUTTONDOWN消息处理函数
  void CMinButtonDlg::OnNcLButtonDown(UINT nHitTest, CPoint point)
  CDialog::OnNcLButtonDown(nHitTest, point);
  //检测是否在最小化按钮区域内按下按钮
  if (m_rtButtMin.PtInRect(point))
  m_BMPPressed=FALSE;//绘制按钮按下时的状态
  DrawButton(); //绘制最小化按钮
  m_BMPPressed=TRUE;//绘制按钮的正常状态
  SendMessage(WM_SYSCOMMAND, SC_MINIMIZE, MAKELPARAM(point.x, point.y));//发送最小化消息
  ⑸ //在最小化按钮区域实现提示文本
  BOOL CToolTips::AddToolTip( UINT nID, LPRECT lpRect, LPCTSTR lpszText )
  TOOLINFO T
  memset(&Tips, 0, sizeof(TOOLINFO));
  Tips.cbSize = sizeof(TOOLINFO);
  Tips.hwnd = GetOwner()-&GetSafeHwnd();
  Tips.uFlags = TTF_SUBCLASS;
  Tips.uId = nID;
特别说明:本网站内容都来源于互联网,供浏览者学习、欣赏,使用原则非商业性或非盈利性用途,使用者不得侵犯本网站及相关权利人的合法权利。此外,使用者如对本网站内容用于其他用途时,须征得本网站及相关权力人的许可。
本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站,予以删除。
我们的服务
杂志申请收录邮箱:; 投诉建议邮箱:
国家信息产业备案号码:京ICP备号 京公网安备81号
【免责声明】:本网站所提供的信息资源如有侵权、违规,请及时联系邮箱:
优先推荐期刊
电话:010-用MFC创建菜单按钮(转)
我的图书馆
用MFC创建菜单按钮(转)
用MFC创建菜单按钮(转)&&
17:24:02|&&分类:
|字号&订阅
& 用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类创建一个公有的成员函数OnClick(),以便在BN_CLICKED的消息处理器中调用。它有两个参数,第一个是菜单资源的ID,第二个参数为子菜单的ID,默认为0。如果只有一组子菜单,则可使用其默认值0。OnClick()函数的返回值为所选的菜单项的命令ID,若未作任何有效选择,则返回0。 下面是程序代码。 头文件: #if !defined(_EWAY_MEMUBUTTON_H__INCLUDED_) #define _EWAY_MEMUBUTTON_H__INCLUDED_ #if _MSC_VER &= 1000 #pragma once #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_ArrowT enum PopupPos { //名称为TopLeft等等,遵守英文习惯; posTopLeft, //左上角; posBottomLeft, //左下角; posTopRight, //右上角; posBottomRight, //右下角; }m_PopupP virtual UINT OnClick(UINT nIDMenuResource,UINT nSubMenu=0); 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_bDrawFocusR //{{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); //得到画笔的颜色; CP 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); CF 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 strA switch (m_ArrowType) { case CMenuButton::arrowRight: strArrow="4";
case CMenuButton::arrowDown: strArrow="6";
case CMenuButton::arrowSmallRight: strArrow="8";
case CMenuButton::arrowSmallDown: strArrow="9";
case CMenuButton::arrowUp: strArrow="5";
case CMenuButton::arrowLeft: strArrow="3";
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::OnClick(UINT nIDMenuResource, UINT nSubMenu/*=0*/) { CM //装载菜单; VERIFY(menu.LoadMenu(nIDMenuResource) ); //得到子菜单; CMenu *pPopup = menu.GetSubMenu(nSubMenu);//默认为第一组子菜单; ASSERT(pPopup != NULL); CR GetWindowRect(rect); POINT //决定弹出菜单的位置; switch (m_PopupPos) { case CMenuButton::posTopLeft://左上角; point.x=rect. point.y=rect.
case CMenuButton::posBottomLeft://左下角; point.x=rect. point.y=rect.
case CMenuButton::posTopRight://右上角; point.x=rect. point.y=rect.
case CMenuButton::posBottomRight://右下角; point.x=rect. point.y=rect.
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 nMenuS } void CMenuButton::PreSubclassWindow()
{ CButton::PreSubclassWindow(); //默认值:加入BS_OWNERDRAW风格; ModifyStyle(0,BS_OWNERDRAW); } void CMenuButton::SetArrowType(CMenuButton::ArrowType type) { m_ArrowType= } void CMenuButton::SetDrawFocusRect(BOOL bDrawFocusRect) { m_bDrawFocusRect=bDrawFocusR } void CMenuButton::SetMenuPopupPos(CMenuButton::PopupPos pos) { m_PopupPos= } 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类型的按钮成员变量,若需改变默认风格,则可在OnInitDialog中调用CMenuButton类的公有成员函数SetArrowType()、SetDrawFocusRect()、SetMenuPopupPos()或SetStyle(),在ClassWizard中为对话框添加按钮的BN_CLICKED消息处理函数,然后在其中调用CMenuButton类的OnClick()成员函数,并指定一个菜单ID给它,最后处理OnClick()函数的返回值即可。下面是一个例子。 void CMenuButtonTestDlg::OnTest()
{ UINT nSel=m_btnTest.OnClick(IDR_POPUP); switch(nSel) { case ID_APP_EXIT: SendMessage(WM_CLOSE,0,0);
case ID_POPUP_ITEM1: AfxMessageBox("您选择了第一项!");
case ID_POPUP_ITEM2: AfxMessageBox("您选择了第二项!");
case ID_POPUP_ITEM3: AfxMessageBox("您选择了第三项!");
default: //D ; } } 所用菜单的资源描述如下,外观可参见文首的图。 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::OnInitDialog()
{ CDialog::OnInitDialog(); //因为这几个值都是默认值,所以注释掉,仅为了演示用法; //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)|
最近读者用MFC创建菜单按钮(转)&&
17:24:02|&&分类:
|字号&订阅
& 用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类创建一个公有的成员函数OnClick(),以便在BN_CLICKED的消息处理器中调用。它有两个参数,第一个是菜单资源的ID,第二个参数为子菜单的ID,默认为0。如果只有一组子菜单,则可使用其默认值0。OnClick()函数的返回值为所选的菜单项的命令ID,若未作任何有效选择,则返回0。 下面是程序代码。 头文件: #if !defined(_EWAY_MEMUBUTTON_H__INCLUDED_) #define _EWAY_MEMUBUTTON_H__INCLUDED_ #if _MSC_VER &= 1000 #pragma once #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_ArrowT enum PopupPos { //名称为TopLeft等等,遵守英文习惯; posTopLeft, //左上角; posBottomLeft, //左下角; posTopRight, //右上角; posBottomRight, //右下角; }m_PopupP virtual UINT OnClick(UINT nIDMenuResource,UINT nSubMenu=0); 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_bDrawFocusR //{{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); //得到画笔的颜色; CP 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); CF 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 strA switch (m_ArrowType) { case CMenuButton::arrowRight: strArrow="4";
case CMenuButton::arrowDown: strArrow="6";
case CMenuButton::arrowSmallRight: strArrow="8";
case CMenuButton::arrowSmallDown: strArrow="9";
case CMenuButton::arrowUp: strArrow="5";
case CMenuButton::arrowLeft: strArrow="3";
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::OnClick(UINT nIDMenuResource, UINT nSubMenu/*=0*/) { CM //装载菜单; VERIFY(menu.LoadMenu(nIDMenuResource) ); //得到子菜单; CMenu *pPopup = menu.GetSubMenu(nSubMenu);//默认为第一组子菜单; ASSERT(pPopup != NULL); CR GetWindowRect(rect); POINT //决定弹出菜单的位置; switch (m_PopupPos) { case CMenuButton::posTopLeft://左上角; point.x=rect. point.y=rect.
case CMenuButton::posBottomLeft://左下角; point.x=rect. point.y=rect.
case CMenuButton::posTopRight://右上角; point.x=rect. point.y=rect.
case CMenuButton::posBottomRight://右下角; point.x=rect. point.y=rect.
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 nMenuS } void CMenuButton::PreSubclassWindow()
{ CButton::PreSubclassWindow(); //默认值:加入BS_OWNERDRAW风格; ModifyStyle(0,BS_OWNERDRAW); } void CMenuButton::SetArrowType(CMenuButton::ArrowType type) { m_ArrowType= } void CMenuButton::SetDrawFocusRect(BOOL bDrawFocusRect) { m_bDrawFocusRect=bDrawFocusR } void CMenuButton::SetMenuPopupPos(CMenuButton::PopupPos pos) { m_PopupPos= } 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类型的按钮成员变量,若需改变默认风格,则可在OnInitDialog中调用CMenuButton类的公有成员函数SetArrowType()、SetDrawFocusRect()、SetMenuPopupPos()或SetStyle(),在ClassWizard中为对话框添加按钮的BN_CLICKED消息处理函数,然后在其中调用CMenuButton类的OnClick()成员函数,并指定一个菜单ID给它,最后处理OnClick()函数的返回值即可。下面是一个例子。 void CMenuButtonTestDlg::OnTest()
{ UINT nSel=m_btnTest.OnClick(IDR_POPUP); switch(nSel) { case ID_APP_EXIT: SendMessage(WM_CLOSE,0,0);
case ID_POPUP_ITEM1: AfxMessageBox("您选择了第一项!");
case ID_POPUP_ITEM2: AfxMessageBox("您选择了第二项!");
case ID_POPUP_ITEM3: AfxMessageBox("您选择了第三项!");
default: //D ; } } 所用菜单的资源描述如下,外观可参见文首的图。 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::OnInitDialog()
{ CDialog::OnInitDialog(); //因为这几个值都是默认值,所以注释掉,仅为了演示用法; //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)|
TA的最新馆藏[转]&[转]&[转]&[转]&[转]&[转]&

我要回帖

更多关于 淘宝做任务,5元一单 的文章

 

随机推荐