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

来源:互联网 发布:安卓版微信营销软件 编辑:程序博客网 时间:2024/05/22 13:24

此文转载,原文地址:

http://blog.csdn.net/xjkstar/article/details/25828097


对话框打印,网上一搜一大堆,基本分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函数,第一次的到结构体的大小,第二次得到打印机列表

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. // TODO: 在此添加额外的初始化代码  
  2.     DWORD dwNeeded;  
  3.     DWORD dwReturn;  
  4.     DWORD dwFlag = PRINTER_ENUM_CONNECTIONS | PRINTER_ENUM_LOCAL;  
  5.   
  6.     EnumPrinters(dwFlag, NULL, 4, NULL, 0, &dwNeeded, &dwReturn);  
  7.   
  8.     PRINTER_INFO_4* p4;  
  9.     p4 = new PRINTER_INFO_4[dwNeeded];  
  10.     EnumPrinters(dwFlag, NULL, 4, (PBYTE)p4, dwNeeded, &dwNeeded, &dwReturn);  
  11.   
  12.     for (int i = 0; i<(int)dwReturn; i++)  
  13.         this->m_cboPrint.AddString(p4[i].pPrinterName);  
  14.   
  15.     delete []p4;  


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

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

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. // TODO: 在此添加控件通知处理程序代码  
  2. //  CDialogEx::OnOK();  
  3.     this->UpdateData();  
  4.   
  5.     CString strMessage;  
  6.     CString strPrintDevice;  
  7.   
  8.     this->GetDlgItem(IDC_EDIT1)->GetWindowTextW(strMessage);  
  9.     strMessage += _T("\r\n");       //添加结尾,方便后面循环读取打印数据  
  10.   
  11.     this->GetDlgItem(IDC_COMBO1)->GetWindowTextW(strPrintDevice);  
  12.   
  13.     DWORD dwFlag = PD_ALLPAGES | PD_NOPAGENUMS | PD_USEDEVMODECOPIES | PD_HIDEPRINTTOFILE;  //打印配置界面的按钮可用性,因为后台打印,其实这个配置没什么意义  
  14.   
  15.     CPrintDialog pPrintdlg(FALSE, dwFlag, this);                                            //CPrintDialog实例化,因为MFC的打印设备无关性,可以理解为这就是一台打印机  
  16.   
  17.     HGLOBAL hDevMode = NULL;  
  18.     HGLOBAL hDevNames = NULL;  
  19.     if (GetPrinterDevice(strPrintDevice.GetBuffer(0), &hDevNames, &hDevMode))               //获得指定打印机的配置、名字  
  20.         AfxGetApp()->SelectPrinter(hDevNames, hDevMode);  
  21.     else  
  22.         AfxMessageBox(_T("Failed to select custom printer"));  
  23.   
  24.     strPrintDevice.ReleaseBuffer();  
  25.   
  26.     pPrintdlg.m_pd.hDevMode = hDevMode;                                                     //让pPrintdlg使用我们指定的打印机  
  27.     pPrintdlg.m_pd.hDevNames = hDevNames;  
  28.   
  29.     CDC dc;  
  30.     dc.Attach(pPrintdlg.CreatePrinterDC());                                                 //后台打印创建法,如果需要弹出打印对话框,请用DoModal  
  31.   
  32.     DOCINFO di;                                                                             //下面的内容网上很多,就不解释了  
  33.     di.cbSize = sizeof(DOCINFO);  
  34.     di.lpszDocName = _T("有驱打印测试");  
  35.     di.lpszDatatype = NULL;  
  36.     di.lpszOutput = NULL;  
  37.     di.fwType = 0;  
  38.   
  39.     dc.StartDocW(&di);  
  40.     dc.StartPage();  
  41.     dc.SetMapMode(MM_TEXT);  
  42.   
  43.     CRect recPrint(0, 0, dc.GetDeviceCaps(LOGPIXELSX), dc.GetDeviceCaps(LOGPIXELSY));  
  44.     dc.DPtoLP(&recPrint);  
  45.     dc.SetWindowOrg(0, 0);  
  46.   
  47.     CFont newFont;  
  48.     VERIFY(newFont.CreatePointFont(120, _T("宋体"), &dc));  
  49.     CFont* oldFont = dc.SelectObject(&newFont);  
  50.   
  51.     dc.SetTextAlign(TA_TOP | TA_LEFT);  
  52.   
  53.     CString strPrint;  
  54.     int nIndex = 0;  
  55.     int x = 50;  
  56.     int y = 50;  
  57.     CSize textSize;  
  58.     textSize = dc.GetTextExtent(_T("00"), 2);                           //根据当前字体的宽、高,后面以此高度为行高  
  59.   
  60.     while ((nIndex = strMessage.Find(_T("\r\n"))) > -1)                  //将IDC_EDIT1编辑框中内容打印,支持换行,一次换行等于'\r\n',所以在开头strMessage += _T("\r\n")  
  61.     {  
  62.         strPrint = strMessage.Left(nIndex);  
  63.         strMessage = strMessage.Mid(nIndex+2);  
  64.   
  65.         dc.TextOutW(x, y, strPrint);  
  66.   
  67.         y += textSize.cy;                                               //下移一行,行高为字体高度  
  68.     }  
  69.   
  70.     dc.SelectObject(oldFont);  
  71.     newFont.DeleteObject();  
  72.     dc.EndPage();  
  73.     dc.EndDoc();  
  74.     DeleteDC(dc.Detach());  

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

