带有弹出式菜单的按钮可以使一个按钮具有多项选择功能,扩展了按钮的功能,相当于把多个按钮集成于一体,可以减少按钮数目。
这种按钮的按钮体分为两个区域,单击主体区域时,执行主体按钮的功能,单击选择区域时,弹出一个菜单,可从中选择要执行的功能。如图所示。
下面,我们看一下它的制作过程:
一、新建一个以CButton类为基类的新类
单击“Insert”→“New Class”,建立一个新类。基类设置为CButton,新类起名为CMenuButton。
二、利用自绘方法绘制按钮,主体区显示按钮文本,选择区画一个小箭头
在CMenuButton类中用ClassWizard添加函数:PreSubclassWindow()和DrawItem()。
PreSubclassWindow()函数在建立按钮时执行,可用于做一些准备工作。在这里我给按钮添加自绘属性:
voidCMenuButton::PreSubclassWindow() { ModifyStyle(0,BS_OWNERDRAW);//设置按钮属性为自绘式
CButton::PreSubclassWindow(); } |
DrawItem()函数用于绘制按钮,左边绘制按钮文字,作为主体区,右边绘制一个小箭头,作为选择区。实际应用中,可根据具体需要绘制想要的形状和内容。
voidCMenuButton::DrawItem(LPDRAWITEMSTRUCTlpDrawItemStruct) { CDC*pDC=CDC::FromHandle(lpDrawItemStruct->hDC); m_ButRect=lpDrawItemStruct->rcItem;//获取按钮尺寸 intnSavedDC=pDC->SaveDC(); VERIFY(pDC);
DrawButton(pDC);//绘制按钮
pDC->RestoreDC(nSavedDC); } |
其中m_ButRect都是CRect型对象,在头文件中进行定义。DrawButton()为绘制按钮的函数,把它定义在外边的目的是方便用户修改,如果你想改变按钮形状,只需修改DrawButton()函数即可。
voidCMenuButton::DrawButton(CDC*pDC) { m_LRect.SetRect(m_ButRect.left,m_ButRect.top, m_ButRect.right-21,m_ButRect.bottom);//按钮主体区尺寸 m_RRect.SetRect(m_ButRect.right-20,m_ButRect.top, m_ButRect.right,m_ButRect.bottom);//按钮选择区尺寸
CPenPen; Pen.CreatePen(PS_SOLID,1,RGB(192,192,192)); pDC->SelectObject(&Pen);
pDC->FillSolidRect(m_ButRect,m_BackColor);//画背景 switch(m_State)//不同状态画不同边框 { case0://正常按钮 pDC->DrawEdge(&m_LRect,BDR_RAISEDINNER,BF_RECT); pDC->DrawEdge(&m_RRect,BDR_RAISEDINNER,BF_RECT); break; case1://鼠标进入时的按钮 pDC->DrawEdge(&m_LRect,BDR_RAISEDINNER,BF_RECT); pDC->DrawEdge(&m_RRect,BDR_RAISEDINNER,BF_RECT); pDC->MoveTo(m_ButRect.TopLeft()); pDC->LineTo(m_ButRect.right,m_ButRect.top); break; case2://单击按钮主体区时的按钮 pDC->DrawEdge(&m_RRect,BDR_RAISEDINNER,BF_RECT); break; case3://单击按钮选择区时的按钮 pDC->DrawEdge(&m_LRect,BDR_RAISEDINNER,BF_RECT); break; }
POINTm_pt[3],m_ptCentre;//箭头坐标(三个顶点) m_ptCentre=m_RRect.CenterPoint();//选择区中点位置 m_pt[0].x=m_ptCentre.x-3;//计算箭头坐标 m_pt[0].y=m_ptCentre.y-2; m_pt[1].x=m_ptCentre.x+4; m_pt[1].y=m_ptCentre.y-2; m_pt[2].x=m_ptCentre.x; m_pt[2].y=m_ptCentre.y+2;
pDC->SelectStockObject(BLACK_BRUSH);//定义画刷(黑色) CRgnrgn; rgn.CreatePolygonRgn(m_pt,3,ALTERNATE); pDC->PaintRgn(&rgn);//画选择区箭头
pDC->SetTextColor(m_ForeColor);//画主体区文字 pDC->SetBkMode(TRANSPARENT); pDC->DrawText(m_strText,&m_LRect,DT_SINGLELINE|DT_CENTER |DT_VCENTER|DT_END_ELLIPSIS); } |
m_State是个标志,=0表示正常按钮;=1表示鼠标进入按钮,绘制暗线边框;=2表示在按钮主体区按下鼠标左键;=3表示在按钮选择区按下鼠标左键。
在m_State的不同取值下,绘制不同的按钮边框,可以增加按钮的动态效果。
三、添加鼠标响应函数
在CMenuButton类中用ClassWizard添加函数:OnMouseMove()、OnLButtonDown()、OnLButtonUp()。
OnMouseMove()函数用于响应鼠标移动消息,当鼠标进入按钮时,设置相应标志,并重绘按钮边框,当鼠标离开按钮时,清除标志,恢复原边框。
voidCMenuButton::OnMouseMove(UINTnFlags,CPointpoint) { if(!b_InFlag||GetCapture()!=this)//鼠标进入按钮 { b_InFlag=true;//设置进入标志 SetCapture();//捕获鼠标 m_State=1;//置按钮状态(1-当前按钮) if(b_ClickFlag)//检测单击选择区标志 { m_Menu.Detach();//清除打开的菜单 m_Menu.DestroyMenu(); b_ClickFlag=false; } Invalidate();//重绘按钮 } else { if(!m_ButRect.PtInRect(point))//鼠标离开按钮 { b_InFlag=false;//清除进入标志 ReleaseCapture();//释放鼠标捕获 b_ClickBut=false;//清除单击标志 m_State=0;//置按钮状态(0-正常按钮) if(b_ClickFlag)//检测单击选择区标志 { m_Menu.Detach();//清除打开的菜单 m_Menu.DestroyMenu(); b_ClickFlag=false; } Invalidate();//重绘按钮 } }
CButton::OnMouseMove(nFlags,point); } |
b_InFlag是个BOOL型量,鼠标进入时设置,离开时清除,目的是防止鼠标在按钮上移动时重复刷新按钮,以避免闪烁。
b_ClickFlag是单击按钮选择区标志,当它为true时,表示弹出菜单已打开,为false时表示菜单未弹出。当菜单已经弹出,而鼠标又移回按钮单击时,应清除菜单。
b_ClickBut是单击按钮主体区标志。
OnLButtonDown()函数响应按钮单击消息,当单击的是按钮主体区时,设置b_ClickBut标志;当单击的是按钮选择区时,要根据单击次数,决定是否弹出菜单。
voidCMenuButton::OnLButtonDown(UINTnFlags,CPointpoint) { if(m_LRect.PtInRect(point))//单击按钮主体区 { m_State=2;//置按钮状态(2-正常按钮) b_ClickBut=true;//设置单击按钮标志 Invalidate();//重绘按钮 } elseif(m_RRect.PtInRect(point)&&m_MenuID)//单击选择区 { m_State=3; b_ClickBut=false;//清除单击按钮标志 Invalidate();//重绘按钮 b_ClickFlag=!b_ClickFlag;//单击选择区标志 if(b_ClickFlag)//一次单击,弹出菜单 { CRectrect=m_RRect; ClientToScreen(rect);//转换为屏幕坐标 point=rect.BottomRight(); point.x-=rect.Width();//设置弹出菜单的位置
VERIFY(m_Menu.LoadMenu(m_MenuID));//装入菜单资源
CMenu*pPopup=m_Menu.GetSubMenu(0); ASSERT(pPopup!=NULL); CWnd*pWndPopupOwner=this;
while(pWndPopupOwner->GetStyle()&WS_CHILD) pWndPopupOwner=pWndPopupOwner->GetParent();
pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON, point.x,point.y,pWndPopupOwner);//弹出菜单 } else//再次单击,清除菜单 { m_Menu.Detach(); m_Menu.DestroyMenu(); } }
CButton::OnLButtonDown(nFlags,point); } |
当单击按钮选择区时,在选择区的左下角弹出菜单,函数中的point是鼠标的屏幕坐标,求菜单位置时也使用屏幕坐标。
m_MenuID是与按钮关联的弹出菜单的ID,它在创建按钮时进行设置。
OnLButtonUp()函数响应按钮弹起消息,这是只要恢复按钮正常状态即可,以产生单击动画效果。
voidCMenuButton::OnLButtonUp(UINTnFlags,CPointpoint) { m_State=0;//恢复为正常按钮 Invalidate();//重绘按钮
CButton::OnLButtonUp(nFlags,point); } |
四、自定义接口函数
提供用户使用按钮的接口。
//设置关联菜单ID voidCMenuButton::SetMenuID(intnID) { m_MenuID=nID; }
//设置按钮文本 voidCMenuButton::SetText(CStringstr) { m_strText=str; }
//设置文本颜色 voidCMenuButton::SetForeColor(COLORREFcolor) { m_ForeColor=color; Invalidate(); }
//设置背景颜色 voidCMenuButton::SetBkColor(COLORREFcolor) { m_BackColor=color; Invalidate(); }
//是否单击主按钮区 BOOLCMenuButton::isClick() { returnb_ClickBut; } |
由于这种按钮分为两个区域,使用时要根据单击区域决定要做的工作,所以设置了isClick()接口函数。
五、变量的初始化
在CMenuButton类的头文件中,定义有以下变量和函数:
MenuButton.h
private: intm_State;//按钮状态 BOOLb_InFlag;//鼠标进入标志 BOOLb_ClickFlag;//单击选择区 BOOLb_ClickBut;//单击主体区 CStringm_strText;//按钮文字 COLORREFm_ForeColor;//文本颜色 COLORREFm_BackColor;//背景色 CRectm_ButRect;//按钮尺寸 CRectm_LRect;//按钮左部尺寸 CRectm_RRect;//按钮右部尺寸 CMenum_Menu;//弹出菜单 intm_MenuID;//菜单ID
voidDrawButton(CDC*pDC);//绘制按钮
public: CMenuButton();//构造函数 voidSetMenuID(intnID);//设置关联菜单ID voidSetForeColor(COLORREFcolor);//设置文本颜色 voidSetBkColor(COLORREFcolor);//设置背景颜色 voidSetText(CStringstr);//设置按钮文本 BOOLisClick();//是否单击主按钮区
|
各变量的初始化在构造函数中进行:
CMenuButton::CMenuButton() { m_MenuID=0;//菜单ID b_InFlag=false;//进入标志 m_State=0;//初始状态 b_ClickFlag=false;//单击选择区标志 b_ClickBut=false;//单击主体区标志 m_strText=_T("");//按钮文本 m_ForeColor=RGB(0,0,0);//文字颜色 m_BackColor=GetSysColor(COLOR_3DFACE);//背景色 } |
这样,带菜单的按钮类就做好了,用它定义的按钮实例可以连接一个弹出式按钮,下面我们就看看怎样定义按钮实例。
六、生成按钮实例
1、在对话框中放置按钮,把它的大小调整合适;
2、用ClassWizard为按钮添加变量,把变量的类型设置为CMenuButton;
3、定义按钮的关联菜单
关联菜单就是普通的弹出式菜单,用VC的菜单编辑器生成即可。
进入资源的“Menu”项,插入一个新的菜单,根据需要添加菜单项。
4、设置按钮
在对话框的OnInitial()函数中初始化按钮:
按钮变量.SetMenuID(菜单ID); 按钮变量.SetText(按钮文本); 按钮变量.SetBkColor(按钮背景色); |
七、按钮的响应
对按钮的响应包括单击按钮主体区的响应和单击菜单项的响应两部分。
用ClassWizard添加按钮的响应函数和各菜单项的响应函数。
在按钮的响应函数中要做如下工作:
voidCMBTestView::OnMenubutton1() { if(m_MenuButton1.isClick()) { //响应按钮操作 } } |
这里要求只有单击按钮的主体区时才进行响应。
至于单击菜单项的响应与普通菜单一样,这里不再详述。
这个按钮类还有几点可考虑改进:
①增加无效状态(变灰)按钮;
②设置按钮文字字体。
相应方法可参考文章《可设置字体和颜色的按钮》。
示例程序界面:

文本所用MFC函数速查:
CDC::DrawEdge CDC::DrawText CDC::FillSolidRect CDC::PaintRgn CDC::RestoreDC CDC::SaveDC CDC::SelectObject CDC::SelectStockObject CDC::SetBkMode CDC::SetTextColor CMenu::DestoryMenu CMenu::Detach CMenu::LoadMenu CMenu::TrackPopupMenu CPen::CreatePen CRect::BottomRight CRect::CenterPoint CRect::PtInRect CRect::SetRect CRect::Width CRgn::CreatePolygonRgn CWnd::ClientToScreen CWnd::GetCapture CWnd::GetParent CWnd::GetStyle CWnd::Invalidate CWnd::ModifyStyle CWnd::ReleaseCapture CWnd::SetCapture
|
相关推荐
visual c++制作带弹出式菜单的按钮
弹出式菜单是一种常见的网页交互元素,用于提供额外的功能选项或信息,通常在用户执行特定操作(如点击或悬浮)时出现。在这个案例中,我们讨论的是一个包含CSS和JS样式的完整弹出式菜单,它能实现一些高级功能,如...
以下是对京东商城左侧弹出式菜单设计制作的详细解析: 1. **菜单结构**:京东商城的左侧菜单通常包含一级分类和二级分类,甚至三级分类。一级分类是大类,如“手机数码”、“家用电器”等,二级分类是更具体的子...
今天给大家带来一个微信小程序的弹出是菜单效果,老规矩先上效果图。(录制的gif动画有点卡,实际真机或是模拟器上很顺畅) 先简单说下思路: 1、首先在屏幕的某个位置放几个悬浮按钮,放几个看你需要的功能 2、点击...
接下来,你可以选择"行为"面板,为这个链接添加"显示弹出式菜单"的行为。 2. **创建菜单项和子菜单项**: 在添加了行为的文字基础上,你可以开始构建菜单结构。在"行为"面板中,点击"+"号来添加新的菜单项和子菜单...
这使得文字具备触发JavaScript事件的能力,例如显示弹出式菜单。 2. **添加菜单项和子菜单项**: 接下来,定义菜单结构,包括主菜单项和可能的子菜单项。这一步骤涉及菜单层次的建立和链接的分配,确保用户能够...
在这篇文档中,我们要探讨的知识点集中在如何用JavaScript实现一个可折叠的弹出式菜单。弹出式菜单是网页中常见的导航组件,它通常用于在有限的空间内展示更多的链接项。通过点击一个触发元素(例如一个链接或按钮)...
一种是通过工具内的“新建”按钮进行截图,但这通常不适用于捕捉弹出式菜单,因为在你点击“新建”后,菜单可能会因为操作而消失。为了准确截取弹出式菜单,我们需要使用更加快捷有效的方法,即通过键盘快捷键“Ctrl...
本文将详细介绍如何使用易语言在指定位置显示弹出式菜单的方法。 首先,我们需要理解“弹出菜单”这个概念。弹出式菜单(PopupMenu)通常在用户执行特定操作时出现,例如右键单击时,它会提供一系列可选的操作选项...
- 在“显示弹出式菜单”对话框中,你可以定义弹出菜单的各个部分,包括菜单项、子菜单项及其关联的链接。在这里,你可以设置菜单的外观,比如字体、颜色、大小,以及菜单的位置,如相对于鼠标的位置或页面的固定...
4. **选择弹出菜单行为**:再次点击加号(+)按钮,这次在弹出菜单中选择“显示弹出式菜单”。 5. **配置弹出菜单**: - 在弹出的对话框中,你可以选择添加新的弹出菜单或使用已有的菜单。 - 设置弹出菜单的位置和...
而“弹出导航”则指这种在需要时才出现的菜单设计,它通常通过点击按钮或者触摸手势触发,适合小屏幕设备。 【知识点详解】 1. **响应式设计**:响应式设计是确保网页在不同设备和屏幕尺寸下都能正常显示和使用的...
"彩色圆形按钮菜单弹出动画ppt特效.rar"是一个专为PowerPoint设计的资源,它包含了一系列彩色圆形按钮,以及与之相关的弹出式菜单动画效果。这个模板允许设计师和演示文稿制作者为他们的幻灯片添加生动且引人注目的...
接着,我们可以利用Dreamweaver内置的行为功能,添加【显示弹出式菜单】行为,如图17-3所示。 接下来,我们需要定义菜单项和子菜单项。这包括设置各个菜单项的文本、链接以及它们的层级关系,确保菜单的逻辑结构...
在Delphi编程环境中,创建一个自动弹出式提示窗体是一项常见的需求,它可以为用户提供即时信息反馈,类似于QQ等即时通讯软件中的消息提示。要实现这样的功能,我们需要掌握以下几个核心知识点: 1. **窗体(Form)...
在“html5页面右下角点击按钮展示圆形菜单动画特效”这个主题中,我们主要探讨的是如何利用HTML5的特性来创建一个交互式的用户体验,特别是通过按钮触发的圆形菜单动画效果。 首先,HTML5的新特性之一是Canvas元素...
总结起来,这个项目的核心是利用jQuery的事件处理和动画功能,结合HTML和CSS创建一个交互式的堆栈弹出式菜单。通过这种方式,我们可以构建一个既美观又实用的用户界面,提升网站或应用的用户体验。
总之,Flash CS3弹出菜单教程旨在帮助你掌握创建交互式菜单的技能,无论你是初学者还是有一定基础的设计师,都能从中受益。通过实践这些实例,你将能够灵活地应用这些知识,创造出符合自己需求的弹出菜单,提升你的...
一旦设置了这个特殊的链接,我们就可以为文字添加“显示弹出式菜单”的行为,如图17-3所示。 接下来,我们要定义菜单项和子菜单项。在Dreamweaver中,这通常涉及到创建多个层次的链接,并为每个菜单项分配相应的...
`jQuery手机端底部弹出菜单列表代码` 正是为了解决这一问题而设计的,它是一款专为智能手机和平板电脑优化的JavaScript库,能够实现点击按钮后自底部弹出一个包含多个图标选项的菜单列表。这个功能对于移动应用或...