[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__