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<Win32::GuiTest>.
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
    
    # $Id: ask.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    # 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
    
    #$Id: calc.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    # Written by Gabor Szabo <gabor@pti.co.il>
    # 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);
    
    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
    # $Id: excel.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    
    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
    
    # $Id: excel2.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    # 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
    # $Id: fonts.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: iswindowstyle.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    
    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
    # $Id: keypress.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: menuselect.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    
    # 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
    # $Id: notepad.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    
    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
    # $Id: notepad_text.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: paint.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: paint_abs.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    # 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
    # $Id: pushbutton.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    
    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
    # $Id: rawkey.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    
    use Win32::GuiTest qw(:FUNC :VK);
    
    while (1) {
        SendRawKey(VK_DOWN, KEYEVENTF_EXTENDEDKEY); 
        SendKeys "{PAUSE 200}";
    }

=head2 eg/selecttabitem.pl

    #!/usr/bin/perl
    # $Id: selecttabitem.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    
    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
    # $Id: showcpl.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: showmouse.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: showwin.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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 <<EOT unless $name;
    Usage: $0 "^Title" [+1|-1]
    +1 show windows
    -1 hide windows
     0 or empty show status
    Be careful when using bare title words: when running the script, the title of 
    the console will change and include the title words, too...
    EOT
    
    
    # $name = "^Microsoft Excel" unless $name;
    my @win = FindWindowLike(0, $name, $class);
    
    showall(@win);
    
    sub showall
    {
      my @win = @_;
      for $win (@win)
      {
        # should normally be only one
        show($win);
        # children
        # showall(FindWindowLike($win, undef, undef));
      }
    }
    
    sub show
    {
      my $win = shift;
    
      # dumpwin($win);
      if ($show > 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
    # $Id: spy--.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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 <gabor@pti.co.il>
    
    # $Id: spy.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    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
    # $Id: start.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    
    # 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 <gabor@pti.co.il>
    
    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
    # $Id: tab.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    
    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
    # $Id: waitwindow.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: which.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: winbmp.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    # 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
    # $Id: wptr.pl,v 1.1.1.1 2007/10/05 08:30:20 dk Exp $
    #
    
    # 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 <INSERT> to copy window text to clipboard.\n";
    	print "Press <ESCAPE> to exit program.\n";
    	return;
    }



=cut

