教程中国
PHOTOSHOP CS9.0中文版 MAYA 8.5 FOR WINDOWS Corel Painter v9.0 Flash MX2004 中文版 Illustrator cs2 中文版
VC++6.0含sp6 中英文版 VB6.0 +sp6 简体中文版 Borland Delphi 7汉化版 MSDN for vb6.0中文版 Visual Studio 2005简体
教程中国下属 文件存储共享专家BIBIDU.COM 提供大型软件,教材,源码,电影,音乐,图书等下载 更多精品请点此进入
  您目前所在位置: 教程中国 >> 编程基地 >> VC++ >> 用VC制作带弹出式菜单的按钮 RSS订阅
用VC制作带弹出式菜单的按钮
用VC制作带弹出式菜单的按钮(1)
教程(视频,书籍)下载:  ASP.NET AutoCAD 数据库 C# ASP java photoshop 网页设计 delphi 3dmax Flash C++ VB 张孝祥 实例   更多请进入BIBIDU搜索
IT搜索引擎   

  带有弹出式菜单的按钮可以使一个按钮具有多项选择功能,扩展了按钮的功能,相当于把多个按钮集成于一体,可以减少按钮数目。

  这种按钮的按钮体分为两个区域,单击主体区域时,执行主体按钮的功能,单击选择区域时,弹出一个菜单,可从中选择要执行的功能。

  下面,我们看一下它的制作过程:

  一、新建一个以CButton类为基类的新类

  单击“Insert”→“New Class”,建立一个新类。基类设置为CButton,新类起名为CMenuButton。

  二、利用自绘方法绘制按钮,主体区显示按钮文本,选择区画一个小箭头

  在CMenuButton类中用ClassWizard添加函数:PreSubclassWindow()和DrawItem()。

  PreSubclassWindow()函数在建立按钮时执行,可用于做一些准备工作。在这里我给按钮添加自绘属性:

void CMenuButton::PreSubclassWindow()
{
 ModifyStyle( 0, BS_OWNERDRAW ); //设置按钮属性为自绘式

 CButton::PreSubclassWindow();
}

  DrawItem()函数用于绘制按钮,左边绘制按钮文字,作为主体区,右边绘制一个小箭头,作为选择区。实际应用中,可根据具体需要绘制想要的形状和内容。
void CMenuButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
 CDC *pDC = CDC::FromHandle( lpDrawItemStruct->hDC );
 m_ButRect = lpDrawItemStruct->rcItem; //获取按钮尺寸
 int nSavedDC = pDC->SaveDC();
 VERIFY( pDC );

 DrawButton(pDC); //绘制按钮

 pDC->RestoreDC( nSavedDC );
}

  其中m_ButRect都是CRect型对象,在头文件中进行定义。DrawButton()为绘制按钮的函数,把它定义在外边的目的是方便用户修改,如果你想改变按钮形状,只需修改DrawButton()函数即可。
void CMenuButton::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 ); //按钮选择区尺寸

 CPen Pen;
 Pen.CreatePen(PS_SOLID, 1, RGB(192,192,192) );
 pDC->SelectObject( &Pen );

 pDC->FillSolidRect( m_ButRect, m_BackColor ); //画背景
 switch( m_State ) //不同状态画不同边框
 {
  case 0: //正常按钮
   pDC->DrawEdge( &m_LRect, BDR_RAISEDINNER, BF_RECT );
   pDC->DrawEdge( &m_RRect, BDR_RAISEDINNER, BF_RECT );
   break;
  case 1: //鼠标进入时的按钮
   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;
  case 2: //单击按钮主体区时的按钮
   pDC->DrawEdge( &m_RRect, BDR_RAISEDINNER, BF_RECT );
   break;
  case 3: //单击按钮选择区时的按钮
   pDC->DrawEdge( &m_LRect, BDR_RAISEDINNER, BF_RECT );
   break;
 }

 POINT m_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 ); //定义画刷(黑色)
 CRgn rgn;
 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()函数用于响应鼠标移动消息,当鼠标进入按钮时,设置相应标志,并重绘按钮边框,当鼠标离开按钮时,清除标志,恢复原边框。
void CMenuButton::OnMouseMove(UINTnFlags, CPoint point)
{
 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标志;当单击的是按钮选择区时,要根据单击次数,决定是否弹出菜单。
void CMenuButton::OnLButtonDown(UINT nFlags, CPoint point)
{
 if( m_LRect.PtInRect(point) ) //单击按钮主体区
 {
  m_State = 2; //置按钮状态(2-正常按钮)
  b_ClickBut = true; //设置单击按钮标志
  Invalidate(); //重绘按钮
 }
 else if( m_RRect.PtInRect(point) && m_MenuID ) //单击选择区
 {
  m_State = 3;
  b_ClickBut = false; //清除单击按钮标志
  Invalidate(); //重绘按钮
  b_ClickFlag = !b_ClickFlag; //单击选择区标志
  if( b_ClickFlag ) //一次单击,弹出菜单
  {
   CRect rect = m_RRect;
   ClientToScreen(rect); //转换为屏幕坐标
   point = rect.BottomRight();

来源:upschool.com.cn
作者:
关键字:按钮
发表日期:2006-4-6

网页显示有限 阅读全文请下载本文完整版WORD文档

上一篇:用Visual C++实现排序算法大全   下一篇:在VC++项目中为MDI主框架窗口添加位图


共2页 9 7 [1] [28 :>

2008-12-4 7:57:21
本文的相类似文章
  • VB实现按钮浮动效果
  • VB 自定义消息框上的按钮的文字
  • VB 使关闭按钮失效
  • 教你用Photoshop打造动感网页按钮
  • 用Photoshop打造嵌入人体的按钮
  • 用Photoshop图层样式制作发光按钮
  • PS中制作“苹果风格按钮”教程
  • 使窗体右上角的X按钮失效
  • 使窗体右上角的X按钮失效
  • 使窗体右上角的X按钮失效
  • 在学习中进步 在进步中成长 教程中国相随您的成长之路
    华腾联合科技股份有限公司版权所有
    广告联系:Rosibo@163.com