1

とりわけ、別の操作のステータスをチェックする小さなコンソール アプリケーションがあります。1 秒に 1 回、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');
}    

これはすべて意図したとおりに機能します。ただし、カフェインを使用して、Win 7 ディスプレイがスリープ状態にならないようにしています。このユーティリティは、59 秒ごとに F15 キーを押すことをシミュレートすることで機能するため、スクリーンセーバーが起動することはありません。ただし、Windows と同様に、コンソール アプリも F15 のシミュレートされたプレスを実際のキープレスとして読み取り、コンソール アプリを終了させます。F15 と照合できれば、除外できます。だから、私の質問:

Term::ReadKey を使用して、F15 が押されたかどうかを判断するにはどうすればよいですか?

これは、Windows 7 Pro、Strawberry 5.12.3、Term::ReadKey v. 2.30.02 にあります。

(私の質問には重要なxy 問題コンポーネントがある可能性があることを認識しており、他の解決策を歓迎します。ただし、これを行う方法に興味があります。ファンクション キーがいつ変更されたかを確認したい理由がわかります。他の状況では押されます。)

4

1 に答える 1

2

[これが非常に xy であることを認識していただければ幸いです :)]

Unix 中心のモジュールを使用しています。より適切なモジュールを使用してください:たとえば、Win32::Console 。

[以前の回答がコメントに変換されました。どうやら、Stack Overflow mods は私の回答が 99%繰り返されるコンテンツであることを望んでいるようです ?!?]

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を参照してください。

キーを識別するには、仮想キー コードを参照してください。


上記のコードのヘッダーと定義:

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;
于 2012-05-01T06:26:29.527 に答える