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

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

1).补充个高级可重载函数PreSubclassWindow(),我的理解是允许用户在子类化之前再做一额外些处理 ,这个重载函数也是非常重要的,要引起相当的注意。可以在这里改变控件的大小,位置,窗口样式,字体 ,等等.....你能想到的能改的,都可以在这里改.

2).关于Edit的补充说明:我最初的自绘方法是利用 WM_NCPAINT 里面处理的非客户区只是自己画了边界,以实现Hover和Leave不同的边界。不过我后来发现由于非客户区太小了边界也就2像素,如果鼠标移动很快有时 系统不能检测到鼠标当前的状态,所以程序里面的Edit是在OnPaint里面做的绘制,不过有个核心API -Default() 下面看代码
void CEditEx::OnPaint() 
{

Default();         // 关键

if(!m_bHover)
DrawBoder();   // 画自己的边界

},这才是程序里面的自绘Edit使用的方法.

3).对于控件的Hover和Leave效果,简单的说 Hover就是鼠标现在浮于控件上面,Leave就是鼠标离开了控件,那么这个效果要怎么实现呢?我直接给源码吧
以Edit控件为列
头文件中加入

afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
CPP中加入:
BEGIN_MESSAGE_MAP(CEditEx, CEdit)
ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave) 
ON_MESSAGE(WM_MOUSEHOVER, OnMouseHover)
ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()
注:ON_WM_MOUSEMOVE() 可以用类向导添加,不过OnMouseLeave,和OnMouseHover是需要手动添加的

然后再CPP中定义:
void CEditEx::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bHover)
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 1;
m_bHover= _TrackMouseEvent(&tme);// m_bHover: BOOL型成员变量

}

CEdit::OnMouseMove(nFlags, point);
}
LRESULT CEditEx::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bHover = false;
//
做相应的操作
//
return 0;
}
LRESULT CEditEx::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
//
做相应的操作
//
return 0;
}
绝大多数控件可以用这种方法,不过某些控件,可能需要你在OnMouseMove里面完全模拟出 Hover和Leave的情况,比如程序里面的TabCtrl...

4).我把以前我看过的帖子整理了下供大家学习参考(由于时间久了,很多帖子都忘记了):

进度条自绘:http://www.codeproject.com/KB/miscctrl/cprogressctrlst.aspx(有项目源码)

透明控件(多个控件)实现:http://www.codeguru.com/cpp/controls/buttonctrl/advancedbuttons/article.php/c15603/General-Solution-for-a-Transparent-Control.htm(有项目源码)

透明窗体:http://msdn.microsoft.com/en-us/library/ms997507 (Menu、窗体、Combobox 都可以参考这种方式实现任意透明度,我也是参考这种方法)

不规则按钮实现:http://www.codeguru.com/cpp/controls/buttonctrl/non-rectangularbuttons/article.php/c2085/Universal-Button---beauty-of-HRGN.htm

自绘按钮2篇帖子:
http://www.vckbase.com/document/viewdoc/?id=551
http://www.vckbase.com/document/viewdoc/?id=561

Custom draw 和 Owner draw 的区别(是全英文,不过要是读懂了对你自绘的思想很有帮助,有时间帮大家翻译下):
http://blog.csdn.net/xiexievv/article/details/6279219

WM_DRAWITEM与DrawItem()的讨论,对控件自绘很有帮助:
http://blog.csdn.net/xiexievv/article/details/6259194

下面这几篇帖子仔细阅读定有意想不到的收获,不只是自绘控件,完全可以让我们对MFC的整体认识都会提升1个等级
MFC中OnDraw与OnPaint的区别:
http://blog.csdn.net/xiexievv/article/details/6271153

深度剖析消息反射机制:
http://blog.csdn.net/xiexievv/article/details/6282205

PreTranslateMessage和TranslateMessage区别:
http://blog.csdn.net/xiexievv/article/details/6299027

WindowProc和DefWindowProc的区别:
http://blog.csdn.net/xiexievv/article/details/6299016

CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow的区别:
http://blog.csdn.net/xiexievv/article/details/6233423

同时推荐几个很好的学习网站: 
http://www.codeproject.com(英文)
http://www.codeguru.com(英文)
http://www.pudn.com
http://www.vckbase.com/document/index.asp

就写这么多吧,个人觉得最有用的资料还是MSDN当然还有强大CSDN,每个控件的自绘都不是固定有规律可循的,不要硬搬乱套,要活学活用。也许你现在才开始学,完全看不懂,没关系大家都是那么过来的啦。

