C Programming
by Al Stevens

Example 1:

void CWinApp::OnFilePrintSetup()
{
   CPrintDialog pd(TRUE);
   DoPrintDialog(&pd);
}



Example 2:

void CQuincyApp::OnFilePrintSetup() 
{
   CQuincyPrintDialog pd(TRUE);
   pd.printlinenumbers = m_bPrintLineNos;
   if (DoPrintDialog(&pd) == IDOK)
       m_bPrintLineNos = pd.printlinenumbers;
}


Listing One
#if !defined(AFX_QUINCYPRINTDIALOG_H__
                            64D73F03_7B38_11D4_B7A3_00207815827F__INCLUDED_)
#define AFX_QUINCYPRINTDIALOG_H__
                            64D73F03_7B38_11D4_B7A3_00207815827F__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
// QuincyPrintDialog.h
////////////////////////////
// CLineNumberButton class
class CLineNumberButton : public CButton
{
    DECLARE_DYNAMIC(CLineNumberButton)
    CFont font;
public:
    CLineNumberButton();
protected:
    //{{AFX_MSG(CLineNumberButton)
    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// CQuincyPrintDialog dialog
class CQuincyPrintDialog : public CPrintDialog
{
    DECLARE_DYNAMIC(CQuincyPrintDialog)
    CLineNumberButton lnobutton;    // print line number checkbox
    static LOGFONT logfont;
public:
    bool printlinenumbers;  // publicly exposed for setting and testing
    CQuincyPrintDialog(BOOL bSetup = FALSE);
// Attributes
public:
// Operations
public:
// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CMainFrame)
    public:
    //}}AFX_VIRTUAL
protected:
    //{{AFX_MSG(CQuincyPrintDialog)
    virtual void OnOK();
    virtual BOOL OnInitDialog();
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Developer Studio will insert additional declarations 
//                                  immediately before the previous line.
#endif // !defined(AFX_QUINCYPRINTDIALOG_H__
                           64D73F03_7B38_11D4_B7A3_00207815827F__INCLUDED_)


Listing Two
// QuincyPrintDialog.cpp
#include "stdafx.h"
#include "quincy.h"
#include "QuincyPrintDialog.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

LOGFONT CQuincyPrintDialog::logfont;

////////////////////////////
// CLineNumberButton class
IMPLEMENT_DYNAMIC(CLineNumberButton, CButton)
CLineNumberButton::CLineNumberButton()
{
}
BEGIN_MESSAGE_MAP(CLineNumberButton, CButton)
    //{{AFX_MSG_MAP(CLineNumberButton)
    ON_WM_CREATE()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
int CLineNumberButton::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
    if (CButton::OnCreate(lpCreateStruct) == -1)
        return -1;
    font.CreateFontIndirect(&CQuincyPrintDialog::logfont);
    SetFont(&font);
    return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CQuincyPrintDialog
IMPLEMENT_DYNAMIC(CQuincyPrintDialog, CPrintDialog)
CQuincyPrintDialog::CQuincyPrintDialog(BOOL bSetup) :
   CPrintDialog(bSetup, PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOSELECTION, 0)
{
    m_pd.nMinPage = 1;
    m_pd.nMaxPage = 0xffff;
    printlinenumbers = false;
}
BEGIN_MESSAGE_MAP(CQuincyPrintDialog, CPrintDialog)
    //{{AFX_MSG_MAP(CQuincyPrintDialog)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CQuincyPrintDialog::OnInitDialog() 
{
    CPrintDialog::OnInitDialog();
    GetFont()->GetLogFont(&logfont);

    CRect rc;
    GetClientRect(&rc);

    rc.top = rc.bottom - 30;
    rc.bottom = rc.top + 20;
    rc.left = 15;
    rc.right = rc.left + 110;

    BOOL b = lnobutton.Create(  "Print line numbers:", 
                    BS_AUTOCHECKBOX | 
                    BS_LEFTTEXT     | 
                    WS_VISIBLE      | 
                    WS_TABSTOP      |
                    WS_CHILD,
                    rc,
                    this,
                    IDC_LINENUMBERS);
    lnobutton.SetCheck(printlinenumbers);
    return TRUE;
}
void CQuincyPrintDialog::OnOK()
{
    printlinenumbers = lnobutton.GetCheck() != 0;
    CPrintDialog::OnOK();
}

Listing Three
// CEditorView printing
BOOL CEditorView::OnPreparePrinting(CPrintInfo* pInfo)
{
    delete pInfo->m_pPD;        // framework has one built on heap
    pInfo->m_pPD = new CQuincyPrintDialog;  
                                // framework will delete this object
    static_cast<CQuincyPrintDialog*>(pInfo->m_pPD)->printlinenumbers = 
                    theApp.PrintLineNumbers();
    return DoPreparePrinting(pInfo);
}
void CEditorView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
    printlinenos = 
           static_cast<CQuincyPrintDialog*>(pInfo->m_pPD)->printlinenumbers;
    int nHeight = -((pDC->GetDeviceCaps(LOGPIXELSY) * 10) / 72);
    m_printerfont.CreateFont(nHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0,
        DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
        DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier");
    TEXTMETRIC tm;
    CFont* pOldFont = pDC->SelectObject(&m_printerfont);
    pDC->GetTextMetrics(&tm);
    m_cyPrinter = tm.tmHeight + tm.tmExternalLeading;
    pDC->SelectObject(pOldFont);

    m_nLinesPerPage =(pDC->GetDeviceCaps(VERTRES) -
       (m_cyPrinter * (3 + (2 * PRINTMARGIN)))) / m_cyPrinter;
    UINT nMaxPage = max(1, (GetDocument()->linecount() + 
                           (m_nLinesPerPage - 1)) / m_nLinesPerPage);
    pInfo->SetMaxPage(nMaxPage);
}
void CEditorView::OnPrint (CDC* pDC, CPrintInfo* pInfo)
{
    PrintPageHeader(pDC, pInfo->m_nCurPage);
    PrintPage(pDC, pInfo->m_nCurPage);
}
void CEditorView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* pInfo)
{
    m_printerfont.DeleteObject ();
    bool plno = 
          static_cast<CQuincyPrintDialog*>(pInfo->m_pPD)->printlinenumbers;
    theApp.SetPrintLineNumbers(plno);
}
void CEditorView::PrintPageHeader(CDC* pDC, UINT nPageNumber)
{
    CString strHeader = GetDocument()->GetTitle();
    CString strPageNumber;
    strPageNumber.Format(" (Page %d)", nPageNumber);
    strHeader += strPageNumber;
    UINT y = m_cyPrinter * PRINTMARGIN;
    CFont* pOldFont = pDC->SelectObject(&m_printerfont);
    pDC->TextOut(0, y, strHeader);
    pDC->SelectObject(pOldFont);
}
void CEditorView::PrintPage (CDC* pDC, UINT nPageNumber)
{
    int lines = GetDocument()->linecount();
    if (GetDocument()->linecount() != 0) {
        UINT nStart = (nPageNumber - 1) * m_nLinesPerPage;
        UINT nEnd = min(lines - 1, nStart + m_nLinesPerPage - 1);
        CFont* pOldFont = pDC->SelectObject(&m_printerfont);
        for (int i = nStart; i <= nEnd; i++) {
            std::string str = GetDocument()->textline(i);
            for (int j = 0; j < str.length(); j++)
                if (str[j] == '\t')
                    str[j] = ' ';
            int y = ((i - nStart) + PRINTMARGIN + 3) * m_cyPrinter;
            CString line;
            if (printlinenos)
                line.Format("%-4d ", i + 1);
            line += str.c_str();
            pDC->TextOut(0, y, line);
        }
        pDC->SelectObject(pOldFont);
    }
}


4


