Download
demo project - 56 Kb
The demo consists of
a doc/view-framework with a CListView
-class.
It has a button to fill with data and another to print
the stuff.
The Problem
MFC has no built-in
feature for printing a List
Control. Some approaches can be found on
the internet but they always have the problem that if
you have more columns then will fit to a single page,
then the rest is clipped away and not printed.
The Solution
My class manages:
- Printing a CListCtrl
or CListView
with support for multiple
pages
- The first column
is printed
again on each page
- The width of the
columns are used for printing
- Columns can be
sorted (nothing new, I know)
My appraoch is mainly
based on the fabulous work of Dan Pilat with his article
Printing with MFC Made Easy.
My work was to build
a kind of wrapper over his classes and do the newpage-logic.
Each single page
is printed just by
his classes with some overriden virtual functions.
The printing from the
CListView
then looks like this:
void CListPrintView::OnFilePrintDirect()
{
CWaitCursor wait;
CListCtrl &listctrl = GetListCtrl();
CListCtrlPrintJob job(&listctrl, !m_bUseSetup);
job.Print();
}
The trick is to
calculate a translater for Screen [Pixels] ->
Printer [mm]. Then I know how much space a column
needs on the paper. This helps me calculating the
amount of columns that fit to a page.
I then loop through
all columns and count their width.
When its time to
begin a new one, I define a print-job the Dan Pilat
way.
Collapse
void CListCtrlPrintJob::OnPrint()
{
...
widthOfPage = m_pListCtrl->GetColumnWidth(0);
iStart = 1;
for( i=1 ; i<m_ColCount ; i++ )
{
widthThisCol = m_pListCtrl->GetColumnWidth(i);
bNewPage = FALSE;
if( widthOfPage+widthThisCol > paperWidthInPixel )
{
bNewPage = TRUE;
}
else
{
if( i == (m_ColCount-1) )
bNewPage = TRUE;
widthOfPage += widthThisCol;
}
if( bNewPage )
{
CListCtrlDataPage data(this, m_pListCtrl, iStart, i);
data.Print();
iStart = i+1;
widthOfPage = m_pListCtrl->GetColumnWidth(0);
}
}
}
CListCtrlDataPage
is derived from GPrintUnit
and also has
this print-function:
Collapse
BOOL CListCtrlDataPage::Print()
{
...
zeilenMax = m_pListCtrl->GetItemCount();
for( zeile=0 ; zeile<zeilenMax ; zeile++ )
{
nRC = StartRow();
if( m_pListCtrl->GetItemText(zeile, 0, szText,
sizeof(szText)) )
PrintCol(colId, szText, DT_LEFT);
colId++;
for( spalte=m_firstCol ; spalte<=m_lastCol ; spalte++ )
{
if( m_pListCtrl->GetItemText(zeile, spalte,
szText, sizeof(szText)) )
PrintCol(colId, szText, DT_LEFT);
colId++;
}
EndRow();
}
EndPage();
...
}
Do you have
Enchancements (e.g. a print-preview)
?