Hi Guys, I've just wrapped wxRichTextPrintout and I'm using it to handle a print preview more precisely.
The printpreview works fine, but when I press the "close" button in preview, the PreviewFrame does not close and I get: "*** glibc detected *** /usr/bin/perl: double free or corruption (!prev): 0x000000000261cb80 ***" The book says that "close" and "destroy" should both be handled automatically. Code follows. You'll need to have the most recent version of wxPerl to show this. I would be grateful for your thoughts. Regards Steve #!/usr/bin/perl -w -- use Wx 0.15 qw[:allclasses]; use strict; package MyFrame; use Wx qw[:everything]; use base qw(Wx::Frame); our $gl_installation_path = ''; our $gl_i_frame_ptr; sub new { my( $self, $parent, $id, $title, $pos, $size, $style, $name ) = @_; my %RTC_Buttons = ( preview=>1, ); $style = wxDEFAULT_FRAME_STYLE unless defined $style; $self = $self->SUPER::new( undef, wxID_ANY, "Rich Text Control", wxDefaultPosition, wxDefaultSize, $style, "" ); $self->SetTitle("Rich Text Control"); $self->{sizer} = Wx::BoxSizer->new( wxVERTICAL ); my $i_RTC_Panel=RichText_Obj->new($self, "first panel", %RTC_Buttons,[800, 300]); $self->{sizer}->Add( $i_RTC_Panel, 1, wxGROW|wxALL, 5 ); $self->SetSizerAndFit( $self->{sizer} ); $self->Layout(); return $self; } package RichText_Obj; use Wx qw[:everything]; sub new{ my ($class, $parent, $name, $buttons_ptr, $size) = @_; $size = wxDefaultSize unless defined $size; my $i_RTC_panel = Wx::Panel->new( $parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, "" ); $i_RTC_panel->{Ctl_Post_Exam_Report_Szr_1} = Wx::BoxSizer->new(wxVERTICAL); # Top level in RTC Object; $i_RTC_panel->{Ctl_Post_Exam_Report_Szr_2} = Wx::BoxSizer->new(wxHORIZONTAL); # Button bar for RTC Object; $i_RTC_panel->{name} = $name; # General Parameters my @loc_parameters_arr; $#loc_parameters_arr=0; # Remove elements from array. @loc_parameters_arr = ("", "", 1, "", -1, -1, "", "", $i_RTC_panel->{Ctl_Post_Exam_Report_Szr_2}, $i_RTC_panel, ""); $loc_parameters_arr [12]= ''; $loc_parameters_arr [13]= ''; # Preview Button if ($$buttons_ptr{preview}){ $loc_parameters_arr [0]= $i_RTC_panel->{Ctl_Report_Preview_Text_Btn}; # Button name, passed by reference $loc_parameters_arr [7]= (("Preview report.")); # Tooltip $loc_parameters_arr [10]= ("Images/wordproccess/16px-Document-print-preview.png"); # Bitmap path $loc_parameters_arr [11]= ( # __new_BitmapButton(@loc_parameters_arr); } $i_RTC_panel->{Ctl_Report_Text_Txt} = Wx::RichTextCtrl->new( $i_RTC_panel, -1, '', [-1, -1], $size ); $i_RTC_panel->{Ctl_Report_Text_Txt} -> SetBackgroundColour(wxWHITE); $i_RTC_panel->{Ctl_Report_Text_Txt} -> SetForegroundColour(wxBLACK); $i_RTC_panel->{Ctl_Post_Exam_Report_Szr_1}->Add($i_RTC_panel->{Ctl_Post_Exam_Report_Szr_2}, 0, 0, 0); $i_RTC_panel->{Ctl_Post_Exam_Report_Szr_1}->Add($i_RTC_panel->{Ctl_Report_Text_Txt}, 0, 0, 0); my $XML_handler = Wx::RichTextXMLHandler->new; my $HTML_handler = Wx::RichTextHTMLHandler->new; my $RTC_Buffer = $i_RTC_panel->{Ctl_Report_Text_Txt}->GetBuffer(); $RTC_Buffer ->AddHandler($XML_handler); $RTC_Buffer ->AddHandler($HTML_handler); $i_RTC_panel->{preview}= Wx::RichTextPrinting->new('Wx::Demo Printing', $i_RTC_panel); $i_RTC_panel->{printout}= Wx::RichTextPrintout->new('Wx::Demo Printing'); $i_RTC_panel->{printout}->GetRichTextBuffer(); $i_RTC_panel->{printout}->GetDC; $i_RTC_panel->SetSizerAndFit( $i_RTC_panel->{Ctl_Post_Exam_Report_Szr_1} ); $i_RTC_panel->Layout(); return $i_RTC_panel; } sub __new_BitmapButton{ # sets field properties, format: # __new_Button($loc_self_ptr, "", $loc_enabled, "", $loc_minsize_x, $loc_minsize_y, "", $loc_tooltip, $loc_sizer_ptr, $loc_panel_ptr, (("Label")); my $loc_bcur = Wx::BusyCursor->new; # Create hourglass within current scope. Hourglass is deleted on exit. my $loc_self_ptr=shift; # pointer to control (Pass by reference) my $loc_ID=shift; # ID used to over-ride wxID_ANY my $loc_enabled=shift; # Enabled or disabled my $loc_max_length=shift; # Not used, set to null my $loc_minsize_x=shift; # Holds minimum size of control (x-axis) my $loc_minsize_y=shift; # Holds minimum size of control (y-axis) my $loc_validation_string=shift; # Not used, set to null my $loc_tooltip=shift; # Holds tooltip already translated. my $loc_sizer_ptr=shift; # pointer to sizer (Pass by reference) my $loc_panel_ptr=shift; # pointer to panel (Pass by reference) my $loc_control_value=shift; # Label for button or bitmap my $loc_button_event_ptr=shift; # Event (pointer.) my $loc_gbposition_ptr=shift; # Gridbag position details (pointer.) my $loc_gbspan_ptr=shift; # Gridbag span details (pointer.) my $bitmap_path = $gl_installation_path.$loc_control_value; if( $loc_ID eq ""){ if ($gl_installation_path ne ""){ $$loc_self_ptr = Wx::BitmapButton-> new($$loc_panel_ptr, wxID_ANY, Wx::Bitmap->new($bitmap_path, wxBITMAP_TYPE_ANY), wxDefaultPosition, [16,16], ); } else { $$loc_self_ptr = Wx::Button-> new($$loc_panel_ptr, wxID_ANY, "Preview", wxDefaultPosition, wxDefaultSize, ); } } else{ $$loc_self_ptr = Wx::Button-> new($$loc_panel_ptr, $loc_ID, __trim($loc_control_value), wxDefaultPosition, wxDefaultSize, ); } if ($loc_enabled == 1){ # Set Enable according to parameter. $$loc_self_ptr->Enable(1); } else{ $$loc_self_ptr->Disable(); } if ($loc_minsize_x ne "") { # Set minimum physical size of field in pixels $$loc_self_ptr->SetMinSize(Wx::Size->new($loc_minsize_x, $loc_minsize_y)) }; $$loc_self_ptr->SetSize($$loc_self_ptr->GetBestSize()); if ($loc_tooltip ne "") {$$loc_self_ptr->SetToolTipString($loc_tooltip)}; #Set tooltip if (defined $loc_gbposition_ptr and $loc_gbposition_ptr ne '') { # Add to GridBag Position and Span if (defined $loc_gbspan_ptr and $loc_gbspan_ptr ne '' ) { # Add to GridBag Position $$loc_sizer_ptr->Add($$loc_self_ptr, $$loc_gbposition_ptr, $$loc_gbspan_ptr); # Add to grid } else { $$loc_sizer_ptr->Add($$loc_self_ptr, $$loc_gbposition_ptr); # Add to grid } } else { $$loc_sizer_ptr->Add($$loc_self_ptr, 0, 0, 0); # Add to grid } if (defined $loc_button_event_ptr) { # Set button press event if ($loc_button_event_ptr ne "") { # Set button press event Wx::Event::EVT_BUTTON( $$loc_panel_ptr , $$loc_self_ptr, $loc_button_event_ptr ); } }; } sub on_click_richtext_preview{ my($self) = @_; # Set up header and footer. my $pv = $self->{preview}; $pv->SetHeaderText('Wx::Demo Richtext Printing', wxRICHTEXT_PAGE_ALL, wxRICHTEXT_PAGE_LEFT); $pv->SetFooterText('Page @PAGENUM@ of @PAGESCNT@', wxRICHTEXT_PAGE_ALL, wxRICHTEXT_PAGE_RIGHT); $pv->SetShowOnFirstPage(0); # we can only set header / footer margins using wxRichTextHeaderFooterData my $hfdata = $pv->GetHeaderFooterData; $hfdata->SetMargins(100,100); $pv->SetHeaderFooterData($hfdata); # Create Printout Object my $po = $self->{printout}; $po->SetRichTextBuffer($self->{Ctl_Report_Text_Txt}->GetBuffer()); # Create Preview object my $preview = Wx::PrintPreview->new($po,$po,$pv->GetPrintData); $preview ->SetZoom(200); my $frame = i_PreviewFrame->new( $preview, wxTheApp->GetTopWindow, "Printing Demo Preview", [-1,-1],[1000,600],wxNO_BORDER); $frame->Initialize(); my $state = $frame->Show(1); #Destroy $frame; #$pv->PreviewBuffer($self->{Ctl_Report_Text_Txt}->GetBuffer()); } package i_PreviewFrame; use strict; use base 'Wx::PlPreviewFrame'; sub Initialize { $_[0]->SUPER::Initialize; } sub CreateControlBar { $_[0]->SetPreviewControlBar ( i_ControlBar->new( $_[0]->GetPrintPreview, $_[0] ) ); $_[0]->GetPreviewControlBar->CreateButtons; } package i_ControlBar; use strict; use base 'Wx::PlPreviewControlBar'; sub new { $_[0]->SUPER::new( $_[1], 0xffffffff, $_[2], [0, 0], [400, 40] ); } sub CreateButtons { shift->SUPER::CreateButtons; } package main; unless(caller){ local *Wx::App::OnInit = sub{1}; my $app = Wx::App->new(); Wx::InitAllImageHandlers(); my $frame_1 = MyFrame->new(); $app->SetTopWindow($frame_1); $frame_1->Show(1); $app->MainLoop(); }