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

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

在采用自绘前界面样式

采用自绘后界面样式

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

自绘控件的步骤:

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

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

    附一段代码为例:

     void CDhsButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    CDC* pDC= CDC::FromHandle(lpDrawItemStruct->hDC);
    CRect rect = &lpDrawItemStruct->rcItem;
    UINT uID = lpDrawItemStruct->CtlID; Graphics g(pDC->m_hDC);
    g.SetSmoothingMode(SmoothingModeHighQuality); if (::GetWindowLong(m_hWnd, GWL_STYLE) & WS_DISABLED)
    {
    if (m_pImageDisable != NULL)
    g.DrawImage(m_pImageDisable, , , rect.Width(), rect.Height());
    else
    g.DrawImage(m_pImageNormal, , , rect.Width(), rect.Height());
    }
    else if (m_nMouseState == Down)
    {
    if (m_pImageOver != NULL)
    g.DrawImage(m_pImageOver, , , rect.Width(), rect.Height());
    else
    g.DrawImage(m_pImageNormal, , , rect.Width(), rect.Height());
    }
    else if (m_bSelected)
    {
    if (m_pImageSelected != NULL)
    g.DrawImage(m_pImageSelected, , , rect.Width(), rect.Height());
    else
    g.DrawImage(m_pImageNormal, , , rect.Width(), rect.Height());
    }
    else
    {
    g.DrawImage(m_pImageNormal, , , rect.Width(), rect.Height());
    } if (!m_strCaption.IsEmpty())
    {
    rect.left += ; if (::GetWindowLong(m_hWnd, GWL_STYLE) & WS_DISABLED)
    {
    PublicFun::GDIDrawText(pDC, m_strCaption, rect, m_pFont, RGB(, , ), FALSE, TRUE);
    }
    else if (m_bSelected)
    {
    PublicFun::GDIDrawText(pDC, m_strCaption, rect, m_pFont, RGB(, , ), FALSE, TRUE);
    }
    else if (m_nMouseState == Over)
    {
    PublicFun::GDIDrawText(pDC, m_strCaption, rect, m_pFont, RGB(, , ), FALSE, TRUE);
    }
    else
    {
    PublicFun::GDIDrawText(pDC, m_strCaption, rect, m_pFont, RGB(, , ), FALSE, TRUE);
    }
    } ReleaseDC(pDC);
    }
  4. 添加OnEraseBkgnd()函数代码,一般都是固定的

    BOOL CDhsButton::OnEraseBkgnd(CDC* pDC)
    { return TRUE; }
  5. 添加虚函数PreSubclassWindow函数代码(PreSubclassWindow函数实际上是在CWnd::CeateEx方法中的 AfxHookWindowCreate(this)方法中实现的,AfxHookWindowCreate作用是设置钩子函数,所以你如果想在创建窗口之前将窗口与自己的派生类进行关联,这时候建立前的处理就要在PreSubclassWindow中写。)

    具体来说,

  • 如果你定义一个窗口(如CButton派生类CMyButton),然后使用对话框数据交换比如通过DDX将一个按钮与自己的派生类对象关联,这时候,一些"建立前"的处理就应该写在"PreSubclassWindow"中。
  • 如果你用的不是"对话框数据关联",而是在OnInitDialg中自己创建.这时候,一些"建立前"的处理就应该写在   "PreCreateWindow"中。)

在PreSubclassWindow函数中,设置ModifyStyle(0, BS_OWNERDRAW);
代码如下

 void CDhsButton::PreSubclassWindow()
{
ModifyStyle(, BS_OWNERDRAW); CButton::PreSubclassWindow();
}

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

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

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

  7.添加按钮事件:

