Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7823271
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 2, 20262026-06-02T08:11:08+00:00 2026-06-02T08:11:08+00:00

How can I catch a shift – some-key combination with this script? When I

  • 0

How can I catch a shift–some-key combination with this script?
When I press the Arrow-keys I get what I expect, but when I press shift–tab it doesn’t return the KEY_BTAB value.

use warnings;
use 5.12.0;
use Win32::Console qw(STD_INPUT_HANDLE ENABLE_MOUSE_INPUT);
use constant {
    RIGHT_ALT_PRESSED  => 0x0001,
    LEFT_ALT_PRESSED   => 0x0002,
    RIGHT_CTRL_PRESSED => 0x0004,
    LEFT_CTRL_PRESSED  => 0x0008,
    SHIFT_PRESSED      => 0x0010,

    VK_LEFT     => 0x25,
    VK_UP       => 0x26,    
    VK_RIGHT    => 0x27,    
    VK_DOWN     => 0x28,    
    VK_TAB      => 0x09,    
};
use constant SHIFTED_MASK =>
    RIGHT_ALT_PRESSED |
    LEFT_ALT_PRESSED |
    RIGHT_CTRL_PRESSED |
    LEFT_CTRL_PRESSED |
    SHIFT_PRESSED;

my %d = (
    KEY_DOWN            => 258,
    KEY_UP              => 259,
    KEY_LEFT            => 260,
    KEY_RIGHT           => 261,
    KEY_BTAB            => 353,
);

my $con_in = Win32::Console->new(STD_INPUT_HANDLE);
$con_in->Mode(ENABLE_MOUSE_INPUT);

while ( 1 ) {
        my $key = getch();
        say "<$key>";
        last if $key == 113;
}

sub getch {
    my @event = $con_in->Input();
    my $event_type = shift( @event );
    if ( defined $event_type and $event_type == 1 ) { 
        my ( $key_down, $repeat_c, $vkcode, $vsccode, $char, $ctrl_ks ) = @event;
        if ( $char ) {
            return $char;
        }
        else {
            if ( $vkcode == VK_UP and ( $ctrl_ks & SHIFTED_MASK ) == 0 ) {
                return $d{KEY_UP};
            }
            elsif ( $vkcode == VK_DOWN and ( $ctrl_ks & SHIFTED_MASK ) == 0 ) {
                return $d{KEY_DOWN};
            }  
            elsif ( $vkcode == VK_RIGHT and ( $ctrl_ks & SHIFTED_MASK ) == 0 ) {
                return $d{KEY_RIGHT};
            }        
            elsif ( $vkcode == VK_LEFT and ( $ctrl_ks & SHIFTED_MASK ) == 0 ) {
                return $d{KEY_LEFT};
            } 
            elsif ( $vkcode == VK_TAB and $ctrl_ks == SHIFT_PRESSED ) {
                return $d{KEY_BTAB};    # <--
            }
            else {
                say "beep";
            }
        }
    }
}

Output when I press shift and tab:
beep
<1>
<9>
<9>
beep
<1>

After editing the getch routine this way

sub getch {
    my @event = $con_in->Input();
    my $event_type = shift( @event );
    if ( defined $event_type and $event_type == 1 ) { 
        my ( $key_down, $repeat_count, $virtual_keycode, $virtual_scancode, $char, $ctrl_key_state ) = @event;
        if ( $char ) {
            if ( $key_down ) {
                return $char for $repeat_count;
            }
        }
        else {
            if ( $virtual_keycode == VK_UP and ( $ctrl_key_state & SHIFTED_MASK ) == 0 ) {
                if ( $key_down ) {
                    return $d{KEY_UP} for $repeat_count;
                } 
            }
            elsif ( $virtual_keycode == VK_DOWN and ( $ctrl_key_state & SHIFTED_MASK ) == 0 ) {
                if ( $key_down ) {          
                    return $d{KEY_DOWN} for $repeat_count;
                }
            }  
            elsif ( $virtual_keycode == VK_RIGHT and ( $ctrl_key_state & SHIFTED_MASK ) == 0 ) {
                if ( $key_down ) {
                    return $d{KEY_RIGHT} for $repeat_count;
                }
            }        
            elsif ( $virtual_keycode == VK_LEFT and ( $ctrl_key_state & SHIFTED_MASK ) == 0 ) {
                if ( $key_down ) {
                    return $d{KEY_LEFT} for $repeat_count;
                }
            } 
            elsif ( $virtual_keycode == VK_TAB and ( $ctrl_key_state & SHIFTED_MASK ) == SHIFT_PRESSED ) {
                if ( $key_down ) {
                    return $d{KEY_BTAB} for $repeat_count;
                }
            }
            else {
                say "beep";
            }
        }
    }
}

I get this output:
beep
<1>
<9>
<0>
beep
<1>

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-02T08:11:11+00:00Added an answer on June 2, 2026 at 8:11 am

    Firstly, $char is set to 9, so you never get to your check. Move the if ($char) check to somewhere more appropriate.


    Secondly, your check is wrong. The following won’t work if, say, Caps Lock is on.

    elsif ( $vkcode == VK_TAB and $ctrl_ks == SHIFT_PRESSED )
    

    You should only check the flags you are interested in.

    elsif ($vkcode==VK_TAB and ( $ctrl_ks & SHIFTED_MASK ) == SHIFT_PRESSED)
    

    Finally, sometimes you only get notified once for multiple presses. That is signaled by $repeat_count. You ignore this, so you potentially ignore keys.

    You try to handle $repeat_count in the second snippet, but fail miserably. Part of the problem is you copied for $repeat_count from my other answer when it should be for 1..$repeat_count, and the other problem is that you only return one value even if $repeat_count is larger than one.


    my @kbd_queue;
    sub getch {
        my @event;
        if (@kbd_queue) {
           @event = ( 1, @{ pop @kbd_queue } );
        } else {
           @event = $con_in->Input();
        }
    
        my $event_type = shift( @event );
        if ( defined $event_type and $event_type == 1 ) { 
            my ( $key_down, $repeat_count, $virtual_keycode, $virtual_scancode, $char, $ctrl_key_state ) = @event;
            return -1 if !$key_down;
    
            if ( $virtual_keycode == VK_UP and ( $ctrl_key_state & SHIFTED_MASK ) == 0 ) {
                push @kbd_queue, \@event for 2..$repeat_count;
                return $d{KEY_UP};
            } 
            ...
            elsif ( $virtual_keycode == VK_TAB and ( $ctrl_key_state & SHIFTED_MASK ) == SHIFT_PRESSED ) {
                push @kbd_queue, \@event for 2..$repeat_count;
                return $d{KEY_BTAB};
            }
            elsif ( $char ) {
                push @kbd_queue, \@event for 2..$repeat_count;
                return $char;
            }
            else {
                say "beep";
            }
        }
    }
    

    You should convert this into something table-driven.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

this bash script can catch all the environment variables which are set when data
Is there some way I can catch when a method generates a write to
I can't get dataform and it's controls to catch exceptions when validating. Fir instance,
I have a UIScrollView in my view control but my UIScrollView can't catch the
Is there any way I can catch the event when I press the back
When we can catch an exception like: Violation of UNIQUE KEY constraint 'IX_Product'. Cannot
In GWT + UiBinder you can catch clicks like this: @UiHandler(cancelButton) void onCancelButtonClicked(ClickEvent e)
I want to create a wordpress plugin that can catch POST/GET requests to a
When my threads complete, I keep getting exceptions thrown. I can catch them, but
We know that we can catch any unexpected exception at application level by using

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.