最后70分求助:编写打印功能遇到困难,实在解决不了,特来求助,急……

pjf2000 2005-02-17 09:06:34
vc/MFC 单文档项目
小弟初次编写打印功能,遇到一些困难让我无从下手,我查了相关资料,也查过了CSDN上面相关的帖子,解决了几个,最后还有4个,我实在没有办法解决了,特来求助,望高手帮忙:

1、自定义纸张大小。
vc/mfc默认提供的纸张是A4,现在由于打印发票的需要,必须改变打印区域的大小。CSDN上面有一个例子提到了改变纸张大小和改变纸张的方向(横向、纵向)的方法。我试了一下,发现“改变纸张的方向”的功能可以实现,但是“改变纸张大小”的功能实现不了。郁闷……

2、打印分页
vc/mfc默认提供的“打印预览”里面有一个按纽是“下一页”,但是当我要打印的东西超过一页时,那个“下一页”的按纽根本不起作用。那么要如何实现分页打印的功能呢?

3、打印走纸的实现
vc/mfc默认提供的纸张是A4,所以打印的时候走纸的长度也是A4的长度。我想要自己控制走纸的长度,具体要怎么实现啊?

4、程序中如何判断用户是完成了打印操作还是仅仅进行了“打印预览”但没有进行打印。

以上4个问题,我摸索了好几天了,始终解决不了,望CSDN的高手可以帮助解决,谢谢!

学习,关注……
...全文
135 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
koko1998 2005-02-18
  • 打赏
  • 举报
回复
用API打印的例子,参考一下吧。

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

(说明:)这一段代码,用以演示《如何在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;
cdcouch 2005-02-18
  • 打赏
  • 举报
回复
你需要改成
pDM->dmPaperSize = DMPAPER_USER; //设定为自定义纸张尺寸
pDM->dmFields |= DM_PAPERSIZE; //允许重新设置纸张大小
pDM->dmPaperLength = 1400; //设定纸长为 14 厘米
pDM->dmPaperWidth=2200;
pDM->dmFields |= -1;
就可以了。呵呵!
red-fly 2005-02-18
  • 打赏
  • 举报
回复
“改变纸张大小”:
你只需要在相应的范围内“写字、画画”就行了,大小只是用户选择的罢了

打印分页:
这个没有弄过,不知道

打印走纸的实现:
这个也没有弄过,不知道怎么实现,但我想不会太难,有空我试一试

程序中如何判断用户是完成了打印操作还是仅仅进行了“打印预览”但没有进行打印:
这应该根据用户按按钮的情况判断
lizmei001 2005-02-18
  • 打赏
  • 举报
回复
你的第而个问题我也郁闷,查了一些资料也没有解决

被的问题我的解决是在打印服务中填加相应大小的纸张,并设置为默认的纸张
xuzheng318 2005-02-18
  • 打赏
  • 举报
回复
帮你顶一下!
pjf2000 2005-02-18
  • 打赏
  • 举报
回复
自己顶一下……
pjf2000 2005-02-18
  • 打赏
  • 举报
回复
谢谢,各位大哥的帮助,结贴!
pjf2000 2005-02-17
  • 打赏
  • 举报
回复
小弟先贴一个CSDN上面的例子
BOOL CMyDialog::DoPreparePrintDC() //准备打印场景
{
  #define FONTSIZE 14
  //获取打印机的设备属性
  CPrintDialog dlgPrint(FALSE);
  //得到当前系统缺省打印机设置
  if(!dlgprint.GetDefau1ts())return FALSE;
  LPDEVMODE pDM=dlgPrint.GetDevMode();
  if (pDM==NULL)return FALSE;
  //调整打印方向
  //pDM->dm0rientation=DMORIENT_LANDSCAPE(横向)‖
  DMORIENT_PORTRAIT(纵向);
  //调整纸张大小
  //制式纸张:pDM->dmPaperSize=DMPAPER_A3等;
  //或自定义大小:单位:1/10毫米
  //pDM->dmPaperSize=DMPAPER_USER;
  //pDM->dmPaperLength=纸张高度;
  //pDM->dmPaperWidth=纸张宽度;
  //解锁由CPrintDialog::GetDevMode()封锁的内存
  ::GlobalUn1ock(pDM);
  //联结打印DC,m_hDC是定义为HDC m_hDC的类成员变量
  m_hDC=dlgPrint.CreatePrinterDC();
  //m_DC是定义为CDC m_DC的类成员变量
  if (!m_DC.Attach(m_hDC))return FALSE;
  //设置打印标志
  m_DC.m_bPrinting=TRUE;
  //根据打印机分辨率建立打印字体
  //得到每英寸点数
  short cxInch=m_DC.GetDeviceCaps(LOGPIXELSX);
  short cyInch=m_DC.GetDeviceCaps(LOGPIXELSY);
  //建立打印字体,m_fontPrint是定义为CFont m_fontPrint的类成员变量
  if(!m_fontPrint.CreateFont(MulDiv(FONTSIZE,-cyInch,
72),
  0,0,0,FW_NORMAL,0,0,0,
  GB2312_CHARSET,OUT_CHARACTER_PRECIS,CLIP_CHA
RACTER_PRECIS,
  DEFAULT_QUALITY,DEFAULT_PITCH|FF—DONTCARE,HFONTNAME)
  return FALSE;
  return TRUE;
}

我试了一下这个例子,发现其中改变纸张方向的功能是可以的,但是改变纸张大小的功能却不行。是不是使用这个例子还需要一些额外的条件啊?

望CSDN上面的高手可以帮助我解决困难,先谢谢了!

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