Printing

From WxWiki

Jump to: navigation, search
  • For simple uses, wxHtmlEasyPrinting will get you started quickly.
  • If you need more complex printing with drawing, here's a small code snippet to quickly get you started with the basics of printing in wxWidgets.

On wxGTK, make sure to build wxWidgets with libgnomeprint support enabled. This provides a much more suitable printing solution.

#include "wx/wx.h"
#include <iostream>
 
#include "wx/print.h"
#include "wx/printdlg.h"
#ifdef __WXMAC__
#include "wx/mac/printdlg.h"
#endif
 
#if wxUSE_LIBGNOMEPRINT
#include "wx/html/forcelnk.h"
FORCE_LINK(gnome_print)
#endif
 
// declarations
 
class MyApp: public wxApp
{
  public:
    MyApp(){};
    bool OnInit();
    int OnExit();
};
 
DECLARE_APP(MyApp)
 
 
// Define a new canvas and frame
class MyFrame: public wxFrame
{
  public:
    MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size);
 
    void OnSize(wxSizeEvent& event);
 
    void OnExit(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
 
 
class MyPrintout: public wxPrintout
{
    wxPrintData *page_data;
    wxPageSetupDialogData* page_setup;
    int orient;
    int max_x, max_y;
    int pageAmount;
 public:
    MyPrintout(wxWindow* parent, int orient=wxPORTRAIT, int pageAmount=1, const wxChar *title = _T("My printout"), bool pageSetup=false);
    ~MyPrintout();
  
    bool OnPrintPage(int page);
    bool HasPage(int page);
    bool OnBeginDocument(int startPage, int endPage);
    void OnBeginPrinting();
    void GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo);
};
 
// definition
 
IMPLEMENT_APP(MyApp)
 
bool MyApp::OnInit(void)
{
    wxInitAllImageHandlers();
 
    // Create the main frame window
    MyFrame* frame = new MyFrame((wxFrame *) NULL, _T("wxWidgets Printing Demo"), 
        wxPoint(0, 0), wxSize(400, 400));
    SetTopWindow(frame);
 
    MyPrintout printout(frame, wxPORTRAIT, 3, wxT("My Printing test"), false /* show page setup dialog */);
 
    return true;
}
 
int MyApp::OnExit()
{
    return 1;
}
 
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
END_EVENT_TABLE()
 
MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size) :
    wxFrame(frame, wxID_ANY, title, pos, size)
{
}
 
void MyFrame::OnExit(wxCommandEvent& WXUNUSED(event))
{
    Close(true /*force closing*/);
}
 
MyPrintout::MyPrintout(wxWindow* parent, int orient, int pageAmount, const wxChar *title, bool pageSetup) : wxPrintout(title)
{
    MyPrintout::orient = orient;
    MyPrintout::pageAmount = pageAmount;
 
    page_data = new wxPrintData();
    page_data -> SetOrientation(orient);
    // You could set an initial paper size here
    // page_data->SetPaperId(wxPAPER_LETTER);
    // page_data->SetPaperId(wxPAPER_A4); 
 
    page_setup = new wxPageSetupDialogData();
    // copy over initial paper size from print record
    (*page_setup) = *page_data;
    // Set some initial page margins in mm. 
    page_setup->SetMarginTopLeft(wxPoint(15, 15));
    page_setup->SetMarginBottomRight(wxPoint(15, 15));
    
    if(pageSetup)
    {
        (*page_setup) = *page_data;
 
        wxPageSetupDialog pageSetupDialog(parent , page_setup);
        pageSetupDialog.ShowModal();
 
        (*page_data) = pageSetupDialog.GetPageSetupDialogData().GetPrintData();
        (*page_setup) = pageSetupDialog.GetPageSetupDialogData();
        orient = page_data->GetOrientation();
    }
 
    wxPrintDialogData printDialogData(* page_data);
 
    wxPrinter printer(& printDialogData);
 
    if (!printer.Print(parent, this, true /*prompt*/))
    {
        if (wxPrinter::GetLastError() == wxPRINTER_ERROR)
            wxMessageBox(_T("There was a problem printing.\nPerhaps your current printer is not set correctly?"), _T("Printing"), wxOK);
        else
            wxMessageBox(_T("You canceled printing"), _T("Printing"), wxOK);
    }
    else
    {
        (*page_data) = printer.GetPrintDialogData().GetPrintData();
    }
}
 
