Ok. This is intensely interesting. I'm sure I'm doing something wrong. I've
attached the latest Windows.pl file, which is where I'm trying to
accomplish this autoscroll thing. You'll have to activate it something like:
&gui_init,
for (1 .. 40) { &gui_note("hey!");
to get it going. It's a gui layer library to a much larger application.
Anyways, a couple of notes:
- I added a "height" to my Richie, and thinking that the Resize
wasn't needed, commented it out. To my surprise, that stopped
the vscrollbar from appearing. Even with all the other junk
you see in there, the vscroll doesn't appear. Only when I
uncomment the Resize (as in this file) does the vscroll
appear.
- As mentioned in a previous note, Johan's thingy doesn't
work the way I want it... As it is now, the Windows.pl
does the same thing as Johan's code. I want it to auto
scroll to the *last printed line*, whilst still showing
all the previous lines above it. The *last printed line*
should be the *last visible line in the window*.
Johan's way doesn't autoscroll.
>$Main->Rich->SendMessage (0x115, 7, 0)
This caused the window to put the *last printed line* in the first *visible
line of the window*. That's not what I want.
>$Main->Rich->SendMessage (0x115, 0, 0);
This, although sounding promising, didn't work either.
Heelpppp! <g>...
###############################################################################
# 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, $icon, $hwnd_class, $window, $menu_bar);
my ($img, $sys_tray_icon, $font, $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);
# create the icon handler.
$icon = new Win32::GUI::Icon($SETTINGS->{gui}->{win_icon});
# create a window class for our window.
$hwnd_class = new Win32::GUI::Class( -name => "$SETTINGS->{app}->{name}
Class",
-icon => $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.
$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 - 600)/2,
-top => ($screen_height - 400)/2,
-width => 480, -height => 400,
-menu => $menu_bar,
-class => $hwnd_class,
-icon => $icon,
-maximizebox => 0
);
# create the systray icon.
$sys_tray_icon = $window->AddNotifyIcon( -name => "_Systray",
-id => 1,
-icon => $icon,
-tip => $SETTINGS->{app}->{name}
);
# create our pretty logo - we need to figure out
# a good window size and height and then fix this
# stuff (and the logbox) up...
$window->AddLabel( -text => "",
-name => "Bitmap",
-left => -34,
-top => -3,
-width => 505,
-height => 116,
-style => 14,
-visible => 1,
);
# actually display the image...
$img = new Win32::GUI::Bitmap($SETTINGS->{gui}->{win_logo});
$window->Bitmap->SetImage($img); $window->Bitmap->Resize(505, 116);
# set the font of our log box below.
$font = Win32::GUI::Font->new( -name => "Verdana",
-size => 12,
);
# create the log box which is gonna hold all our info.
$logbox = $window->AddRichEdit( -name => "_RichEdit",
-font => $font,
-top => 116,
-left => 0,
-width => 505,
-height => 240,
-tabstop => 1,
-style => WS_CHILD | WS_VISIBLE | ES_LEFT |
ES_MULTILINE | ES_AUTOVSCROLL |
WS_VSCROLL |
ES_READONLY,
-exstyle => WS_EX_CLIENTEDGE
);
# and make it a little smaller than our window size.
$logbox->Resize( $window->ScaleWidth, $window->ScaleHeight - 118);
# 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) = @_;
# select our last line.
$logbox->Select(999999,999999);
$logbox->ReplaceSel("$message\n", 1);
select(undef, undef, undef, 0.25);
$logbox->SendMessage (0x115, 0, 0);
# add the string to our box.
# $logbox->Text($logbox->Text . "\r\n $message");
# $logbox->Text($logbox->Text . "\r\n $message");
# $logbox->Text($logbox->Text . "\r\n $message");
# $logbox->Text($logbox->Text . "\r\n $message");
# $logbox->Text($logbox->Text . "\r\n $message");
# 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);
# listen for good measure.
Win32::GUI::PeekMessage(0,0,0);
Win32::GUI::DoEvents();
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; }