📄 easyreport.cpp
字号:
m_NumDataCols = inColCount;
nRows = nMaxRows = 1;
aLeft = m_LeftMargin;
aMax = m_PageWidth - m_RightMargin;
i = 0;
do
{
m_TabStops.Add( (WORD)aLeft );
aCol = inCols + i;
aLeft += aCol->m_CharCount * m_TextSizes[eDataFont].cx;
ASSERT(aLeft < aMax); // check that we do not overflow the right edge
// Calculate the height of this heading text...
nRows = 1;
s = aCol->m_Heading;
if( s)
{
do
{
s = strchr(s,TCHAR('\n'));
if(s==NULL)
break;
++s; // past the '\n'
++nRows; // bump row count
}
while(1);
}
if( nRows > nMaxRows )
nMaxRows = nRows;
++i;
}
while(i < inColCount );
m_TabStops.Add( (WORD)aLeft );
m_TableHeadingHt = nMaxRows * m_TextSizes[ eColHeadingFont ].cy;
if( !m_SuppressBlankTbl )
{
// We need to draw the heading. Check if there is enough room
// on this page to draw the headings.
if( m_DataTop + m_TableHeadingHt + GetDataFontSize().cy > (GetBottomEdge() - m_PageFtrHt) )
EjectPage(false);
if( !m_RepeatTblHdr )
WriteTableHeader();
}
else
{
// deffer drawing the columns till something is written to this table
m_RedrawTblHdr = true;
}
}
/*****************************************************************
*
* method :void CEasyReport::EjectPage(bool inIsLastPage)
*
* parameters : inIsLastPage : true if this is the last page
* of the report.
*
* returns : nothing
*
* description: Call this function to eject the current page. if this
* is the last page, we print the report footer. If there
* is a page footer defined, it will be printed before starting the
* new page.
*
****************************************************************/
bool CEasyReport::EjectPage(bool inIsLastPage)
{
CRect aRect;
int aRequiredHt, aAbsBottom;
bool aAllPrinted = true;
aRect.left = m_LeftMargin;
aRect.right = m_PageWidth - m_RightMargin;
aAbsBottom = m_PageHeight - m_BottomMargin;
if(inIsLastPage)
{
// check to see if the PageFooter and the ReportFooter
// will fit on to the remaining area on this page. If so,
// print the page footer and the report footer.
aRequiredHt = m_PageFtrHt + m_ReportFtrHt;
if( m_DataTop + aRequiredHt <= aAbsBottom )
{
aRect.top = aAbsBottom - (m_PageFtrHt+ m_ReportFtrHt);
aRect.bottom = aRect.top + m_PageFtrHt;
WritePageFooter(aRect);
if( m_ReportFtrHt)
{
aRect.top = aRect.bottom;
aRect.bottom += m_ReportFtrHt;
WriteReportFooter(aRect);
}
}
else
{
aRect.top = aAbsBottom - m_PageFtrHt;
aRect.bottom = aRect.top + m_PageFtrHt;
WritePageFooter(aRect);
aAllPrinted = (m_ReportFtrHt >0 ? false : true);
}
}
else
{
// not the last page of the report. Simply draw the page
// footer bottom aligned on the page
if(m_PageFtrHt > 0 )
{
// bottom align the page footer on the page
aRect.top = aAbsBottom - m_PageFtrHt;
aRect.bottom = aRect.top + m_PageFtrHt;
WritePageFooter(aRect);
}
}
m_PageItems.Add(m_ReportItems.GetSize());
++m_PageCount;
m_DataTop = m_TopMargin;
// If not the last page, then print the page header if there
// is a page header.
if( !inIsLastPage && m_PageHdrHt > 0 )
{
aRect.top = m_DataTop;
aRect.bottom = aRect.top + m_PageHdrHt;
WritePageHeader(aRect);
m_DataTop += m_PageHdrHt;
}
// Print the table header only if needed
// m_RedrawTblHdr = false;
if( !inIsLastPage && m_RepeatTblHdr && m_NumDataCols != 0 )
{
if( !m_SuppressBlankTbl )
WriteTableHeader();
else
m_RedrawTblHdr = true;
}
return aAllPrinted;
}
/*****************************************************************
*
* method :void CEasyReport::WriteTableHeader(void)
*
* parameters :
*
* returns :
*
* description: If a tabular section is in place, write the table
* header.
*
****************************************************************/
void CEasyReport::WriteTableHeader(void)
{
int i;
CRect aRect;
m_RedrawTblHdr = false;
aRect.top = aRect.bottom = m_DataTop;
aRect.bottom += m_TableHeadingHt;
aRect.left= m_LeftMargin;
for(i=0;i < m_NumDataCols; i++)
{
CColInfo *aCol = m_DataCols+i;
aRect.right = aRect.left + aCol->m_CharCount * m_TextSizes[eDataFont].cx;
CTextBox *aBox = new CTextBox(&aRect, aCol->m_Heading, eColHeadingFont);
switch( aCol->m_align)
{
case CColInfo::eLeft:
aBox->SetAlign(DT_LEFT);
break;
case CColInfo::eDecimal:
case CColInfo::eRight:
// for fixed width fonts, if you control the format of data, then
// simply aligning the text right aligns the decimal places. For
// propotional fonts, you will have to adjust the left edge of
// the box. Decimal cols will be supported in a later version
aBox->SetAlign(DT_RIGHT);
break;
case CColInfo::eCenter:
aBox->SetAlign( DT_CENTER );
break;
}
aBox->SetDocPtr(this);
m_ReportItems.Add(aBox);
aRect.left = aRect.right;
}
m_DataTop += m_TableHeadingHt;
}
/*****************************************************************
*
* method :void CEasyReport::NextRow()
*
* parameters :
*
* returns :
*
* description: Advance the current point by one row height
* If this moves the current point below the page margin, call
* EjectPage. EjectPage will automatically write the page footer
* and start a new page
*
****************************************************************/
void CEasyReport::NextRow()
{
m_DataTop += m_TextSizes[eDataFont].cy;
// see if at least one data row will fit into the remaining
// space on the page. If it does not, call EjectPage
if( m_DataTop + m_TextSizes[eDataFont].cy + m_PageFtrHt > GetBottomEdge())
EjectPage();
}
/*****************************************************************
*
* method :void CEasyReport::Start(void)
*
* parameters : none
*
* returns :
*
* description: Start the report generation. Create all the fonts, etc
* Try and get the printer device context, If no printer is set up as
* the default printer on the system, create a screen device context.
*
****************************************************************/
void CEasyReport::Start()
{
ASSERT( m_PrinterDC == NULL );
DoCleanup();
// set up a print date ..
CTime aNow = CTime::GetCurrentTime();
m_ReportDate.Format("Date: %2d/%2d/%4d", aNow.GetMonth(), aNow.GetDay(), aNow.GetYear());
// NOTE: The following is most certainly not correct if there is
// no default printer defined ! If you do not have ANY printer, then
// you might install a Fax printer (eg Microsoft Fax or Bitware etc)
CPrintDialog aPD(false);
if(aPD.GetDefaults())
{
m_PrinterDC = aPD.m_pd.hDC;
}
else
{
m_PrinterDC = ::GetDC(NULL); // get the screen device context
}
//::SetMapMode(m_PrinterDC, MM_ANISOTROPIC);
//::SetWindowExtEx( m_PrinterDC, 254,254,NULL);
//::SetViewportExtEx(m_PrinterDC, GetDeviceCaps(m_PrinterDC,LOGPIXELSX),GetDeviceCaps(m_PrinterDC,LOGPIXELSY),NULL);
SetMapMode( m_PrinterDC, MM_LOMETRIC);
SetupTextStyles( m_PrinterDC );
m_DataTop = m_TopMargin;
m_PageCount = 0;
m_CurPage = 0;
CRect aRect;
// Write the report header...
if( m_ReportHdrHt > 0 )
{
aRect.SetRect(m_LeftMargin, m_TopMargin, m_PageWidth - m_RightMargin,m_TopMargin + m_ReportHdrHt );
aRect.bottom = aRect.top + m_ReportHdrHt;
WriteReportHeader(aRect);
m_DataTop += m_ReportHdrHt;
}
if( m_PageHdrHt > 0)
{
aRect.SetRect(m_LeftMargin, m_DataTop, m_PageWidth - m_RightMargin, m_DataTop + m_PageHdrHt);
WritePageHeader(aRect);
m_DataTop += m_PageHdrHt;
}
}
/*****************************************************************
*
* method :void CEasyReport::End()
*
* parameters :
*
* returns :
*
* description: End the report
*
****************************************************************/
void CEasyReport::End()
{
EjectPage(true);
m_CurPage = 0;
DeleteDC(m_PrinterDC);
}
/*****************************************************************
*
* method :void WriteReportHeader(CRect inRect)
*
* parameters :
*
* returns :
*
* description: Write the default report header, which is a
* simply the CompanyName centered across the page. You might
* want to add the address, etc.
*
****************************************************************/
void CEasyReport::WriteReportHeader(CRect inRect)
{
CTextBox *aBox = new CTextBox(&inRect, m_CompanyName, eCaptionFont, DT_CENTER);
aBox->SetDocPtr(this);
m_ReportItems.Add(aBox);
}
/*****************************************************************
*
* method :void CEasyReport::WriteReportFooter(CRect inRect)
*
* parameters :
*
* returns :
*
* description: Write the report footer. The default Report footer
* is blank.
*
*
****************************************************************/
void CEasyReport::WriteReportFooter(CRect inRect)
{
// CTextBox *aBox = new CTextBox(&inRect, "Report Footer", eCaptionFont);
// aBox->SetDocPtr(this);
// m_ReportItems.Add(aBox);
}
/*****************************************************************
*
* method :void WritePageHeader(CRect inRect)
*
* parameters :
*
* returns :
*
* description: Write the default page header. By default, this
* contains the report title (centered) and date field,
* right aligned
*
****************************************************************/
void CEasyReport::WritePageHeader(CRect inRect)
{
CRect aRect(inRect);
CTextBox *aBox;
aRect.bottom = aRect.top + GetHeadingFontSize().cy;
aBox = new CTextBox(&aRect,m_ReportTitle,eColHeadingFont);
aBox->SetDocPtr(this);
m_ReportItems.Add(aBox);
// make a text area 1/4 of the page width
aRect.right = inRect.right;
aRect.left = inRect.right - inRect.Width()/4;
aBox = new CTextBox(&aRect, m_ReportDate, eColHeadingFont, DT_LEFT);
aBox->SetDocPtr(this);
m_ReportItems.Add(aBox);
aRect.top = inRect.bottom-10; // 1mm from the bottom
aRect.bottom = inRect.bottom;
aRect.left = inRect.left;
aRect.right = inRect.right;
CHline *aLine = new CHline(&aRect,0);
aLine->SetDocPtr(this);
m_ReportItems.Add(aLine);
}
/*****************************************************************
*
* method :void CEasyReport::WritePageFooter(CRect inRect)
*
* parameters :
*
* returns :
*
* description: Write the page footer
*
****************************************************************/
void CEasyReport::WritePageFooter(CRect inRect)
{
CRect aRect(inRect);
aRect.top = aRect.bottom = inRect.top +10; // 1mm below
CHline *aLine = new CHline(&aRect,0);
aLine->SetDocPtr(this);
m_ReportItems.Add(aLine);
aRect.top += 10; // 1mm
aRect.bottom = aRect.top + GetHeadingFontSize().cy;
CPageNum *aPgNumField = new CPageNum(&aRect,eColHeadingFont);
aPgNumField->SetDocPtr(this);
m_ReportItems.Add(aPgNumField);
}
/*****************************************************************
*
* method :void DrawCurrentPage(CDC *inDC)
*
* parameters : inCDC a device context
*
* returns : nothing
*
* description: Draw the current page
*
*
****************************************************************/
void CEasyReport::DrawCurrentPage(CDC *inDC)
{
int i,aStart, aMax;
CElement *aElem;
if( m_CurPage != 0 )
aStart = m_PageItems[m_CurPage-1];
else
aStart = 0;
aMax = m_PageItems[m_CurPage];
for( i =aStart;i< aMax;i++)
{
aElem = (CElement *)m_ReportItems[i];
aElem->Draw(inDC);
}
/*
CRect aRect(m_LeftMargin, -m_TopMargin,
m_PageWidth - m_RightMargin, -(m_PageHeight-m_BottomMargin));
inDC->MoveTo(aRect.left, aRect.top);
inDC->LineTo(aRect.right,aRect.top);
inDC->LineTo(aRect.right, aRect.bottom);
inDC->LineTo(aRect.left, aRect.bottom);
inDC->LineTo(aRect.left, aRect.top);
*/
}
/*****************************************************************
*
* method :const CFont *GetStyle(int inStyleIndex)
*
* parameters : inStyleIndex: integer
*
* returns : CFont *
*
* description: Return a pointer to the font, NULL if the index
* is out of range.
*
*
****************************************************************/
const CFont *CEasyReport::GetStyle(int inStyleIndex)
{
ASSERT(inStyleIndex >=0 && inStyleIndex < eMaxStyles );
if( inStyleIndex < eMaxStyles )
return m_Fonts[ inStyleIndex ];
else
return NULL;
}
//**** end of EasyReport.cpp
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -