in reply to wxPreviewFrame error on closing

I totally missed that I needed https://wxperl.svn.sourceforge.net/svnroot/wxperl/wxPerl/trunk to try to help :)

I have now compiled wxPerl with Alien::wxWidgets::Config::msw_2_8_10_uni_gcc_3_4.

I get an error before any windows are displayed

Faulting application perl.exe, version 0.0.0.0, faulting module wx.dll +, version 0.0.0.0, fault address 0x0000342a.
It occurs on this call
$i_RTC_panel->{printout}->GetRichTextBuffer();
This is likely a wxWidgets 2.8 specific bug

After removing that line I get same type of error after hitting preview

Faulting application perl.exe, version 0.0.0.0, faulting module unknow +n, version 0.0.0.0, fault address 0xf0a8ca63.
I believe this is also related to my version of wxwidgets, but I can't be sure. Bummer.

So I went to see how wxperl_demo does it

sub OnPreview { my( $this, $event ) = @_; my $prev = Wx::DemoModules::wxPrinting::Printout->new( $this->canvas +, "Preview" ); my $print = Wx::DemoModules::wxPrinting::Printout->new( $this->canva +s, "Print" ); my $preview = Wx::PrintPreview->new( $prev, $print ); my $frame = Wx::DemoModules::wxPrinting::PreviewFrame->new( $preview +, wxTheApp->GetTopWindow, "Printing Demo Preview", [-1, -1] +, [600, -1] ); $frame->Initialize(); $frame->Show( 1 ); }
After comparing that with samples/richtext/richtext.cpp...

I realize the problem with your code is that you're trying to share your printout object between your wxRichTextPrinting and wxPreviewFrame, and the docs confirm it

wxPreviewFrame::OnCloseWindow

Enables the other frames in the application, and deletes the print preview object, implicitly deleting any printout objects associated with the print preview object.

So simply losing the wxRichTextPrinting object should work.

Actually, its probably only a partial fix

wxRichTextPrintout::SetRichTextBuffer

Sets the buffer to print. wxRichTextPrintout does not manage this pointer; it should be managed by the calling code, such as wxRichTextPrinting.

So you'll probably have to subclass wxRichTextPrinting like
BEGIN { package MyRichTextPrintout; use base qw[ Wx::RichTextPrintout ]; sub new { my ( $self, $buffer ) = @_; $self = $self->SUPER::new(); $self->SetRichTextBuffer($buffer); return $self; } sub DESTROY { $_[0]->SetRichTextBuffer(undef); return; } } sub on_click_richtext_preview { my ($self) = @_; my $preview = Wx::PrintPreview->new( MyRichTextPrintout->new( $self->{Ctl_Report_Text_Txt}->GetBuff +er() ), MyRichTextPrintout->new( $self->{Ctl_Report_Text_Txt}->GetBuff +er() ), ); $preview->SetZoom(200); my $frame = Wx::PreviewFrame->new( $preview, $self, "Printing Demo + Preview", wxDefaultPosition, [ 1360, 768 ], wxNO_BORDER ); $frame->Initialize(); my $state = $frame->Show(1); }
I hope this works for you. If it doesn't you should use strace (or grind) to try to track down where the error occurs

I gave it a shot but my wxwidgets/wxperl crashes after clicking preview (the window shows up and then the crash window on top of it), and I don't have a strace equivalent handy.

I couldn't compile wxPerl against Alien::wxWidgets::Config::msw_2_9_0_uni_gcc_3_4, maybe I'll try 2.8.11 some time later

Good luck

Replies are listed 'Best First'.
Re^2: wxPreviewFrame error on closing
by Steve_BZ (Chaplain) on Sep 06, 2010 at 12:08 UTC

    Hi Anon,

    I'd like to thank you for the amazing amount of effort you've put into helping me with this. I'm very touched and I'm sorry I've only just noticed your post today. And then you post all your work under under "Anonymous"!

    Your code crashes at about the same time mine does (mine actually crashes on "EXIT" of preview), althought I don't get the error messgaes you do. Mine is Karmic Kubuntu and I think yours is Windows, so that may account for the difference. However, your error messages are very useful. I did try to run it on windows, but my wxPerl installation there is corrupt. I need to reinstall sometime.

    I'm going to work through your points over the next few days and I'll keep this thread updated with my progress.

    So thanks again Anon.

    Regards

    Steve

