如何确定是否按下了F15?

时间:2012-04-30 20:07:54

标签: regex perl

我有一个小的控制台应用程序,其中包括检查另一个操作的状态。每隔一秒,它会使用Term :: ReadKey检查按键。如果已按下'r'键,则刷新显示:

{   # generate display ...
    print "Press 'r' to refresh, any other key to exit:  ";
    my $resp = readkey();
    print $resp;
    redo if $resp =~ /r/i;
}
exit;

sub readkey {   
    my $key;
    ReadMode('cbreak');
    while (not defined $key) {
        if (defined ($key = ReadKey(-1)) ) {
            exit if $key =~ /\cC/i; # allow Ctrl-C to behave normally
            return $key;
        } else {
            sleep 1;
        }
    }
    ReadMode('normal');
}    

这一切都与预期完全一致。但是,我也使用Caffeine让我的Win 7显示器无法进入睡眠状态。这个实用程序的工作原理是每隔59秒模拟一次F15的按下,从而永远不会让屏幕保护程序启动。虽然Caffeine的方法非常糟糕,但它对我来说已经很好用了很多年了。但是,像Windows一样,我的控制台应用程序也会将F15的模拟按键读作真正的按键,导致控制台应用程序退出。如果我可以匹配F15,我可以过滤掉它。所以,我的问题是:

如何使用Term :: ReadKey确定是否已按下F15?

这是在Windows 7 Pro,Strawberry 5.12.3,Term :: ReadKey v.2.30.02。

(我知道我的问题可能有一个重要的x-y problem组件,我欢迎其他解决方案。但是,我很好奇如何做到这一点。我明白为什么我可能想看到在其他情况下按下功能键时。)

1 个答案:

答案 0 :(得分:2)

[你很高兴你认识到这是非常的xy:)]

您正在使用以Unix为中心的模块。使用更合适的模块:Win32::Console,例如。

[我之前的回答转换为评论。显然,Stack Overflow mods希望我的答案是99%repeated content?!?]

my $con_in = Win32::Console->new(STD_INPUT_HANDLE);
for (;;) {
   my @event = $con_in->Input();

   my $event_type = shift(@event);
   next if !defined($event_type) || $event_type != 1;  # 1: Keyboard

   my ($key_down, $repeat_count, $vkcode, $vscode, $char, $ctrl_key_state) = @event;
   if ($vkcode == VK_F15 && ($ctrl_key_state & SHIFTED_MASK) == 0) {
      if ($key_down) {
         say "<Up> pressed/held down" for 1..$repeat_count;
      } else {
         say "<Up> released";
      }
   }
}

有关键盘事件的详情,请参阅KEY_EVENT_RECORD

请参阅Virtual-Key Codes以确定密钥。


上述代码的标题和定义:

use strict;
use warnings;
use feature qw( say );

use Win32::Console qw( STD_INPUT_HANDLE );

use constant {
   RIGHT_ALT_PRESSED  => 0x0001,
   LEFT_ALT_PRESSED   => 0x0002,
   RIGHT_CTRL_PRESSED => 0x0004,
   LEFT_CTRL_PRESSED  => 0x0008,
   SHIFT_PRESSED      => 0x0010,

   VK_F15 => 0x7E,
};

use constant SHIFTED_MASK =>
   RIGHT_ALT_PRESSED |
   LEFT_ALT_PRESSED |
   RIGHT_CTRL_PRESSED |
   LEFT_CTRL_PRESSED |
   SHIFT_PRESSED;