MFC自繪控件學習總結第二貼---轉
睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接
首先感謝大家對第一帖的支持,應一些網友烈要求下面我在關于上一貼的一些補充和說明(老鳥可以無視)
這一貼是實戰+理論不知道第一帖的先看第一帖:
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,每個控件的自繪都不是固定有規律可循的,不要硬搬亂套,要活學活用。也許你現在才開始學,完全看不懂,沒關系大家都是那么過來的啦。
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
這一貼是實戰+理論不知道第一帖的先看第一帖:
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,每個控件的自繪都不是固定有規律可循的,不要硬搬亂套,要活學活用。也許你現在才開始學,完全看不懂,沒關系大家都是那么過來的啦。
RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成