Printing
From WxWiki
- 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() { }
