【问题标题】:Can you Print a wxWindow in wxWidgets?你能在 wxWidgets 中打印一个 wxWindow 吗?
【发布时间】:2012-05-01 11:20:24
【问题描述】:

我正在使用 wxWidgets 为 Windows 开发一个程序。我正在尝试实现一个打印功能,它将一个 wxPanel(或 wxWindow)打印到打印机。 wxWidgets 有一个很好的方便的类,如果你画到 DC 中。

有没有办法让 wxWidgets 在 DC 中绘制 wxPanel 或 wxWindow? 我尝试使用 HandlePrintClient(响应 WM_PRINTCLIENT)函数,但这只是绘制背景。 我还尝试创建一个打印机 DC 并通过与 HandlePrint 类似的功能发送它,但 wxWidget 的东西似乎与 BeginPrint 紧密耦合。

有什么方法可以做我想做的事吗?也许已经编写了一个类,它将附加 wxScrolledWindow 并将其发送到打印机?该窗口将具有其他控件和窗口,例如其上的 wxGrid。

【问题讨论】:

    标签: printing wxwidgets


    【解决方案1】:

    最后,将您想要的内容绘制到 printDC 中可能更容易。但是,请注意,您可以使用 BLIT 将面板中显示的内容复制到 PrintDC 中,而无需重新绘制所有内容。

    因此,在您覆盖 wxPrintout::OnPrintPage 时,您可以编写如下内容:

        wxClientDC frameDC( wxGetApp().GetTopWindow() );
        GetDC()->StretchBlit(0,0,5000,5000,
            &frameDC, 0, 0, 500,500 );
    

    这会将您的应用程序顶层窗口中显示的所有内容复制到打印机DC中。

    问题是打印预览窗口在弹出时往往会抹掉您的*框架内容。如果你有一个大显示器和一个小应用程序窗口,你可以安排一些东西,使它们不重叠

    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);
    

    更好的方法是在弹出打印预览之前将帧显示 BLIT 到 memoryDC,然后从 MemoryDC BLIT 到 printerDC。

    类似的东西:

    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);
    
    }
    

    然后

    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;
        }
    
    };
    

    【讨论】:

    • 我明白你在说什么,但我希望能够打印甚至没有显示的东西。能够将 DC 发送到抽签程序并让它填充 DC 会很棒。我不想自己绘制,因为那样我最终会重写控件(幸运的是在这个例子中它主要只是 wxGrids) 拥有我无法利用的绘制代码似乎很可惜。