最后70分求助:关于“打印分页”的问题!HELP……
vc/mfc 单文档项目
小弟现在想要通过单文档自带的“打印预览”和“打印”功能,写一个打印表格的程序,基本的流程我已经弄清楚了,画表格也没有问题,但是“分页”的功能不会写。
我通过pDC->EndPage() 和 pDC->StatPage()在程序中进行分页。发现“打印预览”的时候显示的是最后一页,而且“打印工具栏”上面的“上一页”和“下一页”按纽也不起作用。
关于分页打印表格的程序,请高手给一个简单的例子,麻烦给出注释!
废话比较多,谢谢看完并回复!
学习,关注……
问题点数:70、回复次数:11Top
1 楼imyourkobe()回复于 2005-04-02 20:18:42 得分 50
你参考参考吧!
void CPrinterJob::OnFilePrint()
{
CPrintInfo printInfo;
ASSERT(printInfo.m_pPD != NULL); // must be set
if (OnPreparePrinting(&printInfo))
{
// hDC must be set (did you remember to call DoPreparePrinting?)
ASSERT(printInfo.m_pPD->m_pd.hDC != NULL);
// gather file to print to if print-to-file selected
CString strOutput;
if (printInfo.m_pPD->m_pd.Flags & PD_PRINTTOFILE)
{
// construct CFileDialog for browsing
CString strDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULTEXT));
CString strPrintDef(MAKEINTRESOURCE(AFX_IDS_PRINTDEFAULT));
CString strFilter(MAKEINTRESOURCE(AFX_IDS_PRINTFILTER));
CString strCaption(MAKEINTRESOURCE(AFX_IDS_PRINTCAPTION));
CFileDialog dlg(FALSE, strDef, strPrintDef, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, strFilter);
dlg.m_ofn.lpstrTitle = strCaption;
if (dlg.DoModal() != IDOK) return;
// set output device to resulting path name
strOutput = dlg.GetPathName();
}
DOCINFO docInfo;
memset(&docInfo, 0, sizeof(DOCINFO));
docInfo.cbSize = sizeof(DOCINFO);
docInfo.lpszDocName = strTitle;
CString strPortName;
int nFormatID;
if (strOutput.IsEmpty())
{
docInfo.lpszOutput = NULL;
strPortName = printInfo.m_pPD->GetPortName();
nFormatID = AFX_IDS_PRINTONPORT;
}
else
{
docInfo.lpszOutput = strOutput;
nFormatID = AFX_IDS_PRINTTOFILE;
}
// setup the printing DC
CDC dcPrint;
dcPrint.Attach(printInfo.m_pPD->m_pd.hDC); // attach printer dc
dcPrint.m_bPrinting = TRUE;
printInfo.m_rectDraw.SetRect(0, 0, dcPrint.GetDeviceCaps(HORZRES), dcPrint.GetDeviceCaps(VERTRES));
dcPrint.DPtoLP(&printInfo.m_rectDraw);
OnBeginPrinting(&dcPrint, &printInfo);
dcPrint.SetAbortProc(_GfxAbortProc);
// disable main window while printing & init printing status dialog
CString csFormat, cs, strTemp;
AfxGetMainWnd()->EnableWindow(FALSE);
CPrintStatus dlgPrintStatus(pParent);
cs.Format("%s ", strTitle);
dlgPrintStatus.SetWindowText(cs);
dlgPrintStatus.GetDlgItemText(IDC_TEXT1, csFormat);
AfxFormatString1(strTemp, nFormatID, strPortName);
cs.Format(csFormat, strTitle, printInfo.m_pPD->GetDeviceName(), strTemp);
dlgPrintStatus.SetDlgItemText(IDC_TEXT1, cs);
dlgPrintStatus.ShowWindow(SW_SHOW);
dlgPrintStatus.UpdateWindow();
// start document printing process
if (dcPrint.StartDoc(&docInfo) == SP_ERROR)
{
// enable main window before proceeding
AfxGetMainWnd()->EnableWindow(TRUE);
// cleanup and show error message
OnEndPrinting(&dcPrint, &printInfo);
dlgPrintStatus.DestroyWindow();
dcPrint.Detach(); // will be cleaned up by CPrintInfo destructor
AfxMessageBox(AFX_IDP_FAILED_TO_START_PRINT);
return;
}
// Guarantee values are in the valid range
UINT nEndPage = printInfo.GetToPage();
UINT nStartPage = printInfo.GetFromPage();
if (nEndPage < printInfo.GetMinPage()) nEndPage = printInfo.GetMinPage();
if (nEndPage > printInfo.GetMaxPage()) nEndPage = printInfo.GetMaxPage();
if (nStartPage < printInfo.GetMinPage()) nStartPage = printInfo.GetMinPage();
if (nStartPage > printInfo.GetMaxPage()) nStartPage = printInfo.GetMaxPage();
int nStep = (nEndPage >= nStartPage) ? 1 : -1;
nEndPage = (nEndPage == 0xffff) ? 0xffff : nEndPage + nStep;
int iPageTot = abs(abs(nEndPage) - abs(nStartPage)), iPrintedPages = 0;
CString csPageFormat;
dlgPrintStatus.GetDlgItemText(IDC_PAGES, csPageFormat);
// begin page printing loop
DWORD dwStart = GetTickCount(), dTickPerPage = 0;
dlgPrintStatus.wndProg.SetRange(0, iPageTot);
dlgPrintStatus.wndProg.SetPos(0);
bool bRectSet = false;
BOOL bError = FALSE;
for (printInfo.m_nCurPage = nStartPage; printInfo.m_nCurPage != nEndPage; printInfo.m_nCurPage += nStep)
{
TCHAR szBuf[80];
iPrintedPages ++;
dlgPrintStatus.wndProg.SetPos(iPrintedPages);
dlgPrintStatus.wndProg.UpdateWindow();
wsprintf(szBuf, "%d %%", iPrintedPages*100/iPageTot);
dlgPrintStatus.SetDlgItemText(IDC_PC, szBuf);
OnPrepareDC(&dcPrint, &printInfo);
// check for end of print
if (!printInfo.m_bContinuePrinting) break;
// write current page
DWORD tck = dTickPerPage * (iPageTot - iPrintedPages + 1) / 1000;
if (tck > 60)
{
// tck != 60;
DWORD tckS = tck%60;
tck /= 60;
strTemp.Format("%d minuti, %d secondi", tck, tckS);
}
else
{
if (iPageTot > 1)
{
if (tck > 0) strTemp.Format("%d secondi", tck);
else strTemp = "??";
}
}
wsprintf(szBuf, csPageFormat, iPrintedPages, iPageTot, strTemp);
dlgPrintStatus.SetDlgItemText(IDC_PAGES, szBuf);
printInfo.m_rectDraw.SetRect(0, 0, dcPrint.GetDeviceCaps(HORZRES), dcPrint.GetDeviceCaps(VERTRES));
dcPrint.DPtoLP(&printInfo.m_rectDraw);
// attempt to start the current page
if (dcPrint.StartPage() < 0)
{
bError = TRUE;
break;
}
OnPrepareDC(&dcPrint, &printInfo);
ASSERT(printInfo.m_bContinuePrinting);
// page successfully started, so now render the page
int is = dcPrint.SaveDC();
OnPrint(&dcPrint, &printInfo);
if (dcPrint.EndPage() < 0 || !_GfxAbortProc(dcPrint.m_hDC, 0))
{
bError = TRUE;
break;
}
dcPrint.RestoreDC(is);
dTickPerPage = (GetTickCount() - dwStart) / iPrintedPages;
}
// cleanup document printing process
if (!bError) dcPrint.EndDoc();
else dcPrint.AbortDoc();
AfxGetMainWnd()->EnableWindow(); // enable main window
OnEndPrinting(&dcPrint, &printInfo); // clean up after printing
dlgPrintStatus.DestroyWindow();
dcPrint.Detach(); // will be cleaned up by CPrintInfo destructor
}
}
Top
2 楼pjfwho()回复于 2005-04-04 08:52:57 得分 0
好好研究一下……Top
3 楼Programmerjacinth(阿聪)回复于 2005-04-04 09:41:07 得分 10
好象还要pCD->setMaxPage()吧,记不太清楚了,是在OnPreparePrinting()函数里面设置,你看看Top
4 楼pjfwho()回复于 2005-04-04 09:58:14 得分 0
pCD->setMaxPage() 我用过的啊,不过还是不行
to: imyourkobe() 大哥:
你给我的代码,我编译的时候很多错误,是不是还用到了什么别的类啊?
学习……Top
5 楼pjfwho()回复于 2005-04-04 12:43:00 得分 0
up……Top
6 楼pjfwho()回复于 2005-04-05 09:02:34 得分 0
学习,关注……Top
7 楼GalaxyPeng(初级程序员)回复于 2005-04-05 10:18:37 得分 5
顶Top
8 楼pjfwho()回复于 2005-04-05 16:35:48 得分 0
ding ……Top
9 楼qaz1984(包弥)回复于 2005-04-05 16:51:37 得分 5
upTop
10 楼pjfwho()回复于 2005-04-07 10:35:08 得分 0
up……Top
11 楼imyourkobe()回复于 2005-04-08 15:42:01 得分 0
对,里面用到了不少类!Top




