home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 June / PCWorld_2005-06_cd.bin / software / vyzkuste / firewally / firewally.exe / framework-2.3.exe / GUI.pm < prev    next >
Text File  |  2004-01-12  |  98KB  |  3,048 lines

  1. ###############################################################################
  2. #
  3. # Win32::GUI - Perl-Win32 Graphical User Interface Extension
  4. #
  5. # 29 Jan 1997 by Aldo Calpini <dada@perl.it>
  6. #
  7. # Version: 0.0.665 (27 Feb 2002)
  8. #
  9. # Copyright (c) 1997..2002 Aldo Calpini. All rights reserved.
  10. # This program is free software; you can redistribute it and/or
  11. # modify it under the same terms as Perl itself.
  12. #
  13. # $Id: GUI.pm,v 1.5 2003/12/28 07:17:42 caelum Exp $
  14. #
  15. ###############################################################################
  16. package Win32::GUI;
  17.  
  18. eval { require Win32 };
  19. require Exporter;       # to export the constants to the main:: space
  20. require DynaLoader;     # to dynuhlode the module.
  21.  
  22. # Reserves GUI in the main namespace for us (uhmmm...)
  23. *GUI:: = \%Win32::GUI::;
  24.  
  25. ###############################################################################
  26. # STATIC OBJECT PROPERTIES
  27. #
  28. $VERSION             = "0.0.670";
  29. $MenuIdCounter       = 1;
  30. $TimerIdCounter      = 1;
  31. $NotifyIconIdCounter = 1;
  32. %Menus               = ();
  33. %Accelerators        = ();
  34. $AcceleratorCounter  = 9001;
  35.  
  36. @ISA = qw( Exporter DynaLoader );
  37. @EXPORT = qw(
  38.     BS_3STATE
  39.     BS_AUTO3STATE
  40.     BS_AUTOCHECKBOX
  41.     BS_AUTORADIOBUTTON
  42.     BS_CHECKBOX
  43.     BS_DEFPUSHBUTTON
  44.     BS_GROUPBOX
  45.     BS_LEFTTEXT
  46.     BS_NOTIFY
  47.     BS_OWNERDRAW
  48.     BS_PUSHBUTTON
  49.     BS_RADIOBUTTON
  50.     BS_USERBUTTON
  51.     BS_BITMAP
  52.     BS_BOTTOM
  53.     BS_CENTER
  54.     BS_ICON
  55.     BS_LEFT
  56.     BS_MULTILINE
  57.     BS_RIGHT
  58.     BS_RIGHTBUTTON
  59.     BS_TEXT
  60.     BS_TOP
  61.     BS_VCENTER
  62.  
  63.     COLOR_3DFACE
  64.     COLOR_ACTIVEBORDER
  65.     COLOR_ACTIVECAPTION
  66.     COLOR_APPWORKSPACE
  67.     COLOR_BACKGROUND
  68.     COLOR_BTNFACE
  69.     COLOR_BTNSHADOW
  70.     COLOR_BTNTEXT
  71.     COLOR_CAPTIONTEXT
  72.     COLOR_GRAYTEXT
  73.     COLOR_HIGHLIGHT
  74.     COLOR_HIGHLIGHTTEXT
  75.     COLOR_INACTIVEBORDER
  76.     COLOR_INACTIVECAPTION
  77.     COLOR_MENU
  78.     COLOR_MENUTEXT
  79.     COLOR_SCROLLBAR
  80.     COLOR_WINDOW
  81.     COLOR_WINDOWFRAME
  82.     COLOR_WINDOWTEXT
  83.  
  84.     DS_3DLOOK
  85.     DS_ABSALIGN
  86.     DS_CENTER
  87.     DS_CENTERMOUSE
  88.     DS_CONTEXTHELP
  89.     DS_CONTROL
  90.     DS_FIXEDSYS
  91.     DS_LOCALEDIT
  92.     DS_MODALFRAME
  93.     DS_NOFAILCREATE
  94.     DS_NOIDLEMSG
  95.     DS_RECURSE
  96.     DS_SETFONT
  97.     DS_SETFOREGROUND
  98.     DS_SYSMODAL
  99.  
  100.     DTS_UPDOWN
  101.     DTS_SHOWNONE
  102.     DTS_SHORTDATEFORMAT
  103.     DTS_LONGDATEFORMAT
  104.     DTS_TIMEFORMAT
  105.     DTS_APPCANPARSE
  106.     DTS_RIGHTALIGN
  107.  
  108.     ES_AUTOHSCROLL
  109.     ES_AUTOVSCROLL
  110.     ES_CENTER
  111.     ES_LEFT
  112.     ES_LOWERCASE
  113.     ES_MULTILINE
  114.     ES_NOHIDESEL
  115.     ES_NUMBER
  116.     ES_OEMCONVERT
  117.     ES_PASSWORD
  118.     ES_READONLY
  119.     ES_RIGHT
  120.     ES_UPPERCASE
  121.     ES_WANTRETURN
  122.  
  123.     GW_CHILD
  124.     GW_HWNDFIRST
  125.     GW_HWNDLAST
  126.     GW_HWNDNEXT
  127.     GW_HWNDPREV
  128.     GW_OWNER
  129.  
  130.     IMAGE_BITMAP
  131.     IMAGE_CURSOR
  132.     IMAGE_ICON
  133.  
  134.     LR_DEFAULTCOLOR
  135.     LR_MONOCHROME
  136.     LR_COLOR
  137.     LR_COPYRETURNORG
  138.     LR_COPYDELETEORG
  139.     LR_LOADFROMFILE
  140.     LR_LOADTRANSPARENT
  141.     LR_DEFAULTSIZE
  142.     LR_LOADMAP3DCOLORS
  143.     LR_CREATEDIBSECTION
  144.     LR_COPYFROMRESOURCE
  145.     LR_SHARED
  146.  
  147.     MB_ABORTRETRYIGNORE
  148.     MB_OK
  149.     MB_OKCANCEL
  150.     MB_RETRYCANCEL
  151.     MB_YESNO
  152.     MB_YESNOCANCEL
  153.     MB_ICONEXCLAMATION
  154.     MB_ICONWARNING
  155.     MB_ICONINFORMATION
  156.     MB_ICONASTERISK
  157.     MB_ICONQUESTION
  158.     MB_ICONSTOP
  159.     MB_ICONERROR
  160.     MB_ICONHAND
  161.     MB_DEFBUTTON1
  162.     MB_DEFBUTTON2
  163.     MB_DEFBUTTON3
  164.     MB_DEFBUTTON4
  165.     MB_APPLMODAL
  166.     MB_SYSTEMMODAL
  167.     MB_TASKMODAL
  168.     MB_DEFAULT_DESKTOP_ONLY
  169.     MB_HELP
  170.     MB_RIGHT
  171.     MB_RTLREADING
  172.     MB_SETFOREGROUND
  173.     MB_TOPMOST
  174.     MB_SERVICE_NOTIFICATION
  175.     MB_SERVICE_NOTIFICATION_NT3X
  176.  
  177.     MF_STRING
  178.     MF_POPUP
  179.  
  180.     SM_ARRANGE
  181.     SM_CLEANBOOT
  182.     SM_CMOUSEBUTTONS
  183.     SM_CXBORDER
  184.     SM_CYBORDER
  185.     SM_CXCURSOR
  186.     SM_CYCURSOR
  187.     SM_CXDLGFRAME
  188.     SM_CYDLGFRAME
  189.     SM_CXDOUBLECLK
  190.     SM_CYDOUBLECLK
  191.     SM_CXDRAG
  192.     SM_CYDRAG
  193.     SM_CXEDGE
  194.     SM_CYEDGE
  195.     SM_CXFIXEDFRAME
  196.     SM_CYFIXEDFRAME
  197.     SM_CXFRAME
  198.     SM_CYFRAME
  199.     SM_CXFULLSCREEN
  200.     SM_CYFULLSCREEN
  201.     SM_CXHSCROLL
  202.     SM_CYHSCROLL
  203.     SM_CXHTHUMB
  204.     SM_CXICON
  205.     SM_CYICON
  206.     SM_CXICONSPACING
  207.     SM_CYICONSPACING
  208.     SM_CXMAXIMIZED
  209.     SM_CYMAXIMIZED
  210.     SM_CXMAXTRACK
  211.     SM_CYMAXTRACK
  212.     SM_CXMENUCHECK
  213.     SM_CYMENUCHECK
  214.     SM_CXMENUSIZE
  215.     SM_CYMENUSIZE
  216.     SM_CXMIN
  217.     SM_CYMIN
  218.     SM_CXMINIMIZED
  219.     SM_CYMINIMIZED
  220.     SM_CXMINSPACING
  221.     SM_CYMINSPACING
  222.     SM_CXMINTRACK
  223.     SM_CYMINTRACK
  224.     SM_CXSCREEN
  225.     SM_CYSCREEN
  226.     SM_CXSIZE
  227.     SM_CYSIZE
  228.     SM_CXSIZEFRAME
  229.     SM_CYSIZEFRAME
  230.     SM_CXSMICON
  231.     SM_CYSMICON
  232.     SM_CXSMSIZE
  233.     SM_CYSMSIZE
  234.     SM_CXVSCROLL
  235.     SM_CYVSCROLL
  236.     SM_CYCAPTION
  237.     SM_CYKANJIWINDOW
  238.     SM_CYMENU
  239.     SM_CYSMCAPTION
  240.     SM_CYVTHUMB
  241.     SM_DBCSENABLED
  242.     SM_DEBUG
  243.     SM_MENUDROPALIGNMENT
  244.     SM_MIDEASTENABLED
  245.     SM_MOUSEPRESENT
  246.     SM_MOUSEWHEELPRESENT
  247.     SM_NETWORK
  248.     SM_PENWINDOWS
  249.     SM_SECURE
  250.     SM_SHOWSOUNDS
  251.     SM_SLOWMACHINE
  252.     SM_SWAPBUTTON
  253.  
  254.     WM_CREATE
  255.     WM_DESTROY
  256.     WM_MOVE
  257.     WM_SIZE
  258.     WM_ACTIVATE
  259.     WM_SETFOCUS
  260.     WM_KILLFOCUS
  261.     WM_ENABLE
  262.     WM_SETREDRAW
  263.     WM_COMMAND
  264.     WM_KEYDOWN
  265.     WM_SETCURSOR
  266.     WM_KEYUP
  267.  
  268.     WS_BORDER
  269.     WS_CAPTION
  270.     WS_CHILD
  271.     WS_CHILDWINDOW
  272.     WS_CLIPCHILDREN
  273.     WS_CLIPSIBLINGS
  274.     WS_DISABLED
  275.     WS_DLGFRAME
  276.     WS_GROUP
  277.     WS_HSCROLL
  278.     WS_ICONIC
  279.     WS_MAXIMIZE
  280.     WS_MAXIMIZEBOX
  281.     WS_MINIMIZE
  282.     WS_MINIMIZEBOX
  283.     WS_OVERLAPPED
  284.     WS_OVERLAPPEDWINDOW
  285.     WS_POPUP
  286.     WS_POPUPWINDOW
  287.     WS_SIZEBOX
  288.     WS_SYSMENU
  289.     WS_TABSTOP
  290.     WS_THICKFRAME
  291.     WS_TILED
  292.     WS_TILEDWINDOW
  293.     WS_VISIBLE
  294.     WS_VSCROLL
  295.  
  296.     WS_EX_ACCEPTFILES
  297.     WS_EX_APPWINDOW
  298.     WS_EX_CLIENTEDGE
  299.     WS_EX_CONTEXTHELP
  300.     WS_EX_CONTROLPARENT
  301.     WS_EX_DLGMODALFRAME
  302.     WS_EX_LEFT
  303.     WS_EX_LEFTSCROLLBAR
  304.     WS_EX_LTRREADING
  305.     WS_EX_MDICHILD
  306.     WS_EX_NOPARENTNOTIFY
  307.     WS_EX_OVERLAPPEDWINDOW
  308.     WS_EX_PALETTEWINDOW
  309.     WS_EX_RIGHT
  310.     WS_EX_RIGHTSCROLLBAR
  311.     WS_EX_RTLREADING
  312.     WS_EX_STATICEDGE
  313.     WS_EX_TOOLWINDOW
  314.     WS_EX_TOPMOST
  315.     WS_EX_TRANSPARENT
  316.     WS_EX_WINDOWEDGE
  317.  
  318.     TPM_LEFTBUTTON
  319.     TPM_RIGHTBUTTON
  320.     TPM_LEFTALIGN
  321.     TPM_CENTERALIGN
  322.     TPM_RIGHTALIGN
  323.     TPM_TOPALIGN
  324.     TPM_VCENTERALIGN
  325.     TPM_BOTTOMALIGN
  326.     TPM_HORIZONTAL
  327.     TPM_VERTICAL
  328.     TPM_NONOTIFY
  329.     TPM_RETURNCMD
  330.     TPM_RECURSE
  331. );
  332.  
  333. ###############################################################################
  334. # This AUTOLOAD is used to 'autoload' constants from the constant()
  335. # XS function.  If a constant is not found then control is passed
  336. # to the AUTOLOAD in AutoLoader.
  337. #
  338.  
  339. sub AUTOLOAD {
  340.     my($constname);
  341.     ($constname = $AUTOLOAD) =~ s/.*:://;
  342.     #reset $! to zero to reset any current errors.
  343.     $! = 0;
  344.     my $val = constant($constname, @_ ? $_[0] : 0);
  345.     if ($! != 0) {
  346.         if ($! =~ /Invalid/) {
  347.             $AutoLoader::AUTOLOAD = $AUTOLOAD;
  348.             goto &AutoLoader::AUTOLOAD;
  349.         } else {
  350.             my($pack,$file,$line) = caller; # undef $pack;
  351.             die "Can't find '$constname' in package '$pack' ".
  352.                 "used at $file line $line.";
  353.         }
  354.     }
  355.     eval "sub $AUTOLOAD { $val }";
  356.     goto &$AUTOLOAD;
  357. }
  358.  
  359. sub bootstrap_subpackage {
  360.     my($package) = @_;
  361.     $package = 'Win32::GUI::' . $package;
  362.     my $symbol = $package;
  363.     $symbol =~ s/\W/_/g;
  364.     no strict 'refs';
  365.     DynaLoader::dl_install_xsub(
  366.         "${package}::bootstrap",
  367.         DynaLoader::dl_find_symbol_anywhere( "boot_$symbol" )
  368.     );
  369.     &{ "${package}::bootstrap" };
  370. }
  371.  
  372. ###############################################################################
  373. # PUBLIC METHODS
  374. # (@)PACKAGE:Win32::GUI
  375.  
  376.     ###########################################################################
  377.     # (@)METHOD:Version()
  378.     # Returns the module version number.
  379. sub Version {
  380.     return $VERSION;
  381. }
  382.  
  383.     ###########################################################################
  384.     # (@)METHOD:SetFont(FONT)
  385.     # Sets the font of the window (FONT is a Win32::GUI::Font object).
  386. sub SetFont {
  387.     my($self, $font) = @_;
  388.     $font = $font->{-handle} if ref($font);
  389.     # 48 == WM_SETFONT
  390.     return Win32::GUI::SendMessage($self, 48, $font, 0);
  391. }
  392.  
  393.     ###########################################################################
  394.     # (@)METHOD:GetFont(FONT)
  395.     # Gets the font of the window (returns an handle; use
  396.     #   $Font = $W->GetFont();
  397.     #   %details = Win32::GUI::Font::Info( $Font );
  398.     # to get font details).
  399. sub GetFont {
  400.     my($self) = shift;
  401.     # 49 == WM_GETFONT
  402.     return Win32::GUI::SendMessage($self, 49, 0, 0);
  403. }
  404.  
  405.     ###########################################################################
  406.     # (@)METHOD:SetIcon(ICON, [TYPE])
  407.     # Sets the icon of the window; TYPE can be 0 for the small icon, 1 for
  408.     # the big icon. Default is the same icon for small and big.
  409. sub SetIcon {
  410.     my($self, $icon, $type) = @_;
  411.     $icon = $icon->{-handle} if ref($icon);
  412.     # 128 == WM_SETICON
  413.     if(defined($type)) {
  414.         return Win32::GUI::SendMessage($self, 128, $type, $icon);
  415.     } else {
  416.         Win32::GUI::SendMessage($self, 128, 0, $icon); # small icon
  417.         Win32::GUI::SendMessage($self, 128, 1, $icon); # big icon
  418.     }
  419. }
  420.  
  421.     ###########################################################################
  422.     # (@)METHOD:SetRedraw(FLAG)
  423.     # Determines if a window is automatically redrawn when its content changes.
  424.     # FLAG can be a true value to allow redraw, false to prevent it.
  425. sub SetRedraw {
  426.     my($self, $value) = @_;
  427.     # 11 == WM_SETREDRAW
  428.     my $r = Win32::GUI::SendMessage($self, 11, $value, 0);
  429.     return $r;
  430. }
  431.  
  432.     ###########################################################################
  433.     # (@)INTERNAL:MakeMenu(...)
  434.     # better used as new Win32::GUI::Menu(...)
  435. sub MakeMenu {
  436.     my(@menudata) = @_;
  437.     my $i;
  438.     my $M = new Win32::GUI::Menu();
  439.     my $text;
  440.     my %data;
  441.     my $level;
  442.     my %last;
  443.     my $parent;
  444.     for($i = 0; $i <= $#menudata; $i += 2) {
  445.         $text = $menudata[$i];
  446.         undef %data;
  447.         if(ref($menudata[$i+1])) {
  448.             %data = %{$menudata[$i+1]};
  449.         } else {
  450.             $data{-name} = $menudata[$i+1];
  451.         }
  452.         $level = 0;
  453.         $level++ while($text =~ s/^\s*>\s*//);
  454.  
  455.         # print "PM(MakeMenu) processing '$data{-name}', level=$level\n";
  456.  
  457.         if($level == 0) {
  458.             $M->{$data{-name}} = $M->AddMenuButton(
  459.                 -id => $MenuIdCounter++,
  460.                 -text => $text,
  461.                 %data,
  462.             );
  463.             $last{$level} = $data{-name};
  464.             $last{$level+1} = "";
  465.         } elsif($level == 1) {
  466.             $parent = $last{$level-1};
  467.             if($text eq "-") {
  468.                 $data{-name} = "dummy$MenuIdCounter";
  469.                 $M->{$data{-name}} = $M->{$parent}->AddMenuItem(
  470.                     -item => 0,
  471.                     -id => $MenuIdCounter++,
  472.                     -separator => 1,
  473.                     -name => $data{-name},
  474.                 );
  475.             } else {
  476.                 $M->{$data{-name}} = $M->{$parent}->AddMenuItem(
  477.                     -item => 0,
  478.                     -id => $MenuIdCounter++,
  479.                     -text => $text,
  480.                     %data,
  481.                 );
  482.             }
  483.             $last{$level} = $data{-name};
  484.             $last{$level+1} = "";
  485.         } else {
  486.             $parent = $last{$level-1};
  487.             if(!$M->{$parent."_Submenu"}) {
  488.                 $M->{$parent."_Submenu"} = new Win32::GUI::Menu();
  489.                 $M->{$parent."_SubmenuButton"} =
  490.                     $M->{$parent."_Submenu"}->AddMenuButton(
  491.                         -id => $MenuIdCounter++,
  492.                         -text => $parent,
  493.                         -name => $parent."_SubmenuButton",
  494.                     );
  495.                 $M->{$parent}->Change(
  496.                     -submenu => $M->{$parent."_SubmenuButton"}
  497.                 );
  498.             }
  499.             if($text eq "-") {
  500.                 $data{-name} = "dummy$MenuIdCounter";
  501.                 $M->{$data{-name}} =
  502.                     $M->{$parent."_SubmenuButton"}->AddMenuItem(
  503.                         -item => 0,
  504.                         -id => $MenuIdCounter++,
  505.                         -separator => 1,
  506.                         -name => $data{-name},
  507.                     );
  508.             } else {
  509.                 $M->{$data{-name}} =
  510.                     $M->{$parent."_SubmenuButton"}->AddMenuItem(
  511.                         -item => 0,
  512.                         -id => $MenuIdCounter++,
  513.                         -text => $text,
  514.                         %data,
  515.                     );
  516.             }
  517.             $last{$level} = $data{-name};
  518.             $last{$level+1} = "";
  519.         }
  520.     }
  521.     return $M;
  522. }
  523.  
  524.     ###########################################################################
  525.     # (@)INTERNAL:_new(TYPE, %OPTIONS)
  526.     # This is the generalized constructor;
  527.     # it works pretty well for almost all controls.
  528.     # However, other kind of objects may overload it.
  529. sub _new {
  530.     # this is always Win32::GUI (class of _new):
  531.     my $xclass = shift;
  532.  
  533.     # the window type passed by new():
  534.     my $type = shift;
  535.  
  536.     # this is the real class:
  537.     my $class = shift;
  538.  
  539.     my $oself = {};
  540.     # bless($oself, $class);
  541.     my %tier = ();
  542.     tie %tier, $class, $oself;
  543.     my $self = bless \%tier, $class;
  544.  
  545.  
  546.     my (@input) = @_;
  547.     # print "PM(Win32::GUI::_new) self='$self' type='$type' input='@input'\n";
  548.     my $handle = Win32::GUI::Create($self, $type, @input);
  549.  
  550.     # $self->{-handle} = $handle;
  551.  
  552.     # print "[_new] enumerating self.keys\n";
  553.     # foreach my $k (keys %$self) {
  554.     #   print "[_new] '$k' = '$self->{$k}'\n";
  555.     # }
  556.     if($handle) {
  557.         return $self;
  558.     } else {
  559.         return undef;
  560.     }
  561. }
  562.  
  563. ###############################################################################
  564. # SUB-PACKAGES
  565. #
  566.  
  567.  
  568. ###############################################################################
  569. # (@)PACKAGE:Win32::GUI::Font
  570. #
  571. package Win32::GUI::Font;
  572. @ISA = qw(Win32::GUI);
  573.  
  574.     ###########################################################################
  575.     # (@)METHOD:new Win32::GUI::Font(%OPTIONS)
  576.     # Creates a new Font object. %OPTIONS are:
  577.     #   -size
  578.     #   -height
  579.     #   -width
  580.     #   -escapement
  581.     #   -orientation
  582.     #   -weight
  583.     #   -bold => 0/1
  584.     #   -italic => 0/1
  585.     #   -underline => 0/1
  586.     #   -strikeout => 0/1
  587.     #   -charset
  588.     #   -outputprecision
  589.     #   -clipprecision
  590.     #   -family
  591.     #   -quality
  592.     #   -name
  593.     #   -face
  594. sub new {
  595.     my $class = shift;
  596.     my $self = {};
  597.  
  598.     my $handle = Create(@_);
  599.  
  600.     if($handle) {
  601.         $self->{-handle} = $handle;
  602.         bless($self, $class);
  603.         return $self;
  604.     } else {
  605.         return undef;
  606.     }
  607. }
  608.  
  609. ###############################################################################
  610. # (@)PACKAGE:Win32::GUI::Bitmap
  611. #
  612. package Win32::GUI::Bitmap;
  613. @ISA = qw(Win32::GUI);
  614.  
  615.     ###########################################################################
  616.     # (@)METHOD:new Win32::GUI::Bitmap(FILENAME, [TYPE, X, Y, FLAGS])
  617.     # Creates a new Bitmap object reading from FILENAME; all other arguments
  618.     # are optional. TYPE can be:
  619.     #   0  bitmap (this is the default)
  620.     #   1  icon
  621.     #   2  cursor
  622.     # You can eventually specify your desired size for the image with X and
  623.     # Y and pass some FLAGS to the underlying LoadImage API (at your own risk)
  624. sub new {
  625.     my $class = shift;
  626.     my $self = {};
  627.  
  628.     my $handle = Win32::GUI::LoadImage(@_);
  629.  
  630.     if($handle) {
  631.         $self->{-handle} = $handle;
  632.         bless($self, $class);
  633.         return $self;
  634.     } else {
  635.         return undef;
  636.     }
  637. }
  638.  
  639. ###############################################################################
  640. # (@)PACKAGE:Win32::GUI::Icon
  641. #
  642. package Win32::GUI::Icon;
  643. @ISA = qw(Win32::GUI);
  644.  
  645.     ###########################################################################
  646.     # (@)METHOD:new Win32::GUI::Icon(FILENAME)
  647.     # Creates a new Icon object reading from FILENAME.
  648. sub new {
  649.     my $class = shift;
  650.     my $file = shift;
  651.     my $self = {};
  652.  
  653.     my $handle = Win32::GUI::LoadImage(
  654.         $file,
  655.         Win32::GUI::constant("IMAGE_ICON", 0),
  656.     );
  657.  
  658.     if($handle) {
  659.         $self->{-handle} = $handle;
  660.         bless($self, $class);
  661.         return $self;
  662.     } else {
  663.         return undef;
  664.     }
  665. }
  666.  
  667.     ###########################################################################
  668.     # (@)INTERNAL:DESTROY()
  669. sub DESTROY {
  670.     my $self = shift;
  671.     Win32::GUI::DestroyIcon($self);
  672. }
  673.  
  674.  
  675. ###############################################################################
  676. # (@)PACKAGE:Win32::GUI::Cursor
  677. #
  678. package Win32::GUI::Cursor;
  679. @ISA = qw(Win32::GUI);
  680.  
  681.     ###########################################################################
  682.     # (@)METHOD:new Win32::GUI::Cursor(FILENAME)
  683.     # Creates a new Cursor object reading from FILENAME.
  684. sub new {
  685.     my $class = shift;
  686.     my $file = shift;
  687.     my $self = {};
  688.  
  689.     my $handle = Win32::GUI::LoadImage(
  690.         $file,
  691.         Win32::GUI::constant("IMAGE_CURSOR", 0),
  692.     );
  693.  
  694.     if($handle) {
  695.         $self->{-handle} = $handle;
  696.         bless($self, $class);
  697.         return $self;
  698.     } else {
  699.         return undef;
  700.     }
  701. }
  702.  
  703.     ###########################################################################
  704.     # (@)INTERNAL:DESTROY()
  705. sub DESTROY {
  706.     my $self = shift;
  707.     Win32::GUI::DestroyCursor($self);
  708. }
  709.  
  710. ###############################################################################
  711. # (@)PACKAGE:Win32::GUI::Class
  712. #
  713. package Win32::GUI::Class;
  714. @ISA = qw(Win32::GUI);
  715.  
  716.     ###########################################################################
  717.     # (@)METHOD: new Win32::GUI::Class(%OPTIONS)
  718.     # Creates a new window class object.
  719.     # Allowed %OPTIONS are:
  720.     #   -name => STRING
  721.     #       the name for the class (it must be unique!).
  722.     #   -icon => Win32::GUI::Icon object
  723.     #   -cursor => Win32::GUI::Cursor object
  724.     #   -color => COLOR or Win32::GUI::Brush object
  725.     #       the window background color.
  726.     #   -menu => STRING
  727.     #       a menu name (not yet implemented).
  728.     #   -extends => STRING
  729.     #       name of the class to extend (aka subclassing).
  730.     #   -widget => STRING
  731.     #       name of a widget class to subclass; currently available are:
  732.     #       Button, Listbox, TabStrip, RichEdit.
  733.     #   -style => FLAGS
  734.     #       use with caution!
  735. sub new {
  736.     my $class = shift;
  737.     my %args = @_;
  738.     my $self = {};
  739.  
  740.     # figure out the correct background color
  741.     # (to avoid the "white background" syndrome on XP)
  742.     if(not exists $args{-color}) {
  743.         my($undef, $major, $minor) = Win32::GetOSVersion();
  744.         if($major == 5 && $minor > 0) {
  745.             $args{-color} = Win32::GUI::constant("COLOR_BTNFACE", 0)+1;
  746.         } else {
  747.             $args{-color} = Win32::GUI::constant("COLOR_WINDOW", 0);
  748.         }
  749.     }
  750.  
  751.     my $handle = Win32::GUI::RegisterClassEx(%args);
  752.  
  753.     if($handle) {
  754.         $self->{-name}   = $args{-name};
  755.         $self->{-handle} = $handle;
  756.         bless($self, $class);
  757.         return $self;
  758.     } else {
  759.         return undef;
  760.     }
  761. }
  762.  
  763.  
  764. ###############################################################################
  765. # (@)PACKAGE:Win32::GUI::Window
  766. #
  767. package Win32::GUI::Window;
  768. @ISA = qw(
  769.     Win32::GUI
  770.     Win32::GUI::WindowProps
  771. );
  772.  
  773.     ###########################################################################
  774.     # (@)METHOD:new Win32::GUI::Window(%OPTIONS)
  775.     # Creates a new Window object.
  776.     # Class specific %OPTIONS are:
  777.     #   -minsize => [X, Y]
  778.     #     specifies the minimum size (width and height) in pixels;
  779.     #     X and Y must be passed in an array reference
  780.     #   -maxsize => [X, Y]
  781.     #     specifies the maximum size (width and height) in pixels;
  782.     #     X and Y must be passed in an array reference
  783.     #   -minwidth  => N
  784.     #   -minheight => N
  785.     #   -maxwidht  => N
  786.     #   -maxheight => N
  787.     #     specify the minimum and maximum size width
  788.     #     and height, in pixels
  789.     #   -topmost => 0/1 (default 0)
  790.     #     the window "stays on top" even when deactivated
  791. sub new {
  792.     my $self = Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__WINDOW", 0), @_);
  793.     if($self) {
  794.         return $self;
  795.     } else {
  796.         return undef;
  797.     }
  798. }
  799.  
  800.     ###########################################################################
  801.     # (@)METHOD:AddButton(%OPTIONS)
  802.     # See new Win32::GUI::Button().
  803. sub AddButton      { return Win32::GUI::Button->new(@_); }
  804.  
  805.     ###########################################################################
  806.     # (@)METHOD:AddLabel(%OPTIONS)
  807.     # See new Win32::GUI::Label().
  808. sub AddLabel       { return Win32::GUI::Label->new(@_); }
  809.  
  810.     ###########################################################################
  811.     # (@)METHOD:AddCheckbox(%OPTIONS)
  812.     # See new Win32::GUI::Checkbox().
  813. sub AddCheckbox    { return Win32::GUI::Checkbox->new(@_); }
  814.  
  815.     ###########################################################################
  816.     # (@)METHOD:AddRadioButton(%OPTIONS)
  817.     # See new Win32::GUI::RadioButton().
  818. sub AddRadioButton { return Win32::GUI::RadioButton->new(@_); }
  819.  
  820.     ###########################################################################
  821.     # (@)METHOD:AddGroupbox(%OPTIONS)
  822.     # See new Win32::GUI::Groupbox().
  823. sub AddGroupbox    { return Win32::GUI::Groupbox->new(@_); }
  824.  
  825.     ###########################################################################
  826.     # (@)METHOD:AddTextfield(%OPTIONS)
  827.     # See new Win32::GUI::Textfield().
  828. sub AddTextfield   { return Win32::GUI::Textfield->new(@_); }
  829.  
  830.     ###########################################################################
  831.     # (@)METHOD:AddListbox(%OPTIONS)
  832.     # See new Win32::GUI::Listbox().
  833. sub AddListbox     { return Win32::GUI::Listbox->new(@_); }
  834.  
  835.     ###########################################################################
  836.     # (@)METHOD:AddCombobox(%OPTIONS)
  837.     # See new Win32::GUI::Combobox().
  838. sub AddCombobox    { return Win32::GUI::Combobox->new(@_); }
  839.  
  840.     ###########################################################################
  841.     # (@)METHOD:AddStatusBar(%OPTIONS)
  842.     # See new Win32::GUI::StatusBar().
  843. sub AddStatusBar   { return Win32::GUI::StatusBar->new(@_); }
  844.  
  845.     ###########################################################################
  846.     # (@)METHOD:AddProgressBar(%OPTIONS)
  847.     # See new Win32::GUI::ProgressBar().
  848. sub AddProgressBar { return Win32::GUI::ProgressBar->new(@_); }
  849.  
  850.     ###########################################################################
  851.     # (@)METHOD:AddTabStrip(%OPTIONS)
  852.     # See new Win32::GUI::TabStrip().
  853. sub AddTabStrip    { return Win32::GUI::TabStrip->new(@_); }
  854.  
  855.     ###########################################################################
  856.     # (@)METHOD:AddToolbar(%OPTIONS)
  857.     # See new Win32::GUI::Toolbar().
  858. sub AddToolbar     { return Win32::GUI::Toolbar->new(@_); }
  859.  
  860.     ###########################################################################
  861.     # (@)METHOD:AddListView(%OPTIONS)
  862.     # See new Win32::GUI::ListView().
  863. sub AddListView    { return Win32::GUI::ListView->new(@_); }
  864.  
  865.     ###########################################################################
  866.     # (@)METHOD:AddTreeView(%OPTIONS)
  867.     # See new Win32::GUI::TreeView().
  868. sub AddTreeView    { return Win32::GUI::TreeView->new(@_); }
  869.  
  870.     ###########################################################################
  871.     # (@)METHOD:AddRichEdit(%OPTIONS)
  872.     # See new Win32::GUI::RichEdit().
  873. sub AddRichEdit    { return Win32::GUI::RichEdit->new(@_); }
  874.  
  875.     ###########################################################################
  876.     # (@)INTERNAL:AddTrackbar(%OPTIONS)
  877.     # Better used as AddSlider().
  878. sub AddTrackbar    { return Win32::GUI::Trackbar->new(@_); }
  879.  
  880.     ###########################################################################
  881.     # (@)METHOD:AddSlider(%OPTIONS)
  882.     # See new Win32::GUI::Slider().
  883. sub AddSlider      { return Win32::GUI::Slider->new(@_); }
  884.  
  885.     ###########################################################################
  886.     # (@)METHOD:AddUpDown(%OPTIONS)
  887.     # See new Win32::GUI::UpDown().
  888. sub AddUpDown      { return Win32::GUI::UpDown->new(@_); }
  889.  
  890.     ###########################################################################
  891.     # (@)METHOD:AddAnimation(%OPTIONS)
  892.     # See new Win32::GUI::Animation().
  893. sub AddAnimation   { return Win32::GUI::Animation->new(@_); }
  894.  
  895.     ###########################################################################
  896.     # (@)METHOD:AddRebar(%OPTIONS)
  897.     # See new Win32::GUI::Rebar().
  898. sub AddRebar       { return Win32::GUI::Rebar->new(@_); }
  899.  
  900.     ###########################################################################
  901.     # (@)METHOD:AddHeader(%OPTIONS)
  902.     # See new Win32::GUI::Header().
  903. sub AddHeader      { return Win32::GUI::Header->new(@_); }
  904.  
  905.     ###########################################################################
  906.     # (@)METHOD:AddComboboxEx(%OPTIONS)
  907.     # See new Win32::GUI::Combobox().
  908. sub AddComboboxEx  { return Win32::GUI::ComboboxEx->new(@_); }
  909.  
  910.     ###########################################################################
  911.     # (@)METHOD:AddSplitter(%OPTIONS)
  912.     # See new Win32::GUI::Splitter().
  913. sub AddSplitter    { return Win32::GUI::Splitter->new(@_); }
  914.  
  915.     ###########################################################################
  916.     # (@)METHOD:AddTimer(NAME, ELAPSE)
  917.     # See new Win32::GUI::Timer().
  918. sub AddTimer       { return Win32::GUI::Timer->new(@_); }
  919.  
  920.     ###########################################################################
  921.     # (@)METHOD:AddNotifyIcon(%OPTIONS)
  922.     # See new Win32::GUI::NotifyIcon().
  923. sub AddNotifyIcon  { return Win32::GUI::NotifyIcon->new(@_); }
  924.  
  925.     ###########################################################################
  926.     # (@)METHOD:AddDateTime(%OPTIONS)
  927.     # See new Win32::GUI::DateTime().
  928. sub AddDateTime  { return Win32::GUI::DateTime->new(@_); }
  929.  
  930.     ###########################################################################
  931.     # (@)METHOD:AddGraphic(%OPTIONS)
  932.     # See new Win32::GUI::Graphic().
  933. sub AddGraphic  { return Win32::GUI::Graphic->new(@_); }
  934.  
  935.     ###########################################################################
  936.     # (@)METHOD:AddMenu()
  937.     # See new Win32::GUI::Menu().
  938. sub AddMenu {
  939.     my $self = shift;
  940.     my $menu = Win32::GUI::Menu->new();
  941.     my $r = Win32::GUI::SetMenu($self, $menu->{-handle});
  942.     # print "SetMenu=$r\n";
  943.     return $menu;
  944. }
  945.  
  946.     ###########################################################################
  947.     # (@)METHOD:GetDC()
  948.     # Returns the DC object associated with the window.
  949. sub GetDC {
  950.     my $self = shift;
  951.     return Win32::GUI::DC->new($self);
  952. }
  953.  
  954.     ###########################################################################
  955.     # (@)INTERNAL:DESTROY(HANDLE)
  956. sub DESTROY {
  957.     my $self = shift;
  958.     if(tied($self)) {
  959.         my $timer;
  960.         if( exists $self->{-timers} ) {
  961.             foreach $timer ($self->{-timers}) {
  962.                 undef $self->{-timers}->{$timer};
  963.             }
  964.         }
  965.     }
  966.     # Win32::GUI::DestroyWindow($self);
  967. }
  968.  
  969.     ###########################################################################
  970.     # (@)INTERNAL:AUTOLOAD(HANDLE, METHOD)
  971. sub AUTOLOAD {
  972.     my($self, $method) = @_;
  973.     $AUTOLOAD =~ s/.*:://;
  974.     # print "Win32::GUI::Window::AUTOLOAD called for object '$self', method '$method', AUTOLOAD=$AUTOLOAD\n";
  975.     if( exists $self->{$AUTOLOAD}) {
  976.         return $self->{$AUTOLOAD};
  977.     } else {
  978.         $AutoLoader::AUTOLOAD = $AUTOLOAD;
  979.         goto &AutoLoader::AUTOLOAD;
  980.     }
  981. }
  982.  
  983.  
  984. ###############################################################################
  985. # (@)PACKAGE:Win32::GUI::DialogBox
  986. #
  987. package Win32::GUI::DialogBox;
  988. @ISA = qw(Win32::GUI::Window);
  989.  
  990.     ###########################################################################
  991.     # (@)METHOD:new Win32::GUI::DialogBox(%OPTIONS)
  992.     # Creates a new DialogBox object. See new Win32::GUI::Window().
  993. sub new {
  994.     my $self = Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__DIALOG", 0), @_);
  995.     if($self) {
  996.         $self->DialogUI(1);
  997.         return $self;
  998.     } else {
  999.         return undef;
  1000.     }
  1001. }
  1002.  
  1003.  
  1004. ###############################################################################
  1005. # (@)PACKAGE:Win32::GUI::MDI
  1006. #
  1007. package Win32::GUI::MDI;
  1008. @ISA = qw(
  1009.     Win32::GUI::Window
  1010.     Win32::GUI::WindowProps
  1011. );
  1012.  
  1013.     ###########################################################################
  1014.     # (@)METHOD:new Win32::GUI::MDI(%OPTIONS)
  1015.     # Creates a new MDI (Multiple Document Interface) object.
  1016.     # Class specific %OPTIONS are:
  1017.     #   -minsize => [X, Y]
  1018.     #     specifies the minimum size (width and height) in pixels;
  1019.     #     X and Y must be passed in an array reference
  1020.     #   -maxsize => [X, Y]
  1021.     #     specifies the maximum size (width and height) in pixels;
  1022.     #     X and Y must be passed in an array reference
  1023.     #   -minwidth  => N
  1024.     #   -minheight => N
  1025.     #   -maxwidht  => N
  1026.     #   -maxheight => N
  1027.     #     specify the minimum and maximum size width
  1028.     #     and height, in pixels
  1029.     #   -topmost => 0/1 (default 0)
  1030.     #     the window "stays on top" even when deactivated
  1031. sub new {
  1032.     my $self = Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__MDICLIENT", 0), @_);
  1033.     if($self) {
  1034.         return $self;
  1035.     } else {
  1036.         return undef;
  1037.     }
  1038. }
  1039.  
  1040.  
  1041. ###############################################################################
  1042. # (@)PACKAGE:Win32::GUI::Button
  1043. #
  1044. package Win32::GUI::Button;
  1045. @ISA = qw(
  1046.     Win32::GUI
  1047.     Win32::GUI::WindowProps
  1048. );
  1049.  
  1050.     ###########################################################################
  1051.     # (@)METHOD:new Win32::GUI::Button(PARENT, %OPTIONS)
  1052.     # Creates a new Button object;
  1053.     # can also be called as PARENT->AddButton(%OPTIONS).
  1054.     # Class specific %OPTIONS are:
  1055.     #     -align   => left/center/right (default left)
  1056.     #     -valign  => top/center/bottom
  1057.     #
  1058.     #     -default => 0/1 (default 0)
  1059.     #     -ok      => 0/1 (default 0)
  1060.     #     -cancel  => 0/1 (default 0)
  1061.     #     -bitmap  => Win32::GUI::Bitmap object
  1062.     #     -picture => see -bitmap
  1063.     #     -icon    => Win32::GUI::Icon object
  1064. sub new {
  1065.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__BUTTON", 0), @_);
  1066. }
  1067.  
  1068.     ###########################################################################
  1069.     # (@)METHOD:SetImage(BITMAP)
  1070.     # Draws the specified BITMAP, a Win32::GUI::Bitmap or Win32::GUI::Icon
  1071.     # object, in the Button.
  1072. sub SetImage {
  1073.     my $self = shift;
  1074.     my $image = shift;
  1075.     my $type = Win32::GUI::constant("IMAGE_BITMAP", 0);
  1076.     $type = Win32::GUI::constant("IMAGE_ICON", 0) if ref($image) =~ /Icon/;
  1077.     $image = $image->{-handle} if ref($image);
  1078.     # 247 == BM_SETIMAGE
  1079.     return Win32::GUI::SendMessage($self, 247, $type, $image);
  1080. }
  1081.  
  1082. ###############################################################################
  1083. # (@)PACKAGE:Win32::GUI::RadioButton
  1084. #
  1085. package Win32::GUI::RadioButton;
  1086. @ISA = qw(
  1087.     Win32::GUI
  1088.     Win32::GUI::WindowProps
  1089. );
  1090.  
  1091.     ###########################################################################
  1092.     # (@)METHOD:new Win32::GUI::RadioButton(PARENT, %OPTIONS)
  1093.     # Creates a new RadioButton object;
  1094.     # can also be called as PARENT->AddRadioButton(%OPTIONS).
  1095.     # %OPTIONS are the same of Button (see new Win32::GUI::Button() ).
  1096. sub new {
  1097.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__RADIOBUTTON", 0), @_);
  1098. }
  1099.  
  1100.     ###########################################################################
  1101.     # (@)METHOD:Checked([VALUE])
  1102.     # Gets or sets the checked state of the RadioButton; if called without
  1103.     # arguments, returns the current state:
  1104.     #   0 not checked
  1105.     #   1 checked
  1106.     # If a VALUE is specified, it can be one of these (eg. 0 to uncheck the
  1107.     # RadioButton, 1 to check it).
  1108. sub Checked {
  1109.     my $self = shift;
  1110.     my $check = shift;
  1111.     if(defined($check)) {
  1112.         # 241 == BM_SETCHECK
  1113.         return Win32::GUI::SendMessage($self, 241, $check, 0);
  1114.     } else {
  1115.         # 240 == BM_GETCHECK
  1116.         return Win32::GUI::SendMessage($self, 240, 0, 0);
  1117.     }
  1118. }
  1119.  
  1120. ###############################################################################
  1121. # (@)PACKAGE:Win32::GUI::Checkbox
  1122. #
  1123. package Win32::GUI::Checkbox;
  1124. @ISA = qw(
  1125.     Win32::GUI
  1126.     Win32::GUI::WindowProps
  1127. );
  1128.  
  1129.     ###########################################################################
  1130.     # (@)METHOD:new Win32::GUI::Checkbox(PARENT, %OPTIONS)
  1131.     # Creates a new Checkbox object;
  1132.     # can also be called as PARENT->AddCheckbox(%OPTIONS).
  1133.     # %OPTIONS are the same of Button (see new Win32::GUI::Button() ).
  1134. sub new {
  1135.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__CHECKBOX", 0), @_);
  1136. }
  1137.  
  1138.  
  1139.     ###########################################################################
  1140.     # (@)METHOD:GetCheck()
  1141.     # Returns the check state of the Checkbox:
  1142.     #   0 not checked
  1143.     #   1 checked
  1144.     #   2 indeterminate (grayed)
  1145. sub GetCheck {
  1146.     my $self = shift;
  1147.     # 240 == BM_GETCHECK
  1148.     return Win32::GUI::SendMessage($self, 240, 0, 0);
  1149. }
  1150.  
  1151.     ###########################################################################
  1152.     # (@)METHOD:SetCheck([VALUE])
  1153.     # Sets the check state of the Checkbox; for a list of possible values,
  1154.     # see GetCheck().
  1155.     # If called without arguments, it checks the Checkbox (eg. state = 1).
  1156. sub SetCheck {
  1157.     my $self = shift;
  1158.     my $check = shift;
  1159.     $check = 1 unless defined($check);
  1160.     # 241 == BM_SETCHECK
  1161.     return Win32::GUI::SendMessage($self, 241, $check, 0);
  1162. }
  1163.  
  1164.     ###########################################################################
  1165.     # (@)METHOD:Checked([VALUE])
  1166.     # Gets or sets the check state of the Checkbox; if called without
  1167.     # arguments, returns the current state:
  1168.     #   0 not checked
  1169.     #   1 checked
  1170.     #   2 indeterminate (grayed)
  1171.     # If a VALUE is specified, it can be one of these (eg. 0 to uncheck the
  1172.     # Checkbox, 1 to check it).
  1173. sub Checked {
  1174.     my $self = shift;
  1175.     my $check = shift;
  1176.     if(defined($check)) {
  1177.         # 241 == BM_SETCHECK
  1178.         return Win32::GUI::SendMessage($self, 241, $check, 0);
  1179.     } else {
  1180.         # 240 == BM_GETCHECK
  1181.         return Win32::GUI::SendMessage($self, 240, 0, 0);
  1182.     }
  1183. }
  1184.  
  1185. ###############################################################################
  1186. # (@)PACKAGE:Win32::GUI::Groupbox
  1187. #
  1188. package Win32::GUI::Groupbox;
  1189. @ISA = qw(
  1190.     Win32::GUI
  1191.     Win32::GUI::WindowProps
  1192. );
  1193.  
  1194.     ###########################################################################
  1195.     # (@)METHOD:new Win32::GUI::Groupbox(PARENT, %OPTIONS)
  1196.     # Creates a new Groupbox object;
  1197.     # can also be called as PARENT->AddGroupbox(%OPTIONS).
  1198. sub new {
  1199.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__GROUPBOX", 0), @_);
  1200. }
  1201.  
  1202.  
  1203. ###############################################################################
  1204. # (@)PACKAGE:Win32::GUI::Label
  1205. #
  1206. package Win32::GUI::Label;
  1207. @ISA = qw(
  1208.     Win32::GUI
  1209.     Win32::GUI::WindowProps
  1210. );
  1211.  
  1212.     ###########################################################################
  1213.     # (@)METHOD:new Win32::GUI::Label(PARENT, %OPTIONS)
  1214.     # Creates a new Label object;
  1215.     # can also be called as PARENT->AddLabel(%OPTIONS).
  1216.     # Class specific %OPTIONS are:
  1217.     #    -align    => left/center/right (default left)
  1218.     #    -bitmap   => Win32::GUI::Bitmap object
  1219.     #    -fill     => black/gray/white/none (default none)
  1220.     #        fills the control rectangle ("black", "gray" and "white" are
  1221.     #        the window frame color, the desktop color and the window
  1222.     #        background color respectively).
  1223.     #    -frame    => black/gray/white/etched/none (default none)
  1224.     #        draws a border around the control. colors are the same
  1225.     #        of -fill, with the addition of "etched" (a raised border).
  1226.     #    -icon     => Win32::GUI::Icon object
  1227.     #    -noprefix => 0/1 (default 0)
  1228.     #        disables the interpretation of "&" as accelerator prefix.
  1229.     #    -notify   => 0/1 (default 0)
  1230.     #        enables the Click(), DblClick, etc. events.
  1231.     #    -picture  => see -bitmap
  1232.     #    -sunken   => 0/1 (default 0)
  1233.     #        draws a half-sunken border around the control.
  1234.     #    -truncate => 0/1/word/path (default 0)
  1235.     #        specifies how the text is to be truncated:
  1236.     #            0 the text is not truncated
  1237.     #            1 the text is truncated at the end
  1238.     #         path the text is truncated before the last "\"
  1239.     #              (used to shorten paths).
  1240.     #    -wrap     => 0/1 (default 1)
  1241.     #        the text wraps automatically to a new line.
  1242. sub new {
  1243.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__STATIC", 0), @_);
  1244. }
  1245.  
  1246.     ###########################################################################
  1247.     # (@)METHOD:SetImage(BITMAP)
  1248.     # Draws the specified BITMAP, a Win32::GUI::Bitmap object, in the Label.
  1249. sub SetImage {
  1250.     my $self = shift;
  1251.     my $image = shift;
  1252.     $image = $image->{-handle} if ref($image);
  1253.     my $type = Win32::GUI::constant("IMAGE_BITMAP", 0);
  1254.     # 370 == STM_SETIMAGE
  1255.     return Win32::GUI::SendMessage($self, 370, $type, $image);
  1256. }
  1257.  
  1258.  
  1259. ###############################################################################
  1260. # (@)PACKAGE:Win32::GUI::Textfield
  1261. #
  1262. package Win32::GUI::Textfield;
  1263. @ISA = qw(
  1264.     Win32::GUI
  1265.     Win32::GUI::WindowProps
  1266. );
  1267.  
  1268.     ###########################################################################
  1269.     # (@)METHOD:new Win32::GUI::Textfield(PARENT, %OPTIONS)
  1270.     # Creates a new Textfield object;
  1271.     # can also be called as PARENT->AddTextfield(%OPTIONS).
  1272.     # Class specific %OPTIONS are:
  1273.     #   -align         => left/center/right (default left)
  1274.     #       aligns the text in the control accordingly.
  1275.     #   -keepselection => 0/1 (default 0)
  1276.     #       the selection is not hidden when the control loses focus.
  1277.     #   -multiline     => 0/1 (default 0)
  1278.     #       the control can have more than one line (note that newline
  1279.     #       is "\r\n", not "\n"!).
  1280.     #   -password      => 0/1 (default 0)
  1281.     #       masks the user input (like password prompts).
  1282.     #   -passwordchar  => char (default '*')
  1283.     #       the char that is shown instead of the text with -password => 1.
  1284.     #   -prompt        => (see below)
  1285.     #   -readonly      => 0/1 (default 0)
  1286.     #       text can't be changed.
  1287.     #
  1288.     # The -prompt option is very special; if a string is passed, a
  1289.     # Win32::GUI::Label object (with text set to the string passed) is created
  1290.     # to the left of the Textfield.
  1291.     # Example:
  1292.     #     $Window->AddTextfield(
  1293.     #         -name   => "Username",
  1294.     #         -left   => 75,
  1295.     #         -top    => 150,
  1296.     #         -prompt => "Your name:",
  1297.     #     );
  1298.     # Furthermore, the value to -prompt can be a reference to a list containing
  1299.     # the string and an additional parameter, which sets the width for
  1300.     # the Label (eg. [ STRING, WIDTH ] ). If WIDTH is negative, it is calculated
  1301.     # relative to the Textfield left coordinate. Example:
  1302.     #
  1303.     #     -left => 75,                          (Label left) (Textfield left)
  1304.     #     -prompt => [ "Your name:", 30 ],       75           105 (75+30)
  1305.     #
  1306.     #     -left => 75,
  1307.     #     -prompt => [ "Your name:", -30 ],      45 (75-30)   75
  1308.     #
  1309.     # Note that the Win32::GUI::Label object is named like the Textfield, with
  1310.     # a "_Prompt" suffix (in the example above, the Label is named
  1311.     # "Username_Prompt").
  1312. sub new {
  1313.     my($class, $parent, @options) = @_;
  1314.     my %options = @options;
  1315.     if(exists $options{-prompt}) {
  1316.         my $add = 0;
  1317.         my ($text, $left, $width, $height, );
  1318.         my $visible = 1;
  1319.         # Convert -pos and -size options to -left, -top, -width and -height options
  1320.         if (exists $options{-pos}) {
  1321.           $options{-left} = $options{-pos}[0];
  1322.           $options{-top}  = $options{-pos}[1];
  1323.         }
  1324.         if (exists $options{-size}) {
  1325.           $options{-width}  = $options{-size}[0];
  1326.           $options{-height} = $options{-size}[1];
  1327.         }
  1328.  
  1329.         if(ref($options{-prompt}) eq "ARRAY") {
  1330.             $left = pop(@{$options{'-prompt'}});
  1331.             $text = pop(@{$options{'-prompt'}});
  1332.             if($left < 0) {
  1333.                 $left = $options{-left} + $left;
  1334.                 $width = -$left;
  1335.             } else {
  1336.                 $width = $left;
  1337.                 $left = $options{-left};
  1338.                 $add = $width;
  1339.             }
  1340.         } else {
  1341.             $text = $options{-prompt};
  1342.             $add = -1;
  1343.         }
  1344.         if(exists $options{-height}) {
  1345.             $height = $options{-height}-3;
  1346.         } else {
  1347.             $height = 0;
  1348.         }
  1349.         if(exists $options{-visible}) {
  1350.             $visible = $options{-visible};
  1351.         }
  1352.         my $prompt = new Win32::GUI::Label(
  1353.             $parent,
  1354.             -name    => $options{-name} . '_Prompt',
  1355.             -width   => $width,
  1356.             -left    => $left,
  1357.             -top     => $options{-top} + 3,
  1358.             -text    => $text,
  1359.             -height  => $height,
  1360.             -visible => $visible,
  1361.         );
  1362.         $add = $prompt->Width if $add == -1;
  1363.         $options{-left} += $add;
  1364.  
  1365.         # Update array options
  1366.         for (my $i = 0; $i < @options; $i += 2) {
  1367.             if ($options[$i] eq '-left') {
  1368.                 $options[$i+1] = $options{-left};
  1369.                 last;
  1370.             }
  1371.             if ($options[$i] eq '-pos') {
  1372.                 $options[$i+1][0] = $options{-left};
  1373.                 last;
  1374.             }
  1375.         }
  1376.     }
  1377.     return Win32::GUI->_new(
  1378.         Win32::GUI::constant("WIN32__GUI__EDIT", 0),
  1379.         $class, $parent, @options,
  1380.     );
  1381. }
  1382.  
  1383.     ###########################################################################
  1384.     # (@)METHOD:Select(START, END)
  1385.     # Selects the specified range of characters.
  1386. sub Select {
  1387.     my($self, $wparam, $lparam) = @_;
  1388.     # 177 == EM_SETSEL
  1389.     return Win32::GUI::SendMessage($self, 177, $wparam, $lparam);
  1390. }
  1391.  
  1392.     ###########################################################################
  1393.     # (@)METHOD:SelectAll()
  1394. sub SelectAll {
  1395.     my($self, $wparam, $lparam) = @_;
  1396.     # 177 == EM_SETSEL
  1397.     #  14 == WM_GETTEXTLENGTH
  1398.     return Win32::GUI::SendMessage(
  1399.         $self, 177,
  1400.         0, Win32::GUI::SendMessage($self, 14, 0, 0),
  1401.     );
  1402. }
  1403.  
  1404.     ###########################################################################
  1405.     # (@)METHOD:MaxLength([CHARS])
  1406. sub MaxLength {
  1407.     my($self, $chars) = @_;
  1408.     if(defined $chars) {
  1409.         # 197 == EM_SETLIMITTEXT
  1410.         return Win32::GUI::SendMessage($self, 197, $chars, 0);
  1411.     } else {
  1412.         # 213 == EM_GETLIMITTEXT
  1413.         return Win32::GUI::SendMessage($self, 213, 0, 0);
  1414.     }
  1415. }
  1416.  
  1417. ###############################################################################
  1418. # (@)PACKAGE:Win32::GUI::Listbox
  1419. #
  1420. package Win32::GUI::Listbox;
  1421. @ISA = qw(
  1422.     Win32::GUI
  1423.     Win32::GUI::WindowProps
  1424. );
  1425.  
  1426.     ###########################################################################
  1427.     # (@)METHOD:new Win32::GUI::Listbox(PARENT, %OPTIONS)
  1428.     # Creates a new Listbox object;
  1429.     # can also be called as PARENT->AddListbox(%OPTIONS).
  1430.     # Class specific %OPTIONS are:
  1431.     #    -multisel => 0/1/2 (default 0)
  1432.     #        specifies the selection type:
  1433.     #            0 single selection
  1434.     #            1 multiple selection
  1435.     #            2 multiple selection ehnanced (with Shift, Control, etc.)
  1436.     #    -sort     => 0/1 (default 0)
  1437.     #        items are sorted alphabetically.
  1438.  
  1439. sub new {
  1440.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__LISTBOX", 0), @_);
  1441. }
  1442.  
  1443.     ###########################################################################
  1444.     # (@)METHOD:SelectedItem()
  1445. sub SelectedItem {
  1446.     my $self = shift;
  1447.     # 392 == LB_GETCURSEL
  1448.     return Win32::GUI::SendMessage($self, 392, 0, 0);
  1449. }
  1450.     ###########################################################################
  1451.     # (@)METHOD:ListIndex()
  1452. sub ListIndex { SelectedItem(@_); }
  1453.  
  1454.     ###########################################################################
  1455.     # (@)METHOD:Select(INDEX)
  1456.     # Selects the zero-based INDEX item in the Listbox.
  1457. sub Select {
  1458.     my $self = shift;
  1459.     my $item = shift;
  1460.     # 390 == LB_SETCURSEL
  1461.     my $r = Win32::GUI::SendMessage($self, 390, $item, 0);
  1462.     return $r;
  1463. }
  1464.  
  1465.     ###########################################################################
  1466.     # (@)METHOD:Reset()
  1467. sub Reset {
  1468.     my $self = shift;
  1469.     # 388 == LB_RESETCONTENT
  1470.     my $r = Win32::GUI::SendMessage($self, 388, 0, 0);
  1471.     return $r;
  1472. }
  1473.     ###########################################################################
  1474.     # (@)METHOD:Clear()
  1475. sub Clear { Reset(@_); }
  1476.  
  1477.  
  1478.     ###########################################################################
  1479.     # (@)METHOD:RemoveItem(INDEX)
  1480.     # Removes the zero-based INDEX item from the Listbox.
  1481. sub RemoveItem {
  1482.     my $self = shift;
  1483.     my $item = shift;
  1484.     # 386 == LB_DELETESTRING
  1485.     my $r = Win32::GUI::SendMessage($self, 386, $item, 0);
  1486.     return $r;
  1487. }
  1488.  
  1489.     ###########################################################################
  1490.     # (@)METHOD:Count()
  1491.     # Returns the number of items in the Listbox.
  1492. sub Count {
  1493.     my $self = shift;
  1494.     # 395 == LB_GETCOUNT
  1495.     my $r = Win32::GUI::SendMessage($self, 395, 0, 0);
  1496.     return $r;
  1497. }
  1498.  
  1499. sub List {
  1500.     my $self = shift;
  1501.     my $index = shift;
  1502.     if(not defined $index) {
  1503.         my @list = ();
  1504.         for my $i (0..($self->Count-1)) {
  1505.             push @list, Win32::GUI::Listbox::Item->new($self, $i);
  1506.         }
  1507.         return @list;
  1508.     } else {
  1509.         return Win32::GUI::Listbox::Item->new($self, $index);
  1510.     }
  1511. }
  1512. sub Item { &List; }
  1513.  
  1514. ###############################################################################
  1515. # (@)PACKAGE:Win32::GUI::Listbox::Item
  1516. #
  1517. package Win32::GUI::Listbox::Item;
  1518.  
  1519. sub new {
  1520.     my($class, $listbox, $index) = @_;
  1521.     $self = {
  1522.         -parent => $listbox,
  1523.         -index  => $index,
  1524.         -string => $listbox->GetString($index),
  1525.     };
  1526.     return bless $self, $class;
  1527. }
  1528.  
  1529. sub Remove {
  1530.     my($self) = @_;
  1531.     $self->{-parent}->RemoveItem($self->{-index});
  1532.     undef $_[0];
  1533. }
  1534.  
  1535. sub Select {
  1536.     my($self) = @_;
  1537.     $self->{-parent}->Select($self->{-index});
  1538. }
  1539.  
  1540.  
  1541. ###############################################################################
  1542. # (@)PACKAGE:Win32::GUI::Combobox
  1543. #
  1544. package Win32::GUI::Combobox;
  1545. @ISA = qw(
  1546.     Win32::GUI
  1547.     Win32::GUI::WindowProps
  1548. );
  1549.  
  1550.     ###########################################################################
  1551.     # (@)METHOD:new Win32::GUI::Combobox(PARENT, %OPTIONS)
  1552.     # Creates a new Combobox object;
  1553.     # can also be called as PARENT->AddCombobox(%OPTIONS).
  1554. sub new {
  1555.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__COMBOBOX", 0), @_);
  1556. }
  1557.  
  1558.     ###########################################################################
  1559.     # (@)METHOD:SelectedItem()
  1560.     # Returns the zero-based index of the currently selected item, or -1 if
  1561.     # no item is selected.
  1562. sub SelectedItem {
  1563.     my $self = shift;
  1564.     # 327 == CB_GETCURSEL
  1565.     return Win32::GUI::SendMessage($self, 327, 0, 0);
  1566. }
  1567.     ###########################################################################
  1568.     # (@)METHOD:ListIndex()
  1569.     # See SelectedItem().
  1570. sub ListIndex { SelectedItem(@_); }
  1571.  
  1572.     ###########################################################################
  1573.     # (@)METHOD:Select(INDEX)
  1574.     # Selects the zero-based INDEX item in the Combobox.
  1575. sub Select {
  1576.     my $self = shift;
  1577.     my $item = shift;
  1578.     # 334 == CB_SETCURSEL
  1579.     my $r = Win32::GUI::SendMessage($self, 334, $item, 0);
  1580.     return $r;
  1581. }
  1582.  
  1583.     ###########################################################################
  1584.     # (@)METHOD:Reset()
  1585. sub Reset {
  1586.     my $self = shift;
  1587.     # 331 == CB_RESETCONTENT
  1588.     my $r = Win32::GUI::SendMessage($self, 331, 0, 0);
  1589.     return $r;
  1590. }
  1591.     ###########################################################################
  1592.     # (@)METHOD:Clear()
  1593. sub Clear { Reset(@_); }
  1594.  
  1595.     ###########################################################################
  1596.     # (@)METHOD:RemoveItem(INDEX)
  1597.     # Removes the zero-based INDEX item from the Combobox.
  1598. sub RemoveItem {
  1599.     my $self = shift;
  1600.     my $item = shift;
  1601.     # 324 == CB_DELETESTRING
  1602.     my $r = Win32::GUI::SendMessage($self, 324, $item, 0);
  1603.     return $r;
  1604. }
  1605.  
  1606.     ###########################################################################
  1607.     # (@)METHOD:Count()
  1608. sub Count {
  1609.     my $self = shift;
  1610.     # 326 == CB_GETCOUNT
  1611.     my $r = Win32::GUI::SendMessage($self, 326, 0, 0);
  1612.     return $r;
  1613. }
  1614.  
  1615.  
  1616.  
  1617. ###############################################################################
  1618. # (@)PACKAGE:Win32::GUI::ProgressBar
  1619. #
  1620. package Win32::GUI::ProgressBar;
  1621. @ISA = qw(
  1622.     Win32::GUI
  1623.     Win32::GUI::WindowProps
  1624. );
  1625.  
  1626.     ###########################################################################
  1627.     # (@)METHOD:new Win32::GUI::ProgressBar(PARENT, %OPTIONS)
  1628.     # Creates a new ProgressBar object;
  1629.     # can also be called as PARENT->AddProgressBar(%OPTIONS).
  1630.     # Class specific %OPTIONS are:
  1631.     #     -smooth   => 0/1 (default 0)
  1632.     #         uses a smooth bar instead of the default segmented bar.
  1633.     #     -vertical => 0/1 (default 0)
  1634.     #         display progress status vertically (from bottom to top).
  1635. sub new {
  1636.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__PROGRESS", 0), @_);
  1637. }
  1638.  
  1639.     ###########################################################################
  1640.     # (@)METHOD:SetPos(VALUE)
  1641.     # Sets the position of the ProgressBar to the specified VALUE.
  1642. sub SetPos {
  1643.     my $self = shift;
  1644.     my $pos = shift;
  1645.     # 1026 == PBM_SETPOS
  1646.     return Win32::GUI::SendMessage($self, 1026, $pos, 0);
  1647. }
  1648.  
  1649.     ###########################################################################
  1650.     # (@)METHOD:StepIt()
  1651.     # Increments the position of the ProgressBar of the defined step value;
  1652.     # see SetStep().
  1653. sub StepIt {
  1654.     my $self = shift;
  1655.     # 1029 == PBM_STEPIT
  1656.     return Win32::GUI::SendMessage($self, 1029, 0, 0);
  1657. }
  1658.  
  1659.     ###########################################################################
  1660.     # (@)METHOD:SetRange([MIN], MAX)
  1661. sub SetRange {
  1662.     my $self = shift;
  1663.     my ($min, $max) = @_;
  1664.     ($min, $max) = (0, $min) unless defined($max);
  1665.     # 1030 == PBM_SETRANGE32
  1666.     # return Win32::GUI::SendMessage($self, 1030, 0, ($max + $min >> 8));
  1667.     return Win32::GUI::SendMessage($self, 1030, $min, $max);
  1668. }
  1669.  
  1670.     ###########################################################################
  1671.     # (@)METHOD:SetStep([VALUE])
  1672.     # Sets the increment value for the ProgressBar; see StepIt().
  1673. sub SetStep {
  1674.     my $self = shift;
  1675.     my $step = shift;
  1676.     $step = 10 unless $step;
  1677.     # 1028 == PBM_SETSTEP
  1678.     return Win32::GUI::SendMessage($self, 1028, $step, 0);
  1679. }
  1680.  
  1681.     # TODO 4.71: Color, BackColor
  1682.  
  1683. ###############################################################################
  1684. # (@)PACKAGE:Win32::GUI::StatusBar
  1685. #
  1686. package Win32::GUI::StatusBar;
  1687. @ISA = qw(
  1688.     Win32::GUI
  1689.     Win32::GUI::WindowProps
  1690. );
  1691.  
  1692.     ###########################################################################
  1693.     # (@)METHOD:new Win32::GUI::StatusBar(PARENT, %OPTIONS)
  1694.     # Creates a new StatusBar object;
  1695.     # can also be called as PARENT->AddStatusBar(%OPTIONS).
  1696. sub new {
  1697.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__STATUS", 0), @_);
  1698. }
  1699.  
  1700.  
  1701. ###############################################################################
  1702. # (@)PACKAGE:Win32::GUI::TabStrip
  1703. #
  1704. package Win32::GUI::TabStrip;
  1705. @ISA = qw(
  1706.     Win32::GUI::Window
  1707.     Win32::GUI::WindowProps
  1708. );
  1709.  
  1710.     ###########################################################################
  1711.     # (@)METHOD:new Win32::GUI::TabStrip(PARENT, %OPTIONS)
  1712.     # Creates a new TabStrip object;
  1713.     # can also be called as PARENT->AddTabStrip(%OPTIONS).
  1714.     # Class specific %OPTIONS are:
  1715.     #   -bottom    => 0/1 (default 0)
  1716.     #   -buttons   => 0/1 (default 0)
  1717.     #   -hottrack  => 0/1 (default 0)
  1718.     #   -imagelist => Win32::GUI::ImageList object
  1719.     #   -justify   => 0/1 (default 0)
  1720.     #   -multiline => 0/1 (default 0)
  1721.     #   -right     => 0/1 (default 0)
  1722.     #   -vertical  => 0/1 (default 0)
  1723. sub new {
  1724.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__TAB", 0), @_);
  1725. }
  1726.  
  1727.     ###########################################################################
  1728.     # (@)METHOD:SelectedItem()
  1729.     # Returns the zero-based index of the currently selected item.
  1730. sub SelectedItem {
  1731.     my $self = shift;
  1732.     # 4875 == TCM_GETCURSEL
  1733.     return Win32::GUI::SendMessage($self, 4875, 0, 0);
  1734. }
  1735.  
  1736.     ###########################################################################
  1737.     # (@)METHOD:Select(INDEX)
  1738.     # Selects the zero-based INDEX item in the TabStrip.
  1739. sub Select {
  1740.     my $self = shift;
  1741.     # 4876 == TCM_SETCURSEL
  1742.     return Win32::GUI::SendMessage($self, 4876, shift, 0);
  1743. }
  1744.  
  1745.     ###########################################################################
  1746.     # (@)METHOD:DisplayArea()
  1747. sub DisplayArea {
  1748.     my $self = shift;
  1749.     my ($left,$top,$right,$bottom) = $self->AdjustRect($self->GetClientRect());
  1750.     return ($left, $top, $right - $left, $bottom - $top);
  1751. }
  1752.  
  1753.  
  1754. ###############################################################################
  1755. # (@)PACKAGE:Win32::GUI::Toolbar
  1756. #
  1757. package Win32::GUI::Toolbar;
  1758. @ISA = qw(
  1759.     Win32::GUI
  1760.     Win32::GUI::WindowProps
  1761. );
  1762.  
  1763.     ###########################################################################
  1764.     # (@)METHOD:new Win32::GUI::Toolbar(PARENT, %OPTIONS)
  1765.     # Creates a new Toolbar object;
  1766.     # can also be called as PARENT->AddToolbar(%OPTIONS).
  1767.     # Class specific %OPTIONS are:
  1768.     #   -flat      => 0/1
  1769.     #   -imagelist => IMAGELIST
  1770.     #   -multiline => 0/1
  1771.     #   -nodivider => 0/1
  1772. sub new {
  1773.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__TOOLBAR", 0), @_);
  1774. }
  1775.  
  1776.     ###########################################################################
  1777.     # (@)METHOD:SetBitmapSize([X, Y])
  1778. sub SetBitmapSize {
  1779.     my $self = shift;
  1780.     my ($x, $y) = @_;
  1781.     $x = 16 unless defined($x);
  1782.     $y = 15 unless defined($y);
  1783.     # 1056 == TB_SETBITMAPSIZE
  1784.     return Win32::GUI::SendMessage($self, 1056, 0, ($x | $y << 16));
  1785. }
  1786.  
  1787.  
  1788. ###############################################################################
  1789. # (@)PACKAGE:Win32::GUI::RichEdit
  1790. #
  1791. package Win32::GUI::RichEdit;
  1792. @ISA = qw(
  1793.     Win32::GUI
  1794.     Win32::GUI::WindowProps
  1795. );
  1796.  
  1797.     ###########################################################################
  1798.     # (@)METHOD:new Win32::GUI::RichEdit(PARENT, %OPTIONS)
  1799.     # Creates a new RichEdit object;
  1800.     # can also be called as PARENT->AddRichEdit(%OPTIONS).
  1801. sub new {
  1802.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__RICHEDIT", 0), @_);
  1803. }
  1804.  
  1805.  
  1806. ###############################################################################
  1807. # (@)PACKAGE:Win32::GUI::ListView
  1808. #
  1809. package Win32::GUI::ListView;
  1810. @ISA = qw(
  1811.     Win32::GUI
  1812.     Win32::GUI::WindowProps
  1813. );
  1814.  
  1815.     ###########################################################################
  1816.     # (@)METHOD:new Win32::GUI::ListView(PARENT, %OPTIONS)
  1817.     # Creates a new ListView object;
  1818.     # can also be called as PARENT->AddListView(%OPTIONS).
  1819. sub new {
  1820.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__LISTVIEW", 0), @_);
  1821. }
  1822.  
  1823. sub Item {
  1824.     my($self, $index) = @_;
  1825.     return Win32::GUI::ListView::Item->new($self, $index);
  1826. }
  1827.  
  1828. ###############################################################################
  1829. # (@)PACKAGE:Win32::GUI::ListView::Item
  1830. #
  1831. package Win32::GUI::ListView::Item;
  1832.  
  1833. sub new {
  1834.     my($class, $listview, $index) = @_;
  1835.     my $self = {
  1836.         -parent => $listview,
  1837.         -index  => $index,
  1838.     };
  1839.     return bless $self, $class;
  1840. }
  1841.  
  1842. sub SubItem {
  1843.     my($self, $index) = @_;
  1844.     return Win32::GUI::ListView::SubItem->new($self, $index);
  1845. }
  1846.  
  1847. sub Remove {
  1848.     my($self) = @_;
  1849.     $self->{-parent}->DeleteItem($self->{-index});
  1850.     undef $_[0];
  1851. }
  1852.  
  1853. sub Select {
  1854.     my($self) = @_;
  1855.     $self->{-parent}->Select($self->{-index});
  1856. }
  1857.  
  1858. sub Text {
  1859.     my($self, $text) = @_;
  1860.     if(not defined $text) {
  1861.         my %data = $self->{-parent}->ItemInfo($self->{-index});
  1862.         return $data{-text};
  1863.     } else {
  1864.         return $self->{-parent}->ChangeItem(
  1865.             -item => $self->{-index},
  1866.             -text => $text,
  1867.         );
  1868.     }
  1869. }
  1870.  
  1871. ###############################################################################
  1872. # (@)PACKAGE:Win32::GUI::ListView::SubItem
  1873. #
  1874. package Win32::GUI::ListView::SubItem;
  1875.  
  1876. sub new {
  1877.     my($class, $parent, $index) = @_;
  1878.     my $self = {
  1879.         -parent    => $parent->{-parent},
  1880.         -index     => $parent->{-index},
  1881.         -subindex  => $index,
  1882.     };
  1883.     return bless $self, $class;
  1884. }
  1885.  
  1886. sub Text {
  1887.     my($self, $text) = @_;
  1888.     if(not defined $text) {
  1889.         my %data = $self->{-parent}->ItemInfo(
  1890.             $self->{-index},
  1891.             $self->{-subindex},
  1892.         );
  1893.         return $data{-text};
  1894.     } else {
  1895.         return $self->{-parent}->ChangeItem(
  1896.             -item => $self->{-index},
  1897.             -subitem => $self->{-subindex},
  1898.             -text => $text,
  1899.         );
  1900.     }
  1901. }
  1902.  
  1903. ###############################################################################
  1904. # (@)PACKAGE:Win32::GUI::TreeView
  1905. #
  1906. package Win32::GUI::TreeView;
  1907. @ISA = qw(
  1908.     Win32::GUI
  1909.     Win32::GUI::WindowProps
  1910. );
  1911.  
  1912.     ###########################################################################
  1913.     # (@)METHOD:new Win32::GUI::TreeView(PARENT, %OPTIONS)
  1914.     # Creates a new TreeView object
  1915.     # can also be called as PARENT->AddTreeView(%OPTIONS).
  1916. sub new {
  1917.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__TREEVIEW", 0), @_);
  1918. }
  1919.  
  1920. ###############################################################################
  1921. # (@)PACKAGE:Win32::GUI::Slider
  1922. # also Trackbar
  1923. #
  1924. package Win32::GUI::Trackbar;
  1925. @ISA = qw(
  1926.     Win32::GUI
  1927.     Win32::GUI::WindowProps
  1928. );
  1929.  
  1930.     ###########################################################################
  1931.     # (@)METHOD:new Win32::GUI::Slider(PARENT, %OPTIONS)
  1932.     # Creates a new Slider object;
  1933.     # can also be called as PARENT->AddSlider(%OPTIONS).
  1934. sub new {
  1935.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__TRACKBAR", 0), @_);
  1936. }
  1937.  
  1938. sub SetRange {
  1939.  
  1940. }
  1941.  
  1942. sub Min {
  1943.     my $self = shift;
  1944.     my $value = shift;
  1945.     if(defined($value)) {
  1946.         my $flag = shift;
  1947.         $flag = 1 unless defined($flag);
  1948.         # 1031 == TBM_SETRANGEMIN
  1949.         return Win32::GUI::SendMessage($self, 1031, $flag, $value);
  1950.     } else {
  1951.         # 1025 == TBM_GETRANGEMIN
  1952.         return Win32::GUI::SendMessage($self, 1025, 0, 0);
  1953.     }
  1954. }
  1955.  
  1956. sub Max {
  1957.     my $self = shift;
  1958.     my $value = shift;
  1959.     if(defined($value)) {
  1960.         my $flag = shift;
  1961.         $flag = 1 unless defined($flag);
  1962.         # 1032 == TBM_SETRANGEMAX
  1963.         return Win32::GUI::SendMessage($self, 1032, $flag, $value);
  1964.     } else {
  1965.         # 1026 == TBM_GETRANGEMAX
  1966.         return Win32::GUI::SendMessage($self, 1026, 0, 0);
  1967.     }
  1968. }
  1969.  
  1970. sub Pos {
  1971.     my $self = shift;
  1972.     my $value = shift;
  1973.     if(defined($value)) {
  1974.         my $flag = shift;
  1975.         $flag = 1 unless defined($flag);
  1976.         # 1029 == TBM_SETPOS
  1977.         return Win32::GUI::SendMessage($self, 1029, $flag, $value);
  1978.     } else {
  1979.         # 1024 == TBM_GETPOS
  1980.         return Win32::GUI::SendMessage($self, 1024, 0, 0);
  1981.     }
  1982. }
  1983.  
  1984. sub TicFrequency {
  1985.     my $self = shift;
  1986.     my $value = shift;
  1987.     # 1044 == TBM_SETTICFREQ
  1988.     return Win32::GUI::SendMessage($self, 1044, $value, 0);
  1989. }
  1990.  
  1991.  
  1992. ###############################################################################
  1993. # (@)PACKAGE:Win32::GUI::Slider
  1994. #
  1995. package Win32::GUI::Slider;
  1996. @ISA = qw(Win32::GUI::Trackbar);
  1997.  
  1998. ###############################################################################
  1999. # (@)PACKAGE:Win32::GUI::UpDown
  2000. #
  2001. package Win32::GUI::UpDown;
  2002. @ISA = qw(
  2003.     Win32::GUI
  2004.     Win32::GUI::WindowProps
  2005. );
  2006.  
  2007.     ###########################################################################
  2008.     # (@)METHOD:new Win32::GUI::UpDown(PARENT, %OPTIONS)
  2009.     # Creates a new UpDown object;
  2010.     # can also be called as PARENT->AddUpDown(%OPTIONS).
  2011. sub new {
  2012.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__UPDOWN", 0), @_);
  2013. }
  2014.  
  2015. ###############################################################################
  2016. # (@)PACKAGE:Win32::GUI::Tooltip
  2017. #
  2018. package Win32::GUI::Tooltip;
  2019. @ISA = qw(
  2020.     Win32::GUI
  2021.     Win32::GUI::WindowProps
  2022. );
  2023.  
  2024.     ###########################################################################
  2025.     # (@)METHOD:new Win32::GUI::Tooltip(PARENT, %OPTIONS)
  2026.     # (preliminary) creates a new Tooltip object
  2027. sub new {
  2028.     my $parent = $_[1];
  2029.     my $new = Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__TOOLTIP", 0), @_);
  2030.     if($new) {
  2031.         if($parent->{-tooltips}) {
  2032.             push(@{$parent->{-tooltips}}, $new->{-handle});
  2033.         } else {
  2034.             $parent->{-tooltips} = [ $new->{-handle} ];
  2035.         }
  2036.     }
  2037.     return $new;
  2038. }
  2039.  
  2040. ###############################################################################
  2041. # (@)PACKAGE:Win32::GUI::Animation
  2042. #
  2043. package Win32::GUI::Animation;
  2044. @ISA = qw(
  2045.     Win32::GUI
  2046.     Win32::GUI::WindowProps
  2047. );
  2048.  
  2049.     ###########################################################################
  2050.     # (@)METHOD:new Win32::GUI::Animation(PARENT, %OPTIONS)
  2051.     # Creates a new Animation object;
  2052.     # can also be called as PARENT->AddAnimation(%OPTIONS).
  2053.     # Class specific %OPTIONS are:
  2054.     #   -autoplay    => 0/1 (default 0)
  2055.     #     starts playing the animation as soon as an AVI clip is loaded
  2056.     #   -center      => 0/1 (default 0)
  2057.     #     centers the animation in the control window
  2058.     #   -transparent => 0/1 (default 0)
  2059.     #     draws the animation using a transparent background
  2060. sub new {
  2061.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__ANIMATION", 0), @_);
  2062. }
  2063.  
  2064. ###############################################################################
  2065. # (@)PACKAGE:Win32::GUI::Rebar
  2066. #
  2067. package Win32::GUI::Rebar;
  2068. @ISA = qw(
  2069.     Win32::GUI
  2070.     Win32::GUI::WindowProps
  2071. );
  2072.  
  2073.     ###########################################################################
  2074.     # (@)METHOD:new Win32::GUI::Rebar(PARENT, %OPTIONS)
  2075.     # Creates a new Rebar object;
  2076.     # can also be called as PARENT->AddRebar(%OPTIONS).
  2077.     # Class specific %OPTIONS are:
  2078.     #   -bandborders => 0/1 (default 0)
  2079.     #     display a border to separate bands.
  2080.     #   -fixedorder => 0/1 (default 0)
  2081.     #     band position cannot be swapped.
  2082.     #   -imagelist => Win32::GUI::ImageList object
  2083.     #   -varheight => 0/1 (default 1)
  2084.     #     display bands using the minimum required height.
  2085. sub new {
  2086.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__REBAR", 0), @_);
  2087. }
  2088.  
  2089. ###############################################################################
  2090. # (@)PACKAGE:Win32::GUI::Header
  2091. #
  2092. package Win32::GUI::Header;
  2093. @ISA = qw(
  2094.     Win32::GUI
  2095.     Win32::GUI::WindowProps
  2096. );
  2097.  
  2098.     ###########################################################################
  2099.     # (@)METHOD:new Win32::GUI::Header(PARENT, %OPTIONS)
  2100.     # Creates a new Header object;
  2101.     # can also be called as PARENT->AddHeader(%OPTIONS).
  2102.     # Class specific %OPTIONS are:
  2103.     #   -buttons => 0/1 (default 0)
  2104.     #     header items look like push buttons and can be clicked.
  2105.     #   -hottrack => 0/1 (default 0)
  2106.     #   -imagelist => Win32::GUI::ImageList object
  2107. sub new {
  2108.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__HEADER", 0), @_);
  2109. }
  2110.  
  2111. ###############################################################################
  2112. # (@)PACKAGE:Win32::GUI::Splitter
  2113. #
  2114. package Win32::GUI::Splitter;
  2115. @ISA = qw(
  2116.     Win32::GUI
  2117.     Win32::GUI::WindowProps
  2118. );
  2119.  
  2120.     ###########################################################################
  2121.     # (@)METHOD:new Win32::GUI::Splitter(PARENT, %OPTIONS)
  2122.     # Creates a new Splitter object;
  2123.     # can also be called as PARENT->AddHeader(%OPTIONS).
  2124.     # Class specific %OPTIONS are:
  2125.     #   -buttons => 0/1 (default 0)
  2126.     #     header items look like push buttons and can be clicked.
  2127.     #   -hottrack => 0/1 (default 0)
  2128.     #   -imagelist => Win32::GUI::ImageList object
  2129. sub new {
  2130.     my $new = Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__SPLITTER", 0), @_);
  2131.     if($new) {
  2132.         $new->{-tracking} = 0;
  2133.         return $new;
  2134.     } else {
  2135.         return undef;
  2136.     }
  2137. }
  2138.  
  2139. ###############################################################################
  2140. # (@)PACKAGE:Win32::GUI::ComboboxEx
  2141. #
  2142. package Win32::GUI::ComboboxEx;
  2143. @ISA = qw(
  2144.     Win32::GUI::Combobox
  2145. );
  2146.  
  2147.     ###########################################################################
  2148.     # (@)METHOD:new Win32::GUI::ComboboxEx(PARENT, %OPTIONS)
  2149.     # Creates a new ComboboxEx object;
  2150.     # can also be called as PARENT->AddComboboxEx(%OPTIONS).
  2151.     # Class specific %OPTIONS are:
  2152.     #   -imagelist => Win32::GUI::ImageList object
  2153.     # Except for images, a ComboboxEx object acts like a Win32::GUI::Combobox
  2154.     # object. See also new Win32::GUI::Combobox().
  2155. sub new {
  2156.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__COMBOBOXEX", 0), @_);
  2157. }
  2158.  
  2159. ###############################################################################
  2160. # (@)PACKAGE:Win32::GUI::DateTime
  2161. #
  2162. package Win32::GUI::DateTime;
  2163. @ISA = qw(
  2164.     Win32::GUI
  2165.     Win32::GUI::WindowProps
  2166. );
  2167.  
  2168.     ###########################################################################
  2169.     # (@)METHOD:new Win32::GUI::DateTime(PARENT, %OPTIONS)
  2170.     # Creates a new DateTime object;
  2171.     # can also be called as PARENT->AddDateTime(%OPTIONS).
  2172.     # Class specific %OPTIONS are:
  2173.     #   -align  => 'right'/'left' (default 'left')
  2174.     #     The drop-down month calendar alignement.
  2175.     #   -format => 'shortdate', 'longdate', 'time'
  2176.     #     Control format type (Use local format date/time).
  2177.     #   -shownone => 0/1 (default 0)
  2178.     #     Allow no datetime (add a prefix checkbox).
  2179.     #   -updown   => 0/1 (default 0 for date, 1 for time format)
  2180.     #     Use updown control instead of the drop-down month calendar.
  2181. sub new {
  2182.     return Win32::GUI->_new(Win32::GUI::constant("WIN32__GUI__DTPICK", 0), @_);
  2183. }
  2184.  
  2185. ###############################################################################
  2186. # (@)PACKAGE:Win32::GUI::Graphic
  2187. #
  2188. package Win32::GUI::Graphic;
  2189. @ISA = qw(
  2190.     Win32::GUI
  2191.     Win32::GUI::WindowProps
  2192. );
  2193.  
  2194.     ###########################################################################
  2195.     # (@)METHOD:new Win32::GUI::Graphic(PARENT, %OPTIONS)
  2196.     # Creates a new Graphic object;
  2197.     # can also be called as PARENT->AddGraphic(%OPTIONS).
  2198.     # Class specific %OPTIONS are:
  2199. sub new {
  2200.     my $class = shift;
  2201.     my $self = {};
  2202.     bless($self, $class);
  2203.     my(@input) = @_;
  2204.     my $handle = Win32::GUI::Create($self, 101, @input);
  2205.     if($handle) {
  2206.         return $self;
  2207.     } else {
  2208.         return undef;
  2209.     }
  2210. }
  2211.  
  2212.     ###########################################################################
  2213.     # (@)METHOD:GetDC()
  2214.     # Returns the DC object associated with the window.
  2215. sub GetDC {
  2216.     my $self = shift;
  2217.     return Win32::GUI::DC->new($self);
  2218. }
  2219.  
  2220.  
  2221. ###############################################################################
  2222. # (@)PACKAGE:Win32::GUI::ImageList
  2223. #
  2224. package Win32::GUI::ImageList;
  2225. @ISA = qw(Win32::GUI);
  2226.  
  2227.     ###########################################################################
  2228.     # (@)METHOD:new Win32::GUI::ImageList(X, Y, FLAGS, INITAL, GROW)
  2229.     # Creates an ImageList object; X and Y specify the size of the images,
  2230.     # FLAGS [TBD]. INITIAL and GROW specify the number of images the ImageList
  2231.     # actually contains (INITIAL) and the number of images for which memory
  2232.     # is allocated (GROW).
  2233. sub new {
  2234.     my $class = shift;
  2235.     my $self = {};
  2236.     my $handle = Win32::GUI::ImageList::Create(@_);
  2237.     if($handle) {
  2238.         $self->{-handle} = $handle;
  2239.         bless($self, $class);
  2240.         return $self;
  2241.     } else {
  2242.         return undef;
  2243.     }
  2244. }
  2245.  
  2246.     ###########################################################################
  2247.     # (@)METHOD:Add(BITMAP, [BITMAPMASK])
  2248.     # Adds a bitmap to the ImageList; both BITMAP and BITMAPMASK can be either
  2249.     # Win32::GUI::Bitmap objects or filenames.
  2250. sub Add {
  2251.     my($self, $bitmap, $bitmapMask) = @_;
  2252.     $bitmap = new Win32::GUI::Bitmap($bitmap) unless ref($bitmap);
  2253.     if(defined($bitmapMask)) {
  2254.         $bitmapMask = new Win32::GUI::Bitmap($bitmapMask) unless ref($bitmapMask);
  2255.         $self->AddBitmap($bitmap, $bitmapMask);
  2256.     } else {
  2257.         $self->AddBitmap($bitmap);
  2258.     }
  2259. }
  2260.  
  2261. ###############################################################################
  2262. # (@)PACKAGE:Win32::GUI::Menu
  2263. #
  2264. package Win32::GUI::Menu;
  2265. @ISA = qw(Win32::GUI);
  2266.  
  2267.     ###########################################################################
  2268.     # (@)METHOD:new Win32::GUI::Menu(...)
  2269. sub new {
  2270.     my $class = shift;
  2271.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2272.     my $self = {};
  2273.  
  2274.     if($#_ > 0) {
  2275.         return Win32::GUI::MakeMenu(@_);
  2276.     } else {
  2277.         my $handle = Win32::GUI::CreateMenu();
  2278.  
  2279.         if($handle) {
  2280.             $self->{-handle} = $handle;
  2281.             bless($self, $class);
  2282.             return $self;
  2283.         } else {
  2284.             return undef;
  2285.         }
  2286.     }
  2287. }
  2288.  
  2289.     ###########################################################################
  2290.     # (@)METHOD:AddMenuButton()
  2291.     # see new Win32::GUI::MenuButton()
  2292. sub AddMenuButton {
  2293.     return Win32::GUI::MenuButton->new(@_);
  2294. }
  2295.  
  2296. ###############################################################################
  2297. # (@)PACKAGE:Win32::GUI::MenuButton
  2298. #
  2299. package Win32::GUI::MenuButton;
  2300. @ISA = qw(Win32::GUI);
  2301.  
  2302.     ###########################################################################
  2303.     # (@)METHOD:new Win32::GUI::MenuButton()
  2304. sub new {
  2305.     my $class = shift;
  2306.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2307.     my $menu = shift;
  2308.     $menu = $menu->{-handle} if ref($menu);
  2309.     # print "new MenuButton: menu=$menu\n";
  2310.     my %args = @_;
  2311.     my $self = {};
  2312.  
  2313.     my $handle = Win32::GUI::CreatePopupMenu();
  2314.  
  2315.     if($handle) {
  2316.         $args{-submenu} = $handle;
  2317.         # print "PM(MenuButton::new) calling InsertMenuItem with menu=$menu, args=", join(", ", %args), "\n";
  2318.         Win32::GUI::MenuButton::InsertMenuItem($menu, %args);
  2319.         # print "PM(MenuButton::new) back from InsertMenuItem\n";
  2320.         $self->{-handle} = $handle;
  2321.         bless($self, $class);
  2322.         $Win32::GUI::Menus{ $args{-id} } = $handle;
  2323.         #if($args{-name}) {
  2324.         #    $Win32::GUI::Menus{$args{-id}} = $self;
  2325.         #    $self->{-name} = $args{-name};
  2326.         #}
  2327.         # print "PM(MenuButton::new) returning self=$self\n";
  2328.         return $self;
  2329.     } else {
  2330.         return undef;
  2331.     }
  2332. }
  2333.  
  2334.     ###########################################################################
  2335.     # (@)METHOD:AddMenuItem()
  2336.     # see new Win32::GUI::MenuItem()
  2337. sub AddMenuItem {
  2338.     return Win32::GUI::MenuItem->new(@_);
  2339. }
  2340.  
  2341. ###############################################################################
  2342. # (@)PACKAGE:Win32::GUI::MenuItem
  2343. #
  2344. package Win32::GUI::MenuItem;
  2345. @ISA = qw(Win32::GUI);
  2346.  
  2347.     ###########################################################################
  2348.     # (@)METHOD:new Win32::GUI::MenuItem()
  2349. sub new {
  2350.     my $class = shift;
  2351.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2352.     my $menu = shift;
  2353.     return undef unless ref($menu) =~ /^Win32::GUI::Menu/;
  2354.     my %args = @_;
  2355.     my $self = {};
  2356.  
  2357.     # print "PM(MenuItem::new) calling InsertMenuItem with menu=$menu, args=", join(", ", %args), "\n";
  2358.     my $handle = Win32::GUI::MenuButton::InsertMenuItem($menu, %args);
  2359.     # print "PM(MenuItem::new) back from InsertMenuItem\n";
  2360.  
  2361.     if($handle) {
  2362.         # $self->{-handle} = $handle;
  2363.         # $Win32::GUI::menucallbacks{$args{-id}} = $args{-function} if $args{-function};
  2364.         $self->{-id} = $args{-id};
  2365.         $self->{-menu} = $menu->{-handle};
  2366.         bless($self, $class);
  2367.         $Win32::GUI::Menus{ $args{-id} } = $menu->{-handle};
  2368.         #if($args{-name}) {
  2369.         #    $Win32::GUI::Menus{$args{-id}} = $self;
  2370.         #    $self->{-name} = $args{-name};
  2371.         #}
  2372.         # print "PM(MenuItem::new) returning self=$self\n";
  2373.         return $self;
  2374.     } else {
  2375.         return undef;
  2376.     }
  2377. }
  2378.  
  2379. ###############################################################################
  2380. # (@)PACKAGE: Win32::GUI::Timer
  2381. #
  2382. package Win32::GUI::Timer;
  2383. @ISA = qw(Win32::GUI);
  2384.  
  2385.     ###########################################################################
  2386.     # (@)METHOD:new Win32::GUI::Timer(PARENT, NAME, ELAPSE)
  2387.     # Creates a new timer in the PARENT window named NAME that will
  2388.     # trigger its Timer() event after ELAPSE milliseconds.
  2389.     # Can also be called as PARENT->AddTimer(NAME, ELAPSE).
  2390. sub new {
  2391.     my $class = shift;
  2392.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2393.     my $window = shift;
  2394.     my $name = shift;
  2395.     my $elapse = shift;
  2396.  
  2397.     my %args = @_;
  2398.     my $id = $Win32::GUI::TimerIdCounter;
  2399.  
  2400.     $Win32::GUI::TimerIdCounter++;
  2401.  
  2402.     Win32::GUI::SetTimer($window, $id, $elapse);
  2403.  
  2404.     my $self = {};
  2405.     bless($self, $class);
  2406.  
  2407.     # add $self->{name}
  2408.     $self->{-id} = $id;
  2409.     $self->{-name} = $name;
  2410.     $self->{-parent} = $window;
  2411.     $self->{-handle} = $window->{-handle};
  2412.     $self->{-interval} = $elapse;
  2413.  
  2414.     # add to $window->timers->{$id} = $self;
  2415.     $window->{-timers}->{$id} = $self;
  2416.     $window->{$name} = $self;
  2417.  
  2418.     return $self;
  2419. }
  2420.  
  2421.     ###########################################################################
  2422.     # (@)METHOD:Interval(ELAPSE)
  2423. sub Interval {
  2424.     my $self = shift;
  2425.     my $interval = shift;
  2426.     if(defined $interval) {
  2427.         Win32::GUI::SetTimer($self->{-parent}->{-handle}, $self->{-id}, $interval);
  2428.         $self->{-interval} = $interval;
  2429.     } else {
  2430.         return $self->{-interval};
  2431.     }
  2432. }
  2433.  
  2434.     ###########################################################################
  2435.     # (@)METHOD:Kill()
  2436. sub Kill {
  2437.     my $self = shift;
  2438.     Win32::GUI::KillTimer($self->{-parent}->{-handle}, $self->{-id});
  2439. }
  2440.  
  2441.     ###########################################################################
  2442.     # (@)INTERNAL:DESTROY(HANDLE)
  2443. sub DESTROY {
  2444.     my $self = shift;
  2445.     Win32::GUI::KillTimer($self->{-handle}, $self->{-id});
  2446.     undef $self->{-parent}->{-timers}->{$self->{-id}};
  2447. }
  2448.  
  2449.  
  2450. ###############################################################################
  2451. # (@)PACKAGE:Win32::GUI::NotifyIcon
  2452. #
  2453. package Win32::GUI::NotifyIcon;
  2454.  
  2455.     ###########################################################################
  2456.     # (@)METHOD:new Win32::GUI::NotifyIcon(PARENT, %OPTIONS)
  2457.     # Creates a new NotifyIcon (also known as system tray icon) object;
  2458.     # can also be called as PARENT->AddNotifyIcon(%OPTIONS).
  2459.     # %OPTIONS are:
  2460.     #     -icon => Win32::GUI::Icon object
  2461.     #     -id => NUMBER
  2462.     #         a unique identifier for the NotifyIcon object
  2463.     #     -name => STRING
  2464.     #         the name for the object
  2465.     #     -tip => STRING
  2466.     #         the text that will appear as tooltip when the mouse is
  2467.     #         on the NotifyIcon
  2468. sub new {
  2469.     my $class = shift;
  2470.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2471.     my $window = shift;
  2472.  
  2473.     my %args = @_;
  2474.  
  2475.     $Win32::GUI::NotifyIconIdCounter++;
  2476.  
  2477.     if(!exists($args{-id})) {
  2478.         $args{-id} = $Win32::GUI::NotifyIconIdCounter;
  2479.     }
  2480.  
  2481.     Win32::GUI::NotifyIcon::Add($window, %args);
  2482.  
  2483.     my $self = {};
  2484.     bless($self, $class);
  2485.  
  2486.     $self->{-id} = $args{-id};
  2487.     $self->{-name} = $args{-name};
  2488.     $self->{-parent} = $window;
  2489.     $self->{-handle} = $window->{-handle};
  2490.  
  2491.     $window->{-notifyicons}->{$args{-id}} = $self;
  2492.     $window->{$args{-name}} = $self;
  2493.  
  2494.     return $self;
  2495. }
  2496.  
  2497.     ###########################################################################
  2498.     # (@)INTERNAL:DESTROY(OBJECT)
  2499.  
  2500. sub DESTROY {
  2501.     my($self) = @_;
  2502.     if ( defined $self &&
  2503.          defined $self->{-parent} &&
  2504.          defined $self->{-id} &&
  2505.          defined $self->{-parent}->{$self->{-name}} ) {
  2506.         Win32::GUI::NotifyIcon::Delete(
  2507.             $self->{-parent},
  2508.             -id => $self->{-id},
  2509.         );
  2510.         undef $self->{-parent}->{$self->{-name}};
  2511.     }
  2512. }
  2513.  
  2514. ###############################################################################
  2515. # (@)PACKAGE:Win32::GUI::DC
  2516. #
  2517. package Win32::GUI::DC;
  2518.  
  2519.     ###########################################################################
  2520.     # (@)METHOD:new Win32::GUI::DC(WINDOW | DRIVER, DEVICE)
  2521.     # Creates a new DC object; the first form (WINDOW is a Win32::GUI object)
  2522.     # gets the DC for the specified window (can also be called as
  2523.     # WINDOW->GetDC). The second form creates a DC for the specified DEVICE;
  2524.     # actually, the only supported DRIVER is the display driver (eg. the
  2525.     # screen). To get the DC for the entire screen use:
  2526.     #     $Screen = new Win32::GUI::DC("DISPLAY");
  2527.     #
  2528. sub new {
  2529.     my $class = shift;
  2530.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2531.  
  2532.     my $self = {};
  2533.     bless($self, $class);
  2534.  
  2535.     my $window = shift;
  2536.     if(defined($window)) {
  2537.         if(ref($window)) {
  2538.             $self->{-handle} = GetDC($window->{-handle});
  2539.             $self->{-window} = $window->{-handle};
  2540.         } else {
  2541.             my $device = shift;
  2542.             $self->{-handle} = CreateDC($window, $device);
  2543.         }
  2544.     } else {
  2545.         $self = CreateDC("DISPLAY", 0);
  2546.     }
  2547.     return $self;
  2548. }
  2549.  
  2550. sub DESTROY {
  2551.     my $self = shift;
  2552.     if($self->{-window}) {
  2553.         ReleaseDC($self->{-window}, $self->{-handle});
  2554.     } else {
  2555.         DeleteDC($self->{-handle});
  2556.     }
  2557. }
  2558.  
  2559. ###############################################################################
  2560. # (@)PACKAGE:Win32::GUI::Pen
  2561. #
  2562. package Win32::GUI::Pen;
  2563.  
  2564.     ###########################################################################
  2565.     # (@)METHOD:new Win32::GUI::Pen(COLOR | %OPTIONS)
  2566.     # Creates a new Pen object.
  2567.     # Allowed %OPTIONS are:
  2568.     #   -style =>
  2569.     #     0 PS_SOLID
  2570.     #     1 PS_DASH
  2571.     #     2 PS_DOT
  2572.     #     3 PS_DASHDOT
  2573.     #     4 PS_DASHDOTDOT
  2574.     #     5 PS_NULL
  2575.     #     6 PS_INSIDEFRAME
  2576.     #   -width => number
  2577.     #   -color => COLOR
  2578. sub new {
  2579.     my $class = shift;
  2580.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2581.  
  2582.     my $self = {};
  2583.     bless($self, $class);
  2584.     $self->{-handle} = Create(@_);
  2585.     return $self;
  2586. }
  2587.  
  2588. ###############################################################################
  2589. # (@)PACKAGE:Win32::GUI::Brush
  2590. #
  2591. package Win32::GUI::Brush;
  2592.  
  2593.     ###########################################################################
  2594.     # (@)METHOD:new Win32::GUI::Brush(COLOR | %OPTIONS)
  2595.     # Creates a new Brush object.
  2596.     # Allowed %OPTIONS are:
  2597.     #   -style =>
  2598.     #     0 BS_SOLID
  2599.     #     1 BS_NULL
  2600.     #     2 BS_HATCHED
  2601.     #     3 BS_PATTERN
  2602.     #   -pattern => Win32::GUI::Bitmap object (valid for -style => BS_PATTERN)
  2603.     #   -hatch => (valid for -style => BS_HATCHED)
  2604.     #     0 HS_ORIZONTAL (-----)
  2605.     #     1 HS_VERTICAL  (|||||)
  2606.     #     2 HS_FDIAGONAL (\\\\\)
  2607.     #     3 HS_BDIAGONAL (/////)
  2608.     #     4 HS_CROSS     (+++++)
  2609.     #     5 HS_DIAGCROSS (xxxxx)
  2610.     #   -color => COLOR
  2611. sub new {
  2612.     my $class = shift;
  2613.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2614.  
  2615.     my $self = {};
  2616.     bless($self, $class);
  2617.     $self->{-handle} = Create(@_);
  2618.     return $self;
  2619. }
  2620.  
  2621.  
  2622. ###############################################################################
  2623. # (@)PACKAGE:Win32::GUI::AcceleratorTable
  2624. # an accelerator table
  2625. #
  2626.  
  2627. package Win32::GUI::AcceleratorTable;
  2628.  
  2629.     ###########################################################################
  2630.     # (@)METHOD:new Win32::GUI::AcceleratorTable(%ACCELERATORS)
  2631.     # Creates an AcceleratorTable object.
  2632.     # %ACCELERATORS is an associative array of key combinations and
  2633.     # accelerator names, in pair:
  2634.     # Example:
  2635.     #     $A = new Win32::GUI::AcceleratorTable(
  2636.     #         "Ctrl-X"       => "Close",
  2637.     #         "Shift-N"      => "New",
  2638.     #         "Ctrl-Alt-Del" => "Reboot",
  2639.     #     );
  2640.     # The AcceleratorTable object can be associated to a window
  2641.     # with the -accel option; then, when an accelerator is used, a
  2642.     # corresponding <name>_Click event is fired.
  2643.     # Keyboard combinations currently support the following modifier :
  2644.     #     Shift
  2645.     #     Ctrl  (or Control)
  2646.     #     Alt
  2647.     # and the following keys:
  2648.     #     A..Z, 0..9
  2649.     #     Left, Right, Up, Down
  2650.     #     Home, End, PageUp, PageDown (or PgUp/PgDn)
  2651.     #     Space, Ins, Del, Esc, Backspace, Tab, Return
  2652.     #     F1..F12
  2653. sub new {
  2654.     my $class = shift;
  2655.     $class = "Win32::" . $class if $class =~ /^GUI::/;
  2656.     my($k, $v);
  2657.     my $flag = 0;
  2658.     my $key = 0;
  2659.     my %accels = @_;
  2660.  
  2661.     while( ($k, $v) = each %accels) {
  2662.         $flag = 0x0001;
  2663.         if($k =~ s/shift[-\+]//i)                { $flag |= 0x0004; }
  2664.         if($k =~ s/(ctrl|control)[-\+]//i)       { $flag |= 0x0008; }
  2665.         if($k =~ s/alt[-\+]//i)                  { $flag |= 0x0010; }
  2666.  
  2667.                                                  # { $key = 0x01; } # VK_LBUTTON
  2668.                                                  # { $key = 0x02; } # VK_RBUTTON
  2669.                                                  # { $key = 0x03; } # VK_CANCEL
  2670.                                                  # { $key = 0x04; } # VK_MBUTTON
  2671.            if($k =~ /^backspace$/i)                { $key = 0x08; } # VK_BACK
  2672.         elsif($k =~ /^tab$/i)                      { $key = 0x09; } # VK_TAB
  2673. #       elsif($k =~ /^clear$/i)                    { $key = 0x0c; } # VK_CLEAR
  2674.         elsif($k =~ /^return$/i)                   { $key = 0x0d; } # VK_RETURN
  2675.                                                  # { $key = 0x10; } # VK_SHIFT
  2676.                                                  # { $key = 0x11; } # VK_CONTROL
  2677.                                                  # { $key = 0x12; } # VK_MENU /ALT
  2678.         elsif($k =~ /^pause$/i)                    { $key = 0x13; } # VK_PAUSE
  2679.         elsif($k =~ /^capslock$/i)                 { $key = 0x14; } # VK_CAPITAL
  2680.         elsif($k =~ /^(esc|escape)$/i)             { $key = 0x1b; } # VK_ESCAPE
  2681.         elsif($k =~ /^space$/i)                    { $key = 0x20; } # VK_SPACE
  2682.         elsif($k =~ /^(pgup|pageup)$/i)            { $key = 0x21; } # VK_PRIOR
  2683.         elsif($k =~ /^(pgdn|pagedn|pagedown)$/i)   { $key = 0x22; } # VK_NEXT
  2684.         elsif($k =~ /^end$/i)                      { $key = 0x23; } # VK_END
  2685.         elsif($k =~ /^home$/i)                     { $key = 0x24; } # VK_HOME
  2686.         elsif($k =~ /^left$/i)                     { $key = 0x25; } # VK_LEFT
  2687.         elsif($k =~ /^up$/i)                       { $key = 0x26; } # VK_UP
  2688.         elsif($k =~ /^right$/i)                    { $key = 0x27; } # VK_RIGHT
  2689.         elsif($k =~ /^down$/i)                     { $key = 0x28; } # VK_DOWN
  2690. #       elsif($k =~ /^select$/i)                   { $key = 0x29; } # VK_SELECT
  2691. #       elsif($k =~ /^print$/i)                    { $key = 0x2a; } # VK_PRINT
  2692. #       elsif($k =~ /^execute$/i)                  { $key = 0x2b; } # VK_EXECUTE
  2693.         elsif($k =~ /^(prntscrn|printscreen)$/i)   { $key = 0x2c; } # VK_SNAPSHOT
  2694.         elsif($k =~ /^ins$/i)                      { $key = 0x2d; } # VK_INSERT
  2695.         elsif($k =~ /^del$/i)                      { $key = 0x2e; } # VK_DELETE
  2696. #       elsif($k =~ /^help$/i)                     { $key = 0x2f; } # VK_HELP
  2697.         elsif($k =~ /^[0-9a-z]$/i)                 { $key = ord(uc($k)); }
  2698.                                                  # 0x30-0x39: ASCII 0-9
  2699.                                                  # 0x41-0x5a: ASCII A-Z
  2700.         elsif($k =~ /^left(win|windows)$/i)        { $key = 0x5b; } # VK_LWIN
  2701.         elsif($k =~ /^right(win|windows)$/i)       { $key = 0x5c; } # VK_RWIN
  2702.         elsif($k =~ /^(app|application)$/i)        { $key = 0x5d; } # VK_APPS
  2703. #       elsif($k =~ /^sleep$/i)                    { $key = 0x5e; } # VK_SLEEP
  2704.         elsif($k =~ /^(num|numeric|keypad)0$/i)    { $key = 0x60; } # VK_NUMPAD0
  2705.         elsif($k =~ /^(num|numeric|keypad)1$/i)    { $key = 0x61; } # VK_NUMPAD1
  2706.         elsif($k =~ /^(num|numeric|keypad)2$/i)    { $key = 0x62; } # VK_NUMPAD2
  2707.         elsif($k =~ /^(num|numeric|keypad)3$/i)    { $key = 0x63; } # VK_NUMPAD3
  2708.         elsif($k =~ /^(num|numeric|keypad)4$/i)    { $key = 0x64; } # VK_NUMPAD4
  2709.         elsif($k =~ /^(num|numeric|keypad)5$/i)    { $key = 0x65; } # VK_NUMPAD5
  2710.         elsif($k =~ /^(num|numeric|keypad)6$/i)    { $key = 0x66; } # VK_NUMPAD6
  2711.         elsif($k =~ /^(num|numeric|keypad)7$/i)    { $key = 0x67; } # VK_NUMPAD7
  2712.         elsif($k =~ /^(num|numeric|keypad)8$/i)    { $key = 0x68; } # VK_NUMPAD8
  2713.         elsif($k =~ /^(num|numeric|keypad)9$/i)    { $key = 0x69; } # VK_NUMPAD9
  2714.         elsif($k =~ /^multiply$/i)                 { $key = 0x6a; } # VK_MULTIPLY
  2715.         elsif($k =~ /^add$/i)                      { $key = 0x6b; } # VK_ADD
  2716. #       elsif($k =~ /^separator$/i)                { $key = 0x6c; } # VK_SEPARATOR
  2717.         elsif($k =~ /^subtract$/i)                 { $key = 0x6d; } # VK_SUBTRACT
  2718.         elsif($k =~ /^decimal$/i)                  { $key = 0x6e; } # VK_DECIMAL
  2719.         elsif($k =~ /^divide$/i)                   { $key = 0x6f; } # VK_DIVIDE
  2720.         elsif($k =~ /^f1$/i)                       { $key = 0x70; } # VK_F1
  2721.         elsif($k =~ /^f2$/i)                       { $key = 0x71; } # VK_F2
  2722.         elsif($k =~ /^f3$/i)                       { $key = 0x72; } # VK_F3
  2723.         elsif($k =~ /^f4$/i)                       { $key = 0x73; } # VK_F4
  2724.         elsif($k =~ /^f5$/i)                       { $key = 0x74; } # VK_F5
  2725.         elsif($k =~ /^f6$/i)                       { $key = 0x75; } # VK_F6
  2726.         elsif($k =~ /^f7$/i)                       { $key = 0x76; } # VK_F7
  2727.         elsif($k =~ /^f8$/i)                       { $key = 0x77; } # VK_F8
  2728.         elsif($k =~ /^f9$/i)                       { $key = 0x78; } # VK_F9
  2729.         elsif($k =~ /^f10$/i)                      { $key = 0x79; } # VK_F10
  2730.         elsif($k =~ /^f11$/i)                      { $key = 0x7a; } # VK_F11
  2731.         elsif($k =~ /^f12$/i)                      { $key = 0x7b; } # VK_F12
  2732. #       elsif($k =~ /^f13$/i)                      { $key = 0x7c; } # VK_F13
  2733. #       elsif($k =~ /^f14$/i)                      { $key = 0x7d; } # VK_F14
  2734. #       elsif($k =~ /^f15$/i)                      { $key = 0x7e; } # VK_F15
  2735. #       elsif($k =~ /^f16$/i)                      { $key = 0x7f; } # VK_F16
  2736. #       elsif($k =~ /^f17$/i)                      { $key = 0x80; } # VK_F17
  2737. #       elsif($k =~ /^f18$/i)                      { $key = 0x81; } # VK_F18
  2738. #       elsif($k =~ /^f19$/i)                      { $key = 0x82; } # VK_F19
  2739. #       elsif($k =~ /^f20$/i)                      { $key = 0x83; } # VK_F20
  2740. #       elsif($k =~ /^f21$/i)                      { $key = 0x84; } # VK_F21
  2741. #       elsif($k =~ /^f22$/i)                      { $key = 0x85; } # VK_F22
  2742. #       elsif($k =~ /^f23$/i)                      { $key = 0x86; } # VK_F23
  2743. #       elsif($k =~ /^f24$/i)                      { $key = 0x87; } # VK_F24
  2744.         elsif($k =~ /^numlock$/i)                  { $key = 0x90; } # VK_NUMLOCK
  2745.         elsif($k =~ /^scrolllock$/i)               { $key = 0x91; } # VK_SCROLL
  2746.                                                  # { $key = 0xa0; } # VK_LSHIFT
  2747.                                                  # { $key = 0xa1; } # VK_RSHIFT
  2748.                                                  # { $key = 0xa2; } # VK_LCONTROL
  2749.                                                  # { $key = 0xa3; } # VK_RCONTROL
  2750.                                                  # { $key = 0xa4; } # VK_LMENU
  2751.                                                  # { $key = 0xa5; } # VK_RMENU
  2752. #       elsif($k =~ /^browserback$/i)              { $key = 0xa6; } # VK_BROWSER_BACK
  2753. #       elsif($k =~ /^browserforward$/i)           { $key = 0xa7; } # VK_BROWSER_FORWARD
  2754. #       elsif($k =~ /^browserrefresh$/i)           { $key = 0xa8; } # VK_BROWSER_REFRESH
  2755. #       elsif($k =~ /^browserstop$/i)              { $key = 0xa9; } # VK_BROWSER_STOP
  2756. #       elsif($k =~ /^browsersearch$/i)            { $key = 0xaa; } # VK_BROWSER_SEARCH
  2757. #       elsif($k =~ /^browserfavorites$/i)         { $key = 0xab; } # VK_BROWSER_FAVORITES
  2758. #       elsif($k =~ /^browserhome$/i)              { $key = 0xac; } # VK_BROWSER_HOME
  2759. #       elsif($k =~ /^volumemute$/i)               { $key = 0xad; } # VK_VOLUME_MUTE
  2760. #       elsif($k =~ /^volumedown$/i)               { $key = 0xae; } # VK_VOLUME_UP
  2761. #       elsif($k =~ /^volumenup$/i)                { $key = 0xaf; } # VK_VOLUME_DOWN
  2762. #       elsif($k =~ /^medianexttrack$/i)           { $key = 0xb0; } # VK_MEDIA_NEXT_TRACK
  2763. #       elsif($k =~ /^mediaprevtrack$/i)           { $key = 0xb1; } # VK_MEDIA_PREV_TRACK
  2764. #       elsif($k =~ /^mediastop$/i)                { $key = 0xb2; } # VK_MEDIA_STOP
  2765. #       elsif($k =~ /^mediaplaypause$/i)           { $key = 0xb3; } # VK_MEDIA_PLAY_PAUSE
  2766. #       elsif($k =~ /^launchmail$/i)               { $key = 0xb4; } # VK_LAUNCH_MAIL
  2767. #       elsif($k =~ /^launchmediaselect$/i)        { $key = 0xb5; } # VK_LAUNCH_MEDIA_SELECT
  2768. #       elsif($k =~ /^launchapp1$/i)               { $key = 0xb6; } # VK_LAUNCH_APP1
  2769. #       elsif($k =~ /^launchapp2$/i)               { $key = 0xb7; } # VK_LAUNCH_APP2
  2770.         elsif($k =~ /^semicolon$/i)                { $key = 0xba; } # VK_OEM_1
  2771.         elsif($k =~ /^(plus|equal)$/i)             { $key = 0xbb; } # VK_OEM_PLUS
  2772.         elsif($k =~ /^(comma|lessthan)$/i)         { $key = 0xbc; } # VK_OEM_COMMA
  2773.         elsif($k =~ /^(minus|underscore)$/i)       { $key = 0xbd; } # VK_OEM_MINUS
  2774.         elsif($k =~ /^(period|greaterthan)$/i)     { $key = 0xbe; } # VK_OEM_PERIOD
  2775.         elsif($k =~ /^(slash|question)$/i)         { $key = 0xbf; } # VK_OEM_2
  2776.         elsif($k =~ /^(acute|tilde)$/i)            { $key = 0xc0; } # VK_OEM_3
  2777.         elsif($k =~ /^(left|open)brac(e|ket)$/i)   { $key = 0xdb; } # VK_OEM_4
  2778.         elsif($k =~ /^(backslash|verticalbar)$/i)  { $key = 0xdc; } # VK_OEM_5
  2779.         elsif($k =~ /^(right|close)brac(e|ket)$/i) { $key = 0xdd; } # VK_OEM_6
  2780.         elsif($k =~ /^(single|double|)quote$/i)    { $key = 0xde; } # VK_OEM_7
  2781. #       elsif($k =~ /^unknown$/i)                  { $key = 0xdf; } # VK_OEM_8
  2782. #       elsif($k =~ /^process$/i)                  { $key = 0xe5; } # VK_PROCESSKEY
  2783.         elsif($k =~ /^(attn|attention)$/i)         { $key = 0xf6; } # VK_ATTN
  2784.         elsif($k =~ /^crsel$/i)                    { $key = 0xf7; } # VK_CRSEL
  2785.         elsif($k =~ /^exsel$/i)                    { $key = 0xf8; } # VK_EXSEL
  2786.         elsif($k =~ /^(ereof|eraseeof)$/i)         { $key = 0xf9; } # VK_EREOF
  2787.         elsif($k =~ /^play$/i)                     { $key = 0xfa; } # VK_PLAY
  2788.         elsif($k =~ /^zoom$/i)                     { $key = 0xfb; } # VK_ZOOM
  2789.         elsif($k =~ /^noname$/i)                   { $key = 0xfc; } # VK_NONAME
  2790.         elsif($k =~ /^pa1$/i)                      { $key = 0xfd; } # VK_PA1
  2791.         elsif($k =~ /^oem_clear$/i)                { $key = 0xfe; } # VK_OEM_CLEAR
  2792.         else {$key = 0; print "Key name '$k' unknown\n"; }
  2793.  
  2794.         if ($key) {
  2795.             my $id = $Win32::GUI::AcceleratorCounter++;
  2796.             push @acc, $id, $key, $flag;
  2797.             $Win32::GUI::Accelerators{$id} = $v;
  2798.         }
  2799.     }
  2800.     my $handle = Win32::GUI::CreateAcceleratorTable( @acc );
  2801.     if($handle) {
  2802.         my $self = {};
  2803.         $self->{-handle} = $handle;
  2804.         bless $self, $class;
  2805.         return $self;
  2806.     } else {
  2807.         return undef;
  2808.     }
  2809. }
  2810.  
  2811. sub DESTROY {
  2812.     my($self) = @_;
  2813.     # print "DESTROYING AcceleratorTable $self->{-handle}\n";
  2814.     if( $self->{-handle} ) {
  2815.         Win32::GUI::DestroyAcceleratorTable( $self->{-handle} );
  2816.     }
  2817. }
  2818.  
  2819. ###############################################################################
  2820. # (@)INTERNAL:Win32::GUI::WindowProps
  2821. # the package to tie to a window hash to set/get properties in a more
  2822. # fashionable way...
  2823. #
  2824. package Win32::GUI::WindowProps;
  2825.  
  2826. my %TwoWayMethodMap = (
  2827.     -text   => "Text",
  2828.     -left   => "Left",
  2829.     -top    => "Top",
  2830.     -width  => "Width",
  2831.     -height => "Height",
  2832.     -dialogui => "DialogUI",
  2833. );
  2834.  
  2835. my $Textfield_TwoWayMethodMap = {
  2836.     -passwordchar => "PasswordChar",
  2837. };
  2838.  
  2839. my %PackageSpecific_TwoWayMethodMap = (
  2840.     Splitter => {
  2841.         -min => "Min",
  2842.         -max => "Max",
  2843.         -horizontal => "Horizontal",
  2844.         -vertical => "Vertical",
  2845.     },
  2846.     MenuItem => {
  2847.         -checked => "Checked",
  2848.         -enabled => "Enabled",
  2849.     },
  2850.     Textfield => $Textfield_TwoWayMethodMap,
  2851.     RichEdit  => $Textfield_TwoWayMethodMap,
  2852. );
  2853.  
  2854.  
  2855. my %OneWayMethodMap = (
  2856.     -scalewidth   => "ScaleHeight",
  2857.     -scaleheight  => "ScaleWidth",
  2858.     -abstop       => "AbsTop",
  2859.     -absleft      => "AbsLeft",
  2860. );
  2861.  
  2862.     ###########################################################################
  2863.     # (@)INTERNAL:TIEHASH
  2864. sub TIEHASH {
  2865.     my($class, $object) = @_;
  2866.     # my $tied = { UNDERLYING => $object };
  2867.     # print "[TIEHASH] called for '$class' '$object'\n";
  2868.     # return bless $tied, $class;
  2869.     return bless $object, $class;
  2870. }
  2871.  
  2872.     ###########################################################################
  2873.     # (@)INTERNAL:STORE
  2874. sub STORE {
  2875.     my($self, $key, $value) = @_;
  2876.     # print "[STORE] called for '$self' {$key}='$value'\n";
  2877.  
  2878.     my $Package = ref($self);
  2879.     $Package =~ s/Win32::GUI:://;
  2880.  
  2881.     if(exists $PackageSpecific_TwoWayMethodMap{$Package}{$key}) {
  2882.         if(my $method = $self->can($PackageSpecific_TwoWayMethodMap{$Package}{$key})) {
  2883.             #print "[STORE] calling method '$PackageSpecific_TwoWayMethodMap{$Package}{$key}' on '$self'\n";
  2884.             return &{$method}($self, $value);
  2885.         } else {
  2886.             #print "[STORE] PROBLEM: method '$PackageSpecific_TwoWayMethodMap{$Package}{$key}' not found on '$self'\n";
  2887.         }
  2888.     } elsif(exists $TwoWayMethodMap{$key}) {
  2889.         if(my $method = $self->can($TwoWayMethodMap{$key})) {
  2890.             # print "[STORE] calling method '$TwoWayMethodMap{$key}' on '$self'\n";
  2891.             return &{$method}($self, $value);
  2892.         } else {
  2893.             # print "[STORE] PROBLEM: method '$TwoWayMethodMap{$key}' not found on '$self'\n";
  2894.         }
  2895.     } elsif($key eq "-style") {
  2896.         # print "[STORE] calling GetWindowLong\n";
  2897.         return Win32::GUI::GetWindowLong($self, -16, $value);
  2898.  
  2899.     } else {
  2900.         # print "[STORE] storing key '$key' in '$self'\n";
  2901.         # return $self->{UNDERLYING}->{$key} = $value;
  2902.         return $self->{$key} = $value;
  2903.     }
  2904. }
  2905.  
  2906.     ###########################################################################
  2907.     # (@)INTERNAL:FETCH
  2908. sub FETCH {
  2909.     my($self, $key) = @_;
  2910.  
  2911.     my $Package = ref($self);
  2912.     $Package =~ s/Win32::GUI:://;
  2913.  
  2914.     if($key eq "UNDERLYING") {
  2915.         # print "[FETCH] returning UNDERLYING for '$self'\n";
  2916.         return $self->{UNDERLYING};
  2917.  
  2918.     } elsif(exists $PackageSpecific_TwoWayMethodMap{$Package}{$key}) {
  2919.         if(my $method = $self->can($PackageSpecific_TwoWayMethodMap{$Package}{$key})) {
  2920.             #print "[FETCH] calling method '$PackageSpecific_TwoWayMethodMap{$package}{$key}' on '$self'\n";
  2921.             return &{$method}($self);
  2922.         } else {
  2923.             #print "[FETCH] PROBLEM: method '$PackageSpecific_TwoWayMethodMap{$package}{$key}' not found on '$self'\n";
  2924.         }
  2925.  
  2926.     } elsif(exists $TwoWayMethodMap{$key}) {
  2927.         # if(my $method = $self->{UNDERLYING}->can($TwoWayMethodMap{$key})) {
  2928.         if(my $method = $self->can($TwoWayMethodMap{$key})) {
  2929.             # print "[FETCH] calling method $TwoWayMethodMap{$key} on $self->{UNDERLYING}\n";
  2930.             # print "[FETCH] calling method '$TwoWayMethodMap{$key}' on '$self'\n";
  2931.             # return &{$method}($self->{UNDERLYING});
  2932.             return &{$method}($self);
  2933.         } else {
  2934.             # print "[FETCH] method not found '$TwoWayMethodMap{$key}'\n";
  2935.             return undef;
  2936.         }
  2937.  
  2938.     } elsif($key eq "-style") {
  2939.         return Win32::GUI::GetWindowLong($self->{UNDERLYING}, -16);
  2940.  
  2941.     #} elsif(exists $self->{UNDERLYING}->{$key}) {
  2942.     #   print "[FETCH] fetching key $key from $self->{UNDERLYING}\n";
  2943.     #   return $self->{UNDERLYING}->{$key};
  2944.  
  2945.     } elsif(exists $self->{$key}) {
  2946.         # print "[FETCH] fetching key '$key' from '$self'\n";
  2947.         return $self->{$key};
  2948.  
  2949.     } else {
  2950.         # print "Win32::GUI::WindowProps::FETCH returning nothing for '$key' on $self->{UNDERLYING}\n";
  2951.         # print "[FETCH] returning nothing for '$key' on '$self'\n";
  2952.         return undef;
  2953.         # return 0;
  2954.     }
  2955. }
  2956.  
  2957. sub FIRSTKEY {
  2958.     my $self = shift;
  2959.     my $a = keys %{ $self };
  2960.     my ($k, $v) = each %{ $self };
  2961. #    print "[FIRSTKEY] k='$k' v='$v'\n";
  2962.     return $k;
  2963. }
  2964.  
  2965. sub NEXTKEY {
  2966.     my $self = shift;
  2967.     my ($k, $v) = each %{ $self };
  2968. #    print "[NEXTKEY] k='$k' v='$v'\n";
  2969.     return $k;
  2970. }
  2971.  
  2972. sub EXISTS {
  2973.     my($self, $key) = @_;
  2974.     # return exists $self->{UNDERLYING}->{$key};
  2975.     return exists $self->{$key};
  2976. }
  2977.  
  2978.  
  2979. ###############################################################################
  2980. # dynamically load in the GUI.dll module.
  2981. #
  2982.  
  2983. package Win32::GUI;
  2984.  
  2985. bootstrap Win32::GUI;
  2986.  
  2987. bootstrap_subpackage 'Animation';
  2988. bootstrap_subpackage 'Bitmap';
  2989. bootstrap_subpackage 'DC';
  2990. bootstrap_subpackage 'Font';
  2991. bootstrap_subpackage 'ImageList';
  2992. bootstrap_subpackage 'Label';
  2993. bootstrap_subpackage 'Listbox';
  2994. bootstrap_subpackage 'ListView';
  2995. bootstrap_subpackage 'NotifyIcon';
  2996. bootstrap_subpackage 'Rebar';
  2997. bootstrap_subpackage 'RichEdit';
  2998. bootstrap_subpackage 'Splitter';
  2999. bootstrap_subpackage 'TabStrip';
  3000. bootstrap_subpackage 'Textfield';
  3001. bootstrap_subpackage 'Toolbar';
  3002. bootstrap_subpackage 'TreeView';
  3003.  
  3004. # Preloaded methods go here.
  3005.  
  3006. $Win32::GUI::StandardWinClass = Win32::GUI::Class->new(
  3007.     -name => "PerlWin32GUI_STD_OBSOLETED"
  3008. );
  3009.  
  3010. $Win32::GUI::StandardWinClassVisual = Win32::GUI::Class->new(
  3011.     -name => "PerlWin32GUI_STD",
  3012.     -visual => 1,
  3013. );
  3014.  
  3015. $Win32::GUI::GraphicWinClass = Win32::GUI::Class->new(
  3016.     -name => "Win32::GUI::Graphic",
  3017.     -widget => "Graphic",
  3018. );
  3019.  
  3020. $Win32::GUI::InteractiveGraphicWinClass = Win32::GUI::Class->new(
  3021.     -name => "Win32::GUI::InteractiveGraphic",
  3022.     -widget => "InteractiveGraphic",
  3023. );
  3024.  
  3025. $Win32::GUI::SplitterHorizontal = Win32::GUI::Class->new(
  3026.     -name => "Win32::GUI::Splitter(horizontal)",
  3027.     -widget => "SplitterH",
  3028. );
  3029. $Win32::GUI::SplitterVertical = Win32::GUI::Class->new(
  3030.     -name => "Win32::GUI::Splitter(vertical)",
  3031.     -widget => "Splitter",
  3032. );
  3033.  
  3034. $Win32::GUI::RICHED = Win32::GUI::LoadLibrary("RICHED32");
  3035.  
  3036. END {
  3037.     # print "Freeing library RICHED32\n";
  3038.     Win32::GUI::FreeLibrary($Win32::GUI::RICHED);
  3039. }
  3040.  
  3041. #Currently Autoloading is not implemented in Perl for win32
  3042. # Autoload methods go after __END__, and are processed by the autosplit program.
  3043.  
  3044. 1;
  3045. __END__
  3046.  
  3047.  
  3048.