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

时间:2023-03-08 17:04:48

首先感谢大家对第一帖的支持,应一些网友烈要求下面我在关于上一贴的一些补充和说明(老鸟可以无视)
这一贴是实战+理论不知道第一帖的先看第一帖:
http://topic.****.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.****.net/xiexievv/article/details/6279219

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

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

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

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

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

CWnd中PreCreateWindow、PreSubclassWindow、SubclassWindow的区别:
http://blog.****.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当然还有强大****,每个控件的自绘都不是固定有规律可循的,不要硬搬乱套,要活学活用。也许你现在才开始学,完全看不懂,没关系大家都是那么过来的啦。