游戏授权,APP授权,一手资源,专业团队 qq群698886111

用VC++实现自绘按钮控制

Microsoft Windows以其丰富一致的图形用户界面,简单灵便的操作,被广大用户所接受。对话框就是其中一个非常重要的界

面形式,并且Windows为其应用程序的开发者提供了相当丰富的界面资源,许多控制可以方便地加入对话框中。但当我们需要编写

一个商业应用,需要一个更友好的图形用户界面时,就会发现资源的贫乏。
  
   Visual C++提供了一个CBitmap Button类在一定程序上缓解了增加新资源的要求。但当我们要求在程序中能动态地改变图形

时,我们就不得不考虑放弃CBitmapButton类,而坐下来自己做一点工作了。
  
   一个可行的办法就是重载CButton类(即按钮控制)。这样对这块区域的大小、位置和ID号都可以通过AppStadio方便地制作

。当然这样作最大的好处还是在于充分利用C++的特性把绘制控制的代码封装了起来,既避免了重复性开发,又使程序变得更简洁

,增强了代码的可读性。现在我们就通过创建一个名叫CColorButton的类来学习这种方法。虽然这是一个功能非常简单的类,通

过调用成员函数ChangeColor可改变其颜色,鼠标点中时则高亮边框表示选中。但利用这种思路我们只需添加几个数据成员和重载

一个函数就可以方便地实现你所需要的功能。
  
   在创建这个类之前,我们必须先了解WM_DRAWITEM消息。当按钮、组合框、列表框或菜单的某一视觉状况发生变化时,系统就

会发送一条WM_DRAWITEM消息给这些控制的拥有者窗口。这个消息的wParam指出这个控制的 id 号,而IParam则是一个指向

DRAWITEMSTRUCT结构的指针,该结构存放有关要绘制的项的信息以及绘制所需的类型。DRAWITEMSTRUCT结构具有如下格式。
  
   typedef struct tagDRAWITEMSTRUCT{
  
   UINT CtlType; // 控制类型
  
   UINT CtlID;// 控制的ID号
  
   UNIT itemID;//菜单项的索引
  
   UINT itemAction;// 说明需要的绘图操作
  
   UINT itemState; // 指明绘图后的可见状态
  
   HWND hwndItem; // 控制的窗口句柄
  
   HDC hDC; // 相关的设备环境
  
   RECT rcItem;//被画控制的边框
  
   DWORD itemData;// 指定与菜单项相联系的应用程序定义的32位值
  
   }DRAWITEMSTRUCT;
  
   其中itemAction 和 itemState决定了需要的绘图操作。itemAction 说明需要的绘图操作,可为下列值中的一个或多个;
  
   值 含 义
  
   ODA_DRAWENTIRE 需要重来全部控制时
  
   ODA_FOCUS 获得或失去输入焦点
  
   ODA_SELECT 选择状态改变
  
   itemState指明当前绘图动作发生之后,项的可见状态。下面是状态标志:
  
   值 含 义
  
   ODS_CHECKD 只用于菜单中
  
   ODS_DISABLE 该项被屏蔽
  
   ODS_FOCUS 该项具有输入焦点
  
   ODS_GRAYED 只用于菜单中
  
   ODS_SELECT 该项处于被选中状态
  
   用VC++实现自绘按钮控制
  
   利用VC++编程会发现,当按钮控制接收到WM-DRMAWITEM消息时会调用Cbotton类的DrawItem函数。因此我们要做的就是利用

C++的多态性通过重载CButton类的Drawitem函数来响应MW-DRAWITEM消息。
  
   下面我们就实际构造一个CColorButton类。
  
   class ccolorButton:public CButton
  
   { private:
  
   COLORREF m-color:
  
   public:
  
   CColorButton():CButton(),m-color(0){}; //构造函数
  
   void ChangeColor(COLORREF color); //改变颜色
  
   virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct
  
   );//重载的函数
  
   };
  
   //重载的虚函数
  
   void CColorButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemtruct)
  
   {
  
   CDC dc;
  
   dc.Attach(lpDrawItemStruct->hDC); //得到绘制的设备环境CDC
  
   VERIFY( lpDrawItemStruct->CtlType==ODT-BUTTON);
  
   if (lpDrawItemStruct->itemAction & ODA-DRAWENTIRE)
  
   {
  
   //重绘整个控制
  
   CBrush brush(m-Color);
  
   dc.FillRect(&(lpDrawItemstruct->reItem),&brush)
  
   ;
  
   } if ((lpDrawItemStruct->itemstate & ODS-SELECTED
  
   ) &&
  
   (lpDrawItemStruct->itemAction &
  
   (ODA-SELECT | ODA-DRAWENTIRE))) { //选中了本控制===>高亮边框
  
   COLORREF fc=RGB(255-GetRvalue(m-color), 255-GetG
  
   Value(m-color), 255-GetBValue(m-color));
  
   CBrush brush(fc);
  
   dc.FrameRect(&(lpDrawItemStruct->rcItem),&brush
  
   );
  
   } if (!(lpDrawItemStruct->itemState & ODS-SELECTED) &&
  
   (lpDrawItemStruct->itemAction & ODA-SELECT)){
  
   //控制的选中状态结束===>去掉边框
  
   CBrush brush(m-color);
  
   dc.FrameRect(&lpDrawItemStruct->rcItem,&brush);
  
   } dc.Detach();
  
   } //用于改变颜色的成员函数
  
   void CColorButton::ChangeColor(COLORREF color) { CRect rect;
  
   m-color=color;
  
   GetClientRect(&rect);
  
   }
  
   m-colorChangeColor(COLORREF color)color,WM-DRAWITEM
  
   上面代码中数据成员m-color和来保存按钮的颜色。ChangeColor(COLORREF color)函数负责改变按钮颜色值为color,然后

