|          
(说明:)这一段代码,用以演示《如何在VC++中使用API直接打印》。并且该段代码可以直接嵌入各种工程中,有实际使用的价值。
 (用途:)在Visual C++中,应用程序通常是使用CView中提供的打印功能,在OnPrint()或OnDraw()中向打印机输出。但是对于对话框中的数据,或基于对话框的程序,打印成了一件繁琐的工作。
 
 该段代码向用户提供了PrintListCtrl()函数,用于打印用户在对话框或FormView中的CListCtrl(控件必须是Report View 形式的)控件中的内容。在打印过程中,根据控件中每列标题的宽度计算打印输出时各列的宽度,并根据数据的行数自动分页。在本代码的基础上稍作修改,就可以适应各种数据的输出。
 
 (用法:)该段代码使用Visual C++ 6.0, 使用Windows API来完成所需功能,使用时将本文本作为头文件使用。打印时直接调用PrintListCtrl(),函数的参数为所要打印的ListCtrl。?联系方法:lff@mail.wl.xj.cn
 
 *///该结构用于存储各列的信息
 typedef struct tagColAtt
 {
 int nColIndex;
 CString strColText;
 int nPrintX;
 int nSubItemIndex;
 }
 COLATT;
 
 BOOL PrintListCtrl(CListCtrl &list)
 {
 PRINTDLG pd;
 pd.lStructSize = sizeof(PRINTDLG);
 pd.Flags = PD_RETURNDC;
 pd.hDC = NULL;
 pd.hwndOwner = NULL;
 pd.hInstance = NULL;
 pd.nMaxPage = 1;
 pd.nMinPage = 1;
 pd.nFromPage = 1;
 pd.nToPage = 1;
 pd.nCopies = 1;
 pd.hDevMode = NULL;
 pd.hDevNames = NULL;
 //显示打印对话框,由用户来设定纸张大小等。
 if(!PrintDlg(&pd)) return FALSE;
 ASSERT(pd.hDC!=NULL);
 int nHorRes = GetDeviceCaps(pd.hDC, HORZRES);
 int nVerRes = GetDeviceCaps(pd.hDC, VERTRES);
 int nXMargin = 2;
 int nYMargin = 2;
 TEXTMETRIC tm;
 GetTextMetrics(pd.hDC, &tm);
 int nCharHeight = tm.tmHeight;
 int nCharWidth = tm.tmAveCharWidth;
 CHeaderCtrl* pHeader = list.GetHeaderCtrl();
 //获得行,列的个数
 int nColCount = pHeader->GetItemCount();
 int nLineCount = list.GetItemCount();
 int ColOrderArray[100];
 COLATT ca[100];
 list.GetColumnOrderArray(ColOrderArray, nColCount);
 int nColX =nXMargin*nCharWidth;
 //检索各列的信息,确定列标题的内容长度。
 for(int i =0 ; i< nColCount; i++)
 {
 ca[i].nColIndex = ColOrderArray[i];
 LVCOLUMN lvc;
 char text[100];
 lvc.mask = LVCF_TEXT|LVCF_SUBITEM;
 lvc.pszText = text;
 lvc.cchTextMax = 100;
 list.GetColumn(ca[i].nColIndex, &lvc);
 ca[i].strColText = lvc.pszText;
 ca[i].nSubItemIndex = lvc.iSubItem;
 ca[i].nPrintX = nColX;
 nColX += nCharWidth * strlen(ca[i].strColText);
 if(nColX > nHorRes)
 {
 DeleteDC(pd.hDC);
 AfxMessageBox("字段太多,无法在一行内打印,请试用较大的纸,或横向打印。");
 return FALSE;
 }
 }
 DOCINFO di;
 di.cbSize = sizeof(DOCINFO);
 di.lpszDocName = "ListCtrl Data Printing";
 di.lpszOutput = (LPTSTR) NULL;
 di.lpszDatatype = (LPTSTR) NULL;
 di.fwType = 0;
 StartDoc(pd.hDC, &di);
 StartPage(pd.hDC);
 //调整各列的宽度,以使各列在后面的打印输出时更均匀的打印在纸上。
 int space = (nHorRes-nXMargin*nCharWidth-nColX) / (nColCount -1);
 for(i =1; i<nColCount; i++)
 {
 ca[i].nPrintX += i*space;
 }
 //输出列标题
 for(i =0; i<nColCount; i++)
 TextOut(pd.hDC, ca[i].nPrintX, nYMargin,
 ca[i].strColText, strlen(ca[i].strColText));
 int nMaxLinePerPage = nVerRes/nCharHeight -3;
 int nCurPage =1;
 //输出各列的数据
 for(i =0; i<nLineCount; i++)
 {
 for(int j =0; j<nColCount; j++)
 {
 if(i+1-(nCurPage-1)*nMaxLinePerPage > nMaxLinePerPage)
 {
 //新的一页
 EndPage(pd.hDC);
 StartPage(pd.hDC);
 nCurPage ++;
 }
 CString subitem = list.GetItemText(i, ca[j].nSubItemIndex);
 TextOut(pd.hDC, ca[j].nPrintX,nYMargin+(i+1-(nCurPage-1)*nMaxLinePerPage)*nCharHeight,subitem, strlen(subitem));
 }
 }
 EndPage(pd.hDC);
 EndDoc(pd.hDC);
 //打印结束
 DeleteDC(pd.hDC);
 return TRUE;
 |