VC控件自绘

转载 2013年12月03日 19:32:42

VC中自画控件的过程和方法(CButton, CEdit, etc)

分类: MFC 749人阅读 评论(0) 收藏 举报

Windows自带控件的样式太过单调,为了界面美观一些很多时候需要自己绘制,譬如 按钮,编辑框,组合框等。
自己总结过程如下:


1.生成一个以要重绘的空间类为基类的派生类。(我想重绘CButton, 则应该生成一个CMyButton : public CButton。

 
2.在派生类里面重载DrawItem虚函数(如果该类中没有DrawItem需函数,可以加入WM_NCPAINT消息来代替,在消息的执行体内绘制)
DrawItem虚函数是一个专门用来重绘自画空间的函数,且该函数只能用在派生类中!我们可以重写函数体,在里面完成对控件的定制绘制。
DrawItem函数的调用要求控件的属性是" Owner Draw", 我们当然可以在资源对话框的属性里面设置空件为"OwnerDraw"属性,但更好的方法是在PreSubclassWindow()中进行。注意:不要和PreCreateWindow()函数混了,后者中执行ModifyStyle()函数不起效果。
当CWnd::Create()或DDX_Control被调用后,这两个函数都会调用SubClassWindow(), SubClassWindow()紧接着会调用PreSubclassWindow(),我们可以在该函数内设置控件的属性为"OwnerDraw"

  1. void CMyButton::PreSubclassWindow()   
  2. {  
  3. CButton::PreSubclassWindow();  
  4.   
  5. ModifyStyle(0, BS_OWNERDRAW); // make the button owner drawn<span style="color:#ff0000;">这个很重要,否则不能重绘  
  6. </span>}  



3.子类化重绘类。
有三种方法都可以实现子类化,主要是:


(1)在创建过程中用DDX子类化一个类。
具体就是在ClassWizard里为对应的对话框内的CButton创建一个类型为CMyButton的变量。
CMyButton m_myButton;
这样, 对话框的DoDataExchange会创建一个DDX_Control调用。DDX_Control会调用SubClassWindow, 这样就可以使得你的按钮实用CMyButton的消息处理,而不用CButton的。

(2)实用一个不被ClassWizard支持的类子类化一个控件。

假如你的项目中已经加入了一个窗口类,你想子类化该类类型的一个对象,但是ClassWizard并不提供给你这种类类型,这时你就需要重建ClassWizard文件。

首先备份以下项目下的.clw文件到一个别的目录下,然后删除项目目录下的.clw文件,然后点击Ctrl+W,这时会弹出一个对话框让你选择你想包含的类。如果没有选择你的新类,你可以自己到头文件里手动修改父类为子类(譬如把CButton 修改为CMyButton)


(3)子类化一个已经存在的窗口类。
用DDX子类化一个类非常简单,但如果我们想子类化的是一个已经存在的类的时候,这种方法就不适合了。例如我们想子类化一个组合框内的编辑框控件,则你需要事先把组合框创建好。
这种情况下,你可以使用方便的SubclassDlgItem()或SubclassWindow()函数来完成。这两个函数允许你动态的子类化一个类, 也就是他们可以使你的的新类类型的对象依附于一个已经存在的窗口。
例如假设我们有一个对话框,上面有一个ID为ID_BUTTON1的按钮控件,这个控件早已经创建成功存在于对话框了,而我们想把这个按钮跟一个CMyButton类的对象建立联系,从而使得这个按钮控件表现出CMyButton定义的行为。


(a)首先我们需要定义一个CMyButton类的对象,这个对象定义为对话框或者视图类(View)的变量就比较合适。
CMyButton m_btnButton;

定义好变量后, 我们可以在对话框的OnInitialDialog()(或者别的合适的地方也可以)调用:
m_btnButton.SubclassDlgItem(IDC_BUTTON1, this);
完成子类化。


(b)如果你不想使用SubclassDlgItem,也可以这样子类化。假设你已经获得了一个指向我们想子类化控件类的指针(譬如这里就是一个指向IDC_BUTTON1所标识的按钮的指针),如果你是在视图类(View)或者别的从CWnd继承来的类里面来完成控件的动态创建,你可以这样:
CWnd* pWnd = GetDlgItem(IDC_BUTTON1); // or use some other method to get
// a pointer to the window you wish
// to subclass
ASSERT( pWnd && pWnd->GetSafeHwnd() );
m_btnMyButton.SubclassWindow(pWnd->GetSafeHwnd());
完成子类化过程。

 

 要在按钮中进行了画图的话,,在窗口进行了刷新操作的话,需要在DrawItem函数中添加if (lpDrawItemStruct->itemAction & ODA_DRAWENTIRE)。。。这是判断是否为刷新的条件语句。


总上,子类化并不难,你只需要认真的选择你需要子类化的类,并且清楚你想自己处理的消息是什么并处理他们。清楚你要子类化的类都有哪些虚拟函数并重写他们。

原文:http://blog.csdn.net/heaven13483/article/details/8206083

相关文章推荐

VC 点滴 之 重绘

一基本知识: 1.OnPaint和OnDraw函数View的父类的OnPaint函数调用了OnDraw函数,若在子类为WM_PAINT消息添加响应函数OnPaint,OnDraw函数将不会被调用。2....
  • awnucel
  • awnucel
  • 2004年09月03日 11:34
  • 3446

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Windows窗体原理及控件重绘技巧

之前有学MFC的同学告诉我觉得Windows的控件重绘难以理解,就算重绘成功了还是有些地方不明白,我觉得可能很多人都有这样的问题,在这里我从Windows窗体的最基本原理来讲解,如果你有类似的疑惑希望...

c# 使用webbrower做界面

直接使用webbrower,会发现其对js支持不友善,会弹出一些警告框,然后停止运行js,导致页面无法渲染成功. 在此要自己封装一次webbrower,对于这些js警告进行静默化 需要添加引用 Mic...

vc自绘控件总结

想必很多使用MFC编程的朋友都想去用微软的控件,但是很多时候我们发现控件的功能并没有想象中的那么强大,而且很多功能我们根本都用不到,我们想去自绘控件,但是又不知道如何着手。本文介绍MFC控件设计的大致...

vc循序渐进实现仿QQ界面(三):界面调色与控件自绘

本篇讲述如何进行界面调色。界面调色一般有两种方法,调色板和HSL色彩变换。调色板局限于256色,这里不采用,因此用HSL色彩变换实现。首先要了解一下什么是HSL色彩空间,完整且详尽的知识请到维基百科...

vc SDK山寨spy++ FinderTool工具(靶心控件)纯GDI自绘

GDI编程本人不是很懂,以下代码,是之前还在MFC写代码的时候,度娘爬楼,挖坟千百次的成果,注释得已经比较详细了,反正我知道的都注释了,我不知道的我也没办法了。 现在只是把这个代码转到win32 SD...
  • Gnorth
  • Gnorth
  • 2013年07月13日 00:38
  • 1861

VC自定义向导(含控件自绘)

  • 2013年06月13日 16:15
  • 2.28MB
  • 下载

VC自绘的滑块 浮标控件

  • 2015年12月09日 12:01
  • 3KB
  • 下载

【MFC控件自绘】VC控件自绘制

http://blog.csdn.net/lijie45655/article/details/6362441 实现自定义绘制的三步曲 既然您已经了解了绘制控件可用的各种选项(包括使用自定...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VC控件自绘
举报原因:
原因补充:

(最多只允许输入30个字)