[Home]  [Prev]  [Next]    A guide, a tutorial for developing well-designed cross-platform applications

9. Printing

Printing is so obvious it's sometimes forgotten, especially in applications which usually just are used to change some internal data. But there's always a case where something has to be documented and printed. So printing should always be present.

Sample code

wxPrintData *g_printData = (wxPrintData*) NULL;
wxPageSetupData *g_pageSetupData = (wxPageSetupData*) NULL;
...

class AppFrame: public wxFrame {
    ...

    void OnPrintSetup (wxCommandEvent &event);
    void OnPrintPreview (wxCommandEvent &event);
    void OnPrint (wxCommandEvent &event);

    ...
};

...

class Printout: public wxPrintout {

public:
    //! Constructor
    Printout (wxChar *title = _T("Test printout")): wxPrintout(title) {}

    //! Event handlers
    bool OnPrintPage(int page);

    //! Print functions
    bool HasPage(int page);
    bool OnBeginDocument(int startPage, int endPage);
    void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo);

};

bool App::OnInit () {
    ...

    g_printData = new wxPrintData;
    g_pageSetupData = new wxPageSetupDialogData;

    ...
}

int App::OnExit () {
    ...

    if (g_printData) delete g_printData;
    if (g_pageSetupData) delete g_pageSetupData;

    ...
}

BEGIN_EVENT_TABLE (AppFrame, wxFrame)
    ...
    EVT_MENU (wxID_PRINT_SETUP,      AppFrame::OnPrintSetup)
    EVT_MENU (wxID_PREVIEW,          AppFrame::OnPrintPreview)
    EVT_MENU (wxID_PRINT,            AppFrame::OnPrint)
    ...
END_EVENT_TABLE ()
...

// print event handlers
void AppFrame::OnPrintSetup (wxCommandEvent &WXUNUSED(event)) {
    (*g_pageSetupData) = * g_printData;
    wxPageSetupDialog pageSetupDialog(this, g_pageSetupData);
    pageSetupDialog.ShowModal();
    (*g_printData) = pageSetupDialog.GetPageSetupData().GetPrintData();
    (*g_pageSetupData) = pageSetupDialog.GetPageSetupData();
}

void AppFrame::OnPrintPreview (wxCommandEvent &WXUNUSED(event)) {
    wxPrintDialogData printDialogData( *g_printData);
    wxPrintPreview *preview =
        new wxPrintPreview (new Printout,
                            new Printout,
                            &printDialogData);
    if (!preview->Ok()) {
        delete preview;
        wxMessageBox (_("There was a problem with previewing.\n\
                         Perhaps your current printer is not correctly?"),
                      _("Previewing"), wxOK);
        return;
    }
    wxRect rect = DeterminePrintSize();
    wxPreviewFrame *frame = new wxPreviewFrame (preview, this, _("Print Preview"));
    frame->SetSize (rect);
    frame->Centre(wxBOTH);
    frame->Initialize();
    frame->Show(true);
}

void AppFrame::OnPrint (wxCommandEvent &WXUNUSED(event)) {
    wxPrintDialogData printDialogData( *g_printData);
    wxPrinter printer (&printDialogData);
    Printout printout;
    if (!printer.Print (this, &printout, true)) {
        if (wxPrinter::GetLastError() == wxPRINTER_ERROR) {
        wxMessageBox (_("There was a problem with printing.\n\
                         Perhaps your current printer is not correctly?"),
                      _("Previewing"), wxOK);
            return;
        }
    }
    (*g_printData) = printer.GetPrintDialogData().GetPrintData();
}

...

//----------------------------------------------------------------------------
// Printout
//----------------------------------------------------------------------------

bool Printout::OnPrintPage (int page) {

    wxDC *dc = GetDC();
    if (dc)
    {
        dc->SetDeviceOrigin(0, 0);
        dc->SetUserScale(1.0, 1.0);

        wxChar buf[200];
        wxSprintf(buf, wxT("PAGE %d"), page);
        dc->DrawText(buf, 10, 10);

        return true;
    }else{
        return false;
    }
}

bool Printout::OnBeginDocument(int startPage, int endPage) {

    if (!wxPrintout::OnBeginDocument(startPage, endPage)) {
        return false;
    }
    return true;
}

void Printout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo) {

    *minPage = 1;
    *maxPage = 9999;
    *selPageFrom = *minPage;
    *selPageTo = *maxPage;
}

bool Printout::HasPage (int pageNum) {

    return true;
}