// SAPrint.cpp - StandAlone Print - uses MFC
#include "stdafx.h"
#include "SAPrint.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
SAPrint::SAPrint(const CString& sDocName, const CString&
sFaceName,
const UINT nLinesTot,
const UINT nMaxLineSize)
{
CPrintDialog *pDlg = NULL;
TEXTMETRIC *pTM = NULL;
DOCINFO *pDI = NULL;
CFont *pOldFont = NULL;
LPCTSTR lpszFacename = NULL;
BOOL bRet;
CSize size;
UINT len;m_bConstructed = FALSE;
m_bDelDoc = FALSE;
m_bPageStarted = FALSE;
m_bDocStarted = FALSE;m_pDC = NULL;
m_pFont = NULL;m_iPrintJobNo = 0;
m_nLinesPerPage = 0;
m_nMaxPageNo = 0;m_nVMax = 0;
m_nHMax = 0;
m_nLinesTotal = 0;
m_nMaxLineSize = 0;
m_nPageNo = 0;
m_nLineNo = 0;
m_sDocName = sDocName;
m_sFaceName = "";pDlg=new CPrintDialog(FALSE);
if (!pDlg) return;if (!pDlg->DoModal()) goto Cleanup;
m_pDC = new CDC;
if (!m_pDC) goto Cleanup;if (! m_pDC->Attach(pDlg->GetPrinterDC()) )
goto Cleanup;delete pDlg;
pDlg = 0;m_pFont = new CFont;
if (!m_pFont) goto Cleanup;pTM = new TEXTMETRIC;
if (!pTM) goto Cleanup;pDI = new DOCINFO;
if (!pDI) goto Cleanup;::ZeroMemory(pDI, sizeof(DOCINFO));
if (sDocName != "")
m_sDocName = sDocName;
UINT len = m_sDocName.GetLength();
pDI->lpszDocName=m_sDocName.GetBuffer(len+1);LPCTSTR lpszFacename = NULL;
if (sFaceName != "")
{
m_sFaceName = sFaceName;
lpszFacename = m_sFaceName;
}if (nLinesTot) m_nLinesTotal = nLinesTot;
if (nMaxLineSize)m_nMaxLineSize=nMaxLineSize;
// get basic printer info
m_iHeight=-((m_pDC->GetDeviceCaps(LOGPIXELSY) * 10) / PIXELS_PER_INCH );
if (! m_pFont->CreateFont ( m_iHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH || FF_DONTCARE, lpszFacename ))
goto Cleanup;// this code checks to see what font was
// really used. Unfortunately, since
// FF_DONTCARE was specified, a name that
// does not quite match causes its name to be
// returned, but does not affect the font
// that is actually used, which is often the
// default font. If no name is given or
// NULL is passed into CreateFont, a null
// string will be returned by GetLogFont()
// function.LOGFONT lf;
pOldFont = m_pDC->SelectObject(m_pFont);
if (m_pFont->GetLogFont(&lf))
m_sFaceName = lf.lfFaceName;m_pDC->GetTextMetrics (pTM);
m_cy = pTM->tmHeight +
pTM->tmExternalLeading;
delete pTM;
pTM = 0;m_nVMax = m_pDC->GetDeviceCaps(VERTRES);
m_nHMax = m_pDC->GetDeviceCaps(HORZRES);
m_nLinesPerPage = (m_nVMax) / m_cy;
m_nMaxPageNo=(nLinesTot+(m_nLinesPerPage-1)) / m_nLinesPerPage;// use "W", one of the widest letters
size = m_pDC->GetTextExtent("W", m_nMaxLineSize);
m_cxWidth = size.cx;
m_cxOffset = (m_cxWidth > m_nHMax ? 0 : m_nHMax - m_cxWidth) / 2;m_iPrintJobNo = m_pDC->StartDoc(pDI);
if (m_iPrintJobNo > 0)
m_bDocStarted = TRUE;
else
{
CString s = "Unable to print ";
s += m_sDocName;
AfxMessageBox(s, MB_OK);
goto Cleanup;
}
delete pDI;
pDI = 0;m_pDC->SelectObject (pOldFont);
m_bConstructed = TRUE;return;
Cleanup:
delete pDI;
delete pTM;
delete pDlg;
CleanUp(FALSE);
}
SAPrint::~SAPrint()
{
CleanUp(TRUE);
}
void SAPrint::CleanUp(BOOL bEndDoc)
{
if (m_bDocStarted && m_bPageStarted)
m_pDC->EndPage();
if (m_bDocStarted && !m_bDelDoc && bEndDoc)
m_pDC->EndDoc();
else
m_pDC->AbortDoc();if (m_pDC)
m_pDC->Detach();
if (m_pFont)
m_pFont->DeleteObject();
delete m_pDC;
delete m_pFont;
}
inline void SAPrint::DeleteDoc(void)
{ m_bDelDoc = TRUE; }
inline UINT SAPrint::GetLinesPerPg(void) const
{ return m_nLinesPerPage; }
inline UINT SAPrint::GetPageNo(void) const
{ return m_nPageNo; }
inline UINT SAPrint::GetMaxPageNo(void) const
{ return m_nMaxPageNo; }
inline UINT SAPrint::GetLineNo(void) const
{ return m_nLineNo; }
UINT SAPrint::GetLineNoNext(void) const
{ return (m_nLineNo % m_nLinesPerPage)+1; }
UINT SAPrint::GetPageNoNext(void) const
{
if ((m_nLineNo % m_nLinesPerPage) == 0)
return m_nPageNo + 1;
return m_nPageNo;
}
UINT SAPrint::SetMaxPageNo(const UINT nMaxPageNo)
{
UINT nOldMaxPageNo = m_nMaxPageNo;
if (nMaxPageNo >= 0)
m_nMaxPageNo = nMaxPageNo;
return nOldMaxPageNo;
}
BOOL SAPrint::StartPage(void)
{
if (!m_bConstructed) return FALSE;
m_bPageStarted = FALSE;
if (m_pDC->StartPage() > 0)
{
++m_nPageNo;
m_nLineNo = 0;
m_bPageStarted = TRUE;
}
return m_bPageStarted;
}
BOOL SAPrint::PrintLine(const CString& sLine)
{
BOOL bCont = FALSE;
if (!m_bConstructed) return bCont;
CString s;
if (m_nLineNo == 0)
if (!StartPage())
return bCont;
CFont* pOldFont;
pOldFont = m_pDC->SelectObject (m_pFont);UINT y = m_nLineNo * m_cy;
bCont = m_pDC->TextOut(m_cxOffset,y,sLine);
if (bCont)
if (++m_nLineNo == m_nLinesPerPage)
{
bCont = EndPage();
m_nLineNo = 0;
}m_pDC->SelectObject (pOldFont);
return bCont;
}
BOOL SAPrint::EndPage(void)
{
if (!m_bConstructed) return FALSE;
BOOL bCont = FALSE;
if (m_bPageStarted)
{
bCont = (m_pDC->EndPage() >= 0);
if (bCont)
m_bPageStarted = FALSE;
}return bCont;
}
CString SAPrint::GetFaceName() const
{
if (!m_bConstructed) return CString();
CFont* pOldFont;
pOldFont = m_pDC->SelectObject (m_pFont);
LOGFONT lf;
if (m_pFont->GetLogFont(&lf))
CString sFaceName = lf.lfFaceName;
m_pDC->SelectObject (pOldFont);
return m_sFaceName;
}
BOOL SAPrint::SetFaceName(const CString& sFace)
{
if (!m_bConstructed) return FALSE;
LPCTSTR lpszFaceName = NULL;
if (sFace != "")
{
m_sFaceName = sFace;
lpszFaceName = m_sFaceName;
}if (m_pFont)
m_pFont->DeleteObject();BOOL bRet = m_pFont->CreateFont( m_iHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH || FF_DONTCARE, lpszFaceName );
if (!bRet) return bRet;
CFont* pOldFont = m_pDC->SelectObject (m_pFont);
LOGFONT lf;
if (m_pFont->GetLogFont(&lf))
m_sFaceName = lf.lfFaceName;m_pDC->SelectObject (pOldFont);
return bRet;
}
#ifdef _DEBUG
BOOL SAPrint::Test(const CString& sTestName,
const UINT nLinesTotal)
{
BOOL bCont = TRUE;
CString sFmt = "%s Page %d line %d of %d/page of %d
total in %s";
UINT nMaxPage = max(1, (nLinesTotal + (GetLinesPerPg() - 1))
/ GetLinesPerPg());
SetMaxPageNo(nMaxPage);
UINT n = 0;
CString s;
CString sFaceName = GetFaceName();
if (sFaceName == "")
sFaceName = "<Default
Font>";
for (UINT i=0; (i < nMaxPage)
&& bCont; ++i)
{
for (UINT j=0; bCont&&(j <
m_nLinesPerPage); ++j)
{
s.Format(sFmt,sTestName, GetPageNoNext(), GetLineNoNext(), GetLinesPerPg(),
nLinesTotal, sFaceName);
bCont &=
PrintLine(s);
bCont &=
(++n < nLinesTotal);
}
}
return TRUE;
}
#endif