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

Reply via email to