This was menat to go to the lit as well as to Glenn M.

Regards,
Rob.

Robert May wrote:
Glenn W Munroe wrote:

It would be useful to be able to define handlers for key presses on a per-control basis. For example, it is common to end text entry with a press of the “Enter” key; the action on that key press could be different depending on the control. I have tried to define different accelerator tables for different controls, but that doesn’t work. Is this something that is broken, hasn’t yet been implemented or is that way by design? I see that there is an {-accel} key for every control’s hash, but I haven’t figured out how to use it.

I've had a quick look through the code, and it looks like it was never intended that the -accel option was used on anything other than a top-level window.

I don't think it would be hard to have it work on a per control basis (although I would assume that we would want it to fall through to the top level windows, so that we don't have to define menu accelerators for each control accelerator table).

If you think this would be useful, could you raise an RFE.

I have also tried to handle the “KeyUp/KeyDown” events, but they don’t ever seem to fire. To which controls do those events apply?

Pretty much all of them. The code below shows them working for a button controls.

The only way I have found to do this is to define a window-level accelerator table and perform the relevant action depending on which control has focus. That’s ugly and it’s a pain to get the control’s name from its handle (perhaps that would be a useful method to build into the module). Even that is not trivial in the case of, say, a combobox, where it isn’t the combobox itself that has focus, but the dynamically created child edit control.

Has anybody come up with an elegant solution for this?


Is this elegant enough for you?

Regards,
Rob.

#!perl -w
use strict;
use warnings;

use Win32::GUI qw(WM_SETFOCUS);

my $mw = Win32::GUI::Window->new(
    -title => "Accel Tables",
    -pos => [100,100],
    -size => [400,300],
    #-dialogui => 1,
);
$mw->Hook(WM_SETFOCUS, \&setAccel);

# When -dialoui => 1 is specified on the window, then button
# will stop recieiving WM_CHAR (onChar) events; read about
# WM_GETDLGCODE for why.
my $but = $mw->AddButton(
    -text => "Button",
    -pos => [10,10],
    -tabstop => 1,
    -notify => 1,
    -onGotFocus => \&setAccel,
    -onKeyDown => sub {print "Button onKeyDown, $_[2]\n"},
    -onChar => sub {print "Button onChar, $_[2]\n"},
    -onKeyUp => sub {print "Button onKeyUp $_[2]\n"},
);

my $com = $mw->AddCombobox(
    -text => "Default",
    -pos => [10,40],
    -size => [100,100],
    -tabstop => 1,
    -onGotFocus => \&setAccel,
);

# A set of accelerator tables, keyed by the stringified object reference,
# allows for simple lookup in a common GotFocus handler
my %accels = (
    $mw  => Win32::GUI::AcceleratorTable->new(
                "A" => sub{print "Accel a pressed\n";1;},
            ),
    $but => Win32::GUI::AcceleratorTable->new(
                "B" => sub{print "Accel b pressed\n";1;},
            ),
    $com => Win32::GUI::AcceleratorTable->new(
                "C" => sub{print "Accel c pressed\n";1;},
            ),
);

$mw->Show();
Win32::GUI::Dialog();

exit(0);

sub setAccel
{
    my ($self) = @_;

    # Really should cope with there not being a handler in the hash
    # better.
    $mw->Change(-accel => $accels{$self}) if exists $accels{$self};

    return 1;
}
__END__

Reply via email to