MFC之自绘控件

在描绘MFC界面时,MFC自带的控件样式是绝对不满足界面的需求的。

所以我们就要在MFC自带控件基础上对控件样式进行重绘。

在采用自绘前界面样式

采用自绘后界面样式

是不是自绘控件后看起来正常了很多?

自绘控件的步骤:

我们以做一个关闭按钮为例

  1. 先创建一个MFC类继承自CButton。
  2. 给这个类添加 一个虚函数DrawItem()和 一个afx BOOL OnEraseBkgnd()函数(一般以afx开头的函数都会在消息映射里面有一条映射)
  3. DrawItem()是控件的自绘处理函数,在这个函数中可以对控件的样式进行描绘。

    附一段代码为例:

      1 void CDhsButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
      2
      3 {
      4
      5     CDC* pDC= CDC::FromHandle(lpDrawItemStruct->hDC);
      6
      7     CRect rect = &lpDrawItemStruct->rcItem;
      8
      9     UINT uID = lpDrawItemStruct->CtlID;
     10
     11
     12
     13     Graphics g(pDC->m_hDC);
     14
     15     g.SetSmoothingMode(SmoothingModeHighQuality);
     16
     17
     18
     19     if (::GetWindowLong(m_hWnd, GWL_STYLE) & WS_DISABLED)
     20
     21     {
     22
     23         if (m_pImageDisable != NULL)
     24
     25             g.DrawImage(m_pImageDisable, 0, 0, rect.Width(), rect.Height());
     26
     27         else
     28
     29             g.DrawImage(m_pImageNormal, 0, 0, rect.Width(), rect.Height());
     30
     31     }
     32
     33     else if (m_nMouseState == Down)
     34
     35     {
     36
     37         if (m_pImageOver != NULL)
     38
     39             g.DrawImage(m_pImageOver, 0, 0, rect.Width(), rect.Height());
     40
     41         else
     42
     43             g.DrawImage(m_pImageNormal, 0, 0, rect.Width(), rect.Height());
     44
     45     }
     46
     47     else if (m_bSelected)
     48
     49     {
     50
     51         if (m_pImageSelected != NULL)
     52
     53             g.DrawImage(m_pImageSelected, 0, 0, rect.Width(), rect.Height());
     54
     55         else
     56
     57             g.DrawImage(m_pImageNormal, 0, 0, rect.Width(), rect.Height());
     58
     59     }
     60
     61     else
     62
     63     {
     64
     65         g.DrawImage(m_pImageNormal, 0, 0, rect.Width(), rect.Height());
     66
     67     }
     68
     69
     70
     71     if (!m_strCaption.IsEmpty())
     72
     73     {
     74
     75         rect.left += 5;
     76
     77
     78
     79         if (::GetWindowLong(m_hWnd, GWL_STYLE) & WS_DISABLED)
     80
     81         {
     82
     83             PublicFun::GDIDrawText(pDC, m_strCaption, rect, m_pFont, RGB(120, 120, 120), FALSE, TRUE);
     84
     85         }
     86
     87         else if (m_bSelected)
     88
     89         {
     90
     91             PublicFun::GDIDrawText(pDC, m_strCaption, rect, m_pFont, RGB(0, 0, 0), FALSE, TRUE);
     92
     93         }
     94
     95         else if (m_nMouseState == Over)
     96
     97         {
     98
     99             PublicFun::GDIDrawText(pDC, m_strCaption, rect, m_pFont, RGB(0, 0, 0), FALSE, TRUE);
    100
    101         }
    102
    103         else
    104
    105         {
    106
    107             PublicFun::GDIDrawText(pDC, m_strCaption, rect, m_pFont, RGB(0, 0, 0), FALSE, TRUE);
    108
    109         }
    110
    111     }
    112
    113
    114
    115     ReleaseDC(pDC);
    116
    117 }
  4. 添加OnEraseBkgnd()函数代码,一般都是固定的
    1 BOOL CDhsButton::OnEraseBkgnd(CDC* pDC)
    2
    3 {
    4
    5 return TRUE;
    6
    7 }
  5. 添加虚函数PreSubclassWindow函数(PreSubclassWindow函数实际上是在CWnd::CeateEx方法中的 AfxHookWindowCreate(this)方法中实现的,AfxHookWindowCreate作用是设置钩子函数,所以你如果想在创建窗口之前将窗口与自己的派生类进行关联,这时候建立前的处理就要在PreSubclassWindow中写。
  6. 具体来说,
  • 如果你定义一个窗口(如CButton派生类CMyButton),然后使用对话框数据交换比如通过DDX将一个按钮与自己的派生类对象关联,这时候,一些"建立前"的处理就应该写在"PreSubclassWindow"中。
  • 如果你用的不是"对话框数据关联",而是在OnInitDialg中自己创建.这时候,一些"建立前"的处理就应该写在   "PreCreateWindow"中。)

在PreSubclassWindow函数中,设置ModifyStyle(0, BS_OWNERDRAW);

BS_OWNERDRAW属性是要创建CButton的继承类,并在其中重载DrawItem方法才可以。你要是不想改变Button的外观不要用这个属性。

意思就是如果你要重载派生类按钮中的DrawItem方法,必须要设置了BS_OWNERDRAW 才能重载

  7.因为是通过DDX关联的方式,所以在使用上,要用DoDataExchange方法将派生类与资源中的按钮进行关联。

  8.添加按钮事件:

