对话框打印,网上一搜一大堆,基本分2类:

A类: CPrintDialog.DoModal,然后在模态对话框里选打印机、打印配置;

B类:GetPrinterDeviceDefaults,调用默认打印机。

我的工作内容是理解以上2类后,再根据MSDN,实现MDF对话框后台指定打印机打印。

废话不多说,上菜~

功能:基于对话框的MFC打印(非文档视图结构),指定打印机,后台打印(不弹出对话框)

思路:

1、枚举打印机,并选择其中一个;

2、CPrintDialog实例指定到选中的打印机;

3、CPrintDialog后台打印

具体实现:

1、变量(控件)。在对话框上添加一个combobox(IDC_COMBO1,对应变量m_cboPrint)、一个edit(IDC_EDIT1),edit允许回车,多行(代码就不贴了,知道MFC应该就懂);

2、在OnInitDialog里枚举打印机设备,如果报函数未定义,加入头文件#include <winspool.h>

需要调用两次EnumPrinters函数,第一次的到结构体的大小,第二次得到打印机列表

// TODO: 在此添加额外的初始化代码DWORD dwNeeded;DWORD dwReturn;DWORD dwFlag = PRINTER_ENUM_CONNECTIONS | PRINTER_ENUM_LOCAL;EnumPrinters(dwFlag, NULL, 4, NULL, 0, &dwNeeded, &dwReturn);PRINTER_INFO_4* p4;p4 = new PRINTER_INFO_4[dwNeeded];EnumPrinters(dwFlag, NULL, 4, (PBYTE)p4, dwNeeded, &dwNeeded, &dwReturn);for (int i = 0; i<(int)dwReturn; i++)this->m_cboPrint.AddString(p4[i].pPrinterName);delete []p4;

3、操作对话框,在IDC_EDIT1里输入打印的内容,在IDC_COMBO1里选中打印机;

4、打印(我是用OK按钮打印的,大家随便)

// TODO: 在此添加控件通知处理程序代码
//  CDialogEx::OnOK();this->UpdateData();CString strMessage;CString strPrintDevice;this->GetDlgItem(IDC_EDIT1)->GetWindowTextW(strMessage);strMessage += _T("\r\n");       //添加结尾,方便后面循环读取打印数据this->GetDlgItem(IDC_COMBO1)->GetWindowTextW(strPrintDevice);DWORD dwFlag = PD_ALLPAGES | PD_NOPAGENUMS | PD_USEDEVMODECOPIES | PD_HIDEPRINTTOFILE;    //打印配置界面的按钮可用性,因为后台打印,其实这个配置没什么意义CPrintDialog pPrintdlg(FALSE, dwFlag, this);                                         //CPrintDialog实例化,因为MFC的打印设备无关性,可以理解为这就是一台打印机HGLOBAL hDevMode = NULL;HGLOBAL hDevNames = NULL;if (GetPrinterDevice(strPrintDevice.GetBuffer(0), &hDevNames, &hDevMode))             //获得指定打印机的配置、名字AfxGetApp()->SelectPrinter(hDevNames, hDevMode);elseAfxMessageBox(_T("Failed to select custom printer"));strPrintDevice.ReleaseBuffer();pPrintdlg.m_pd.hDevMode = hDevMode;                                                        //让pPrintdlg使用我们指定的打印机pPrintdlg.m_pd.hDevNames = hDevNames;CDC dc;dc.Attach(pPrintdlg.CreatePrinterDC());                                                  //后台打印创建法,如果需要弹出打印对话框,请用DoModalDOCINFO di;                                                                                //下面的内容网上很多,就不解释了di.cbSize = sizeof(DOCINFO);di.lpszDocName = _T("有驱打印测试");di.lpszDatatype = NULL;di.lpszOutput = NULL;di.fwType = 0;dc.StartDocW(&di);dc.StartPage();dc.SetMapMode(MM_TEXT);CRect recPrint(0, 0, dc.GetDeviceCaps(LOGPIXELSX), dc.GetDeviceCaps(LOGPIXELSY));dc.DPtoLP(&recPrint);dc.SetWindowOrg(0, 0);CFont newFont;VERIFY(newFont.CreatePointFont(120, _T("宋体"), &dc));CFont* oldFont = dc.SelectObject(&newFont);dc.SetTextAlign(TA_TOP | TA_LEFT);CString strPrint;int nIndex = 0;int x = 50;int y = 50;CSize textSize;textSize = dc.GetTextExtent(_T("00"), 2);                           //根据当前字体的宽、高,后面以此高度为行高while ((nIndex = strMessage.Find(_T("\r\n"))) > -1)                  //将IDC_EDIT1编辑框中内容打印,支持换行,一次换行等于'\r\n',所以在开头strMessage += _T("\r\n"){strPrint = strMessage.Left(nIndex);strMessage = strMessage.Mid(nIndex+2);dc.TextOutW(x, y, strPrint);y += textSize.cy;                                             //下移一行,行高为字体高度}dc.SelectObject(oldFont);newFont.DeleteObject();dc.EndPage();dc.EndDoc();DeleteDC(dc.Detach());

