Waldemar Biernacki wrote:
Robert,

thank you for your efforts and email, I'll try my best to clarify...

Thank you. I can see the problem clearly. It's because you're destroying a window while in the middle of processing an event sent to it, and the code isn't expecting that, and so ends up trying to access some of the window's properties after they have been freed. I've got a solution to most of it, but there are a couple of areas where I'm not sure how to resolve it ... some more thought required, but I'll try to get a fix into the next release.

For the record, here's the shortest example I can come up with that exhibits the problem:

#!perl -w
use strict;
use warnings;

use Win32::GUI();

my $mw;

$mw = Win32::GUI::Window->new(
    -onKeyDown => sub { undef $mw; return -1; },
);

$mw->Show();
Win32::GUI::Dialog();
__END__


The point is that in WindowsXP it works fine but in Widows 98 SP2 it does not.
Windows' error screen points to USER32.DLL error.

I concur that the problem only manifests itself on Win98, but that's just lucky. With various variations of the script I can get the error to appear in either User32.dll or Perl58.dll.

Here's one way around the problem - I think this is pretty close to the behaviour of your current script (except for behaviour on clicking the 'close' button on the windows, which is somewhat unusual here, but I didn't know what you were expecting:

#!perl -w
use strict;
use warnings;

use Win32::GUI qw(VK_LEFT VK_RIGHT VK_RETURN);

my @Window;

makewindow();

$Window[0]->AddLabel(
    -pos  => [4,20],
    -size => [150,150],
    -text => "HELP:\n\n".
             " Right=add window\n".
             " Left=close (only top) window\n".
             " Enter=switch windows",
);

while(@Window) {
    Win32::GUI::Dialog();
    pop @Window;
}

exit(1);

sub makewindow {
    return if @Window > 4;

    push @Window, Win32::GUI::Window->new(
        -title    => @Window ? "Item: " . @Window : "Main Window",
        -pos     => [10+(@Window*202), 20],
        -size    => [200, 200],
        -onKeyDown   => \&keydown,
    );

    $Window[-1]->Show();

    return;
}

sub keydown {
    my ( $self, undef, $key ) = @_;

    if($key == VK_RIGHT) {
        makewindow();
    }
    elsif($key == VK_LEFT) {
        return -1;
    }
    elsif($key == VK_RETURN) {
        for my $index (0 .. $#Window) {
            if($self == $Window[$index]) {
                $Window[++$index % @Window]->SetFocus();
            }
        }
    }

    return 0;
}
__END__

Regards,
Rob.

Reply via email to