14.2.2 CDC类(1)
应当使用CDC类的成员在程序中完成所有绘图。这个类和其派生的类的所有对象都包含把图形和文本发送到显示器和打印机时需要的一个设备上下文和成员函数。另外还有一些成员函数用于检索有关正在使用的物理输出设备的信息。
由于CDC类对象可以通过图形输出提供用户可能需要的几乎所有东西,所以这个类的成员函数很多--实际上大大超过了100个。所以,本章只分析打算在Sketcher程序中使用的成员函数,以后需要使用其他成员函数时再分析它们。
对于图形输出,MFC包括一些派生于CDC的更专用的类。例如,我们要使用CClientDC类的对象。CClientDC类超过CDC类的优点是它始终包含只代表窗口工作区的设备上下文,这正是用户在大多数情况下所需要的。
1. 显示图形
在设备上下文中,将相对于当前位置绘制实体,如直线、圆和文本。当前位置是工作区中的一个点,它或者由以前绘制的实体设置,或者是通过调用函数进行设置。例如,可以扩展OnDraw()函数,设置如下所示的当前位置:
- void CSketcherView::OnDraw(CDC* pDC)
- {
- CSketcherDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);
- if(!pDoc)
- return;
- pDC->MoveTo(50, 50); // Set the current position as 50,50
- }
第一个行是粗体显示,因为编译代码时,必须解除参数名注释。第二个粗体显示的行将调用pDC所指的CDC对象的MoveTo()函数。这个成员函数将当前位置设置为参数指定的x和y坐标。默认映射模式是MM_TEXT,所以坐标的单位是像素,当前位置设置成一个距窗口内部左边框50个像素、距工作区顶部50个像素的点。
CDC类将重载MoveTo()函数,这样就可以灵活地指定设置当前位置的方式。MoveTo()函数有两个版本,它们在CDC类中声明为:
- CPoint MoveTo(int x, int y); // Move to position x,y
- CPoint MoveTo(POINT aPoint); // Move to position defined by aPoint
第一个版本接受作为独立参数的x和y坐标。第二个版本接受一个POINT类型的参数,它是一个具有如下定义的结构:
- typedef struct tagPOINT
- {
- LONG x;
- LONG y;
- } POINT;
其中的坐标是struct的x和y成员,类型为LONG(这种类型在Windows API中定义为32位有符号整数)。您可能喜欢使用类,而不喜欢使用结构,这时可以在能够使用POINT对象的地方使用CPoint类的对象。CPoint类具有LONG类型的数据成员x和y,使用CPoint对象的优点在于这个类还定义了操作CPoint和POINT对象的成员函数。这看来似乎不可思议,因为CPoint的出现似乎使POINT对象变得过时,但是要记住,Windows API是在MFC出现之前建立的,而且POINT对象是在Windows API中使用的,所以迟早要处理它。由于在示例中要使用CPoint对象,因此用户将有机会了解其中一些成员函数的应用。
MoveTo()函数的返回值是一个CPoint对象,它指定的当前位置和移动之前一样。这也许有点奇怪,不过考虑这样一种情况:您想移动到一个新位置,画点东西,然后退回来。在移动之前,您也许不知道当前位置,在移动以后,将丢失当前位置,所以在移动之前返回这个位置将确保您在需要时可以使用它。
绘制直线
在对OnDraw()函数中的MoveTo()调用以后,调用函数LineTo(),这将在工作区中绘制一条直线,它从当前位置到LineTo()函数的参数指定的位置,如图14-3所示。

CDC类还定义两个版本的LineTo()函数,它们具有下列原型:
- BOOL LineTo(int x, int y); // Draw a line to position x,y
- BOOL LineTo(POINT aPoint); // Draw a line to position defined by aPoint