关于GetPrinterDevice,来自微软的一篇文章, 点我跳转

代码也贴出来

BOOL CMFCApplication2Dlg::GetPrinterDevice(LPTSTR pszPrinterName, HGLOBAL* phDevNames, HGLOBAL* phDevMode)
{// if NULL is passed, then assume we are setting app object's// devmode and devnamesif (phDevMode == NULL || phDevNames == NULL)return FALSE;// Open printerHANDLE hPrinter;if (OpenPrinter(pszPrinterName, &hPrinter, NULL) == FALSE)return FALSE;// obtain PRINTER_INFO_2 structure and close printerDWORD dwBytesReturned, dwBytesNeeded;GetPrinter(hPrinter, 2, NULL, 0, &dwBytesNeeded);PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAlloc(GPTR,dwBytesNeeded);if (GetPrinter(hPrinter, 2, (LPBYTE)p2, dwBytesNeeded,&dwBytesReturned) == 0) {GlobalFree(p2);ClosePrinter(hPrinter);return FALSE;}ClosePrinter(hPrinter);// Allocate a global handle for DEVMODEHGLOBAL  hDevMode = GlobalAlloc(GHND, sizeof(*p2->pDevMode) +p2->pDevMode->dmDriverExtra);ASSERT(hDevMode);DEVMODE* pDevMode = (DEVMODE*)GlobalLock(hDevMode);ASSERT(pDevMode);// copy DEVMODE data from PRINTER_INFO_2::pDevModememcpy(pDevMode, p2->pDevMode, sizeof(*p2->pDevMode) +p2->pDevMode->dmDriverExtra);GlobalUnlock(hDevMode);// Compute size of DEVNAMES structure from PRINTER_INFO_2's dataDWORD drvNameLen = lstrlen(p2->pDriverName)+1;  // driver nameDWORD ptrNameLen = lstrlen(p2->pPrinterName)+1; // printer nameDWORD porNameLen = lstrlen(p2->pPortName)+1;    // port name// Allocate a global handle big enough to hold DEVNAMES.HGLOBAL hDevNames = GlobalAlloc(GHND,sizeof(DEVNAMES) +(drvNameLen + ptrNameLen + porNameLen)*sizeof(TCHAR));ASSERT(hDevNames);DEVNAMES* pDevNames = (DEVNAMES*)GlobalLock(hDevNames);ASSERT(pDevNames);// Copy the DEVNAMES information from PRINTER_INFO_2// tcOffset = TCHAR Offset into structureint tcOffset = sizeof(DEVNAMES)/sizeof(TCHAR);ASSERT(sizeof(DEVNAMES) == tcOffset*sizeof(TCHAR));pDevNames->wDriverOffset = tcOffset;memcpy((LPTSTR)pDevNames + tcOffset, p2->pDriverName,drvNameLen*sizeof(TCHAR));tcOffset += drvNameLen;pDevNames->wDeviceOffset = tcOffset;memcpy((LPTSTR)pDevNames + tcOffset, p2->pPrinterName,ptrNameLen*sizeof(TCHAR));tcOffset += ptrNameLen;pDevNames->wOutputOffset = tcOffset;memcpy((LPTSTR)pDevNames + tcOffset, p2->pPortName,porNameLen*sizeof(TCHAR));pDevNames->wDefault = 0;GlobalUnlock(hDevNames);GlobalFree(p2);   // free PRINTER_INFO_2// set the new hDevMode and hDevNames*phDevMode = hDevMode;*phDevNames = hDevNames;return TRUE;
}

基本上是完整代码了,如果有内存错误,请联系我