MFC之自绘控件的更多相关文章

  1. MFC 全部自绘控件 界面库

    http://download.csdn.net/detail/q97082645/8160793 http://download.csdn.net/user/q97082645/uploads/3

  2. MFC自绘控件学习总结

    前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或 ...

  3. MFC自绘控件学习总结第二贴---转

    首先感谢大家对第一帖的支持,应一些网友烈要求下面我在关于上一贴的一些补充和说明(老鸟可以无视)这一贴是实战+理论不知道第一帖的先看第一帖:http://topic.csdn.net/u/2011071 ...

  4. MFC基础,MFC自绘控件学习总结.---转

    前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或 ...

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

    首先感谢大家对第一帖的支持,应一些网友烈要求下面我在关于上一贴的一些补充和说明(老鸟可以无视)这一贴是实战+理论不知道第一帖的先看第一帖:http://topic.csdn.net/u/2011071 ...

  6. 用ATL和MFC来创建ActiveX控件

    摘要:目前MFC和ATL代表了两种框架,分别面向不同类型的基于Windows的开发.MFC代表了创建独立的Windows应用的一种简单.一致的方法:ATL提供了一种框架来实现创建COM客户机和服务器所 ...

  7. android图片验证码--自绘控件

    自绘控件的内容都是自己绘制出来的 大致流程如下: 1.定义一个类继承view 使用TypedArray初始化属性集合 在view的构造方法中 有一个AttributeSet的参数 很明显是用来保存控件 ...

  8. 【C++】自绘控件基础

    由于我们对控件的功能.外观的需求,公共控件并不能很好地满足这一点,所以我们就得自绘控件. 自绘控件有许多方法,比如:处理WM_PAINT消息,设置ownDraw风格,处理WM_CTLCOLOR消息,等 ...

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

    OpenCV 2.2 以及后面的版本号取消掉了 CvvImage.h 和CvvImage.cpp 两个文件,直接导致了苦逼的程序猿无法调用里面的显示函数来将图片显示到 MFC 的 Picture Co ...

随机推荐

  1. popupWindow使用timePicker时点击出现闪屏问题的解决办法

    记录一下刚解决的新鲜bug,噔噔噔噔: 首先说明,我并不知道到底是什么原理导致和解决的问题 总之就是,我在使用popupWindow时的弹出方法使用的是popupWindow.showAsDropDo ...

  2. C和C++的内存操作小贴士(一):const char*的内存释放问题

    C和C++的内存操作一直是困扰开发人员的老问题,基本概念相信老司机们都很清楚了,在这里就不做过多的描述了,只是把在实际开发中可能遇到的一些小问题的案例列举下,供大家参考.“C和C++的内存操作小贴士” ...

  3. 修改socket文件, MySQL启动报错

    事情是这样的, 我要搭建MySQL主从, 做读写分离, 然后就要了一台服务器搭建mysql, 最近犯懒, 就寻思搞一个二进制的吧直接启用 一堆问题就出现了 [ERROR] Can't start se ...

  4. jQuery AJAX中文乱码处理

    最近工作中用jQuery ajax返回出现乱码,用的Notepad++编辑器,当JS部分传递中文时,另一页面接收的话会出现乱码,在网上找了很多方法,基本上没有很好的解决. 页面用GB2312编码,JS ...

  5. SAP Actual Costing with Material Ledger 激活实际成本后台配置

    Actual Costing with Material Ledger 1      Purpose This configuration guide provides the information ...

  6. OpenGL光照设置

    一.设置光源 (1)光源的种类 环境光 环境光是一种无处不在的光.环境光源放出的光线被认为来自任何方向.因此,当你仅为场景指定环境光时,所有的物体无论法向量如何,都将表现为同样的明暗程度. 点光源 由 ...

  7. 第三百九十一节,Django+Xadmin打造上线标准的在线教育平台—404,403,500页面配置

    第三百九十一节,Django+Xadmin打造上线标准的在线教育平台—404,403,500页面配置 路由映射在全局也就是根目录里的urls.py里配置404路由映射 注意:不是写在urlpatter ...

  8. CI框架 -- 核心文件 之 Output.php(输出类文件)

    CI输出类Output.php的功能是将最终web页面发送给浏览器,这里面的东西可能是你用的最少的.你使用装载器加载了一个视图文件, 这个视图文件的内容会自动传递给输出类对象, 然后呢,在方法执行完毕 ...

  9. JAXB:Java对象序和XML互相转化的利器

    JAXB(Java Architecture for XML Binding简称JAXB)允许Java开发人员将Java类映射为XML表示方式.JAXB提供两种主要特性:将一个Java对象序列化为XM ...

  10. C# 最小化到托盘,托盘右击菜单显示

    添加notifyIcon控件,并添加Icon,否则托盘没有图标(托盘右键菜单也可直接在属性里添加): 主要的代码: public partial class Form1 : Form { #regio ...