1.2编程基础
下面将了解打印编程中至关重要的两个概念"设备环境"和"映射模式"
1.2.1设备环境
设备环境本身是GDI(Graphics Device interface)对象.每个C++设备对象有一个相关的设备环境.它由
一个32位HDC类型句柄来标识.GDI是Windows核心DLL中的一组接口函数.这些函数处于硬件的驱动程序
之上.当应用程序调用这些函数的时候,它们再调用驱动程序提供的接口函数.
1.CDC类
使用MFC编程,所用的设备环境不是CDC就是从CDC派生的。CDC类中有两个与底层
GDI对象有关的句柄m_hDC和m_hAttribDC.与m_hDC相关的GDI对象处理绘图函数的所有
输出流;与m_hAttribDC句柄有关的GDI对象处理所有与绘图属性有关的操作。如颜色属性
和绘图模式。
每个窗口、控件都拥有一个覆盖窗口或控件的设备环境。我们可以使用任何一个控件的设备环境,
从而绘制控件或者改善倥件的外观。
获得设备环境对象指针需要调用GetDC函数。在构造一个CDC对象,并且对它处理完之后,务必使用
ReleaseDC()函数将CDC对象释放。
GetDC()函数和ReleaseDC()函数是CWnd类的成员函数,任何CWnd类及其派生类都可以通过调用它获得
和释放设备环境对象。
2. CClientDC和CWindowDC
窗口客户区不包括边框、标题栏和菜单栏,创建CClientDC对象将获得客户区的设备
环境。构造CClientDC对象,只需要向它传递一个指向窗口的指针,GetDC()函数会被
自动调用。当ClientDC对象被销毁时,它会自动调用ReleaseDC()函数。
CClientDC派生于CDC,在构造时调用了Windows函数GetDC,在析构时调用了ReleaseDC.
和CClientDC对象相关的设备上下文是窗口的客户区.
CClientDC 构造一个连接到CWnd上的CClientDC对象.
CClientDC(CWnd *pWnd);
throw (CResourceException);
参数:
pWnd:设备上下文将要存取的客户区所在的窗口.
CWindowDC能够在整个应用程序窗口上绘图,包括标题栏和窗口边框。一般情况下CWindowDC
对象很少用,但是当读者不欢喜Windows标准窗口标题栏的样式和按钮,就可以应用它了。
CWindowDC类是从CDC继承的,它在构造的时候调用Windows函数GetWindowDC,在销毁的时候调用ReleaseDC.
这意味着CWindowDC对象可以访问CWnd的全部屏幕区域(包括客户区和非客户区).
AfxGetMainWnd()函数用于获得框架(包括标题栏、菜单栏、状态栏、边框)窗口的指针。
AfxGetMainWnd()获得主框架窗口指针。
3、CPaintDC
CPaintDC类是一个特殊的设备环境封装类。它用来处理来自Windows的WM_PAINT消息。
当窗口上覆盖的其他窗口移走,或者窗口最小化后又最大化时,窗口就会收一个系统
发来的WM_PAINT消息,这时应用程序就会重画可见的区域。这个被重画的区域,我们称
它为无效区域。WM_PAINT消息发出后,Windows会帮助用户判断哪些区域需要重画,哪些
区域保持不变,从而加快窗口的显示速度。
CPaintDC类有一个成员变量m_ps,m_ps有一个RECT类型的成员变量rcPaint.这个矩形变量
保存了需要重画的矩形区域,即无效区域。m_ps是一个PAINTSTRUCT结构类型的变量。
PAINTSTRUCT结构的定义如下所示:
typedef struct tagPAINTSTRUCT
{
HDC hDC;
BOOL fErase;
RECT rcPaint;
BOOL fRestore;
BOOL fIncUpdate;
byte rgbReserved[32];
}PAINTSTRUCT;
hdc是底层的GDI设备环境对象的句柄.Ferase标志判断背景是否被清除,如果这个标志
被设置为TRUE,在重画之前将清除背景.rcPaint 保存了窗口无效区域(即需要重画的
区域).最后三个变量被声明为保留变量.一般不改动.
4、内存设备环境
内存设备环境是一个没有设备与它联系的环境。我们一般利用与某个标准设备环境兼容
的内存设备环境把一个位图复制到屏幕上去。为此可以先创建一个与某个标准设备环境兼容
的内存设备环境,然后把所要显示的位图复制到内存设备环境中,最后再从内存设备环境复
制到真正的设备环境,从而把位图显示出来。
还可以创建内存设备环境对象,使用该对象在内存中绘图来代替在屏幕上绘图,绘制完成后,
再调用BitBlt()函数把它复制到屏幕上去。这种方法绘图可以克服屏幕闪烁现象。
CGdiObject::GetObject 把描述了将Windows GDI对象附加给CGdiObject对象的数据填充到缓冲区。
int GetObject(int nCount,LPVOID lpObject)const;
返回值:获取的字节数。如果发生错误,则返回0
参数:
nCount 指定要拷贝到lpObject缓冲区的字节数
lpObject 指向用户应用缓冲区的指针以接收信息。
说明:
用定义指定对象的数据填充缓冲区。函数获得一个类型由图像对象决定
的数据结构,列表如下所示:
LoadBitmap 从应用的可执行文件中加载一个命名的位图资源来初始化位图对象。
CDC::BitBlt 从指定设备上下文拷贝位图
BOOL BitBlt(int x,int y,int nWidth,int nHeight,CDC *pSrcDC,int xSrc,int ySrc,DWORD dwRop);
返回值:函数成功,返回非零值,否则为0
参数:x 指定目标矩形左上角的逻辑x坐标
y 指定目标矩形左上角的逻辑y坐标
nWidth 指定目标矩形矩形和源位图的宽度(逻辑单位)
nHeight 指定目标矩形和源位图的高度(逻辑单位)
pSrcDC 指向CDC对象的指针,标识待拷贝位图的设备上下文。
xSrc 指定源位图左上角的逻辑x坐标
ySrc 指定源位图左上角的逻辑y坐标
dwRop 指定要执行的光栅操作。
CDC::CreateCompatibleDC 创建内存设备上下文,与另一个设备上下文匹配。可以
用它在内存中准备图像。
virtual BOOL CreateCompatibleDC(CDC *pDC);
返回值:如果成功,则返回非零值,否则为0
参数:
pDC 设备上下文指针。如果pDC为NULL,函数将产生与系统兼容的内存设备上下文。
说明:
产生与pDC指定设备兼容的设备上下文内存,设备上下文内存包含显示表面的信息,
它用于在向实际的兼容设备表面发送图像之前在内存中作好准备。
void CPrintProjView::OnDrawBitmap()
{
CBitmap bitmap;
bitmap.LoadBitmap(IDB_BITMAP1);
BITMAP bmpInfo;
CDC *pDC = GetDC();
CDC memDC;
memDC.CreateCompatibleDC();
CBitmap *pBitmap = memDC.SelectObject(&bitmap);
bitmap.GetObejct(sizeof(bmpInfo),&bmpInfo);
pDC->BitBlt(0,0,bmpInfo.bmWidth,bmpInfo.bmHeight,&memDC,0,0,SRCCOPY);
memDC.DeleteDC();
ReleaseDC(pDC);
}
上面这段程序,先获得视图的设备环境,然后声明了一个内存设备环境memDC.
memDC调用了CreateCompatibleDC()函数,作用是设置内存设备环境的大小等各种属性,
从而使内存设备环境与屏幕窗口兼容。Bitmap是位图对象,它调用成员函数LoadBitmap
载入位图;bmpInfo是BITMAP结构类型的变量,它保存了位图的长、宽等信息。
BitBlt()函数把内存设备环境复制到屏幕设备环境。BitBlt()是一个图像复制函数。
当向函数传递需要复制区域的宽、高度、开始偏移和复制模式这些参数时,它会将需要复制的
矩形区域从内存设备环境复制到屏幕上。
注意:
程序中使用的位图类型是GDI位图。有两种类型的Windows位图:GDI位图和DIB位图。
GDI位图对象是由MFC库的CBitmap类表示的。GDI位图对象有一个与之相关的Windows
数据结构,它在Windows GDI模块内进行维护,它是与设备相关的。对于GDI位图来说,
显示器的“位图”实际上就是显示器表面的映像,打印机设备的“位图”是打印机本身。
因此,不能将位图选入显示设备环境或打印设备环境,这就是为什么必须使用
CDC::CreateCompatibleDC函数创建一个特殊的内存设备环境。
5、打印机设备上下文
CDC::CreateDC 为指定设备创建设备上下文
virtual BOOL CreateDC(LPCTSTR lpszDriverName,
LPCTSTR lpszDeviceName,
LPCTSTR lpszOutput,
const void *lpInitData)
返回值:如果成功,则返回非零值,否则为0
参数:
lpszDriverName:指向空终止字符串的指针,字符串为设备驱动程序的文件名(不带扩展名,
例如:"EPSON")也可以为该参数传递CString对象。
lpszDeviceName:指向空终止字符串的指针,字符串为支持特定设备的文件名(例如:
"EPSON FX-80")
lpszOutput:指向空终止字符串的指针。字符串为指定了物理输出媒介的文件和设备名
(文件或输出端口).也可以为该参数传递CString对象。
lpInitData:指向DEVMODE结构的指针,该结构包含有指定设备驱动程序的初始数据,Windows
的DocumentProperties函数从该结构中获得指定设备的信息。如果设备驱动程序使用用户
在控制面板的缺省值,lpInitData参数一定要设置为NULL.
说明:
为指定的设备创建设备上下文。
如果使用DEVMODE结构,就需要PRINT.H头文件。
或者参数作如下说明:
lpszDriverName是打印机所用的设备驱动程序。
lpszDeviceName是进行打印的打印设备名称。设备驱动程序可以支持多种打印设备。
lpszOutput:指定设备的串口名。
lpInitData:是设备专用的初始化数据。
使用打印机设备环境之后,必须调用DeleteDC()成员函数销毁它。但是,如果在堆栈
中创建CDC类,程序返回时,设备环境自动删除。
至此Windows提供的五个公共设备环境已经全部介绍完了。