雖說現在已經有越來越多的人轉向用C#來做界面的開發,但是對于一個習慣了C這種半面向對象語言的人來說,MFC依然是難割舍的存在。最近在做些數據庫相關的事,因為是數據庫,自然離不開打印報表之類的東西,所以順帶的也去研究了下如何用MFC來進行打印相關的的
雖說現在已經有越來越多的人轉向用C#來做界面的開發,但是對于一個習慣了C++這種半面向對象語言的人來說,MFC依然是難割舍的存在。最近在做些數據庫相關的事,因為是數據庫,自然離不開打印報表之類的東西,所以順帶的也去研究了下如何用MFC來進行打印相關的的操作。
本篇文章參考的比較多的是這篇文章和MSDN的示例代碼,另外這篇文章也提供了很多有用的參考,如果想看原文的話可以去看看。
直接用微軟提供的CPrintDialog類進行打印的相關操作是非常簡單的,本人將代碼封裝成為兩個函數,除了實際往一頁紙上繪制東西的部分在第二個函數中進行定義外,其他與打印相關的操作都在第一個函數上實現了。具體如下:
打印相關操作主函數:
void CPrinttToPrinterDlg::OnBnClickedButtonPrint() { CPrintDialog dlg(FALSE, PD_ALLPAGES, NULL);//打印對話框對象定義,參數一設置彈出對話框為打印對話框,參數二設置打印范圍為全部頁面,參數三可指定打印機,這里缺省即可 /*打印對話框的初始值設置,在實際應用中可根據需要進行設置,如通過預先計算得到要打印的頁面范圍等*/ dlg.m_pd.nMinPage = 1;//指定開始/結束頁碼編輯控件的頁碼范圍的最小值,若nMinPage=nMaxPage,則“頁碼范圍”單選鈕和開始/結束頁碼編輯控件被灰化 dlg.m_pd.nMaxPage = 2;//指定開始/結束頁碼編輯控件的頁碼范圍的最大值 dlg.m_pd.nCopies = 1;//指定拷貝份數編輯控件的初始值 dlg.m_pd.nFromPage = 1;//指定開始頁碼編輯控件的初始值 dlg.m_pd.nToPage = 2;//指定結束頁碼編輯控件的初始值 if (dlg.DoModal() == IDOK) { HDC hdcPrinter = dlg.GetPrinterDC(); if (hdcPrinter == NULL)//檢取設備環境的句柄,檢索不到則提醒并退出 { MessageBox(_T("Buy a printer!")); } else { /*創建圖形設備環境并與打印機設備關聯,在上面繪圖就相當于往打印機要打出的紙上繪圖*/ CDC dcPrinter; dcPrinter.Attach(hdcPrinter); /* *在打印設置過程中有些東西我們希望用戶來選,所以使用了對話框的形式,但是有些 *東西比如紙張大小和打印方向等我們希望它是固定的,不能讓用戶隨意設置造成麻煩 *因此,我們利用已經得到的打印機圖形設備環境,通過修改它來實現固定設置的功能 */ LPDEVMODE pDevMode; pDevMode = (LPDEVMODE)GlobalLock(dlg.m_pd.hDevMode); pDevMode->dmOrientation = DMORIENT_LANDSCAPE;//設置打印方向為橫向 pDevMode->dmPaperSize = DMPAPER_A4;//設置紙張大小為A4 dcPrinter.ResetDC(pDevMode); //通知打印機驅動程序接收打印文檔并開始打印 DOCINFO docinfo; memset(&docinfo, 0, sizeof(docinfo)); docinfo.cbSize = sizeof(docinfo); docinfo.lpszDocName = _T("CDC::StartDoc() Code Fragment"); //如果初始化失敗則提醒并退出 if (dcPrinter.StartDoc(&docinfo) < 0) { MessageBox(_T("Printer wouldn't initalize")); } else { /*打印的紙張大小我們是需要知道的,此外我們還需要設備像素點和實際長度單位的換算關系即DPI*/ int xDPI = GetDeviceCaps(hdcPrinter, LOGPIXELSX);//返回X方向上每英寸的設備點數,即DPI float mmdpix = xDPI / 25.4;//每毫米所占的設備點數 int yDPI = GetDeviceCaps(hdcPrinter, LOGPIXELSY);//返回Y方向上每英寸的設備點數,即DPI float mmdpiy = yDPI / 25.4;//每毫米所占的設備點數 float printerscreenx, printerscreeny;//這里得到打印機屏幕的寬高,也就是紙張的大小,會比實際小約6mm printerscreenx = GetDeviceCaps(hdcPrinter, HORZSIZE); printerscreeny = GetDeviceCaps(hdcPrinter, VERTSIZE); /*因為要打印的頁碼范圍和份數是用戶選擇的,所以在此對用戶選擇的項做處理*/ int pagebegin, pageend;//打印范圍 if (dlg.PrintAll())//看用戶是否選擇了全部打印這一項,是的話則全部打印 { pagebegin = dlg.m_pd.nMinPage; pageend = dlg.m_pd.nMaxPage; } else if (dlg.PrintRange())//用戶選擇了選定頁碼范圍項 { pagebegin = dlg.m_pd.nFromPage; pageend = dlg.m_pd.nToPage; } else//用戶選擇了選定范圍打印,因為我們在這里沒有提供選定范圍的功能,所以用戶一旦選擇這里當成是操作錯誤處理即可 { MessageBox(_T("Could not choise this one")); dcPrinter.AbortDoc();//錯誤退出區別于EndDoc } int ncopy = dlg.m_pd.nCopies;//用戶選擇打印分數 /*在這里進行打印工作*/ while (ncopy--)//逐份打印 { for (int page = pagebegin; page <= pageend; page++)//從選定范圍開始打印 { if (dcPrinter.StartPage() < 0) { MessageBox(_T("Could not start page")); dcPrinter.AbortDoc();//錯誤退出區別于EndDoc } else//如果進入這里則繪出要打印內容并結束掉一頁的打印 { doThePrint(dcPrinter, page, mmdpix, mmdpiy, printerscreenx, printerscreeny); dcPrinter.EndPage(); } } } } dcPrinter.EndDoc();//打印完成退出 dcPrinter.Detach();//釋放DC } } }
void CPrinttToPrinterDlg::doThePrint(CDC &dc,int page, float mdpix, float mdpiy, float mpagex, float mpagey)//打印實際繪圖函數,往參數一傳入的CDC上面繪圖 { CPen pen, *pOldPen;// 定義筆對象和指針 // 創建10單位寬的綠色實心筆 pen.CreatePen(PS_SOLID, 100, RGB(0, 255, 0)); pOldPen = dc.SelectObject(&pen);// 選入綠色筆 dc.Re【本文來自鴻網互聯 (http://www.68idc.cn)】ctangle(0 * mdpix, 0 * mdpiy, mpagex*mdpix, mpagey*mdpiy);// 畫矩形 dc.SelectObject(pOldPen);// 選出綠色筆 pen.DeleteObject();// 刪除綠色筆 }
打印預覽還有如何去打印數據表格這些功能本人后面如果研究實現了的話也會貼上來,或者發個鏈接上來,這篇文章就先到這里吧。
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com