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