http://www.perlmonks.org?node_id=863585

teoma has asked for the wisdom of the Perl Monks concerning the following question:

I have a dialogbox, to which i populate elements(labels) on activate event. I want to remove these elements(labels) when the window is being deactivated. something like:its erroneous fragment of main code but explanatory

my $wchRW = Win32::GUI::DialogBox->new( -name => "wchR", -title => "whed", -left => CW_USEDEFAULT, -size => [300, 130], -parent => $mw, ); $wchRW->AddGroupbox( -name => "wchR_gb", -text => "being watched", -width => $wchRW->ScaleWidth() - $padding, -height => 100, -left => $padding/2, ); sub wchR_Activate { my $wchtxt = "sample"; # lbleft, lbtop are calculated here $wchRW->AddLabel( -name => "wchR_lb0", -text => $wchTxt, -left => $lbLeft, -top => $lbTop, ); } sub gitni_wchR_Deactivate { print "Here\n"; Win32::GUI::DestroyWindow($wchRW->wchR_lb0); #this is line n } #i have a button in main window $mw. onclick of this button this dialo +gbox is shown. #sub b1_Click { $wchRW->DoModal(); return 0; }

But the problem is, "Here" in deactivate is called many times and an exception is thrown thereafter can't locate auto/wchR_.al in @INC .... line n. Freezing the main window and only option is to end process through task-manager.

Please help me out. Why "here" is printed many times? How to remove element permanently? Thanks

Replies are listed 'Best First'.
Re: remove elements win32 gui
by zentara (Archbishop) on Oct 05, 2010 at 13:22 UTC
    I don't use Win32::Gui, but in general, you don't destroy widgets to get rid of their data. Looking at the Win32::Gui tutorial, you may want Remove() instead of DestroyWindow. Maybe:
    sub gitni_wchR_Deactivate { print "Here\n"; ####Win32::GUI::DestroyWindow($wchRW->wchR_lb0); #this is line n Win32::GUI::Remove($wchRW->wchR_lb0); }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: remove elements win32 gui
by kejohm (Hermit) on Oct 06, 2010 at 07:02 UTC

    Win32::GUI doesn't allow you to destroy controls yourself, but if you really need to, you can remove the reference to the control from it's parent Window object and any other references to the control, if any. Example:

    #!perl use strict; use warnings; use feature qw(:5.12); use Win32::GUI qw(); use Win32::GUI::Constants qw(CW_USEDEFAULT); my $win = Win32::GUI::Window->new( -name => 'win', -text => 'Destroy Window', -size => [ 320, 240 ], -left => CW_USEDEFAULT, ); my $label = $win->AddLabel( -name => 'label', -text => 'Label', -size => [ 80, 25 ], -pos => [ 10, 10 ], ); my $button = $win->AddButton( -name => 'button', -text => 'Remove', -size => [ 80, 25 ], -pos => [ 10, 50 ], -onClick => sub { state $show = 1; if($show){ undef $label; # remove stored reference to cont +rol delete $win->{label}; # remove reference stored in pare +nt window $show = 0; } else { $label = $win->AddLabel( # recreate control -name => 'label', -text => 'Label', -size => [ 80, 25 ], -pos => [ 10, 10 ], ); $show = 1; } return 1; }, ); $win->Show(); Win32::GUI::Dialog(); __END__

    This usually isn't the best idea. As mentioned by zentara above, it's usually best to just show and hide the control instead. Example:

    #!perl use strict; use warnings; use feature qw(:5.12); use Win32::GUI qw(); use Win32::GUI::Constants qw(CW_USEDEFAULT); my $win = Win32::GUI::Window->new( -name => 'win', -text => 'Destroy Window', -size => [ 320, 240 ], -left => CW_USEDEFAULT, ); my $label = $win->AddLabel( -name => 'label', -text => 'Label', -size => [ 80, 25 ], -pos => [ 10, 10 ], ); my $button = $win->AddButton( -name => 'button', -text => 'Remove', -size => [ 80, 25 ], -pos => [ 10, 50 ], -onClick => sub { if($label->IsVisible()){ $label->Hide(); } else { $label->Show(); } return 1; }, ); $win->Show(); Win32::GUI::Dialog(); __END__