Windows自定义打印的实现
来源:互联网 发布:网络商学院 编辑:程序博客网 时间:2024/06/07 00:23
Windows自定义打印的实现之一
其实在Windwos中调用Windows API实现打印是比较简单的,而且具有代码紧凑、实现灵活的优点。我们只要掌握了几个要点,就可以随心所欲的打印了。下面我们将一一讨论:
- 打印机的选择,打印设置对话框的调用
- 在程序中设置打印选项
- 打印单位的转换
- 打印基本流程
- 打印字体的设置
打印机的选择,打印设置对话框的调用
这个不多说了,相关的主要API只有一个--PrintDlg(LPPRINTDLG lppd)--看例子代码。
PRINTDLG printInfo; ZeroMemory(&printInfo,sizeof(printInfo)); //清空该结构 printInfo.lStructSize = sizeof(printInfo); printInfo.hwndOwner = 0; printInfo.hDevMode = 0; printInfo.hDevNames = 0; //这个是关键,PD_RETURNDC 如果不设这个标志,就拿不到hDC了 // PD_RETURNDEFAULT 这个就是得到默认打印机,不需要弹设置对话框 printInfo.Flags = PD_RETURNDC | PD_RETURNDEFAULT; //调用API拿出默认打印机 PrintDlg(&printInfo); //看看出错没有 DWORD rst = CommDlgExtendedError(); if(rst != 0) { //出错了,清空标志再次调用API,此时就会弹出打印设置对话框供用户选择了 printInfo.Flags = 0; PrintDlg(&printInfo); }
从上面的代码,我们就知道弹不弹对话框的关键是设置PRINTDLG结构的Flags字段。
在程序中设置打印选项
要想在程序中定制我们的打印选项,DEVMODE结构就是关键了。在这里我们只举例如何为打印设定自定义纸张。更详细的设置信息可以查询MSDN。
//首先得到DEVMODE结构,同时申请系统锁定,我们要修改它了 LPDEVMODE lpDevMode = (LPDEVMODE)::GlobalLock(printInfo.hDevMode); if(lpDevMode) //成功得到该结构了 { lpDevMode->dmPaperSize = DMPAPER_USER; //自定义纸张 //设定自定义纸张标志 lpDevMode->dmFields = lpDevMode ->dmFields | DM_PAPERSIZE | DM_PAPERLENGTH | DM_PAPERWIDTH; lpDevMode->dmPaperWidth = (short)width; //纸宽多少 lpDevMode->dmPaperLength = (short)height; //纸高多少 //顺便设定纸张走纸方向,横向还是纵向 lpDevMode->dmOrientation = DMORIENT_PORTRAIT; } //记住要解锁 GlobalUnlock(printInfo.hDevMode); //这个也不能忘了,否则更改不会生效 ResetDC(printInfo.hDC, lpDevMode);Windows自定义打印的实现之二
打印单位的转换
这个的关键是我们要得到显示设备的DPI,即每英寸设备支持的点数。有了DPI我们就可以在我们习惯的单位和设备单位之间转换了,用到的API是GetDeviceCaps(),这个函数功能强大,具体可参考MSDN,在这里我们只用来得到设备DPI。看示例代码:
//某些设备水平和垂直方向的DPI可能不同,所以要分别得到。 //得到水平方向的转换比例 float getXScale(HDC printDC) //printDC: 打印机DC设备句柄 { //得到打印机水平方向的DPI int xDPI = GetDeviceCaps(printDC, LOGPIXELSX); //254.0: 每英寸25.4毫米 float xScale = (float)(254.0 / xDPI); return xScale; } //得到垂直方向的转换比例 float getYScale(HDC printDC) //printDC: 打印机DC设备句柄 { //得到打印机垂直方向的DPI int yDPI = GetDeviceCaps(printDC, LOGPIXELSY); float yScale = (float)(254.0 / yDPI); return yScale; } //厘米转换为设备像素,水平方向 double cm2Unit_W(float xScale, double w) //w单位为厘米 { return w*100/xScale; } //厘米转换为设备像素,垂直方向 double cm2Unit_H(float yScale, double h) //h单位为厘米 { return h*100/yScale; }上面代码中,如果将printDC换为显示器设备DC句柄,即可得到厘米转换为显示器像素单位,打印预览时使用。得到显示器设备句柄可用::GetDC(NULL)得到。
打印基本流程
有了前面的知识,现在我们就可以打印了。Windows打印是有着固定的流程的,流程也比较简单。按照固定的顺序调用打印API即可:StartDoc() -> StartPage() -> 打印具体内容 -> EndPage() -> EndDoc()。如果要打印多页,循环StartPage()至EndPage()即可。
示例代码:
DOCINFO doc; ZeroMemory(&doc,sizeof(doc)); doc.cbSize = sizeof(doc); doc.lpszDocName = (LPCTSTR)"Print Test File"; StartDoc(printDC, &doc); //准备打印 StartPage(printDC); //开始打印页 //在(2.5cm, 2.5cm)处打印文本 char* text = "打印测试文本"; float xScale = getXScale(printDC); float yScale = getYScale(printDC); double x = cm2Unit_W(xScale, 2.5); double y = cm2Unit_H(yScale, 2.5); //在指定位置打印文本 TextOut(printDC, (int)x, (int)y, (LPTSTR)text, strlen(text)); EndPage(printDC); //结束打印页 EndDoc(printDC); //结束打印打印字体的设置
很多时候我们希望能控制打印字体,下面的代码可以创建你想要的字体格式:
/* 创建自定义打印字体 fontFace:字体名称,如果为NULL,默认采用“宋体” fontHeight:字体高度,单位为厘米 isBold:是否加粗 isItalic:是否斜体 isUnderLine:是否下划线 isStrikeOut:是否删除线 */ HFONT getFont(LPCTSTR fontFace, double fontHeight, bool isBold, bool isItalic, bool isUnderLine, bool isStrikeOut) { int width = 0; //字体宽度由系统决定 int weight = FW_NORMAL; DWORD italic = 0; DWORD underLine = 0; DWORD strikeOut = 0; DWORD charSet = DEFAULT_CHARSET; LPCTSTR face = (LPCTSTR)"宋体"; float height = cm2Unit_H(fontHeight); if(fontFace != 0) { face = fontFace; } if(isBold) { weight = FW_BOLD; } if(isItalic) { italic = 1; } if(isUnderLine) { underLine = 1; } if(isStrikeOut) { strikeOut = 1; } HFONT font = CreateFont((int)height, width, 0, 0, weight, italic, underLine, strikeOut, charSet, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH | FF_DONTCARE, face ); return font; }小结
以上就是我们在实现打印中遇到的常见问题,相信理解了这些,在我们自己的程序中实现打印就不再是什么困难的事情了。
- Windows自定义打印的实现
- Printing tools 自定义模板打印的实现
- Jquery、Js实现网页打印,及打印样式的自定义
- Windows Mobile无线打印的实现
- 自定义reportviewer打印设置按钮的另类实现方法
- QuickReport在Win2000中实现自定义纸张的打印方法
- 简单的通过宏定义实现自定义打印函数
- 自定义的打印宏
- MySQL自定义函数的Windows版本实现
- Windows Phone 7 自定义按钮的实现
- windows“运行”自定义“命令”的实现
- 自定义Windows资源管理器预览的实现
- 通过自定义打印纸张的大小,实现打印到哪里纸张就停止在哪里。
- 通过自定义打印纸张的大小,实现打印到哪里纸张就停止在哪里
- 自定义动态生成页面打印以及打印预览的一个实现例子
- 单据的自定义纸张打印
- python:自定义对象的打印
- python3 自定义对象的打印
- Ubuntu下Postgresql-8.4安装及配置
- 详解Oracle数据库中DUAL表的使用
- ...
- 放大图片
- 放大图片1
- Windows自定义打印的实现
- 网站后台只能显示数据库信息 不能更改删除添加信息
- 项目中...
- iis里右击浏览无反应(转)
- Oracle Enterprise Linux 4.0下安装oracle 10G
- 存储过程实现SQL2005查询Access数据库
- 并口编程教程
- 搜狗浏览器超越火狐 进入1%俱乐部
- 修改Eboot过程的一点经验