首页 > 代码库 > MFC中的GDI绘图(1)

MFC中的GDI绘图(1)

一.关于GDI的基本概念

什么是GDI

        Windows绘图的实质就是利用Windows提供的图形设备接口GDIGraphics Device Interface)将图形绘制在显示器上。

        在Windows操作系统中,动态链接库C:\WINDOWS\system32\gdi32.dll(GDI Client DLL)中定义了GDI函数,实现与设备无关的包括屏幕上输出像素、在打印机上输出硬拷贝以及绘制Windows用户界面功能。在Visual C++6.0中的头文件C:\Program Files\Microsoft Visual Studio\VC98\Include\wingdi.h和Visual Studio 2005中的头文件C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include\WinGDI.h是访问gdi32.dll库文件的钥匙。下面我们大致浏览一下wingdi.hincluded in Windows.h头文件:

/* Bitmap Header Definition */定义了BITMAP位图结构

/* Mapping Modes */定义了DC中的坐标映射方式,包括以下常用函数:

SetMapMode、SetViewportExtEx、SetViewportOrgEx、 SetWindowExtEx 、SetWindowOrgEx。

/* Stock Logical Objects */系统预定义的堆(STOCK)对象,包括BRUSH、PEN和FONT对象

/* Brush Styles */定义了画刷格式,包括SOLID、HOLLOW、HATCHED等格式

/* Hatch Styles */定义了画刷阴影格式,包括:

HS_VERTICAL    /* ||||| */

HS_FDIAGONAL  /* \\\\\ */

HS_BDIAGONAL  /* ///// */

HS_CROSS       /* +++++ */

HS_DIAGCROSS  /* xxxxx */

/* Pen Styles */定义了画笔格式,包括SOLID、DASH、DOT等格式

什么是DC

设备环境DC(Device Context),也称为设备描述表或设备上下文。

设备环境保存了绘图操作中一些共同需要设置的信息,如当前的画笔、画刷、字体和位图等图形对象及属性,以及坐标映射、颜色和背景等影响图形输出的绘图模式。形象的说,一个设备环境提供了一张画布和一些绘画的工具,我们可以使用不同格式、颜色的绘画工具在上面涂鸦。这里,设备环境中的“设备”是指任何类型的显示器或打印机等输出设备,绘图时,我们不必关心所使用设备的编程的原理和方法,所有的绘制操作必须通过设备环境进行间接的处理,Windows会自动将设备环境所描述的结构映射到相应的物理设备上。

从根本上来说,DC它是Windows内部使用的数据结构,它存储着向设备输出时说需要的信息,应用程序利用它定义图形对象及其属性,并实现应用程序、设备驱动程序和输出设备之间绘图命令的转换。要想调用GDI函数向某个区域输出文字或绘制图形,必须先取得或建立设备环境句柄,应用程序每一次绘图操作均按照设备环境中的设置的绘图属性进行。

设备环境不像其他Windows结构,在程序中不能直接存取设备环境结构,只能通过系统提供的一系列函数或使用设备环境的句柄HDC来间接地获取或设置设备环境结构中的各项属性,这些属性包括显示器高度和宽度、支持的颜色数和分辨率等。

MFC中与GDI有关的类

为了支持GDI绘图,MFC提供了两种重要的类:设备环境DC(Device Context)类,用于设置绘图属性和绘制图形;绘图对象类,封装了各种GDI绘图对象,包括画笔、刷子、字体、位图、调色板和区域。

   在MFC中,CDC是设备环境类的基类,除了一般的窗口显示外,还用于基于桌面的全屏幕绘制和非屏幕显示的打印机输出。CDC类封装了所有图形输出函数,包括矢量、光栅和文本输出。CDC的派生类包括CClientDC、CPaintDC、WindowDC、CMetaFileDC。

            

(1)CPaintDC类是一个来自CDC的设备环
境类。它在构造期间执行CWnd::BeginPaint,在析构期间执行CWnd::EndPaint,EndPaint()除了释放设备环境外,还负责从消息队列中清除WM_PAINT消息。一个CPaintDC对象只在响应一个窗口重绘消息(WM_PAINT)的时候被使用,通常是在你的OnPaint消息处理成员函数中。因此,在处理窗口重画时,必须使用CPaintDC,否则WM_PAINT消息无法从消息队列中清除,将引起不断的窗口重画。

CPaintDC类成员:

数据成员

m_ps:包含了用于画客户区的PAINTSTRUCT 

m_hWnd: CPaintDC对象所附着的HWND 

构造函数CPaintDC:构造一个连接到指定的CWnd上的CPaintDC对象

(2)CClientDC(窗口客户区设备环境)类用于管理窗口用户区对应的显示上下文,它在构造时调用了Windows函数GetDC,在析构时调用了ReleaseDC。这意味着和CClientDC对象相关的设备上下文是窗口的客户区。一般在响应非窗口重画消息(如键盘输入时绘制文本、鼠标绘图)绘图时要用到它。

CClientDC类的成员:

构造函数CClientDC:构造一个连接到CWnd上的CClientDC对象数据成员

数据成员m_hWnd:所在的有效窗口的HWND

(3)CWindowDC(窗口设备环境)类用于管理与整个窗口对应的显示上下文,包括它的结构和控件。它在构造的时候调用Windows函数GetWindowDC,在销毁的时候调用ReleaseDC。这意味着CWindowDC对象可以访问CWnd的全部屏幕区域(包括客户区和非客户区)。它用于窗口(包括窗口边框、标题栏、控制按钮等)的绘制,除非要自己绘制窗口边框和按钮(如一些CD播放程序等),否则一般不用它。

 CWindowDC类成员:

 Construction CWindowDC:构造一个CWindowDC对象

 Data Members m_hWnd:与这个CWindowDC相关联的HWND句柄

(4)CMetaFileDC专门用于图元文件的绘制。图元文件记录一组GDI命令,可以通过这一组GDI命令重建图形输出。使用CMetaFileDC时,所有的图形输出命令会自动记录到一个与CMetaFileDC相关的图元文件中。

(5)此外我们还可以利用Windows内存DC进行绘图,此时涉及到屏幕DC和内存DC。把所要绘制的一切先在内存DC中进行绘制,之后全部搬到屏幕DC中,从而把所有繁琐的绘制过程都在内存DC中完成了,我们在屏幕上看到的是一幅完整的图画,所以不可能出现闪烁的情况。

--------------------To be continued------------------

MFC中的GDI绘图(1)