CListCtrl的打印及预览 大家好 我想实现CListCtrl中的内容的打印,要有预览功能,我的程序是基于对话框结构的.其中要打印出CListCtrl中的标题和内容,要能够自动分页,在网上找了好久都没有找到有用的.希望大家能够帮帮我实现这个功能. 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 http://www.codeproject.com/KB/combobox/listprint.aspx看看这个~:) http://www.programbbs.com/doc/1428.htm 是的,我在对话框中加入了一个列表控件,通过查询数据库把数据库中的记录放入到列表控件中,我想把其中的内容打印出来,就像DOC-VIEW结构一样可以有打印预览功能 谢谢 [email protected] 一个函数就OK了。看看修改一下啦BOOL PrintKq_Deal_QueryCtrl(CListCtrl &list) //请假信息的打印{ HFONT hRecordFont;//记录的字体 HFONT hTopicFont;//标题的字体 HFONT hCodeFont;//字段的字体 //创建(输出内容的)字体 hRecordFont=CreateFont(93,29,1,0,FW_EXTRALIGHT,0,0,0,ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "宋体字"); //创建标题的字体 hTopicFont=CreateFont(260,47,10,0,FW_BOLD,0,0,0,ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "楷体_GB2312"); //创建字段的字体 hTopicFont=CreateFont(150,21,1,0,FW_BOLD,0,0,0,ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "楷体_GB2312"); //设置打印对话框 PRINTDLG pd; pd.lStructSize=sizeof(PRINTDLG); pd.Flags=PD_RETURNDC; pd.hDC=NULL; pd.hwndOwner=NULL; pd.hInstance=NULL; pd.nMaxPage=2; 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 = 20;//页边的空白 int nYMargin = 6; /////////////////////////////////////////////////////////// TEXTMETRIC tm;/*映射结构体*/ GetTextMetrics(pd.hDC, &tm); int nCharWidth = tm.tmAveCharWidth; int ncaps=(tm.tmPitchAndFamily &1?3:2)*nCharWidth/2; int nCharHeight =tm.tmExternalLeading +tm.tmHeight+ncaps;// /////////////////////////////////////////////////////////// CHeaderCtrl* pHeader = list.GetHeaderCtrl(); //获得行,列的个数 int nColCount = pHeader->GetItemCount();//获取列头的个数 int nLineCount = list.GetItemCount(); //获取ListCtrl的记录行数 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 = "考勤报表"; di.lpszOutput = (LPTSTR)NULL; di.lpszDatatype = (LPTSTR)NULL; di.fwType = 0; StartDoc(pd.hDC,&di); StartPage(pd.hDC); SelectObject(pd.hDC,hTopicFont); TextOut(pd.hDC,nHorRes/3,nYMargin,"考 勤 报 表",strlen("考 勤 报 表")); //////////////////////////////////////////////// //调整各列的宽度,以使各列在后面的打印输出时更均匀的打印在纸上. int space =(nHorRes-nXMargin*nCharWidth-nColX)/(nColCount); for(i=1;i<nColCount;i++) { ca[i].nPrintX+=i*space; } SelectObject(pd.hDC,hCodeFont); //输出列标题 for(i =0;i<nColCount;i++) TextOut(pd.hDC,ca[i].nPrintX,nYMargin+260, ca[i].strColText,strlen(ca[i].strColText)); int nMaxLinePerPage =nVerRes/nCharHeight -3; int nCurPage=1; SelectObject(pd.hDC,hRecordFont);//将字体选入设备描述表里 //输出各列的数据 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].nColIndex); TextOut(pd.hDC,ca[j].nPrintX, nYMargin+300+(i+1-(nCurPage-1)*nMaxLinePerPage)*nCharHeight, subitem,strlen(subitem)); } } EndPage(pd.hDC); EndDoc(pd.hDC); //打印结束 DeleteObject(hTopicFont); DeleteObject(hRecordFont); DeleteObject(hCodeFont); DeleteDC(pd.hDC); return TRUE; } 本帖最后由 laiyiling 于 2008-04-22 15:13:17 编辑 UTF-8 转换为汉字 一个比较不常见的问题,WinINet能穿透SOCKS5代理吗? 如何理解CoInitialize? 逆袭的外星文明!!!背包问题再度屠戮人间!!! 请帮我解决一个窗口显示的问题,多谢了 有谁对"将IPX协议转换成TCP/IP协议"比较熟悉 现在大家说的vc++技术内幕到底是哪本? 怎么关闭当前窗口? CString sComment = _T("")什么意思? 恩。主席说了。有难度 谁有关于C++ 中socket的英文资料,谢谢!! OpenGL波浪的渲染
[email protected]
{ HFONT hRecordFont;//记录的字体 HFONT hTopicFont;//标题的字体 HFONT hCodeFont;//字段的字体 //创建(输出内容的)字体
hRecordFont=CreateFont(93,29,1,0,FW_EXTRALIGHT,0,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
"宋体字");
//创建标题的字体 hTopicFont=CreateFont(260,47,10,0,FW_BOLD,0,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
"楷体_GB2312");
//创建字段的字体 hTopicFont=CreateFont(150,21,1,0,FW_BOLD,0,0,0,ANSI_CHARSET,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
"楷体_GB2312");
//设置打印对话框 PRINTDLG pd; pd.lStructSize=sizeof(PRINTDLG);
pd.Flags=PD_RETURNDC;
pd.hDC=NULL; pd.hwndOwner=NULL; pd.hInstance=NULL; pd.nMaxPage=2; 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 = 20;//页边的空白 int nYMargin = 6; /////////////////////////////////////////////////////////// TEXTMETRIC tm;/*映射结构体*/ GetTextMetrics(pd.hDC, &tm); int nCharWidth = tm.tmAveCharWidth; int ncaps=(tm.tmPitchAndFamily &1?3:2)*nCharWidth/2; int nCharHeight =tm.tmExternalLeading +tm.tmHeight+ncaps;// ///////////////////////////////////////////////////////////
CHeaderCtrl* pHeader = list.GetHeaderCtrl(); //获得行,列的个数 int nColCount = pHeader->GetItemCount();//获取列头的个数 int nLineCount = list.GetItemCount(); //获取ListCtrl的记录行数
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 = "考勤报表";
di.lpszOutput = (LPTSTR)NULL; di.lpszDatatype = (LPTSTR)NULL; di.fwType = 0; StartDoc(pd.hDC,&di); StartPage(pd.hDC); SelectObject(pd.hDC,hTopicFont); TextOut(pd.hDC,nHorRes/3,nYMargin,"考 勤 报 表",strlen("考 勤 报 表"));
////////////////////////////////////////////////
//调整各列的宽度,以使各列在后面的打印输出时更均匀的打印在纸上.
int space =(nHorRes-nXMargin*nCharWidth-nColX)/(nColCount);
for(i=1;i<nColCount;i++)
{
ca[i].nPrintX+=i*space;
}
SelectObject(pd.hDC,hCodeFont); //输出列标题 for(i =0;i<nColCount;i++) TextOut(pd.hDC,ca[i].nPrintX,nYMargin+260,
ca[i].strColText,strlen(ca[i].strColText));
int nMaxLinePerPage =nVerRes/nCharHeight -3; int nCurPage=1; SelectObject(pd.hDC,hRecordFont);//将字体选入设备描述表里
//输出各列的数据
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].nColIndex);
TextOut(pd.hDC,ca[j].nPrintX,
nYMargin+300+(i+1-(nCurPage-1)*nMaxLinePerPage)*nCharHeight,
subitem,strlen(subitem));
}
} EndPage(pd.hDC); EndDoc(pd.hDC); //打印结束 DeleteObject(hTopicFont); DeleteObject(hRecordFont); DeleteObject(hCodeFont); DeleteDC(pd.hDC); return TRUE;
}