MyPrintout::~MyPrintout()
{
    delete page_data;
    delete page_setup;
}
 
void MyFrame::OnSize(wxSizeEvent& event )
{
    wxFrame::OnSize(event);
}
 
 
bool MyPrintout::OnPrintPage(int pageNum)
{
    // set-up coordinate system however we want
    // we'll use it when drawing
        
    // here i'm using arbitrary an size, use whatever you wish
    if(orient == wxPORTRAIT)
    {
        max_x = 680;
        max_y = 880;
    }
    else 
    {
        max_x = 880;
        max_y = 680;
    }
        
    FitThisSizeToPageMargins(wxSize(max_x, max_y), *page_setup);
    
    std::cout << "printing page " << pageNum << std::endl;
        
    static const int brush_size = 3;
        
    wxDC* ptr = GetDC();
    if(ptr==NULL or !ptr->IsOk())
    {
        std::cout << "DC is not Ok, interrupting printing" << std::endl;
        return false;
    }
    wxDC& dc = *ptr;
        
    // get bounds information, to know where to render stuff
    //wxRect bounds = GetLogicalPageRect();
    wxRect bounds = GetLogicalPageMarginsRect(*page_setup);
    const int x0 = bounds.x;
    const int y0 = bounds.y;
    const int width = bounds.width;
    const int height = bounds.height;
    const int x1 = x0 + width;
    const int y1 = y0 + height;
        
    const int center_x = x0 + width/2;
    const int center_y = y0 + height/2;
        
    std::cout << "printable area : (" << x0 << ", " << y0 << ") to (" << x1 << ", " << y1 << ")" << std::endl;
        
    dc.Clear();
        
    dc.SetPen(  wxPen( wxColour(0,0,0), brush_size ) );
    dc.SetBrush( *wxTRANSPARENT_BRUSH );
        
    // draw a rectangle to show its bounds.
    dc.DrawRectangle(x0+15, y0+15, width-15, height-15);
        
    // draw wxWidgets logo
    dc.SetBrush( *wxRED_BRUSH );
    dc.DrawRectangle(center_x-45-38, center_y, 76, 76);
    dc.SetBrush( *wxBLUE_BRUSH );
    dc.DrawRectangle(center_x-38, center_y-45, 76, 76);
    dc.SetBrush( wxBrush( wxColor(255,244,0) ) );
    dc.DrawRectangle(center_x+45-38, center_y-10, 76, 76);
        
    // draw page number label
    wxString label( wxT("This is page #") );
    label << pageNum;
    dc.SetTextBackground( wxColour(255,255,0) );
    dc.SetTextForeground( wxColour(0,0,0) );
    dc.DrawText( label, x0 + width/5, y0 + height - 50 );
        
    return true;
}
 
bool MyPrintout::OnBeginDocument(int startPage, int endPage)
{
    if (!wxPrintout::OnBeginDocument(startPage, endPage))
        return false;
 
    return true;
}
 
void MyPrintout::GetPageInfo(int *minPage, int *maxPage, int *selPageFrom, int *selPageTo)
{
    *minPage = 1;
    *maxPage = pageAmount;
    *selPageFrom = 1;
    *selPageTo = pageAmount;
}
 
bool MyPrintout::HasPage(int pageNum)
{
    return (pageNum > 0 && pageNum <= pageAmount);
}
 
void MyPrintout::OnBeginPrinting()
{
}
Personal tools