《C语言实例教程(PDF格式)》第111章


return FALSE;

else

PaintTitleBar(FALSE);
return FALSE;


…………………………………………………………Page 525……………………………………………………………
下面补充说明一下应用程序MulticlrdCaption的创建。由于该应用程 
序的结构比较简单,因此我们不打算使用AppWizard来创建框架应用 
程序。这里,我们先创建一个Win32 Application工程,然后添加一 
个C++ source file,在该源代码文件中输入上面的代码。这个过程 
已经在本书前面的章节中使用过,因此你应该能够很轻松的完成它。 
下面我们来分析这个应用程序。首先,我们在类CMyWnd中添加一个成 
员函数PaintTitleBar。该成员函数用来绘制窗口的标题条,其参数 
bActive给出了窗口的激活状态。如果当前窗口正处于激活状态,我 
们使用从红色到绿色再到蓝色的渐变颜色来绘制应用程序的标题条, 
如果当前窗口正处于非激活状态,我们使用从黑色到灰色再到黑色的 
渐变色来绘制标题条。
由于我们需要通过设备上下文在窗口的非客户区(这里指窗口的标题 
条区域)在进行绘制,所以我们选用了CWindowDC类。在类CWindowDC 
构造函数中自动调用了GetWindowDC函数,在其析构函数中自动调用 
了ReleaseDC函数。类CWindowDC的构造函数使用了一个指向CWnd对象 
的指针作为其参数,通过所创建的CWindowDC对象可以在窗口的非客 
户区进行图形输出。
在创建了类型为CWindowDC的设备上下文对象dc之后,我们调用API函 
数GetSystemMetrics来获得当前窗口的边框高度和宽度以及标题条的 
高度。这里我们指出一点,即这些度量值仅适用于具有常规样式的窗 
口,对于一些特殊的窗口可能不成立,如对于工具条窗口,其标题条 
高度要小得多。这是上面的应用程序的一个局限,但不可以对一个仅 
用来讲解CWindowDC对象的使用的示例过于苛求,否则我们就不得不 
花篇幅去介绍很多完善整个应用程序所需要的额外代码。这种对应用 
程序的简化的处理方法下面还会遇到。通过使用不同的参数调用 
GetSystemMetrics函数可以得到不同的系统度量。我们所使用的仅仅 
是这些度量值中的很少一部分。
如果窗口是处于激活状态,我们使用参数COLOR_ACTIVECAPTION调用 
API函数GetSysColor得到当前系统颜色设置中激活状态条使用的颜色 
(我们不能假定用户的Windows窗口在激活时都使用标准的蓝色标题 
条,因此用户可以很方便的使用控制面板或通过右击桌面选择 “属 
性”来更改这些设置)。然后,我们调用在类CWindowDC的基类CDC中 
定义的成员函数GetPixel来获得标题条上的每一点的颜色值,如果这 
一点的颜色值等于当前使用的激活标题条颜色的话,就调用函数 
SetPixelV将该点的颜色设置为新的值。这种方式不会不正确的擦除 
当前标题条上的标题文本、应用程序图标以及窗口右上角最大化、最 
小化和关闭按钮,但是,由于在新的Windows操作系统Windows 98 以 
…………………………………………………………Page 526……………………………………………………………
及Windows NT 5。0中,标题条的颜色在默认情况下是渐变的,因此应 
用程序将不能正确工作。类CDC的成员函数GetPixel返回一个 
COLORREF值以指示位于指定坐标的点的颜色值。成员函数SetPixelV 
将位于指定坐标的点的颜色设置为新的值,另一个成员函数SetPixel 
可以完成同样的功能,并且更常用。但是,与成员函数SetPixel不 
同,SetPixelV不需要返回设置的实际颜色值,因此它要比SetPixel 
快。尽管如此,上面的程序仍只能作为一个示例程序出现,因为这种 
一个点一个点的描绘的方法实在是太慢,在作者的具有64M内存和 
K6/200的CPU的计算机上,更新一个常规大小的窗口的标题条的颜色 
需要大约0。3秒的时间,在这样长的时间段内,用户还是可以清楚的 
看到标题条一点一点绘制的过程。提高应用程序的绘制速度的一种方 
案是使用位图来内存中对位图进行变换和处理,然而再使用位图来更 
新标题条。由于位图的绘制速度要比一个点一个点的描快得多,从而 
有可能大幅度的提高标题条的重绘速度,但是这种算法要使用到我们 
在这里不打算深入讲述的一些概念和技巧,为了便于理解,我们还是 
采用了上面给出的算法。
下面要做的事是处理两个重要的非客户区消息,WM_NCPAINT和 
WM_NCACTIVATE。第一个消息WM_NCPAINT在非客户区的全部或一部分 
需要重绘时由操作系统发送。如果试图给窗口绘制特殊的边框或标题 
条,处理这个消息是必要的。MFC在CWnd中定义了该消息的默认处理 
函数OnNcPaint,该成员函数对WM_NCPAINT的默认处理绘制了窗口的 
正常边框。我们在类CMyWnd中重载了该成员函数。由于我们只是绘制 
了窗口的标题条,因此在此之前有必要调用一下基类中的默认实现绘 
制窗口的边框。然后,通过判断由API函数GetActiveWindow返回的窗 
口句柄(它代表了当前激活窗口)和当前窗口的句柄是否相等来以不同 
的参数调用PaintTitleBar成员函数来绘制窗口处于激活状态和非激 
活状态的标题条。
另一个必须考虑的事件是当窗口的激活状态发生改变时正确绘制窗口 
的标题条以反映窗口的新的激活状态。这时窗口将会收到 
WM_NCACTIVATE消息,该消息所带的参数给出了窗口新的激活状态。 
MFC在CWnd中定义了该消息的默认处理函数OnNcActivate。我们在类 
CMyWnd中重载了该成员函数。该函数根据窗口新的激活状态调用了 
PaintTitleBar来绘制新的窗口标题条以反映激活状态的改变。
整个应用程序使用了典型的MFC的结构,代码也比较简单和清晰,这 
里我们就不多作的介绍了。你可以根据上面的源代码清单和本书前面 
章节中讲述的内容来完成该应用程序。
完成上面的步骤之后我们就可以编译并试运行该应用程序了。在编译 
…………………………………………………………Page 527……………………………………………………………
之前我们需要做一些额外的工作:
1。 单击Project菜单下的Settings命令或按下快捷键Alt+F7,打开如 
图9。1所示的工程设置对话框。
图9。 1 设置应用程序的工程属性
2。 在General选项卡中的Microsoft Foundation Classes下拉列表框 
中选择Use MFC in a Shared DLL或Use MFC in a Static Library
(仅适用于Visual C++ 5。0的专业版和企业版)。你需要对应用程序的 
调试版本和发行版本各重复一次上面的设置过程。如果忽略此步设置 
的话,在链接应用程序的过程中会出现错误。
现在就可以编译并运行上面的程序了。其运行结果如图9。2所示。
图9。 2 具有五彩标题条的窗口
…………………………………………………………Page 528……………………………………………………………
上面的程序还有其它的一些局限性。比如当窗口处于非激状态时,如 
果使用鼠标在窗口上移动其它窗口,窗口的标题条将会变成标准的灰 
色;还有,如果应用程序通过调用。要完善这些功能需要考虑更多的 
问题和处理更多的消息。这并不是本书在这里引入上面的示例程序的 
目的,我们只是为了演示一下CWindowDC对象的使用,而不是编写一 
个功能完善的应用程序。当然,你可以使用更好和更完善的方法来实 
现该应用程序并将它用于你的其它应用程序。一个特殊的标题条常常 
会给程序带来一些吸引人的东西,但是过分花哨的用户界面可能会使 
用户感到不适应甚至招至用户的反感。
使用CClie
小说推荐
返回首页返回目录