Reputation: 91
I am developing a program for windows using wxWidgets. I'm trying to implement a print function that will print a wxPanel (or wxWindow) to the printer. wxWidgets has a nice handy class that does this, if you draw into a DC.
Is there a way to get wxWidgets to draw a wxPanel or wxWindow in a DC? I tried to use the HandlePrintClient (in response to a WM_PRINTCLIENT) function, but this just draws the background. I also tried to create a printer DC and send it trough a similar function to HandlePrint, but the wxWidget stuff seems to be to tightly coupled with BeginPrint.
Is there some way to do what I want to do? Perhaps a class already written that will tack a wxScrolledWindow and send it to the printer? The window will have other controls and windows, like a wxGrid on it.
Upvotes: 0
Views: 1345
Reputation: 20472
In the end, it is probably easier to draw what you want into the the printDC. However, with some care, you can use BLIT to copy what is displayed in your panel into the PrintDC without having to redraw everything.
So, in your override of the wxPrintout::OnPrintPage you can write something like this:
wxClientDC frameDC( wxGetApp().GetTopWindow() );
GetDC()->StretchBlit(0,0,5000,5000,
&frameDC, 0, 0, 500,500 );
This will copy everything displayed in your applications top level wondow into the printerDC.
The snag is that the print preview window tends to obliterate your top level frame contents when it pops up. If you have a large monitor and a small application window you can arrange things so they do not overlap
void MyFrame::OnPrint(wxCommandEvent& )
{
wxPrintPreview *preview = new wxPrintPreview(new MyPrintout(this), new MyPrintout(this));
wxPreviewFrame *frame = new wxPreviewFrame(preview, this,
"Demo Print Preview",
wxPoint(600, 100), // move preview window out of the way
wxSize(500, 500));
//frame->Centre(wxBOTH);
frame->Initialize();
frame->Show(true);
A better approach would be to BLIT the frame display into a memoryDC before popping up the print preview, then BLIT from the MemoryDC to the printerDC.
Something along these lines:
void MyFrame::OnPrint(wxCommandEvent& )
{
// save the display before it is clobbered by the print preview
static wxMemoryDC memDC;
static wxBitmap bitmap(500,500);
memDC.SelectObject( bitmap );
wxClientDC frameDC( wxGetApp().GetTopWindow() );
memDC.Blit(0,0,5000,5000,
&frameDC, 0, 0 );
wxPrintPreview *preview = new wxPrintPreview(new MyPrintout(memDC), new MyPrintout(memDC));
wxPreviewFrame *frame = new wxPreviewFrame(preview, this,
"Demo Print Preview",
wxPoint(600, 100), // move preview window out of the way
wxSize(500, 500));
frame->Centre(wxBOTH);
frame->Initialize();
frame->Show(true);
}
and then
class MyPrintout : public wxPrintout
{
wxMemoryDC & myMemDC;
public:
MyPrintout( wxMemoryDC & memDC)
: myMemDC( memDC )
{
}
bool OnPrintPage( int PageNum )
{
// copy saved dispay to printer DC
GetDC()->StretchBlit(0,0,5000,5000,
&myMemDC, 0, 0, 500,500 );
return true;
}
};
Upvotes: 1