通过使控制的客户区无效而激发WM-DRAWITEM消息。现在这个按钮控制类就算搭好了。下面我们把它加入到对话框中来试验一下
  
   用VC++实现自绘按钮控制
  
   1.首先通过AppWizard创建一个单文档的应用。
  
   2.紧接着启动AppStadio创建一个对话框。添加一个按钮控制,并将其ID设置为 IDC-COLORBUTTON.最后一定要记住将push

ButtonProperties对话框中的Owner Draw检查框置上检查标志。
  
   3.在AppStadio内运行ClassWizzand来产生CTestDialog类。然后在CTestdialog类中加入数据成员,在CTestDialog类说明

加入如下的private型数据成员:
  
   private:
  
   ccolorButton m-ColorButton;
  
   4.现在剩下的问题是到底要怎样才能使m-ColorButton的DrawItem函数能响应系统发往ID值为IDC-COLORBUTTON的按钮控制的

WM-DRAWITEM消息。这时就要用到CWnd类的成员函数BOOL CWnd::SubclassDlgItem(UINT nID,CWnd *pParent)。通过调用这个函

数,我们可以动态地接管从对话框模板产生的控制,并把它隶属于CWnd对象。即用当前的CWnd对象接管发向隶属于pParent的ID号

为nID的控制的一切消息。对于按钮控制而言,它把当前的按钮控制的位置和大小也清成和nID对应的按钮控制一样。于是我们对

CTestDialog的源文件进行如下的编辑:
  
   BOOL CTestDialog::OnInitDialog()
  
   { CDialog::OnInitDialog();
  
   //TODO:Add extra initialization here
  
   m-ColorButton.SubclassDlgtem(IDC-COLORBUTTON,this)
  
   ;//接管消息
  
   m-ColorButton.ChangeColor(RGB(255,0,0);//设置为红色(可设为任何颜色)
  
   return(TRUE);
  
   }
  
   接着通过ClassWizzard在CTestDialog中加入一个响应鼠标点击IDC-COLORBUTTON按钮的消息的函数:
  
   void CTestDialog::OnColerbutton()
  
   { //TODO:Add your control notification handler code
  
   here
  
   int r=int(((float)rand()/RAND-MAX)*255
  
   int g=int(((float)rand()/RAND-MAX)*255
  
   int b=int(((float)rand()/RAND-MAX)*255
  
   m-ColorButton.ChangeColor(RGB(r,g,b));
  
   }
  
   5.最后,利用ClassWizzard为View加入一个响应WM-LBUTTONDOWN的函数,以便激活对话框。请按如下代码对其进行编辑。
  
   void CTestView::OnLButtonDown(UINT nflags,POINT point)
  
   { CTestDialog dlg;
  
   dlg.Domodal();
  
   }
  
   6.编译并测试该程序。当鼠标在落视窗中时,按下鼠标左键应能弹出一个对话框。在对话框中的红色矩形区域内按下鼠标左

键就会使其边框变成高亮状态,若在这块区域内释放左键则这城区域就会改变颜色且颜色是随机的。
  
   只需更改DrawItem函数中的重绘代码,就可以得到自己的需要图形按钮

0
广告位招租

评论0

请先

广告位招租
易学手机界面分析工具上线!可用于安卓手机界面,模拟器界面分析,加速自动化开发!查看详情
没有账号? 注册忘记密码?

社交账号快速登录

微信扫一扫关注
如已关注,请回复“登录”二字获取验证码
'); })();