http://blog.csdn.net/xiexievv/article/details/6598696

时间: 2025-01-16 14:19:37

MFC自绘控件学习总结第二贴的相关文章

MFC自绘控件学习总结

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

MFC 之ActiveX控件学习

本文将介绍ActiveX控件的应用与工作原理,读者可以把ActiveX控件看成一个极小服务器的应用程序,它不能独立运行,必须要嵌入到容器程序中与容器一起运行,就像电脑主机中的显卡,它自己在电脑硬件系统中是不能发挥作用的必须要和嵌入到主板中,与主板一起工作. ActiveX控件与普通的Windows控件有共同之处也存在差异.首先ActiveX控件有自己的属性和方法.对ActiveX控件的操作通过调用控件对外的方法即可.而Windows控件是Windows内部的对象,虽然它们也有自己的属性和方法但是

MFC之自绘控件

在描绘MFC界面时,MFC自带的控件样式是绝对不满足界面的需求的. 所以我们就要在MFC自带控件基础上对控件样式进行重绘. 在采用自绘前界面样式 采用自绘后界面样式 是不是自绘控件后看起来正常了很多? 自绘控件的步骤: 我们以做一个关闭按钮为例 先创建一个MFC类继承自CButton. 给这个类添加 一个虚函数DrawItem()和 一个afx BOOL OnEraseBkgnd()函数(一般以afx开头的函数都会在消息映射里面有一条映射) DrawItem()是控件的自绘处理函数,在这个函数中

MFC中按钮控件的用法笔记(转)

VC学习笔记1:按钮的使能与禁止 用ClassWizard的Member Variables为按钮定义变量,如:m_Button1:则m_Button1.EnableWindow(true); 使按钮处于允许状态m_Button1.EnableWindow(false); 使按钮被禁止,并变灰显示 VC学习笔记2:控件的隐藏与显示 用CWnd类的函数BOOL ShowWindow(int nCmdShow)可以隐藏或显示一个控件. 例1:CWnd *pWnd;pWnd = GetDlgItem(

VC MFC按钮(CButton)控件

VC MFC按钮(CButton)控件 2012年11月11日 19:15   作者:TCEO   分类:技术文章   浏览:4,298 按钮控件 1如何在按钮控件上显示图片 首先确定你要显示在按钮控件的图片类型是什么,这里我是ico图标,由于要在按钮里显示ico图标,所以要把按钮控件的属性改一下, 方法是右击按钮控件,选择属性,单击样式选项卡,把图标这一项给勾上. 然后为这个按钮控件关联一个变量如:m_Quit,类型是”Control”,以后不做说明的话,类型都是”Control”. 按钮控件

Android自定义控件_自绘控件

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

[VC/MFC]虚拟列表控件

[VC/MFC]虚拟列表控件 一.什么是虚拟列表控件 虚拟列表控件是指带有LVS_OWNERDATA风格的列表控件.. 二.为什么使用虚拟列表控件 我们知道,通常使用列表控件CListCtrl,需要调用InsertItem把要显示的数据插入列表中,之后我们就不必关心数据在哪里了,这是因为控件自己开辟了内存空间来保存这些数据.现在假设我们要显示一个数据库,里面的信息量很大,有几十万条记录.通常有两种方法解决这个问题:1是仅仅在ListCtrl中插入少量的数据,比如100个,然后通过[上一页][下一

基于wince的MFC Tab Control控件的使用

1,先建立一个对话框MFC应用程序,然后在工具箱里面把Tab Control控件放到对话框中的合适位置上. 再在对话框类中,声明一个CTabCtrl变量: CTabCtrl m_tab; 变量m_tab用来与对话框中的Tab Control控件交互,为此要在DoDataExchange函数中加入DDX_Control语句: 1 //{{AFX_DATA_MAP(CTABDlg) 2 DDX_Control(pDX, IDC_TAB, m_tab); 3 //}}AFX_DATA_MAP IDC_

MFC动态创建控件及添加消息响应

MFC动态创建控件及添加消息响应 分类: 控件技术2013-01-24 14:12 7020人阅读 评论(0) 收藏 举报 转载地址:http://blog.csdn.net/luy3728000/article/details/8193918 动态控件是指在需要时由Create()创建的控件,这与预先在对话框中放置的控件是不同的. 一.创建动态控件: 为了对照,我们先来看一下静态控件的创建. 放置静态控件时必须先建立一个容器,一般是对话框,这时我们在对话框编辑窗口中,从工具窗口中拖出所需控件放