Hey there... this is driving me flippin' batty. I've included a GUI layer library below that can be dropped into an existing program (currently, the one I'm using it with is AmphetaDesk at disobey.com/amphetadesk/).

Besides some uninit's that I know about and plan on fixing, I'm getting uninit's *every single time* that the DoEvents is called. The specific lines are 130 and 160, which match up to these blocks:

        sub gui_listen {

        # anyone there?
        Win32::GUI::PeekMessage(0,0,0);
        Win32::GUI::DoEvents();

        return 1;
        }

The error is the normal "use of unitialized value" junk, and it points strictly to the DoEvents line.

What am I doing wrong? How can I make 'em go away?
###############################################################################
# LIST OF ROUTINES BELOW:                                                     #
###############################################################################
# gui_init() - start the gui and display the window                           #
# gui_listen() - listen for window events for our gui                         #
# gui_note() - send a note to our gui window                                  #
# open_url() - open a url in the system's default browser                     #
# _things() - various routines that control the gui and should be private     #
###############################################################################


# these variables are global for
# the Windows gui - they just keep
# track of various things that listen
# and notes need to know about.
my ($hwnd, $hwnd_class, $window, $logbox);


###############################################################################
# gui_init() - start the gui and display the window                           #
###############################################################################
# USAGE:                                                                      #
#   &gui_init;                                                                #
#                                                                             #
# NOTES:                                                                      #
#   This routine loads specific libraries specific to the OS and attempts to  #
#   do everything necessary to start up a GUI window and start listening for  #
#   events. Further down in this file, you should see supplementary GUI       #
#   routines (starting with _) that are part of the GUI happenings this       #
#   routine inits.                                                            #
#                                                                             #
#   Most of the code within this routine is thanks to David Berube.           #
#                                                                             #
# RETURNS:                                                                    #
#   1; this routine always returns happily.                                   #
###############################################################################

sub gui_init {

   use Win32::GUI;

   # hwnd is a handle to a window - basically, window's
   # way of keeping track of it's program windows...
   $hwnd = GUI::GetPerlWindow();

   # comment this to see error messages in a dos window
   # otherwise, this will hide the blasted thing...
   # GUI::Hide($hwnd);

   # get the width and height of the user's system.
   my $screen_width  = Win32::GUI::GetSystemMetrics(0);
   my $screen_height = Win32::GUI::GetSystemMetrics(1);

   # set some default entries for our window.
   my $minwidth = 600; my $minheight = 240;

   # create a window class for our window.
   $hwnd_class = new Win32::GUI::Class( -name => "$SETTINGS->{app}->{name} 
Class",
                                        -icon => "$SETTINGS->{gui}->{icon}"
                                      );

   # set up our menu bar. these point to various
   # routines defined later on in this file, as 
   # well as set up key commands for the items.
   my $menu_bar = new Win32::GUI::Menu( "&File"                 => "File",
                                        " > E&xit"              => "_FileExit",
                                        "&Edit"                 => "Edit",
                                        " > &Copy Ctrl+C"       => "_EditCopy",
                                        " > Select &All Ctrl+A" => 
"_EditSelectAll"
                                      );

   # creates the main window. notice that we use a generic
   # "Name" parameter, which is used for events, which must
   # have the format Name_EventName.
   $window = new Win32::GUI::Window( -name   => '_Window', 
                                     -text   => $SETTINGS->{app}->{name},
                                     -left   => ($screen_width - $minwidth)/2,
                                     -top    => ($screen_height - $minheight)/2,
                                     -width  => $minwidth,
                                     -height => $minheight,
                                     -menu   => $menu_bar,
                                     -class  => $hwnd_class,
                                     -icon   => $SETTINGS->{gui}->{icon}
                                   );

   # create the systray icon.
   my $sys_tray_icon = $window->AddNotifyIcon( -name => "_Systray",
                                               -id   => 1,
                                               -icon => 
$SETTINGS->{gui}->{icon},
                                               -tip  => $SETTINGS->{app}->{name}
                                             );

   # create the log box which is gonna hold all our info.
   $logbox = $window->AddListbox( -top     => 10,
                                  -left    => 5,
                                  -tabstop => 1,
                                  -style   => WS_VISIBLE | WS_VSCROLL
                                );

   # and make it a little smaller than our window size.
   $logbox->Resize( $window->ScaleWidth - 10, $window->ScaleHeight - 35);

   # finally, show all the junk we just did.
   $window->Show();

   return 1;
}

1;


###############################################################################
# gui_listen() - listen for window events for our gui                         #
###############################################################################
# USAGE:                                                                      #
#   &gui_listen;                                                              #
#                                                                             #
# NOTES:                                                                      #
#   This routine checks the event queue and sees if there is anything that    #
#   needs to be done. It's called from the main loop of our program.          #
#                                                                             #
# RETURNS:                                                                    #
#   1; this routine always returns happily.                                   #
###############################################################################

sub gui_listen {

   # anyone there?
   Win32::GUI::PeekMessage(0,0,0);
   Win32::GUI::DoEvents();

   return 1;
}

1;


###############################################################################
# gui_note() - send a note to our gui window                                  #
###############################################################################
# USAGE:                                                                      #
#   &gui_note("This is a gui window line. Yup.");                             #
#                                                                             #
# NOTES:                                                                      #
#   Much like &note, only we send our message to our os specific gui window.  #
#                                                                             #
# RETURNS:                                                                    #
#   1; this routine always returns happily.                                   #
###############################################################################

sub gui_note {

   my ($message) = @_;

   # add the string to our box.
   $logbox->AddString($message);

   # listen for good measure.
   Win32::GUI::PeekMessage(0,0,0);
   Win32::GUI::DoEvents();

   # autoscroll the window. 277 is the number
   # of the WM_VSCROLL constant, which Win32::GUI
   # doesn't seem to define for us.
   Win32::GUI::SendMessage($logbox, 277, 7, 7);

   return 1;
}

1;


###############################################################################
# open_url() - open a url in the system's default browser                     #
###############################################################################
# USAGE:                                                                      #
#    &open_url( "http://127.0.0.1:8888/"; );                                   #
#                                                                             #
# OS SPECIFIC NOTES:                                                          #
#    This routine loads the Win32::Shell module to execute the "open"         #
#    command which will open the browser and load the URL. However, if the    #
#    user has defined a local path to a browser, we try to open that instead. #
#                                                                             #
# RETURNS:                                                                    #
#    1; we instruct the user to open their browser if we can't.               #
###############################################################################

sub open_url {

   my ($url) = @_;

   # we spit out our suggestion just to catch all instances.
   &note("If your browser doesn't load, go to <$url>", 1);

   # if a browser_path hasn't been set, try
   # to open the default browser using the native API.
   # and no, I have no clue what this junk does.
   if (! $SETTINGS->{user}->{browser_path}) {
      use Win32::API;
      my $ShellExecute = new Win32::API("shell32", "ShellExecuteA", ['N', 'P', 
'P', 'P', 'P', 'I'], 'N');
      $ShellExecute->Call(0, "open", $url, 0, 0, 1);
   }

   # if a browser_path has been defined, try passing
   # the $url to the .exe and hope it understands.
   else {

      # if we see "program files" or "internet explorer", we take
      # a chance and try to change them to their common eight char
      # equivalents. this won't work for all users but covers
      # a good large portion of them. yup yup. fun. chicks on speed.
      $SETTINGS->{user}->{browser_path} =~ s/program files/progra~1/ig;
      $SETTINGS->{user}->{browser_path} =~ s/internet explorer/intern~1/ig;

      &note("Trying to load $SETTINGS->{user}->{browser_path}.");
      unless ( fork ) { system("$SETTINGS->{user}->{browser_path} $url"); }
   }

   return 1;
}

1;


###############################################################################
# _things() - various routines that control the gui and should be private     #
###############################################################################
# USAGE:                                                                      #
#    These are internally called by the GUI and shouldn't be publically       #
#    used. So stop poking around here. Sheesh. Flippin' nosy people. Sigh.    #
###############################################################################

# various menu commands.
sub _FileExit_Click      { GUI::Show($hwnd); $window->Disable(); $window->Hide; 
exit; }
sub _EditCopy_Click      { my $something_needs_to_happen_here; }
sub _EditSelectAll_Click { my $something_needs_to_happen_here; }

# hide the window if it's been minimized. the only
# way to get it back would be from the systray icon.
# we need to figure out what to do when people click
# the "X' on the window. minimize? or close the app?
sub _Window_Minimize  { $window->Hide(); }
sub _Window_Terminate { exit; }

# if the systray icon is clicked, reenable the window.
# if it's right clicked, hide the main window (weird).
sub _Systray_Click      { $window->Enable(); $window->Show; }
sub _Systray_RightClick { $window->Disable(); $window->Hide; }


Morbus Iff
.sig on other machine.
http://www.disobey.com/
http://www.gamegrene.com/

Reply via email to