如何在VC++中使用API直接打印

Visual  C++中,应用程序通常是使用CView中提供的打印功能,在OnPrint()或OnDraw()中向打印机输出。但是对于对话框中的数据,或基于对话框的程序,打印成了一件繁琐的工作。  
 
该段代码向用户提供了PrintListCtrl()函数,用于打印用户在对话框或FormView中的CListCtrl(控件必须是Report  View  形式的)控件中的内容。在打印过程中,根据控件中每列标题的宽度计算打印输出时各列的宽度,并根据数据的行数自动分页。在本代码的基础上稍作修改,就可以适应各种数据的输出。  
 
(用法:)该段代码使用Visual  C++  6.0,  使用Windows  API来完成所需功能,使用时将本文本作为头文件使用。打印时直接调用PrintListCtrl(),函数的参数为所要打印的ListCtrl。?联系方法:[email protected]  
 
*///该结构用于存储各列的信息  
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;  

你可能感兴趣的:(如何在VC++中使用API直接打印)