一旦应用程序初始化必要的变量,注册其AbortProc 功能,并显示其无模式取消对话框,可以通过调用StartDoc功能启动打印作业。
应用程序开始打印作业后,可以通过调用StartPage和EndPage函数来定义文档中的各个页面,并将适当的调用嵌入到此括号中的GDI绘图函数中。应用程序定义最后一页后,可以通过调用EndDoc功能关闭文档并结束打印作业。
以下示例显示打印文本字符串和位图图像所需的代码。以页面顶部为中心的文本字符串标识包含位图图像的文件的路径和文件名。在页面上垂直和水平居中的位图图像被绘制,以保持用于在应用程序窗口中绘制图像的相同比例。
/*
*初始化DOCINFO的成员
* 结构体。
*/
di.cbSize = sizeof(DOCINFO);
di.lpszDocName = "Bitmap Printing Test";
di.lpszOutput = (LPTSTR) NULL;
di.lpszDataType = (LPTSTR) NULL;
di.fwType = 0;
/*
*通过调用StartDoc开始打印作业
*功能。
*/
nError = StartDoc(pd.hDC, &di);
if (nError == SP_ERROR) {
errhandler("StartDoc", hwnd);
goto Error;
}
/*
*通知驱动程序该应用程序
*即将开始发送数据。
*/
nError = StartPage(pd.hDC);
if (nError <= 0) {
errhandler("StartPage", hwnd);
goto Error;
}
/*
*检索每个逻辑 - 英寸的像素数
*在水平和垂直方向
*用于显示位图
*被创建。
*/
fLogPelsX1 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSX);
fLogPelsY1 = (float) GetDeviceCaps(pd.hDC, LOGPIXELSY);
/*
*检索每个逻辑 - 英寸的像素数
*在水平和垂直方向
*用于打印机的位图
*将被打印。
*/
fLogPelsX2 = (float) GetDeviceCaps(pd.hDC,
LOGPIXELSX);
fLogPelsY2 = (float) GetDeviceCaps(pd.hDC,
LOGPIXELSY);
/*
*确定所需的缩放因子
*打印位图并保留原来的位图
*比例。
*/
if(fLogPelsX1 > fLogPelsX2)
fScaleX = (fLogPelsX1 / fLogPelsX2);
其他
fScaleX = (fLogPelsX2 / fLogPelsX1);
if(fLogPelsY1 > fLogPelsY2)
fScaleY = (fLogPelsY1 / fLogPelsY2);
其他
fScaleY = (fLogPelsY2 / fLogPelsY1);
/*
*计算左上角的坐标
*中心位图的一角。
*/
cWidthPels = GetDeviceCaps(pd.hDC, HORZRES);
xLeft = ((cWidthPels / 2) -
((int)(((float)bmih.biWidth)
* fScaleX)) / 2);
cHeightPels = GetDeviceCaps(pd.hDC, VERTRES);
yTop = ((cHeightPels / 2) -
((int)(((float)bmih.biHeight)
* fScaleY)) / 2);
/*
*创建兼容的内存DC
*打印机并选择位图(其中
*用户请求)进入此DC。
*/
hdcMem = CreateCompatibleDC(pd.hDC);
if(!SelectObject(hdcMem,hbm))
errhandler("SelectObject Failed", hwnd);
/*
*使用StretchBlt功能缩放
*位图并保持其原始比例
*(也就是说,如果位图是平方的
*出现在应用程序的客户区,
*它也应该在页面上显示为正方形)。
*/
if(!StretchBlt(pd.hDC,xLeft,yTop,
(int)((float)bmih.biWidth * fScaleX),
(int)((float)bmih.biHeight * fScaleY),
Hdakanem,0,0,
bmih.biWidth,bmih.biHeight,
SRCCOPY))
errhandler("StretchBlt Failed", hwnd);
/ *删除内存DC。*/
DeleteDC(hdcMem);
/*
*检索字符串的宽度
*指定完整的路径和文件名
*包含位图的文件。
*/
GetTextExtentPoint32(pd.hDC,ofn.lpstrFile,
ofn.nFileExtension + 3,cy
&szMetric);
/*
*计算出的起点
*文本输出操作。字符串会
*水平定位
*从页面顶部三行下来。
*/
xLeft = ((cWidthPels / 2) - (szMetric.cx / 2));
yTop = (szMetric.cy * 3);
/*
*打印位图的路径和文件名,
*以页面顶部为中心。
*/
TextOut(pd.hDC,xLeft,yTop,ofn.lpstrFile,
ofn.nFileExtension + 3);
/*
*确定用户是否按下
* AbortPrintJob中的取消按钮
* dialog box; if the button has been pressed,
*调用AbortDoc功能。uz否则,通知
*页面完成的后台处理程序。
*/
nError = EndPage(pd.hDC);
if (nError <= 0) {
errhandler("EndPage", hwnd);
goto Error;
}
/ *通知司机该文件已经结束。*/
nError = EndDoc(pd.hDC);
if (nError <= 0)
errhandler("EndDoc", hwnd);
错误:
/ *启用应用程序的窗口。*/
EnableWindow(hwnd, TRUE);
/ *删除AbortPrintJob对话框。*/
DestroyWindow(hdlgCancel);
/ *删除打印机DC。*/
DeleteDC(pd.hDC);
因为屏幕上的像素通常具有与打印机上的点不同的尺寸,因此需要缩放位图图像以获得所见即所得的效果。这是通过获得水平和垂直缩放因子,然后将这些因子应用于传递给StretchBlt函数的宽度和高度值来完成的。在样本应用中,通过检索两个器件的水平和垂直逻辑像素计数来获得缩放因子。一旦获得了缩放因子,就用它们来调整位图宽度和高度。
要将页面中的位图居中,应用程序首先计算缩放位图的宽度和高度。(位图被缩放以保持图像的原始比例。)这些值被除以2,然后从页面的宽度和高度的一半中减去。结果定义了位图左上角的坐标。
要将文本居中在页面顶部,应用程序称为GetTextExtentPoint32函数来检索指定路径名和文件名的字符串的宽度和高度。获得这些值后,应用程序使用高度将字符串的三行放置在页面和宽度上,以将字符串水平居中放置在页面上。
下图显示当应用程序在WINLOGO.BMP文件中打印位图图像时出现的页面的表示。该图还描绘了用于定位文本并定位和缩放位图的变量。