關(guān)鍵字:滾動條(ScrollBar)
一、說明
我們大家對MFC控件本身的美化工作都比較熟悉了,這方面的文章也是比較多的。但是對于控件中的滾動條美化,相關(guān)資料卻比較少。已有的實(shí)現(xiàn)采用的是禁用控件的滾動條,然后在原有的位置上重新繪制滾動條,為了實(shí)現(xiàn)滾動條的功能,需要在代碼中進(jìn)行一些較復(fù)雜的計(jì)算。
本文采用的“遮擋”方法只是單純的對滾動條界面進(jìn)行美化,而功能則保持原有的實(shí)現(xiàn)。
二、原理
一個人要想不被人認(rèn)出,除了整容還有什么辦法?還可以采用戴面具擋臉的方法。
一般我們對MFC控件進(jìn)行美化都是對比如WM_CTLCOLOR、WM_DRAWITEM之類的消息進(jìn)行處理,這也相當(dāng)于“整容”了。
滾動條只是作為控件的一部分沒有相應(yīng)的消息可以重寫,所以本文設(shè)想做一個“面具”來遮擋滾動條,這樣即可以保留滾動條的原有功能不變,又看到一個漂亮的“面具”。
三、實(shí)現(xiàn)
“遮擋”方法的原理很簡單,要想實(shí)現(xiàn)這個方法需要解決以下幾個問題:
1.“面具”的材料是什么?
要想把一個控件中的滾動條擋住又不影響功能的使用,那就需要一個可以穿透消息的東西。很簡單,立刻想到了靜態(tài)文本控件(CStatic)。
2.“面具”的形狀是什么樣的?
Windows API函數(shù):
BOOL GetScrollBarInfo(HWND hwnd, LONG idObject, PSCROLLBARINFO psbi);
參數(shù)psbi指向的SCROLLBARINFO結(jié)構(gòu)體包含有具體的大小。
3.“面具”如何一直掛在滾動條上?
這個問題是關(guān)鍵所在,不解決它一切免談。
首先要讓控件繪制時不去繪制滾動條的部分,這可以通過給控件設(shè)置WS_CLIPSIBLINGS屬性實(shí)現(xiàn)。圖1較詳細(xì)的解釋了這個屬性,MSDN也有詳細(xì)的說明
然后讓“面具”CStatic控件的放置位置置于Z-Order的最頂端,通過WS_EX_TOPMOST屬性實(shí)現(xiàn)。
解決了以上三個問題之后就是見證奇跡的時刻了:
四、使用
本文用CScrollBarEx類已經(jīng)封裝好“面具”的制作過程了,唯一需要的注意的是美化所用圖片的資源ID是因人而異的,使用時注意更換。
1. 派生一個需要美化的控件,這個大家都會,不詳細(xì)說了,假設(shè)派生是一個樹控件CScrollBarTree.
2. 在CScrollBarTree定義兩個滾動條變量(垂直和水平各一個)
class CScrollBarTree : public CTreeCtrl{DECLARE_DYNAMIC(CScrollBarTree)public:CScrollBarTree();virtual ~CScrollBarTree();protected:DECLARE_MESSAGE_MAP()private:CScrollBarEx m_HScroll;CScrollBarEx m_VScroll;protected:virtual void PreSubclassWindow();public:afx_msg void OnPaint();};3. 在PreSubClassWindow()中對滾動條進(jìn)行初始化設(shè)置
void CScrollBarTree::PreSubclassWindow(){// TODO: Add your specialized code here and/or call the base classCTreeCtrl::PreSubclassWindow();m_HScroll.InitScrollBar(this, SB_HORZ);m_VScroll.InitScrollBar(this, SB_VERT);}4. 在OnPaint()中進(jìn)行滾動條的繪制
void CScrollBarTree::OnPaint(){// CPaintDC dc(this); // device context for paintingCTreeCtrl::OnPaint(); //注意這里,使用CTreeCtrl的原有實(shí)現(xiàn)m_HScroll.UpdateScrollBar();m_VScroll.UpdateScrollBar();}五.說明
int CXxxTree::OnCreate(LPCREATESTRUCT lpCreateStruct){// Create windowif (CWnd::OnCreate(lpCreateStruct) == -1){return -1;}m_HScroll.InitScrollBar(this, SB_HORZ);m_VScroll.InitScrollBar(this, SB_VERT);return 0;}
2.滾動條美化所用的圖片的資源ID因人而異,一定要注意更換。
3.源程序在VS2008+WinXP中調(diào)試通過。