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