时间: 2024-08-19 05:50:25

MFC之自绘控件的相关文章

MFC自绘控件学习总结

前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或者有更好的方法,请不吝赐教.我的机器环境是:Windows7旗舰版 Service Pack 1,Visual studio 20051).重绘某个控件时,强烈推荐使用子类化方法,比如想自绘Button控件, 首先添加自己的类CMYButton 继承自 CButton ,声明一个CMYButton

MFC自绘控件学习总结第二贴

首先感谢大家对第一帖的支持,应一些网友烈要求下面我在关于上一贴的一些补充和说明(老鸟可以无视)这一贴是实战+理论不知道第一帖的先看第一帖:http://topic.csdn.net/u/20110710/19/5209f358-31c8-4057-b108-02155a417fd0.html 1).补充个高级可重载函数PreSubclassWindow(),我的理解是允许用户在子类化之前再做一额外些处理 ,这个重载函数也是非常重要的,要引起相当的注意.可以在这里改变控件的大小,位置,窗口样式,字

Android自定义控件_自绘控件

控件的划分:自绘控件.组合控件.继承控件 每种方式是如何自定义View的? 第一:自绘控件 继承view,重写onDraw方法,在布局文件里面引用     示例:水波纹 WaterRipplesActivity 1 public class WaterRipplesActivity extends Activity { 2 @Override 3 protected void onCreate(Bundle savedInstanceState) { 4 super.onCreate(saved

MFC入门教程之控件(7)设备自动检测ondevicechange的添加和使用

MFC入门学习(1)了解MFC 源文档<http://blog.csdn.net/codectq/article/details/19131227> MFC入门学习之控件(2)创建一个对话框窗口并在运行时显示 源文档<http://blog.csdn.net/codectq/article/details/19131289> MFC入门学习之控件(3)标签控件Tab Control的添加和使用 源文档<http://blog.csdn.net/codectq/article/

Android 自定义View之自绘控件

首先要提前声明一下,我对于自定义View的理解并不是很深,最近啃了几天guolin博主写的关于自定义View的博客,讲的非常棒,只不过涉及到源码和底层的一些东西,我自己就懵逼了,目前只是会了关于自定义View的简单使用,不过还是要写出来,当做练习了,哈哈~对于一些没有接触过的初学者,希望会有所帮助,共同成长: 按类型,自定义View可以分为三种:自绘控件.组合控件.继承控件,对于这三种类型,我会写三篇博客来分别介绍和使用. 自定义View中有三个非常重要的方法,分别为: onMeasure():

OpenCV 通过 MFC 的 Picture Control 控件操作图像

如果希望对显示在MFC Picture Control 控件里的图像进行操作,比如画线画点之类的,可以利用 OpenCV 结合 MFC 本身的鼠标响应函数来实现. 如何将图像显示到 Picture Control 控件不谈,本文是采用的这篇博客所介绍的方法实现的. 点击打开链接 给对话框添加 WM_LBUTTONDOWN 鼠标左键点击消息,在消息响应函数中添加如下代码: void CMFCOpenCVShowDlg::OnLButtonDown(UINT nFlags, CPoint point

自绘控件时添加LBS_OWNERDRAWFIXED风格,离奇报错的解决方案!

   在自绘CListBox的时候本人遇到过一件很头痛的事情,当然,这点小问题对于大牛来说,压根不屑一顾,可是初学者遇到的话,一时半会还真没什么办法解决.      自绘控件很简单,按照书上的步骤一步一步来操作即可,就拿自绘CListBox为例.      我们从CListBox派生出一个子类CListBoxEx,然后添加DrawItem和MeasureItem函数即可.我不知道有多少人和我一样,喜欢通过机器自动给我们添加.     机器添加代码之后,我们的类大概就变成了这样子:       好

OpenCV 2.2版本以上显示图片到 MFC 的 Picture Control 控件中

OpenCV 2.2 以及后面的版本取消掉了 CvvImage.h 和CvvImage.cpp 两个文件,直接导致了苦逼的程序员无法调用里面的显示函数来将图片显示到 MFC 的 Picture Control 控件中.为此,网上很多人表示只要将那两个文件人为的提取出来然后放到工程里面就解决问题了,也提供了两个文件的下载,但是这麻烦不说,还会导致一些奇奇怪怪的报错(至少本人是这样的,很崩溃!).所以在了解了一些gdi绘图之后结合网上的代码写了如下的函数,只需调用就可以将OpenCV的图片显示在上面

VS2010/MFC对话框:为控件添加消息处理函数

为控件添加消息处理函数 创建对话框类和添加控件变量在上一讲中已经讲过,这一讲的主要内容是如何为控件添加消息处理函数. MFC为对话框和控件等定义了诸多消息,我们对它们操作时会触发消息,这些消息最终由消息处理函数处理.比如我们点击按钮时就会产生BN_CLICKED消息,修改编辑框内容时会产生EN_CHANGE消息等.一般为了让某种操作达到效果,我们只需要实现某个消息的消息处理函数. 一.添加消息处理函数 以前面的加法计算器的程序为例,说明怎样为“计算”按钮控件添加消息处理函数.添加方法列出4种: