虽说现在已经有越来越多的人转向用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();// 删除绿色笔 }
到此文章就已经写得七七八八了,调用主函数就可以实现往打印机上打印动东西的功能。至于打印什么东西,如何去打,就是GDI绘图的事了。另外由于我们还没有实现打印预览的功能,所以可以用虚拟打印机来看效果,当然如果有钱,也可以直接用真的打印机来看啦哈哈,本人用的是finepring,简而言之就两个字形容,神器!
打印预览还有如何去打印数据表格这些功能本人后面如果研究实现了的话也会贴上来,或者发个链接上来,这篇文章就先到这里吧。

MySQL使用的是GPL許可證。 1)GPL許可證允許自由使用、修改和分發MySQL,但修改後的分發需遵循GPL。 2)商業許可證可避免公開修改,適合需要保密的商業應用。

選擇InnoDB而不是MyISAM的情況包括:1)需要事務支持,2)高並發環境,3)需要高數據一致性;反之,選擇MyISAM的情況包括:1)主要是讀操作,2)不需要事務支持。 InnoDB適合需要高數據一致性和事務處理的應用,如電商平台,而MyISAM適合讀密集型且無需事務的應用,如博客系統。

在MySQL中,外鍵的作用是建立表與表之間的關係,確保數據的一致性和完整性。外鍵通過引用完整性檢查和級聯操作維護數據的有效性,使用時需注意性能優化和避免常見錯誤。

MySQL中有四種主要的索引類型:B-Tree索引、哈希索引、全文索引和空間索引。 1.B-Tree索引適用於範圍查詢、排序和分組,適合在employees表的name列上創建。 2.哈希索引適用於等值查詢,適合在MEMORY存儲引擎的hash_table表的id列上創建。 3.全文索引用於文本搜索,適合在articles表的content列上創建。 4.空間索引用於地理空間查詢,適合在locations表的geom列上創建。

toCreateAnIndexinMysql,usethecReateIndexStatement.1)forasingLecolumn,使用“ createIndexIdx_lastNameEnemployees(lastName); 2)foracompositeIndex,使用“ createIndexIndexIndexIndexIndexDx_nameOmplayees(lastName,firstName,firstName);” 3)forauniqe instex,creationexexexexex,

MySQL和SQLite的主要區別在於設計理念和使用場景:1.MySQL適用於大型應用和企業級解決方案,支持高性能和高並發;2.SQLite適合移動應用和桌面軟件,輕量級且易於嵌入。

MySQL中的索引是數據庫表中一列或多列的有序結構,用於加速數據檢索。 1)索引通過減少掃描數據量提升查詢速度。 2)B-Tree索引利用平衡樹結構,適合範圍查詢和排序。 3)創建索引使用CREATEINDEX語句,如CREATEINDEXidx_customer_idONorders(customer_id)。 4)複合索引可優化多列查詢,如CREATEINDEXidx_customer_orderONorders(customer_id,order_date)。 5)使用EXPLAIN分析查詢計劃,避

在MySQL中使用事務可以確保數據一致性。 1)通過STARTTRANSACTION開始事務,執行SQL操作後用COMMIT提交或ROLLBACK回滾。 2)使用SAVEPOINT可以設置保存點,允許部分回滾。 3)性能優化建議包括縮短事務時間、避免大規模查詢和合理使用隔離級別。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

Atom編輯器mac版下載
最受歡迎的的開源編輯器

禪工作室 13.0.1
強大的PHP整合開發環境