[EMAIL PROTECTED] wrote:
I'v got the following problem. I want the Up,Down,Tab and ShiftTab keys
work in tables as usual. It means Tab changes only columns to right on so
on. The working example is enclosed.
OK - I'm not sure I would describe that as normal navigation behaviour,
but I get what you want.
ONE THING bother me; when I press Tab key a sound from computer is sending
as it was error. This sound is not emited when I press Up and Down keys.
That is standard Window Edit Control behaviour - you can't insert a tab
into a single line edit control, and the default behaviour is to beep.
How to manage? Could anyone help me?
You need to process the _Char event, and not pass it on to the edit
control if it is TAB. See below for a solution in your code, followed
by my re-implementation of the same functionality at the end.
You might also want to investigate the Win32::GUI::Grid package:
http://rocherl.club.fr/Win32GUI.html#Grid
Regards,
Rob.
#!/usr/bin/perl -w
use strict;
use Win32::GUI;
my $mw = new Win32::GUI::Window(
-name => "Main",
-width => 900,
-height => 400,
# -tabstop=>1,
);
#$mw->DialogUI( 1 );
my @edit = ();
my $dimX = 4;
my $dimY = 4;
for ( my $i = 0; $i < $dimY; $i++ ) {
for ( my $j = 0; $j < $dimX; $j++ ) {
$edit[$i][$j] = $mw->AddTextfield (
-text => $i.'x'.$j,
-name => 'edit'.$i.$j,
-left => 50 + 100*$j,
-top => 50 + 20*$i,
-width => 99,
-height => 20,
# -tabstop => 1,
# -dialogui => 1,
);
eval ('sub edit'.$i.$j.'_KeyDown { what_to_do( '.$i.','.$j.' )
}');
eval ('sub edit'.$i.$j.'_Char { return 0 if $_[1] == 9; return
1; }');
}
}
sub what_to_do {
my ( $i, $j ) = ( shift, shift );
my $hash_EVENT = Win32::GUI::GetKeyboardState;
my $_EVENT = what_event( $hash_EVENT );
my $nextX = $j + 1; $nextX = 0 if $nextX >= $dimX;
my $prevX = $j - 1; $prevX = $dimX-1 if $prevX < 0;
my $nextY = $i + 1; $nextY = $dimY-1 if $nextY >= $dimY;
my $prevY = $i - 1; $prevY = 0 if $prevY < 0;
if ( $_EVENT eq 'Tab' ) { $edit[$i][$nextX]->SetFocus() }
if ( $_EVENT eq 'ShiftTab' ) { $edit[$i][$prevX]->SetFocus() }
if ( $_EVENT eq 'Up' ) { $edit[$prevY][$j]->SetFocus() }
if ( $_EVENT eq 'Down' ) { $edit[$nextY][$j]->SetFocus() }
}
$edit[0][0]->SetFocus();
$mw->Show();
Win32::GUI::Dialog();
sub Main_Terminate { -1; }
sub what_event {
my $_EVENT = shift;
my $result = '';
my $SHIFT = '';
if (( $_EVENT->[160] )||( $_EVENT->[161] )) { $SHIFT = 'Shift' }
for ( my $i = 0; $i < 256; $i++ ) {
if ( $_EVENT->[$i] ) {
if ( $i == 9 ) { $result = $SHIFT.'Tab' }
elsif ( $i == 38 ) { $result = $SHIFT.'Up' }
elsif ( $i == 40 ) { $result = $SHIFT.'Down'}
}
}
return $result;
}
__END__
#!/usr/bin/perl -w
use strict;
use warnings;
use Win32::GUI();
sub VK_TAB() {9}
sub VK_SHIFT() {16}
sub VK_LEFT() {37}
sub VK_UP() {38}
sub VK_RIGHT() {39}
sub VK_DOWN() {40}
my $mw = Win32::GUI::Window->new(
-name => "Main",
-width => 900,
-height => 400,
);
my @edit = ();
my $dimX = 4;
my $dimY = 4;
for ( my $y = 0; $y < $dimY; $y++ ) {
for ( my $x = 0; $x < $dimX; $x++ ) {
$edit[$x][$y] = $mw->AddTextfield (
-text => "${x}x$y",
-name => "Edit:$x:$y",
-left => 50 + 100*$x,
-top => 50 + 20*$y,
-width => 99,
-height => 20,
-onKeyDown => \&keydown,
-onChar => \&char,
);
$edit[$x][$y]->UserData( [ $x, $y] );
}
}
$edit[0][0]->SetFocus();
$mw->Show();
Win32::GUI::Dialog();
exit(0);
sub keydown {
my ($self, undef, $key) = @_;
my ($x,$y) = @{$self->UserData()};
if($key == VK_UP) {
--$y; $y = 0 if $y < 0;
}
elsif($key == VK_DOWN) {
++$y; $y = ($dimY - 1) if $y >= $dimY;
}
elsif($key == VK_TAB) {
my $shift = Win32::GUI::GetKeyboardState()->[VK_SHIFT];
# Better to use GetKeyState(VK_SHIFT), but not
# currently in Win32::GUI
if($shift) {
--$x; $x = ($dimX - 1) if $x < 0;
}
else {
++$x; $x = 0 if $x >= $dimX;
}
}
else {
return 1;
}
$edit[$x][$y]->SetFocus();
return 0;
}
sub char {
my (undef, undef, $key) = @_;
return 0 if $key == 9; # Don't pass TAB to edit control
return 1;
}
__END__