From: Piotr K. <pka...@pi...> - 2005-10-06 13:34:38
|
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? --Piotr |
From: Jeremy W. <jez...@ho...> - 2005-10-06 13:49:27
|
>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? Interesting question. As a quick/dirty answer, yes it could be possible. The basic problem is that when Win::GUI object's are destroyed the underlying window handle is also "destroyed".This could be solved by having some sort of flag to say if Win::GUI actually owns the object or not. As I type I'm starting to think of other issues - but I'm sure work arounds could be found. What kind of methods/functions would you want to call on these objects? Cheers, jez |
From: Jeremy W. <jez...@ho...> - 2005-10-06 14:17:16
|
Hummm replying to my own post:) >>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? > >Interesting question. As a quick/dirty answer, yes it could be possible. >The basic problem is that when Win::GUI object's are destroyed the >underlying window handle is also "destroyed".This could be solved by having >some sort of flag to say if Win::GUI actually owns the object or not. Ok - the above is true when we're using objects via method calls but most of the internals can also be called as functions. For example: $win->Show(); #shows the window but we could also call it this way: Win32::GUI::Show($win); Where $win is a Win32::GUI object OR the handle...So, if you've got a handle for some other app, then it should just work... Hope that makes some sense. Cheers, jez. |
From: Robert M. <rm...@po...> - 2005-10-06 21:08:27
|
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; } |