MFC之自绘控件
在描绘MFC界面时,MFC自带的控件样式是绝对不满足界面的需求的。
所以我们就要在MFC自带控件基础上对控件样式进行重绘。
在采用自绘前界面样式
采用自绘后界面样式
是不是自绘控件后看起来正常了很多?
自绘控件的步骤:
我们以做一个关闭按钮为例
- 先创建一个MFC类继承自CButton。
- 给这个类添加 一个虚函数DrawItem(),一个虚函数PreSubclassWindow()和 一个afx BOOL OnEraseBkgnd()函数(一般以afx开头的函数都会在消息映射里面有一条映射)
- 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);
} 添加OnEraseBkgnd()函数代码,一般都是固定的
BOOL CDhsButton::OnEraseBkgnd(CDC* pDC)
{ return TRUE; }添加虚函数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之自绘控件的更多相关文章
- MFC 全部自绘控件 界面库
http://download.csdn.net/detail/q97082645/8160793 http://download.csdn.net/user/q97082645/uploads/3
- MFC自绘控件学习总结
前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或 ...
- MFC自绘控件学习总结第二贴---转
首先感谢大家对第一帖的支持,应一些网友烈要求下面我在关于上一贴的一些补充和说明(老鸟可以无视)这一贴是实战+理论不知道第一帖的先看第一帖:http://topic.csdn.net/u/2011071 ...
- MFC基础,MFC自绘控件学习总结.---转
前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或 ...
- MFC自绘控件学习总结第二贴
首先感谢大家对第一帖的支持,应一些网友烈要求下面我在关于上一贴的一些补充和说明(老鸟可以无视)这一贴是实战+理论不知道第一帖的先看第一帖:http://topic.csdn.net/u/2011071 ...
- 用ATL和MFC来创建ActiveX控件
摘要:目前MFC和ATL代表了两种框架,分别面向不同类型的基于Windows的开发.MFC代表了创建独立的Windows应用的一种简单.一致的方法:ATL提供了一种框架来实现创建COM客户机和服务器所 ...
- android图片验证码--自绘控件
自绘控件的内容都是自己绘制出来的 大致流程如下: 1.定义一个类继承view 使用TypedArray初始化属性集合 在view的构造方法中 有一个AttributeSet的参数 很明显是用来保存控件 ...
- 【C++】自绘控件基础
由于我们对控件的功能.外观的需求,公共控件并不能很好地满足这一点,所以我们就得自绘控件. 自绘控件有许多方法,比如:处理WM_PAINT消息,设置ownDraw风格,处理WM_CTLCOLOR消息,等 ...
- OpenCV 2.2版本号以上显示图片到 MFC 的 Picture Control 控件中
OpenCV 2.2 以及后面的版本号取消掉了 CvvImage.h 和CvvImage.cpp 两个文件,直接导致了苦逼的程序猿无法调用里面的显示函数来将图片显示到 MFC 的 Picture Co ...
随机推荐
- 查看和调试Qt源码
简述 在调试程序的时候,有时需要调试进入 Qt 源码,这不仅有利于我们了解内部实现机制,而且对于解决一些隐蔽性问题很有帮助. 都知道 F11 是“单步进入”,可是在调试的过程中,按下 F11 却无法进 ...
- Opencv-Python:图像尺寸、图像的读取、显示、保存与复制
Opencv-Python:图像尺寸.图像的读取.显示.保存与复制 原创 2017年11月23日 21:30:49 4440 在使用opencv的方法时,首先必须导入opencv包.新的opencv导 ...
- pandas汇总和计算描述统计
pandas 对象拥有一组常用的数学和统计方法. 他们大部分都属于简约和汇总统计, 用于从Series中提取单个值(如sum或mean) 或从DataFrame的行或列中提取一个Series.跟对应的 ...
- Eclipse创建一个Maven Web项目
在这篇文章中,我们将演示如何在Eclipse IDE中使用maven创建一个动态Web项目. 使用的工具和技术 - Eclipse Jee Oxygen Maven 3.3.3 JavaSE 1.8 ...
- (转)使用FFMPEG类库分离出多媒体文件中的H.264码流
出自:http://blog.csdn.net/leixiaohua1020/article/details/11800877 在使用FFMPEG的类库进行编程的过程中,可以直接输出解复用之后的的 ...
- linux vi命令详解2
刚开始学着用linux,对vi命令不是很熟,在网上转接了一篇. vi编辑器是所有Unix及Linux系统下标准的编辑器,它的强大不逊色于任何最新的文本编辑器,这里只是简单地介绍一下它的用法和一小部分指 ...
- oracle 11g RAC 在Windows 7下安装
oracle 11g RAC 在Windows 7下安装 完全要参考RAC11gR2OnWindows.pdf 难点总是在Grid Infrastructure 而安装Grid Infrastruct ...
- Umbraco中使用Related Links显示内部链接和外部链接
在Umbraco的论坛里看到的办法,演示了如何在Umbraco中使用Related Links并显示的过程. 原文地址:http://www.nibble.be/?p=48
- 【ML】人脸识别
https://github.com/colipso/face_recognition https://medium.com/@ageitgey/machine-learning-is-fun-par ...
- Gridview、DataList、Repeater获取行索引号
Gridview.DataList.Repeater如何获取行索引号?很多情况下都会用得到,下面贴出代码,注意行索引号是从0开始,不是从1开始,如果要从1开始,请在代码里面+1就行了. Gridvie ...