代码也贴出来

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. BOOL CMFCApplication2Dlg::GetPrinterDevice(LPTSTR pszPrinterName, HGLOBAL* phDevNames, HGLOBAL* phDevMode)  
  2. {  
  3.     // if NULL is passed, then assume we are setting app object's  
  4.     // devmode and devnames  
  5.     if (phDevMode == NULL || phDevNames == NULL)  
  6.         return FALSE;  
  7.   
  8.     // Open printer  
  9.     HANDLE hPrinter;  
  10.     if (OpenPrinter(pszPrinterName, &hPrinter, NULL) == FALSE)  
  11.         return FALSE;  
  12.   
  13.     // obtain PRINTER_INFO_2 structure and close printer  
  14.     DWORD dwBytesReturned, dwBytesNeeded;  
  15.     GetPrinter(hPrinter, 2, NULL, 0, &dwBytesNeeded);  
  16.     PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAlloc(GPTR,  
  17.         dwBytesNeeded);  
  18.     if (GetPrinter(hPrinter, 2, (LPBYTE)p2, dwBytesNeeded,  
  19.         &dwBytesReturned) == 0) {  
  20.             GlobalFree(p2);  
  21.             ClosePrinter(hPrinter);  
  22.             return FALSE;  
  23.     }  
  24.     ClosePrinter(hPrinter);  
  25.   
  26.     // Allocate a global handle for DEVMODE  
  27.     HGLOBAL  hDevMode = GlobalAlloc(GHND, sizeof(*p2->pDevMode) +  
  28.         p2->pDevMode->dmDriverExtra);  
  29.     ASSERT(hDevMode);  
  30.     DEVMODE* pDevMode = (DEVMODE*)GlobalLock(hDevMode);  
  31.     ASSERT(pDevMode);  
  32.   
  33.     // copy DEVMODE data from PRINTER_INFO_2::pDevMode  
  34.     memcpy(pDevMode, p2->pDevMode, sizeof(*p2->pDevMode) +  
  35.         p2->pDevMode->dmDriverExtra);  
  36.     GlobalUnlock(hDevMode);  
  37.   
  38.     // Compute size of DEVNAMES structure from PRINTER_INFO_2's data  
  39.     DWORD drvNameLen = lstrlen(p2->pDriverName)+1;  // driver name  
  40.     DWORD ptrNameLen = lstrlen(p2->pPrinterName)+1; // printer name  
  41.     DWORD porNameLen = lstrlen(p2->pPortName)+1;    // port name  
  42.   
  43.     // Allocate a global handle big enough to hold DEVNAMES.  
  44.     HGLOBAL hDevNames = GlobalAlloc(GHND,  
  45.         sizeof(DEVNAMES) +  
  46.         (drvNameLen + ptrNameLen + porNameLen)*sizeof(TCHAR));  
  47.     ASSERT(hDevNames);  
  48.     DEVNAMES* pDevNames = (DEVNAMES*)GlobalLock(hDevNames);  
  49.     ASSERT(pDevNames);  
  50.   
  51.     // Copy the DEVNAMES information from PRINTER_INFO_2  
  52.     // tcOffset = TCHAR Offset into structure  
  53.     int tcOffset = sizeof(DEVNAMES)/sizeof(TCHAR);  
  54.     ASSERT(sizeof(DEVNAMES) == tcOffset*sizeof(TCHAR));  
  55.   
  56.     pDevNames->wDriverOffset = tcOffset;  
  57.     memcpy((LPTSTR)pDevNames + tcOffset, p2->pDriverName,  
  58.         drvNameLen*sizeof(TCHAR));  
  59.     tcOffset += drvNameLen;  
  60.   
  61.     pDevNames->wDeviceOffset = tcOffset;  
  62.     memcpy((LPTSTR)pDevNames + tcOffset, p2->pPrinterName,  
  63.         ptrNameLen*sizeof(TCHAR));  
  64.     tcOffset += ptrNameLen;  
  65.   
  66.     pDevNames->wOutputOffset = tcOffset;  
  67.     memcpy((LPTSTR)pDevNames + tcOffset, p2->pPortName,  
  68.         porNameLen*sizeof(TCHAR));  
  69.     pDevNames->wDefault = 0;  
  70.   
  71.     GlobalUnlock(hDevNames);  
  72.     GlobalFree(p2);   // free PRINTER_INFO_2  
  73.   
  74.     // set the new hDevMode and hDevNames  
  75.     *phDevMode = hDevMode;  
  76.     *phDevNames = hDevNames;  
  77.     return TRUE;  
  78. }  


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


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 江苏大学专业选修课挂了怎么办 电信翼企享福卡怎么办 教育部学籍在线验证报告过期怎么办 身份证被别人注册了学信网怎么办 大专文凭查不到学籍该怎么办 学信网上查不到学历怎么办 学信网上没有学历照片怎么办 学信网上没照片怎么办 学历认证报告丢了怎么办 学历认证弄丢了怎么办 手机系统安全证书有问题怎么办 台式电脑的浏览器证书出错怎么办 网上银行k宝密码忘了怎么办 工行证书介质已被锁定怎么办 学历认证是假的怎么办 怕被公司查学历怎么办 淘宝玩具没有怎么办3c 家庭遭遇小三我该怎么办 老公出轨把小三带回家了怎么办 小三怀孕了怎么办准生证 小三怀孕了起诉怎么办 不知情做了小三怎么办 发现自己被三了怎么办 被扇巴掌脸肿了怎么办 分到上海市金鼎学校怎么办 被列入维稳对象怎么办? 资金涉及诈骗案冻结了怎么办 小米浏览器浏览记录找不到了怎么办 米聊账号封了怎么办 管家婆创业版管理员忘记密码怎么办 手机不记得密码了怎么办 手机不记得开锁密码怎么办 oppo手机不记得密码怎么办 电脑密码不记得了怎么办 vivo手机不记得密码了怎么办 运管把车扣了怎么办 大学通选课挂科怎么办 通识必修课挂了怎么办 我想开3d艺术馆怎么办 档案回原籍报到证怎么办 服刑的人孩子上学怎么办