为应用程序窗口的滚动条着色






3.08/5 (12投票s)
一篇关于为应用程序窗口的滚动条着色的文章。
引言
这是我对2001年很久以前发表的关于为窗口滚动条着色的文章的更新。我很抱歉花了5年时间才一次性回来更新CodeProject上的这篇文章。在接下来的几天里,我计划在这个网站上发布几篇关于各种不同主题的文章。
我一直在寻找一种技术来为我的应用程序窗口的滚动条着色,以便使 UI 的外观更具吸引力,尤其是用 VC++ 开发的 UI。你知道,要在 MFC 中完成任何事情,都需要做很多工作。但是,最终,我们可以在互联网上找到大量的资源来帮助我们实现任何我们想要的东西。这就是我为让这篇文章接近初学者 VC++ 开发者所做的事情。我将向您展示如何将滚动条静态附加到应用程序的主窗口,更有趣的是,如何为它着色。
背景 [技术细节]
根据 MSDN 的说法,滚动条允许用户选择在相关窗口中滚动信息的方向和距离。滚动条有两种类型:水平滚动条和垂直滚动条。现在,让我介绍滚动条的组成部分。如果我们看一个标准的垂直滚动条,它有
- 顶部的箭头按钮
- 底部的箭头按钮
- 滚动框 [也称为滚动滑块]
- 滑块浮动区域
精确地说,本文演示了如何为滚动条的第四项着色,即滚动区域,仅此而已。
使用代码
各位,我们将把滚动条附加到 SDI 应用程序的主窗口框架,然后我们将看到如何为它们着色。我想以教程风格呈现文章的其余部分,以便您能够清楚地学习概念,然后给出提示,您也可以为 MDI 应用程序的子窗口着色。
#1
开发一个单文档界面类型的 MFC 应用程序。为项目起一个您喜欢的名字,并接受 AppWizard 的所有默认选择,然后单击“完成”。从 AppWizard 获取骨架代码后,您将在框架类中添加一些 `CScrollBar` 类型的变量。您可以手动完成,如下所示。
class CMainFrame : public CFrameWnd
{
private:
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
CScrollBar myHScroll;
CScrollBar myVScroll;
CScrollBar myCutebox;
CBrush m_brColor;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
...
...
};
#2
现在,在框架窗口类的 `OnCreate()` 处理程序中,在框架创建后像往常一样创建滚动条
int CMainFrame::OnCreate(...)
{
// code edited by the wizards by default ......
......
......
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
CRect rect(0,0,0,0);
myHScroll.Create(WS_VISIBLE|WS_CHILD|SBS_HORZ, rect, this, AFX_IDW_HSCROLL_FIRST);
myVScroll.Create(WS_VISIBLE|WS_CHILD|SBS_VERT, rect, this, AFX_IDW_HSCROLL_FIRST+1);
myCutebox.Create(WS_VISIBLE|WS_CHILD|SBS_SIZEBOX, rect, this,-1);
m_brColor.CreateSolidBrush(RGB(255,0,0));
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
return 0;
}
如上面的代码块所示,您还必须创建一个滚动条框。这个框就是一个小巧的窗口,位于水平滚动条和垂直滚动条的交汇处。
#3
您还必须编写代码来在调整窗口大小时相应地调整滚动条的大小。这可以通过重写的虚拟函数 `RecalcLayout(..)` 来完成,如下所示
void CMainFrame::RecalcLayout(BOOL bNotify)
{
// must call the base class version before working with any child.
CFrameWnd::RecalcLayout();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
CColorizedScrollsView* pView = (CColorizedScrollsView*)GetActiveView();
if (pView)
{
CRect rect;
pView->GetWindowRect(&rect);
ScreenToClient(&rect);
int cyHScroll = GetSystemMetrics(SM_CYHSCROLL);
int cxVScroll = GetSystemMetrics(SM_CXVSCROLL);
rect.right -= cxVScroll;
rect.bottom -= cyHScroll;
pView->MoveWindow(rect);
rect.left = rect.right;
rect.right += cxVScroll;
myVScroll.MoveWindow(rect);
rect.left = 0;
rect.right -= cxVScroll;
rect.top = rect.bottom;
rect.bottom += cyHScroll;
myHScroll.MoveWindow(rect);
rect.left = rect.right;
rect.right +=cxVScroll;
myCuteBox.MoveWindow(rect);
}// if
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
}
#4
最后,是将颜色放入滚动区域的实际步骤。因为这只能通过处理 `WM_CTLCOLOR` 窗口消息来完成,所以每个子窗口都会将颜色通知发送到其父容器窗口。代码如下
HBRUSH CMainFrame::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CFrameWnd::OnCtlColor(pDC, pWnd, nCtlColor);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
if(nCtlColor==CTLCOLOR_SCROLLBAR)
return m_brColor;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
return hbr;
}
#5
别忘了在框架 CPP 文件(即 `MainFrm.cpp`)中 `#include` 头文件,例如
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
#include "ColorizedScrollsDoc.h"
#include "ColorizedScrollsView.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
就是这样。编译并执行代码,即可在应用程序窗口中看到着色后的滚动条。
注释
- 在本文中,我没有讨论滚动条如何工作以滚动内容。这是一种文档/视图的主题。基本上,要使滚动条生效,您必须处理 `WM_HSCROLL` 和 `WM_VSCROLL` 消息。这留给您作为练习。
- 我上面承诺过,我会给出关于在 MDI 应用程序上练习本文的提示。你知道,MDI 在主框架内包含子框架窗口。所以,滚动条会出现在子框架而不是主框架中。您只需要记住,我们在主框架类中所做的一切,都将在子框架类中完成。此外,您需要记住两件事。一是 AppWizard 不会自动在 Child Frame 类中编写 `OnCreate(..)` 处理程序,您必须自己编写。二是当您运行应用程序时,将不会看到任何滚动条。要使它们显示出来,您必须最大化子窗口。或者您必须处理 `WM_SHOWWINDOW` 消息,并在其中说
- 我提供了源代码,可以通过 MS VC++ 6.0 编辑器或 MS Visual Studio .NET 编辑器打开/编译/执行,因为我为前者提供了单独的 `.dsp` 文件和 `.dsw` 文件,为后者提供了 `.sln` 文件。
- 如果您是 VC++ 6.0 开发者,您必须自己编写 `WM_CTLCOLOR` 消息处理程序、其原型以及消息映射中的一个条目,因为类向导不会列出此消息。您只需将上面的示例代码复制到您的框架类的头文件和实现文件中即可。
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
ShowWindow(SW_SHOWMAXIMIZED);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>
就这样,完成了。祝您编程愉快.....