按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
的参数调用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对象的使用,而不是编写一
个功能完善的应用程序。当然,你可以使用更好和更完善的方法来实
现该应用程序并将它用于你的其它应用程序。一个特殊的标题条常常
会给程序带来一些吸引人的东西,但是过分花哨的用户界面可能会使
用户感到不适应甚至招至用户的反感。
使用CClientDC的应用程序与此类似,只不过我们通常在一些需要直
接在窗口的客户区进行绘制的场合创建和使用该设置上下文对象。比
如在一些使用鼠标绘图的应用程序中,当用户在客户区中单击鼠标
时,我们通常需要直接在客户区中绘制出相应的图形,而不必等到
WM_PAINT消息发送。对于这样的应用程序,我们一般在鼠标的移动和
单击事件的处理函数中创建类型为CClientDC的设置上下文对象,并
通过该设备上下文对象进行绘制。如果使用了AppWizard来生成MFC应
用程序的话,我们一般使用ClassWizard来完成添加这些消息处理成
员函数和相应的消息映射项。
如前所述,在WM_PAINT消息的处理函数中,我们一般不使用
CClientDC对象,而应该使用CPaintDC对象。
在下面的小节中,我们将讲述MFC中的GDI绘图对象类的使用。
第二节 画笔对象
MFC类CPen封装了GDI中的画笔对象,画笔对象代表了进行绘制时所用
的线条。我们一般通过两个步骤来创建画笔对象:首先构造一个CPen
对象,再调用对象的CreatePen成员函数。成员函数CreatePen按指定
的样式、宽度等属性创建一个逻辑画笔,然后将该画笔与CPen对象相
关联。
9。2。1 创建画笔
成员函数CreatePen有两种形式。第一种形式的如下:
BOOL CreatePen( int nPenStyle; int nWidth; COLORREF crColor );
参数nPenStyle代表了画笔的样式,可以为下列值之一:
…………………………………………………………Page 529……………………………………………………………
PS_SOLID: 创建一个实线画笔
PS_DASH: 创建一个虚线画笔。一个虚线画笔
的宽度不能超过一个设备单位。
PS_DOT: 创建一个点线画笔。一个点划线画
笔的宽度不能超过一个设备单位。
PS_DASHDOT: 创建一个点划线画笔。同样,这种
样式的画笔宽度也不能超过一个设
备单位。
PS_DASHDOTDOT: 创建一个双点划线画笔。这种样式
的画笔宽度也不能超过一个设备单
位
PS_NULL: 创建一个空画笔
PS_INSIDEFRAME: 对于那些指定一个边界矩形的GDI输
出函数,具有这种样式的画笔将线
条绘制到输出形状框架的内侧。而
对于那些没有指定边界矩形的GDI输
出函数,这种画笔的绘制区域则不
受框架的限制。
参数nWidth以逻辑单位给出画笔的宽度。如果参数nWidth为零,则无
论当前使用何种映射模式,所创建和画笔的宽度都为一个象素。参数
crColor为画笔的颜色,这里可以使用RGB宏来生成合适的颜色值。
另一种形式的CreatePen函数使用如下的参数:
BOOL CreatePen( int nPenStyle; int nWidth; const LOGBRUSH* pLogBrush;
int nStyleCount = 0; const DWORD* lpStyle = NULL );
这种形式的CreatePen可以创建一个具有指定的宽度、样式和刷子属
性的逻辑修饰 (cosmetic)或几何 (geometric)画笔。参数nPenStyle指
定了画笔的样式,它可以为PS_COSMETIC、PS_GEOMETRIC或它们与一
些附加属性的组合,详细的说明这里不进行说明,如果需要的话你可
以参考联机文档中对构造函数CPen::CPen的说明。nWidth以逻辑单位
指定画笔的宽度,如果nPenStyle参数包括了PS_COSMETIC的话,参数
nWidth必须为1。参数pLogBrush为指向一个LOGBRUSH结构的指针,该
LOGBRUSH结构定义了画笔的刷子属性。最末两个参数nStyleCount和
…………………………………………………………Page 530……………………………………………………………
lpStyle定义了画笔的每一划及它们之间的空白的长度。
画笔对象实际上也可以一步创建,这时所使用的构造函数也使用与函
数CreatePen相一致的参数。以使用一步创建的方式创建画笔对象
时,我们通过捕获一个异常是否发生来判断是否出错。
9。2。2 使用画笔在设备上下文中进行输出
一旦画笔对象创建成功之后,即可使用CDC类的成员函数
SelectObject将其选入设备描述表中进行各种输出。
下面的示例程序PenDemo演示了画笔对象的使用。
创建工程PenDemo的方法同在9。1。2中引入的示例程序
MulticlrdCaption相同。您可以参照上一节的讲述来创建工程
PenDemo。其代码清单如下:
#include
#include
#include
// 派生应用程序类
class CMyApp : public CWinApp
{
public:
virtual BOOL InitInstance();
};
// 派生窗口类
class CMyWnd : public CFrameWnd
{
protected:
// 声明消息处理函数
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP();
…………………………………………………………Page 531……………………………………………………………
};
// 初始化应用程序实例
BOOL CMyApp::InitInstance()
{
// 创建应用程序的主窗口
CMyWnd *pWnd=new CMyWnd;
pWnd…》Create(NULL; 〃各种画笔的示例〃);
// 显示应用程序主窗口并刷新其客户区
pWnd…》ShowWindow(SW_SHOW);
pWnd…》UpdateWindow();
// 在主窗口关闭时终止应用程序的执行线程
m_pMainWnd=pWnd;
return TRUE;
}
// 声明唯一的应用程序对象
CMyApp MyApp;
// 应用程序主窗口的消息映射
BEGIN_MESSAGE_MAP(CMyWnd; CWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()
// 应用程序主窗口的重绘函数
void CMyWnd::OnPaint()
{
// 获得窗口的客户区设备上下文句柄
CPaintDC dc(this);
// 定义一个画笔数组
…………………………………………………………Page 532……………………………………………………………
CPen pen'8';
// 创建实线画笔
pen'0'。CreatePen(PS_SOLID; 10; RGB(255; 0; 0));
// 创建虚线画笔
pen'1'。CreatePen(PS_DASH; 1; RGB(0; 255; 0));
// 创建点线画笔
pen'2'。CreatePen(PS_DOT; 1; RGB(0; 0; 255));
// 创建点划线画笔
pen'3'。CreatePen(PS_DASHDOT; 1; RGB(0; 255; 255));
// 创建双点划线画笔
pen'4'。CreatePen(PS_DASHDOTDOT; 1; RGB(255; 0; 255));
// 创建空画笔
pen'5'。CreatePen(PS_NULL; 1; RGB(255; 255; 0));
// 创建内侧实线画笔
pen'6'。CreatePen(PS_INSIDEFRAME; 10; RGB(0; 0; 0));
// 创建具有刷子属性的几何画笔
LOGBRUSH lb;
lb。lbStyle=BS_HATCHED;
lb。lbColor=RGB(128; 128; 128);
lb。lbHatch=HS_DIAGCROSS;
pen'7'。CreatePen(PS_GEOMETRIC; 10; &lb);
// 保存指向设备上下文原有画笔的指针
CPen *pOldPen;
// 以实线画笔绘制矩形
pOldPen=dc。SelectObject(&pen'0');
dc。Rectangle(10; 10; 110; 110