CPrintDialog dlg(TRUE, PD_ALLPAGES|PD_ALLPAGES|PD_NOPAGENUMS, NULL); PRINTDLG *pPrintDlg = &dlg.m_pd; AfxGetApp()->GetPrinterDeviceDefaults(pPrintDlg); DEVMODE* lpDevMode = (DEVMODE*)::GlobalLock(pPrintDlg->hDevMode); ::GlobalUnlock(pPrintDlg->hDevMode); lpDevMode->dmPaperSize = DMPAPER_A4; //A4 297 x 420 mm lpDevMode->dmOrientation = DMORIENT_LANDSCAPE; //橫向 if(dlg.DoModal() == IDCANCEL) return; // create a CDC and attach it to the default printer CDC dcPrinter; dcPrinter.Attach(dlg.CreatePrinterDC()); // initialize DOCINFO DOCINFO docinfo; memset(&docinfo, 0, sizeof(docinfo)); docinfo.cbSize = sizeof(docinfo); CString title; GetWindowText(title); docinfo.lpszDocName = title; // if it fails, complain and exit gracefully if (dcPrinter.StartDoc(&docinfo) < 0) { MessageBox(_T("プリンタは初期化できません")); return; } CPrintHelper helper(&dcPrinter); // 變量初始化:行數,頁數,當前行,當前頁 int lineNumber = m_Grid.GetRows() - 1; int pageNumber = (int) ceil( (double)lineNumber/helper.LinesPerPage()); int line = 1; int page = 1; while (page <= pageNumber) { if (dcPrinter.StartPage() < 0) { MessageBox(_T("ページ処理は開始できません")); dcPrinter.AbortDoc(); return; } helper.PrintHeader(strTitleText.c_str(), _startYear, _startImage , _endYear, _endImage); helper.PrintPage(m_Grid, line); helper.PrintFooter(page, pageNumber); dcPrinter.EndPage(); ++page; line += helper.LinesPerPage(); } dcPrinter.EndDoc();
The OnBeginPrinting function prepares printer fonts and calculates paper, page, header, footer and body rectangles.void CListDemoViewPrint::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) { // Create fonts m_pFontHeader = CreateFont(pDC,_T("Arial"), 12, FW_BOLD); m_pFontFooter = CreateFont(pDC,_T("Arial"), 10); m_pFontColumn = CreateFont(pDC,_T("Arial"), 9, FW_BOLD); m_pFontBody = CreateFont(pDC,_T("Times New Roman"), 10); // Calculate character size m_CharSizeHeader = GetCharSize(pDC, m_pFontHeader); m_CharSizeFooter = GetCharSize(pDC, m_pFontFooter); m_CharSizeBody = GetCharSize(pDC, m_pFontBody); // Prepare layout m_rectPaper = GetPaperRect(pDC); m_rectPage = GetPageRect(); m_rectHeader = GetHeaderRect(); ... m_RatioX = GetTextRatioX(pDC); ... } Character sizes are used later to calculate header and footer vertical height, body character size is used to calculate row (cell) height, number of rows per page and horizontal X ratio to adjust column width.Character size is calculated simply by selecting font and getting sample string extent as follows.CSize CListDemoViewPrint::GetCharSize(CDC* pDC, CFont* pFont) { CFont *pOldFont = pDC->SelectObject(pFont); CSize charSize = pDC->GetTextExtent(_T("abcdefghijkl mnopqrstuvwxyzABCDEFGHIJKLMNOPQRSATUVWXYZ"),52); charSize.cx /= 52; pDC->SelectObject(pOldFont); return charSize; } Horizontal text ratio is calculated using body font character size and list control average character size.double CListDemoViewPrint::GetTextRatioX(CDC* pDC) { ASSERT(pDC != NULL); ASSERT(m_pListCtrl); CDC* pCurrentDC = m_pListCtrl->GetDC(); TEXTMETRIC tmSrc; pCurrentDC->GetTextMetrics(&tmSrc); m_pListCtrl->ReleaseDC(pCurrentDC); return ((double)m_CharSizeBody.cx) / ((double)tmSrc.tmAveCharWidth); } Using the code Add the CListDemoViewPrint class member to your CListView derived class.class CListDemoView : public CListView { ... CListDemoViewPrint m_Print; }; Add the following printing functions to your class.BOOL CListDemoView::OnPreparePrinting(CPrintInfo* pInfo) { m_Print.OnPreparePrinting(pInfo); return DoPreparePrinting(pInfo); }void CListDemoView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo) { m_Print.OnBeginPrinting(pDC, pInfo); }void CListDemoView::OnPrint(CDC* pDC, CPrintInfo* pInfo) { m_Print.OnPrint(pDC, pInfo); }void CListDemoView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo) { m_Print.OnEndPrinting(pDC, pInfo); } Andres Kaasik
使你的dialog支持打印预览第2步, 在OnPrint里面处理,根据list, 先画header, 再画列表。网上应该有代码吧
PRINTDLG *pPrintDlg = &dlg.m_pd;
AfxGetApp()->GetPrinterDeviceDefaults(pPrintDlg);
DEVMODE* lpDevMode = (DEVMODE*)::GlobalLock(pPrintDlg->hDevMode);
::GlobalUnlock(pPrintDlg->hDevMode);
lpDevMode->dmPaperSize = DMPAPER_A4; //A4 297 x 420 mm
lpDevMode->dmOrientation = DMORIENT_LANDSCAPE; //橫向 if(dlg.DoModal() == IDCANCEL)
return; // create a CDC and attach it to the default printer
CDC dcPrinter;
dcPrinter.Attach(dlg.CreatePrinterDC()); // initialize DOCINFO
DOCINFO docinfo;
memset(&docinfo, 0, sizeof(docinfo));
docinfo.cbSize = sizeof(docinfo);
CString title;
GetWindowText(title);
docinfo.lpszDocName = title; // if it fails, complain and exit gracefully
if (dcPrinter.StartDoc(&docinfo) < 0)
{
MessageBox(_T("プリンタは初期化できません"));
return;
}
CPrintHelper helper(&dcPrinter);
// 變量初始化:行數,頁數,當前行,當前頁
int lineNumber = m_Grid.GetRows() - 1;
int pageNumber = (int) ceil( (double)lineNumber/helper.LinesPerPage());
int line = 1;
int page = 1; while (page <= pageNumber)
{
if (dcPrinter.StartPage() < 0)
{
MessageBox(_T("ページ処理は開始できません"));
dcPrinter.AbortDoc();
return;
} helper.PrintHeader(strTitleText.c_str(), _startYear, _startImage , _endYear, _endImage);
helper.PrintPage(m_Grid, line);
helper.PrintFooter(page, pageNumber);
dcPrinter.EndPage(); ++page;
line += helper.LinesPerPage();
} dcPrinter.EndDoc();
{
// Create fonts
m_pFontHeader = CreateFont(pDC,_T("Arial"), 12, FW_BOLD);
m_pFontFooter = CreateFont(pDC,_T("Arial"), 10);
m_pFontColumn = CreateFont(pDC,_T("Arial"), 9, FW_BOLD);
m_pFontBody = CreateFont(pDC,_T("Times New Roman"), 10); // Calculate character size
m_CharSizeHeader = GetCharSize(pDC, m_pFontHeader);
m_CharSizeFooter = GetCharSize(pDC, m_pFontFooter);
m_CharSizeBody = GetCharSize(pDC, m_pFontBody); // Prepare layout
m_rectPaper = GetPaperRect(pDC);
m_rectPage = GetPageRect();
m_rectHeader = GetHeaderRect();
...
m_RatioX = GetTextRatioX(pDC);
...
}
Character sizes are used later to calculate header and footer vertical height, body character size is used to calculate row (cell) height, number of rows per page and horizontal X ratio to adjust column width.Character size is calculated simply by selecting font and getting sample string extent as follows.CSize CListDemoViewPrint::GetCharSize(CDC* pDC, CFont* pFont)
{
CFont *pOldFont = pDC->SelectObject(pFont);
CSize charSize = pDC->GetTextExtent(_T("abcdefghijkl
mnopqrstuvwxyzABCDEFGHIJKLMNOPQRSATUVWXYZ"),52);
charSize.cx /= 52;
pDC->SelectObject(pOldFont);
return charSize;
}
Horizontal text ratio is calculated using body font character size and list control average character size.double CListDemoViewPrint::GetTextRatioX(CDC* pDC)
{
ASSERT(pDC != NULL);
ASSERT(m_pListCtrl);
CDC* pCurrentDC = m_pListCtrl->GetDC();
TEXTMETRIC tmSrc;
pCurrentDC->GetTextMetrics(&tmSrc);
m_pListCtrl->ReleaseDC(pCurrentDC);
return ((double)m_CharSizeBody.cx) / ((double)tmSrc.tmAveCharWidth);
}
Using the code
Add the CListDemoViewPrint class member to your CListView derived class.class CListDemoView : public CListView
{
...
CListDemoViewPrint m_Print;
};
Add the following printing functions to your class.BOOL CListDemoView::OnPreparePrinting(CPrintInfo* pInfo)
{
m_Print.OnPreparePrinting(pInfo);
return DoPreparePrinting(pInfo);
}void CListDemoView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
m_Print.OnBeginPrinting(pDC, pInfo);
}void CListDemoView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
{
m_Print.OnPrint(pDC, pInfo);
}void CListDemoView::OnEndPrinting(CDC* pDC, CPrintInfo* pInfo)
{
m_Print.OnEndPrinting(pDC, pInfo);
}
Andres Kaasik