package Win32::GuiTest::Examples; 1; =head1 NAME Win32::GuiTest::Examples - collection of the scripts from eg =head1 Synopsis This module was autogenerated from the files in the eg directory of the distribution. For detailed (cough) documenataion see L. To run the examples either copy-paste them from here or download and unpack the distribution and take the files from the eg directory. =head1 Examples =head2 eg/ask.pl #!perl -w # # Just ask a number of questions on the command line using # the functions provided by Win32::GuiTest::Cmd use strict; use Win32::GuiTest::Cmd ':ALL'; Pause("Press ENTER to start the setup..."); print "GO!\n" if YesOrNo("Setup networking component?"); my $address = AskForIt("What's your new ip address?", "122.122.122.122"); my $dir = AskForDir("Where should I put the new files?", "c:\\temp"); my $exe = AskForExe("Where is your net setup program?", "/foo/bar.exe"); print "\nAddress '$address'\n"; print "Dir '$dir'\n"; print "Exe '$exe'\n"; =head2 eg/calc.pl #!perl -w # # Written by Gabor Szabo # An example how to access the built in calculator (calc.exe) of Windows. # This code assumes your calulator defaults to the Standard view (and not the Scientific) use strict; use Win32::GuiTest qw(:ALL); use Win32; warn "** Warning! calc.exe is very different on Windows 7, probably won't work\n" if Win32::GetOSName =~ /Win7/; if (not @ARGV or ($ARGV[0] ne "keyboard" and $ARGV[0] ne "mouse")) { die "Usage: $0 [keyboard|mouse]\n" } system "start calc.exe"; sleep(1); my @windows = FindWindowLike(undef, "Calculator"); if (not @windows) { die "Could not find Calculator\n"; } if (@windows > 1) { die "There might be more than one Calculators running\n"; } if ($ARGV[0] eq "keyboard") { PushButton '7'; sleep(1); PushButton '\*'; sleep(1); PushButton '5'; sleep(1); PushButton '='; sleep(2); # Catch the content of the first child, # At this point we can only hope that this is the child that holds the result # as it does not have a title, maybe it has a type that we can check ? my @children = GetChildWindows($windows[0]); printf "Result: %s\n", WMGetText($children[0]); SendKeys("%{F4}"); # Alt-F4 to exit } if ($ARGV[0] eq "mouse") { my ($left, $top, $right, $bottom) = GetWindowRect($windows[0]); # find the appropriate child window and click on it my @children = GetChildWindows($windows[0]); foreach my $title (qw(7 * 5 =)) { my ($c) = grep {$title eq GetWindowText($_)} @children; my ($left, $top, $right, $bottom) = GetWindowRect($c); MouseMoveAbsPix(($right+$left)/2,($top+$bottom)/2); SendMouse("{LeftClick}"); sleep(1); } printf "Result: %s\n", WMGetText($children[0]); MouseMoveAbsPix($right-10,$top+10); # this probably depends on the resolution sleep(2); SendMouse("{LeftClick}"); } =head2 eg/excel.pl #!perl -w # use strict; use Win32::GuiTest qw(FindWindowLike GetWindowText SetForegroundWindow); $Win32::GuiTest::debug = 0; # Set to "1" to enable verbose mode # Find top level (1) windows containg Excel in their title my @windows = FindWindowLike(undef, "Excel", "", undef, 1); for (@windows) { print "$_>\t'", GetWindowText($_), "'\n"; } print "------------\n"; # Find all windows matching Microsoft Excel in the title, and XLMAIN$ # as the class. @windows = FindWindowLike(undef, "^Microsoft Excel", "^XLMAIN\$"); for (@windows) { print "$_>\t'", GetWindowText($_), "'\n"; SetForegroundWindow($_); } print "------------\n"; die "You should start Excel before running this example.\n" unless @windows; # Find all children of a specified window. my @children = FindWindowLike($windows[0]); for (@children) { print "$_>\t'", GetWindowText($_), "'\n"; } =head2 eg/excel2.pl #!perl -w # # Exercise Win32::GuiTest using MS-Excel. Will only work with non-localized # versions of Excel (hard-coded hot-keys). # use strict; use Win32::GuiTest qw(FindWindowLike GetWindowText SetForegroundWindow SendKeys); $Win32::GuiTest::debug = 0; # Set to "1" to enable verbose mode my @windows = FindWindowLike(0, "^Microsoft Excel", "^XLMAIN\$"); die "You should start Excel before running this example.\n" unless @windows; print "$windows[0]>\t'", GetWindowText($windows[0]), "'\n\n"; SetForegroundWindow($windows[0]); SendKeys("%fn~{PAUSE 1000}"); SendKeys("Randal, look!{TAB}"); SendKeys("Just{TAB}Another{TAB}Perl{TAB}Hacker{TAB}"); SendKeys("{DOWN}{LEFT 5}This is another test!{TAB}{DOWN}{LEFT}"); SendKeys("I hope we're on cell A3!{ENTER}"); my @xl_children = FindWindowLike($windows[0]); for (@xl_children) { print "$_>\t'", GetWindowText($_), "'\n"; } print "\n"; SendKeys("{PAUSE 2000}%to{PAUSE 2000}"); SendKeys("{ESC}Test finished.{ENTER}"); =head2 eg/fonts.pl #!perl -w # Use Win32::GuiTest to get a list of supported fonts from a # dialog box. # By Ernesto Guisado (erngui@acm.org). use strict; use Win32::GuiTest qw(:ALL); #sub FontTxt { "Fuente"; } # i18n #sub OpenFont { "%ef"; } # i18n # Let's see notepad system("start notepad.exe"); sleep 1; # Open the Font dialog #SendKeys(OpenFont); MenuSelect("F&ormat|&Font"); # this is also language dependent ! sleep(1); # Find the Font dialog using the title and window class # The Font dialog isn't a child of the notepad window #my ($fontdlg) = FindWindowLike(0, FontTxt); my $fontdlg = GetForegroundWindow(); die "We could not fing the Font dialog\n" if not defined $fontdlg; print GetWindowText($fontdlg), "\n\n"; sleep(3); # Find the right combo using it's control id my ($combo) = FindWindowLike($fontdlg, "", "ComboBox", 0x470); die "Where is the combo with the font names?" unless $combo; # Print all the font names for (GetComboContents($combo)) { print "'$_'" . "\n"; } # Close the dialog and notepad SendKeys("{ESC}%{F4}"); =head2 eg/iswindowstyle.pl #!/usr/bin/perl # use Win32::GuiTest qw(:FUNC :LVS); # Test IsWindowStyle() # Get handle to desktop listview. Note: Tested on Win2k and NT4. my ($pm) = FindWindowLike(GetDesktopWindow(), "", "Progman"); my ($sdv) = FindWindowLike($pm, "", "SHELLDLL_DefView"); my ($dlv) = FindWindowLike($sdv, "", "SysListView32"); # Check to see if desktop icons are marked for auto-arrange. if (IsWindowStyle($dlv, LVS_AUTOARRANGE)) { print "Desktop icons are set to auto-arranged.\n"; } else { print "Desktop icons are NOT set to auto-arranged.\n"; ## Code to auto-arrange desktop icons (MouseClick,SendKeys) ## } =head2 eg/keypress.pl #!/usr/bin/perl # This example shows an easy way to check for certain keystrokes. # The IsKeyPressed function takes a string with the name of the key. # This names are the same ones as for SendKeys. use Win32::GuiTest qw(SendKeys IsKeyPressed); # Wait until user presses several specified keys @keys = qw/ESC F5 F11 F12 A B 8 DOWN/; for (@keys) { until (IsKeyPressed($_)) { print "Please press $_...\n"; SendKeys "{PAUSE 200}"; } } =head2 eg/menuselect.pl #!perl -w # Example how to get the names of the menus use strict; use Win32::GuiTest qw(:ALL); system "start notepad"; sleep 1; my $menu = GetMenu(GetForegroundWindow()); print "Menu: $menu\n"; my $submenu = GetSubMenu($menu, 0); print "Submenu: $submenu\n"; print "Count:", GetMenuItemCount($menu), "\n"; use Data::Dumper; my %h = GetMenuItemInfo($menu, 1); # Edit on the main menu print Dumper \%h; %h = GetMenuItemInfo($submenu, 1); # Open in the File menu print Dumper \%h; %h = GetMenuItemInfo($submenu, 4); # Separator in the File menu print Dumper \%h; print "===================\n"; menu_parse($menu); #MenuSelect("&Archivo|&Salir"); # Close the menu and notepad SendKeys("{ESC}%{F4}"); # this function receives a menu id and prints as much information about that menu and # all its submenues as it can # One day we might include this in the distributionor in some helper module sub menu_parse { my ($menu, $depth) = @_; $depth ||= 0; foreach my $i (0..GetMenuItemCount($menu)-1) { my %h = GetMenuItemInfo($menu, $i); print " " x $depth; print "$i "; print $h{text} if $h{type} and $h{type} eq "string"; print "------" if $h{type} and $h{type} eq "separator"; print "UNKNOWN" if not $h{type}; print "\n"; my $submenu = GetSubMenu($menu, $i); if ($submenu) { menu_parse($submenu, $depth+1); } } } SendKeys("%{F4}"); =head2 eg/notepad.pl #!/usr/bin/perl # use Win32::GuiTest; system("start notepad.exe"); sleep 3; Win32::GuiTest::SendKeys("If you're reading this inside notepad,\n"); Win32::GuiTest::SendKeys("we might consider this test succesful.\n"); Win32::GuiTest::SendKeys("Now I'll send notepad an ALT{+}F4 to close\n"); Win32::GuiTest::SendKeys("it. Please wait......."); sleep 1; Win32::GuiTest::SendKeys("."); sleep 1; Win32::GuiTest::SendKeys("."); sleep 1; Win32::GuiTest::SendKeys("."); Win32::GuiTest::SendKeys("%{F4}{TAB}{ENTER}"); =head2 eg/notepad_text.pl #!perl -w # If you have a notepad window open this prints the contents. use strict; use Win32::GuiTest qw(FindWindowLike WMGetText); my @windows = FindWindowLike(0, "", "Notepad"); die "More than one notepad open\n" if @windows > 1; die "No notepad is running, please open one with some text in it.\n" if not @windows; my $notepad = $windows[0]; my @edits = FindWindowLike($notepad, "", "Edit"); die "More than one edit inside notepad: " . @edits . "\n" if @edits > 1; die "No edit window found inside notepad\n" if not @edits; print "----------------------------------------------------------\n"; print WMGetText($edits[0]); print "\n"; print "----------------------------------------------------------\n"; =head2 eg/paint.pl #!perl -w # Draw triangles in MS Paint. use strict; use Win32::GuiTest qw(:ALL); system("start /max mspaint"); sleep 2; my @windows = FindWindowLike(0, "Paint", ""); die "Could not find Paint\n" if not @windows; SetForegroundWindow($windows[0]); sleep 1; # totaly guess work about the location of the area where one can draw. # A better guess would be welcome MouseMoveAbsPix((GetWindowRect($windows[0]))[0,1]); SendMouse ( "{REL50,50}" ); # Using high-level functions SendMouse ( "{LEFTDOWN}" ); for (1..100) { SendMouse ( "{REL1,1}" ); } for (1..100) { SendMouse ( "{REL1,-1}" ); } for (1..200) { SendMouse ( "{REL-1,0}" ); } SendMouse ( "{LEFTUP}" ); # Using low level functions SendMouseMoveRel(5,20); SendLButtonDown(); for (1..100) { SendMouseMoveRel(1,1); } for (1..100) { SendMouseMoveRel(1,-1); } for (1..200) { SendMouseMoveRel(-1,0); } SendLButtonUp(); =head2 eg/paint_abs.pl #!perl -w # # Draw an X and a box around it # use strict; use Win32::GuiTest qw(FindWindowLike SetForegroundWindow SendMouse MouseMoveAbsPix SendLButtonDown SendLButtonUp); system("start /max mspaint"); sleep 2; my @windows = FindWindowLike(0, "Paint", ""); die "Could not find Paint\n" if not @windows; SetForegroundWindow($windows[0]); sleep 1; #Using low level functions MouseMoveAbsPix(100,100); SendLButtonDown(); MouseMoveAbsPix(300,300); SendLButtonUp(); sleep 1; MouseMoveAbsPix(100,300); SendLButtonDown(); MouseMoveAbsPix(300,100); SendLButtonUp(); sleep 1; MouseMoveAbsPix(100,100); SendLButtonDown(); MouseMoveAbsPix(300,100); MouseMoveAbsPix(300,300); MouseMoveAbsPix(100,300); MouseMoveAbsPix(100,100); SendLButtonUp(); =head2 eg/pushbutton.pl #!/usr/bin/perl # use strict; use Win32::GuiTest qw(PushButton FindWindowLike SetForegroundWindow SendKeys WaitWindow IsWindow); # Test PushButton() # Remove old saved document unlink("C:\\temp\\PushButton.txt"); system("start notepad.exe"); my @windows = WaitWindow("Untitled - Notepad"); #my @windows = WaitWindow(" - Bloc de notas"); die unless scalar @windows == 1 && IsWindow($windows[0]); SetForegroundWindow($windows[0]); SendKeys("Sample Text\n"); SendKeys("%{F4}"); # Push Yes button to save document PushButton("Yes"); #PushButton("Sí"); # Type Filename SendKeys("C:\\temp\\PushButton.txt"); # Push &Save to save and exit PushButton("&Save"); #PushButton("&Guardar"); =head2 eg/rawkey.pl #!/usr/bin/perl # use Win32::GuiTest qw(:FUNC :VK); while (1) { SendRawKey(VK_DOWN, KEYEVENTF_EXTENDEDKEY); SendKeys "{PAUSE 200}"; } =head2 eg/selecttabitem.pl #!/usr/bin/perl # use Win32::GuiTest qw(GetWindowID GetChildWindows GetWindowText GetForegroundWindow PostMessage PushButton SendKeys SelectTabItem); use Win32::GuiTest::Cmd qw(System); # Test # Open System Properties # Tested on Win2k an NT4 System(); #system("start RunDLL32.exe shell32,Control_RunDLL sysdm.cpl,\@0,2"); sleep(2); # Select various items on tab control # Using Window ID SelectTabItem(12320, 0); sleep(1); SelectTabItem(12320, 2); sleep(1); SelectTabItem(12320, 1); sleep(1); #PushButton("^Cancel"); SendKeys("{ESC}"); =head2 eg/showcpl.pl #!/usr/bin/perl # Shows how to open control panel apps programmatically # use Win32::GuiTest::Cmd qw( Accessibility AppWizard Console DateTime Display Exchange Internet Joystick Modem Mouse Multimedia Network Odbc Pcmcia Ports Ras Regional Server System Telephony Ups Users); use Win32::GuiTest qw(SendKeys); Modem(); sleep 1; SendKeys("%{F4}"); Network();sleep 1; SendKeys("%{F4}"); Console();sleep 1; SendKeys("%{F4}"); Accessibility();sleep 1; SendKeys("%{F4}"); AppWizard(); sleep 1; SendKeys("%{F4}"); Pcmcia(); sleep 1; SendKeys("%{F4}"); Regional(); sleep 1; SendKeys("%{F4}"); Joystick(); sleep 1; SendKeys("%{F4}"); Mouse(); sleep 1; SendKeys("%{F4}"); Multimedia(); sleep 1; SendKeys("%{F4}"); Odbc(); sleep 1; SendKeys("%{F4}"); Ports(); sleep 1; SendKeys("%{F4}"); Server(); sleep 1; SendKeys("%{F4}"); System(); sleep 1; SendKeys("%{F4}"); Telephony();sleep 1; SendKeys("%{F4}"); DateTime();sleep 1; SendKeys("%{F4}"); Ups();sleep 1; SendKeys("%{F4}"); Internet(); sleep 1; SendKeys("%{F4}"); Display(); sleep 1; SendKeys("%{F4}"); Ras(); sleep 1; SendKeys("%{F4}"); Users(); sleep 1; SendKeys("%{F4}"); =head2 eg/showmouse.pl #!/usr/bin/perl # This script has been written by Jarek Jurasz jurasz@imb.uni-karlsruhe.de use Win32::GuiTest qw(GetCursorPos); while (1) { ($x, $y) = GetCursorPos(); print "\rx:$x y:$y "; sleep 1; } =head2 eg/showwin.pl #!/usr/bin/perl # This script has been written by Jarek Jurasz jurasz@imb.uni-karlsruhe.de # selectively show/hide a group of windows # side effect: showing the window activates it use Win32::GuiTest qw(:ALL :SW); $name = shift; $show = shift; $class = undef; die < 0) { ShowWindow($win, SW_SHOW) unless (IsWindowVisible($win)); # EnableWindow($win, 1); } elsif ($show < 0) { ShowWindow($win, SW_HIDE) if (IsWindowVisible($win)); } dumpwin($win); } sub dumpwin { my $win = shift; print "Null handle\n", return unless ($win); print "$win>\tt:", GetWindowText($win), " c:", GetClassName($win); print " vis:", IsWindowVisible($win); print " en:", IsWindowEnabled($win); print "\n"; } =head2 eg/spy--.pl #!/usr/bin/perl # MS has a very nice tool (Spy++). # This is Spy-- # use Win32::GuiTest qw(FindWindowLike GetWindowText GetClassName GetChildDepth GetDesktopWindow); for (FindWindowLike()) { $s = sprintf("0x%08X", $_ ); $s .= ", '" . GetWindowText($_) . "', " . GetClassName($_); print "+" x GetChildDepth(GetDesktopWindow(), $_), $s, "\n"; } =head2 eg/spy.pl #!perl -w use strict; # Based on the spy--.pl within the distribution # Parse a subtree of the whole windoing systme and print as much information as possible # about each window and each object. # This software is in a very early stage. Its options and output format will change a lot. # Your input is welcome ! # Written by Gabor Szabo my $VERSION = "0.02"; use Getopt::Long; use Win32::GuiTest qw(:ALL); my %opts; GetOptions(\%opts, "help", "title=s", "all", "id=i", "class=s"); usage() if $opts{help} or not %opts; my %seen; my $desktop = GetDesktopWindow(); my $root = 0; my $start; $start = 0 if $opts{all}; $start = $opts{id} if $opts{id}; if ($opts{title} or $opts{class}) { my @windows = FindWindowLike(0, $opts{title}, $opts{class}); #my @windows = FindWindowLike(0, $opts{title}) if $opts{title}; #@windows = FindWindowLike(0, '', $opts{class}) if $opts{class}; if (@windows > 1) { print "There are more than one window that fit:\n"; foreach my $w (@windows) { printf "%s | %s | %s\n", $w, GetClassName($w), GetWindowText($w); } exit; } die "Did not find such a window." if not @windows; $start = $windows[0]; } usage() if not defined $start; my $format = "%-10s %-10s, '%-25s', %-10s, Rect:%-3s,%-3s,%-3s,%-3s '%s'\n"; printf $format, "Depth", "WindowID", "ClassName", "ParentID", "WindowRect","","","", "WindowText"; parse_tree($start); sub GetImmediateChildWindows { my $WinID = shift; grep {GetParent($_) eq $WinID} GetChildWindows $WinID; } sub parse_tree { my $w = shift; if ($seen{$w}++) { print "loop $w\n"; return; } prt($w); #foreach my $child (GetChildWindows($w)) { # parse_tree($child); #} foreach my $child (GetImmediateChildWindows($w)) { print "------------------\n" if $w == 0; parse_tree($child); } } # GetChildDepth is broken so here is another version, this might work better. # returns the real distance between two windows # returns 0 if the same windows were provides # returns -1 if one of the values is not a valid window # returns -2 if the given "ancestor" is not really an ancestor of the given "descendant" sub MyGetChildDepth { my ($ancestor, $descendant) = @_; return -1 if $ancestor and (not IsWindow($ancestor) or not IsWindow($descendant)); return 0 if $ancestor == $descendant; my $depth = 0; while ($descendant = GetParent($descendant)) { $depth++; last if $ancestor == $descendant; } return $depth + 1 if $ancestor == 0; } sub prt { my $w = shift; my $depth = MyGetChildDepth($root, $w); printf $format, (0 <= $depth ? "+" x $depth : $depth), $w, ($w ? GetClassName($w) : ""), ($w ? GetParent($w) : "n/a"), ($w ? GetWindowRect($w) : ("n/a", "", "", "")), ($w ? GetWindowText($w) : ""); } sub usage { print "Version: v$VERSION\n"; print "Usage:\n"; print " $0 --help\n"; print " $0 --all\n"; print " $0 --title TITLE\n"; print "\n"; print "As the output is quite verbose, probably you'll want to redirect \n"; print "the output to a file: $0 options > out.txt\n"; print "\n"; exit; } =head2 eg/start.pl #!/usr/bin/perl # Disclaimer: I tried this on my WindowsXP, # Other Windows, or other configurations might place the "Run" option # of the "Start" menu in different place so before running this script # make sure that your version of Windows will bring you to the "Run" option # if you press the left windows key and then the Up key 3 times. # Written by Gabor Szabo use Win32::GuiTest; # open the Start menu by pressing the Left Windows Key # and then close it by hitting ESC. Win32::GuiTest::SendKeys("{LWI}"); sleep 2; Win32::GuiTest::SendKeys("{ESC}"); # Check out the version of your perl by opening a cmd.exe and typing perl -v # the sleep 1; lines were added only so the viewer can observe the process # you could actually send all the keys in one SendKeys call. Win32::GuiTest::SendKeys("{LWI}"); sleep 1; Win32::GuiTest::SendKeys("{UP}"); sleep 1; Win32::GuiTest::SendKeys("{UP}"); sleep 1; Win32::GuiTest::SendKeys("{UP}"); sleep 1; Win32::GuiTest::SendKeys("{ENTER}"); sleep 1; Win32::GuiTest::SendKeys("cmd{ENTER}"); sleep 1; Win32::GuiTest::SendKeys("perl -v"); sleep 1; Win32::GuiTest::SendKeys("{ENTER}"); sleep 1; Win32::GuiTest::SendKeys("exit"); sleep 1; Win32::GuiTest::SendKeys("{ENTER}"); =head2 eg/tab.pl #!/usr/bin/perl # use Win32::GuiTest qw(:FUNC :VK); SendRawKey(VK_MENU, 0); SendKeys("{TAB}{PAU 1000}{TAB}{PAU 1000}{TAB}"); SendRawKey(VK_MENU, KEYEVENTF_KEYUP); =head2 eg/waitwindow.pl #!/usr/bin/perl # Slightly modified from version submitted by anonymous contributor. # use strict; use Win32::GuiTest qw(IsWindow FindWindowLike SendKeys PushButton WaitWindow); # Test WaitWindow() # en i18n constants sub SOL { "^Solitaire" } sub GAME { "%G" } sub OPT { "O" } sub OPTIONS { "^Options" } sub CANCEL { "Cancel" } # es i18n constants #sub SOL { "^Solitario" } #sub GAME { "%J" } #sub OPT { "O" } #sub OPTIONS { "^Opciones" } #sub CANCEL { "Cancelar" } # Open program system("start sol.exe"); # Wait for program window to appear. die "Couldn't open solitaire program!\n" unless WaitWindow(SOL); # Select game menu SendKeys(GAME); # Open options menu SendKeys(OPT); # Wait for options menu to appear for up to 5 seconds. WaitWindow(OPTIONS, 5); # Close options menu PushButton(CANCEL); # Close program SendKeys("%{F4}"); =head2 eg/which.pl #!/usr/bin/perl # Similar to UNIX which command. # # On my NT box: # # D:\src\perl\win32-guitest>eg\which.pl perl # D:\perl\bin\perl.EXE # D:\src\perl\win32-guitest>eg\which.pl regedit # C:\WINNT\regedit.EXE # D:\src\perl\win32-guitest>eg\which.pl notepad # C:\WINNT\system32\notepad.EXE # D:\src\perl\win32-guitest> # use strict; use Win32::GuiTest::Cmd qw(WhichExe); print WhichExe(shift); =head2 eg/winbmp.pl #!/usr/bin/perl # This script has been written by Jarek Jurasz jurasz@imb.uni-karlsruhe.de # Save a given window as BMP file # Copy the contents to the clipboard use Win32::GuiTest qw(:ALL); ($w) = FindWindowLike(0, "^Calc"); $w = GetDesktopWindow unless $w; $ds = new Win32::GuiTest::DibSect; $ds->CopyWindow($w); #$ds->CopyClient(GetDesktopWindow(), \@{[GetWindowRect($w)]}); # $ds->Invert(); #$ds->CopyClient(GetDesktopWindow(), \@{[GetWindowRect($w)]}); # $ds->Invert(); #$ds->ToGrayScale(); $ds->SaveAs("bla.bmp"); $ds->ToClipboard(); =head2 eg/wptr.pl #!/usr/bin/perl # # Module Pragmas use strict; use warnings; # Module Imports use Win32::GuiTest qw(GetCursorPos GetClassName GetWindowText GetWindowRect WindowFromPoint GetWindowID IsKeyPressed WMGetText); use Win32::Clipboard; # Module Level Variables my $Clip = Win32::Clipboard(); my $cur_info = ""; my $oldhwnd = 0; my $oldcx = 0; my $oldcy = 0; # Core Loop while (1) { my ($cx, $cy) = GetCursorPos(); # Is different cursor position? if ( ($cx != $oldcx) || ($cy != $oldcy) ) { $oldcx = $cx; $oldcy = $cy; # Get handle of window my $hwnd = WindowFromPoint($cx, $cy); if ($hwnd == $oldhwnd) { # Same window as before, don't query information again. next; } # Different window, so cache the handle value. $oldhwnd = $hwnd; # Get information for the new window in which the cursor is over. $cur_info = GetWindowInfo($hwnd); ClearScreen(); # Output window information to console. DispWindowInfo($cur_info); # Display menu. DispMenu(); } # INSERT to copy window data to clipboard. if (IsKeyPressed("INS")) { $Clip->Empty(); $Clip->Set($cur_info); select(undef, undef, undef, 0.50); print "Copied data to clipboard.\n"; } # ESCAPE to exit this program. if (IsKeyPressed("ESC")) { print "Goodbye!\n"; last; } } sub ClearScreen { system("command /c cls"); return; } sub GetWindowInfo { my $hwnd = shift; my $info = "# Window Text: '" . GetWindowText($hwnd) . "'\r\n"; $info = $info . "# Window Class: '" . GetClassName($hwnd) . "'\r\n"; $info = $info . "# Window ID: " . GetWindowID($hwnd) . "\r\n"; my ($left, $top, $right, $bottom) = GetWindowRect($hwnd); $info = $info . "# Window Rect: ($left, $top) - ($right, $bottom)\r\n"; print "Text: " . WMGetText($hwnd) . "\r\n"; return($info); } sub DispWindowInfo { print shift; return; } sub DispMenu { print "\n\nPress to copy window text to clipboard.\n"; print "Press to exit program.\n"; return; } =cut