MFC对话框使用CPrintDialog实现打印,指定打印机、后台打印相关推荐

  1. .NET(C#) 查找打印机指定打印机名称打印代码(PrintDocument)

    本文主要介绍.NET(C#)调用打印机打印相关操作(PrintDocument)代码,以及管理打印机的状态以及查询修改打印机属性,获取已安装的打印机驱动名,连接打印机并发送指令方法. 原文地址:.NE ...

  2. JS指定打印机进行打印

    思路:通过修改默认打印机,进行打印,之后再把默认打印机改回原来的以便不影响客户的使用. 大体代码如下: var defaultPrinter='${defaultPrinter}';//默认打印机(通 ...

  3. Java 指定打印机名称打印图片

    最近写个指定打印机打印条码,并且上传服务器保存备份,方便下次打印 如果不需要上传直接将图片流直接给 new FileInputStream(filePath); Doc doc = new Simpl ...

  4. 计算机打印机提示无法打印,打印机无法打印_打印机无法打印怎么办【步骤|图文教程】-太平洋IT百科...

    打印机不能打印怎么回事 打印机无法打印的原因有很多,如果我们遇到打印机无法打印应该首先从简单到复杂入手.首先必须排除一些最简单的问题,比如打印机是否正常安装.另外打印机内部是不是已经放置有墨盒以及打印 ...

  5. ZPL指令打印 斑马打印机指令打印

    首先ZPL(Zebra Programming language)是斑马家搞的ZPL语言,用于和打印机通讯打印开发的指令.然后理解了这个只是个指令的东西后,我们接着就想想怎么弄,本着怎么简单怎么来的原 ...

  6. epson连接计算机后无法打印,epson打印机无法打印,教您epson打印机无法打印怎么解决...

    epson爱普生打印机是现在市面上最受欢迎的打印机,我们在使用这个打印机肯定会碰到这样那样的问题,这时候我们不要手忙脚乱,也不要上去敲敲打打,如果是打印机无法打印的情况,就先来看看epson爱普生打印 ...

  7. 计算机没有a3打印,打印机如何设置打印a3,打印机如何打印a3纸

    caxa实体设计是一款功能十分强大的三维设计软件,其中的设计元素库功能尤为突出,创建立体五角星是学习三维建模最常见的实训演练,那么,在caxa实体设计中如何利用设计元素库快速创建一个立体红色五角星呢? ...

  8. MFC中获取指定打印机的打印队列的方法

    void CPrintListTestDlg::OnBnClickedButton1() {GetDlgItem(IDC_TxtList)->SetWindowText(L"" ...

  9. java 指定打印机打印_java 指定打印机 进行打印

    代码如下: package com.printer; import java.io.*; import java.util.Locale; import javax.print.*; import j ...

最新文章

  1. 作为互联网流量入口,CDN日志大数据你该怎么玩?
  2. hdu-6166(最短路+二进制分组)
  3. C++知识点总结(纯C++!!)
  4. 军用软件概算计价规范_超强干货分享:547建筑工程计量与计价,帮你轻松掌握计量与计价...
  5. docker commit 命令
  6. [codevs 1922] 骑士共存问题
  7. mysql 查询条件优先级_mysql条件查询and or使用实例及优先级介绍
  8. Linux服务器编程之:link()函数,ln命令,symlink,readlink,案例说明
  9. easy ui 使用总结
  10. Android studio导入第三方库的各种方法和eclipse的导入方式对比
  11. 03.结构化机器学习项目 W1.机器学习策略(1)
  12. 深浅拷贝的应用-copy、mutableCopy
  13. 推荐一波对你来说,非常有用的网站,记得收藏
  14. python json详解
  15. datatable排序:DataTable的排序、检索、合并
  16. 【TSP】基于matlab GUI粒子群算法求解旅行商问题【含Matlab源码 1334期】
  17. Web系统大规模并发-电商秒杀与抢购
  18. windows聚焦 电脑锁屏不显示图片问题
  19. mysql 查询结果作为参数_如何将数据库查询出来的字段值作为参数传入下一个请求中...
  20. 在ubuntu上搭建IC数模混合环境

热门文章

  1. 千兆光模块与交换机如何搭配使用?
  2. 如何在ICEM中将有对称面的半模结构网格转变为全模(解决uncovered faces 问题)
  3. Recyclerview之瀑布流分割线左右间距均等问题
  4. java 对接webapi接口数据提交方式之 application/x-www-form-urlencoded
  5. Linux安装多功能词典GoldenDict
  6. 58同城——青龙脚本
  7. h5红包雨代码_js+css实现红包雨效果
  8. SECI知识转化螺旋
  9. 全端通用快速开发UI组件库UnifyUi大更新,Unify Ui是基于uni-app的全端(vue/nvue)组件库
  10. 小学生利用计算机资源简报,享高雅艺术,绘金色童年小学生电子小报成品,简报报刊手抄报模板,画报剪报板报样板,电脑报纸示范样例...