一种美化控件滚动条(ScrollBar)的方法 - VC知识库文章

来源:百度文库 编辑:神马文学网 时间:2024/04/27 20:25:22

一种美化控件滚动条(ScrollBar)的方法
作者:Nobita

下载源代码

摘 要:本文采用“遮挡”方法对MFC控件中的滚动条(ScrollBar)进行了美化工作,即保留了滚动条的功能,又美化了界面

关键字:滚动条(ScrollBar)

一、说明
我们大家对MFC控件本身的美化工作都比较熟悉了,这方面的文章也是比较多的。但是对于控件中的滚动条美化,相关资料却比较少。已有的实现采用的是禁用控件的滚动条,然后在原有的位置上重新绘制滚动条,为了实现滚动条的功能,需要在代码中进行一些较复杂的计算。
本文采用的“遮挡”方法只是单纯的对滚动条界面进行美化,而功能则保持原有的实现。

二、原理
一个人要想不被人认出,除了整容还有什么办法?还可以采用戴面具挡脸的方法。
一般我们对MFC控件进行美化都是对比如WM_CTLCOLOR、WM_DRAWITEM之类的消息进行处理,这也相当于“整容”了。
滚动条只是作为控件的一部分没有相应的消息可以重写,所以本文设想做一个“面具”来遮挡滚动条,这样即可以保留滚动条的原有功能不变,又看到一个漂亮的“面具”。

三、实现
“遮挡”方法的原理很简单,要想实现这个方法需要解决以下几个问题:
1.“面具”的材料是什么?
要想把一个控件中的滚动条挡住又不影响功能的使用,那就需要一个可以穿透消息的东西。很简单,立刻想到了静态文本控件(CStatic)。

2.“面具”的形状是什么样的?
Windows API函数:
BOOL GetScrollBarInfo(HWND hwnd, LONG idObject, PSCROLLBARINFO psbi);
参数psbi指向的SCROLLBARINFO结构体包含有具体的大小。

3.“面具”如何一直挂在滚动条上?
这个问题是关键所在,不解决它一切免谈。
首先要让控件绘制时不去绘制滚动条的部分,这可以通过给控件设置WS_CLIPSIBLINGS属性实现。图1较详细的解释了这个属性,MSDN也有详细的说明

图1

然后让“面具”CStatic控件的放置位置置于Z-Order的最顶端,通过WS_EX_TOPMOST属性实现。

解决了以上三个问题之后就是见证奇迹的时刻了:


图2 在VS2008下的实现效果

四、使用
本文用CScrollBarEx类已经封装好“面具”的制作过程了,唯一需要的注意的是美化所用图片的资源ID是因人而异的,使用时注意更换。
1. 派生一个需要美化的控件,这个大家都会,不详细说了,假设派生是一个树控件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()中对滚动条进行初始化设置
void CScrollBarTree::PreSubclassWindow()            {            // TODO: Add your specialized code here and/or call the base class            CTreeCtrl::PreSubclassWindow();            m_HScroll.InitScrollBar(this, SB_HORZ);            m_VScroll.InitScrollBar(this, SB_VERT);            }            
4. 在OnPaint()中进行滚动条的绘制
void CScrollBarTree::OnPaint()            {            //CPaintDC dc(this); // device context for painting            CTreeCtrl::OnPaint(); //注意这里,使用CTreeCtrl的原有实现            m_HScroll.UpdateScrollBar();            m_VScroll.UpdateScrollBar();            }            
五.说明
1.如果派生的控件是动态生成的的话,则必需在OnCreate而不是PreSubClassWindow中进行滚动条初始化,
int CXxxTree::OnCreate(LPCREATESTRUCT lpCreateStruct)            {            // Create window            if (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中调试通过。

http://www.vckbase.com/document/viewdoc/?id=1902