On 11/07/07, Robert May <[EMAIL PROTECTED]> wrote:
On 11/07/07, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> I have a small program which can be minimized to the tray.
> Now I want to have an accelerator which fires to minimize the program to the
> tray => this works fine.
> But now I want to restore the window with an accelerator anytime.
> It should work if I'm writing a text or in internet explorer or firefox ...
everytime.
> is this possible?
> how can I install the accelerator so that it can be activated?
I'll attach some code that shows the WM_SETHOTKEY method to this mail
- it doesn't quite meet your requirements, but it's close and can be
done with Win32::GUI alone. I'll follow-up with code that uses the
Win32 RegisterHotKey() function - I think it exactly meets what you
want to do, but needs Win32::API() to call the functions that are
missing from Win32::GUI.
This is the follow-up using RegisterHotKey() and WM_HOTKEY. It's a
bit more complex than the last example:
#!perl -w
use strict;
use warnings;
# What this script does:
# Creates a Window, and a notify icon.
# Register a Hotkey (Ctrl-A) for the window.
# When the window is minimised, it is hidden.
# Left-clicking on the notify icon, or pressing the
# Hotkey combination will Show the window again.
# Pressing the HotKey when the window is visible
# hides it.
# We can't use WM_SETHOTKEY, as we never see any WM_SYSCOMMAND
# once the window is hidden, so we use Win32::API to give
# us access to RegisterHotKey/UnregisterHotKey and catch
# the WM_HOTKEY messages to o our bidding.
use Win32::API();
Win32::API->Import('user32', 'RegisterHotKey', 'LiII', 'I');
Win32::API->Import('user32', 'UnregisterHotKey', 'Li', 'I');
use Win32::GUI 1.05 qw( CW_USEDEFAULT
WM_HOTKEY
VK_A
IDI_DEFAULTICON );
# Some constants missing from Win32::GUI::Constants
sub MOD_ALT() {0x001} # Alt key
sub MOD_CONTROL() {0x002} # Ctrl key
sub MOD_SHIFT() {0x004} # Shift key
sub MOD_WIN() {0x008} # Windows key
my $HOTKEY_ID = 0x1234; # Any unique number for this app - need
# a different number for each hotkey
my $mw = Win32::GUI::Window->new(
-title => 'HotKey demonstration',
-left => CW_USEDEFAULT,
-size => [400,300],
-onMinimize => \&toggle_show_state,
);
# We need to catch WM_HOTKEY messages
$mw->Hook(WM_HOTKEY, \&handle_wm_hotkey);
my $icon = Win32::GUI::Icon->new(IDI_DEFAULTICON);
$mw->AddNotifyIcon(
-icon => $icon,
-onClick => \&toggle_show_state,
);
set_hotkey($mw, $HOTKEY_ID, VK_A, MOD_CONTROL);
$mw->Show();
Win32::GUI::Dialog();
# Before we exit we must remove the hotkey, else it won't be available
# for other apps, and we'll leak system memory
# Using and END block to that this get called, even if we exit other
# than by falling off the end here.
END { unset_hotkey($mw, $HOTKEY_ID); }
sub toggle_show_state {
my ($win) = @_;
# Less obviously written as:
# $win->Show(!$win->IsVisible());
if($win->IsVisible()) {
$win->Hide();
}
else {
$win->Show();
}
return 0;
}
# Set the hotkey for a window (or replace it if this is called
# more than once)
sub set_hotkey {
my ($win, $id, $key, $modifiers) = @_;
# $win - any top level window
# $id - unique identifier for the hotkey
# $key - any virtual keycode (VK_*) except F12 (and others??)
# $modifiers - any combination of the MOD_* constants (or 0 for no modifier)
if(!RegisterHotKey($win->{-handle}, $id, $modifiers, $key)) {
die("set_hotkey() failed to register the hotkey - $^E");
}
return;
}
sub unset_hotkey {
my ($win, $id) = @_;
# $win - any top level window
# $id - unique identifier for the hotkey
if(!UnregisterHotKey($win->{-handle}, $id)) {
die("unset_hotkey() failed to unregister the hotkey - $^E");
}
return;
}
sub handle_wm_hotkey {
my ($win, $id, $lparam, $type, $msgcode) = @_;
return unless $type == 0;
return unless $msgcode == WM_HOTKEY;
# decode virtual key and modifiers from lparam:
# my ($modifiers, $key) = unpack("SS", pack("L", $lparam));
# my $mod = '';
# $mod .= "A" if($modifiers & MOD_ALT);
# $mod .= "C" if($modifiers & MOD_CONTROL);
# $mod .= "S" if($modifiers & MOD_SHIFT);
# $mod .= "W" if($modifiers & MOD_WIN);
# print "Saw WM_HOTKEY with id: $id (vkey: $key, mod: $mod)\n";
# should really check ID to determine what to do, but we can get
# away without that, as we only have one hotkey
toggle_show_state($win);
return;
}