Piotr Kaluski wrote:
Hi,
I am one of developers of Win32::GuiTest library. It is a module for GUI
test automation. I am actually pretty impressed with all the great work
you have done. Using your module should free us from writing some
functions ourselves.
I have one question. My impression is, that your library is object
oriented and it assumes, that a script using it has actually created all
windows it manipulates. Is it possible to attach to a window/control
created by some other application? Say I have a handle of a main window of
Windows calculator. How do I turn it into Win::GUI object?

Firstly I'd like to iterate Jeremy's reply that most of the method calls in Win32::GUI (and especially the ones that have underlying w32api calls that operate on handles) are overloaded, so that they can be called statically with an extra first parameter that is a window handle, so Win32::GUI is not limited to working with objects that it created itself. At the bottom is a (rather messy and hastily thrown together) script that enumerates the windows you have on your desktop, and allows you to minimise/restore then, showing how this can be done. This usage is also touched on in Part 1 of the tutorial (http://perl-win32-gui.sourceforge.net/docs/Win32/GUI/Tutorial/Part1.html#centring_the_window_and_the_text)

It is an interesting time for this conversation to come up, as we have been touching the subject of testing on the hackers list a few times in recent months, and if you were to look in the TODO file in CVS you would see that I added a comment yesterday that I was leaning towards a Win32::GUI::Test package. I have not discussed my reasoning yet (and my position is still forming) but I'll try to outline my thinking. Please bear in mind that I haven't given Win32::GuiTest more than a cursory glance yet, and that nothing is set in stone.

(1) As a Win32::GUI developer I am primarily looking at a package that will simplify writing tests for the Win32::GUI distribution. That said, our users would almost certainly benefit from a well written test package for testing their own applications.

(2) Whatever package we end up with must be readily usable within the standard perl test framework: this means being able to write tests that run under the Test::Harness framework, and can be invoked using 'make test' and 'prove'.

(3) I'd prefer not to have to make an external package a pre-requsite for building and testing Win32::GUI - but will continue to consider it as I have no desire to re-generate good work that has already been done by someone else. I would be very interested in seeing a list of the win32api functions that Win32::GuiTest uses, so that we could see how much we would need to add to Win32::GUI to get the same functionality. As Ariel points out in his reply there are certainly calls missing from Win32::GUI - things that I am sure we would need that spring to mind are EnumWindows, EnumChildWindows and FindWindowEx - but these and others really should be in Win32::GUI, so I'd have no problems adding them.

So, from a Win32:GUI point of view I would think that building Win32::Gui::Test on top of the existing Win32::GUI framework makes a lot of sense. From a Win32::GuiTest point of view I think there needs to be some thought as to whether having it installable as a separate module, without Win32::GUI makes sense - as has already been mentioned, Win32::GUI is not a small download, and may be rather heavy-weight for someone looking for a test framework to test Win32 paps built in other environments.

Regards,
Rob.

#!perl -w
use strict;
use warnings;

use Win32::GUI;

my $winInfo;
my $selHwnd = 0;

my $mw = Win32::GUI::DialogBox->new(
        -title => $0,
        -pos   => [100,100],
        -size  => [300,100],
        -helpbutton  => 0,
);

my $c = $mw->AddCombobox(
        -pos      => [10,10],
        -size     => [$mw->ScaleWidth()-20,100],
        -sort     => 1,
        -vscroll  => 1,
        -onChange => \&Select,
        -dropdownlist => 1,
);

$mw->AddButton(
        -text    => "Refresh",
        -pos     => [10, $mw->ScaleHeight()-30],
        -size    => [60,20],
        -onClick => sub {populateCombo($c); 0;},
);

my $b = $mw->AddButton(
        -text    => "Minimize",
        -pos     => [$mw->ScaleWidth()-70, $mw->ScaleHeight()-30],
        -size    => [60,20],
        -onClick => \&Action,
);

populateCombo($c);
$mw->Show();
Win32::GUI::Dialog();
exit(0);

sub populateCombo
{
        my $c = shift;

        $selHwnd = 0;
        $b->Enable(0);
        $winInfo = WindowList();

        $c->Clear();
        for my $w (keys %$winInfo) {
                $c->Add($w);
        }
}

sub WindowList
{
        my %windows;

        # walk all the top level windows (immediate children of desktop):
        my $hwnd = Win32::GUI::GetDesktopWindow();
        my $mode = GW_CHILD;
        while( $hwnd = Win32::GUI::GetWindow($hwnd, $mode) ) {
                $mode = GW_HWNDNEXT;
                next unless Win32::GUI::IsWindow($hwnd);
                next unless Win32::GUI::IsVisible($hwnd);
                my $text = Win32::GUI::Text($hwnd);
                $windows{$text} = $hwnd if length($text) > 0;
        }

        return \%windows;
}

sub Action
{
        my $b = shift;

        return unless Win32::GUI::IsWindow($selHwnd);

        if($b->Text() eq "Minimize") {
                Win32::GUI::Minimize($selHwnd);
        }
        else {
                Win32::GUI::Restore($selHwnd);
        }
        $b->Text( Win32::GUI::IsIconic($selHwnd) ? "Restore" : "Minimize" );

    return;
}

sub Select
{
        my $c = shift;
        $selHwnd = $winInfo->{$c->GetLBText($c->GetCurSel())};

        return unless Win32::GUI::IsWindow($selHwnd);

        $b->Enable(1);
        $b->Text( Win32::GUI::IsIconic($selHwnd) ? "Restore" : "Minimize" );
        
        return;
}


Reply via email to