Re^2: wxPreviewFrame error on closing
by Steve_BZ (Chaplain) on Sep 08, 2010 at 21:14 UTC

    Hi Anon,

    Well, I've followed through some of your links. The first thing I noticed was that wxPreviewFrame::OnCloseWindow isn't wrapped for wxPerl (or at least it doesn't seem to be. A fact not noted in the documentation. So I created my own version:

    sub on_click_richtext_preview_close { my($self,$event) = @_; $self->Destroy; }

    And called it with:

    Wx::Event::EVT_CLOSE( $frame , \&on_click_richtext_preview_close ) +;

    just before the initialise. It Seems to work, but the main frame, to which it is returned, is disabled (in my version of the code). Can I just enable it, or is that too easy?

    Regards

    Steve

      The first thing I noticed was that wxPreviewFrame::OnCloseWindow isn't wrapped for wxPerl

      It doesn't make sense to wrap it

      http://svn.wxwidgets.org/svn/wx/wxWidgets/trunk/src/common/prntbase.cpp

      IMPLEMENT_CLASS(wxPreviewFrame, wxFrame) BEGIN_EVENT_TABLE(wxPreviewFrame, wxFrame) EVT_CLOSE(wxPreviewFrame::OnCloseWindow) END_EVENT_TABLE() ... void wxPreviewFrame::OnCloseWindow(wxCloseEvent& WXUNUSED(event)) { if (m_windowDisabler) delete m_windowDisabler; // Need to delete the printout and the print preview wxPrintout *printout = m_printPreview->GetPrintout(); if (printout) { delete printout; m_printPreview->SetPrintout(NULL); m_printPreview->SetCanvas(NULL); m_printPreview->SetFrame(NULL); } delete m_printPreview; Destroy(); }
      It Seems to work, but the main frame, to which it is returned, is disabled (in my version of the code). Can I just enable it, or is that too easy?

      You could do that, but as you can see above the wxWindowDisabler is deleted, which re-enables the previously disabled windows, so it should work already :)

        Hi Anon,

        Well then, is it possible that one of the wrappings (maybe the one I did on RichTextPrintout) is not passing the event on to wxPrintout or whatever it's equivalent is? Because when I manually capture EVT_CLOSE and handle it, it's as near as I can get to the correct processing.

        Alternatively, I could mimic the above c-processing, but I'd need a couple of hints:

        1. How to access windowDisabler since I don't know its Hash-name or address-pointer within the parent object.
        2. I'm not sure what the difference between delete and Destroy() is. I guess delete is remove an element from a Hash and then Destroy() is remove the object. In Perl, wouldn't the deletes be automatic if you just Destroy()ed the object?

        So in that case all I have to do is to delete/Destroy() the windowDisabler as well.

        Regards

        Steve

Re^2: wxPreviewFrame error on closing
by Steve_BZ (Chaplain) on Sep 10, 2010 at 12:14 UTC

    Hi Anon,

    I've just been over all your code again, because it seems like the nearest to a solution so far.

    I got to the same point as you, crashing on preview. It's the line my $state = $frame->Show(1);.

    I picked out your other bits and pieces and used them selectively, but I got no further than before where I could get the preview to show, but I have to capture the preview EVT_COSE command on exit and handle it manually.

    However, two more clues are:

    1. The Printing demonstration command in the demo also uses Wx::PreviewFrame (actually PlPreviewFrame but that doesn't work with this code either) and has no code at all to handle the exit - but it exits perfectly and returns control to the calling window.
    2. The $i_RTC_panel->{printout}->GetDC; which I put in for a test, doesn't fail with a "no such method" style error, but it doesn't return anything (which it should). Just a null instead of the pointer to the MemoryDC associated with the preview.

    So I wonder if the two are linked.

    Regards

    Steve.

      So I wonder if the two are linked.

      Maybe, but why wonder when you can find out? Fire up strace or debugger and find out exactly where the error occurs in c/xs code... then you can either fix it, or file the appropriate bug report