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 ¬e, 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.
¬e("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;
¬e("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/