2012-04-30 2 views
1

J'ai une petite application de console qui vérifie entre autres le statut d'une autre opération. Une fois par seconde, il vérifie les touches en utilisant Term :: ReadKey. Si la touche 'r' a été pressée, l'affichage est actualisé:Comment puis-je déterminer si F15 a été pressé?

{ # 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'); 
}  

Ceci fonctionne comme prévu. Cependant, j'utilise également Caffeine pour empêcher l'affichage de mon écran Win 7. Cet utilitaire fonctionne en simulant une pression de F15 toutes les 59 secondes, ne permettant donc jamais à l'économiseur d'entrer en jeu. Bien que l'approche de Caffeine soit assez kludgy, cela a très bien fonctionné pour moi pendant des années. Cependant, à l'instar de Windows, mon application de console lit également la pression simulée de F15 comme une véritable pression sur la touche, provoquant la sortie de l'application de la console. Si je pouvais égaler F15, je pourrais le filtrer. Donc, ma question:

Comment puis-je déterminer si F15 a été pressé, en utilisant Term :: ReadKey?

Ceci est sur Windows 7 Pro, Strawberry 5.12.3, Term :: ReadKey v. 2.30.02.

(Je suis conscient qu'il peut y avoir un composant significatif à ma question, et je me réjouis d'autres solutions.) Cependant, je suis curieux de savoir comment on pourrait faire cela. Je peux voir pourquoi je pourrais vouloir voir quand une fonction touche a été appuyée dans d'autres situations.)

Répondre

2

[Il est bon que vous reconnaissez que cela est très xy :)]

vous utilisez un module unix-centrée. Utilisez un module plus approprié: Win32::Console, par exemple.

[Ma réponse précédente a été convertie en commentaire. Apparemment, les mods Stack Overflow veut ma réponse soit 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"; 
     } 
    } 
} 

Voir KEY_EVENT_RECORD pour plus d'informations sur les événements clavier.

Voir Virtual-Key Codes pour identifier les clés.


en-têtes et définitions pour le code ci-dessus:

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; 
+0

Merci @ikegami, qui servira admirablement. [Aussi, merci d'avoir répondu à la question posée malgré sa nature x-y :)] – Twixi

Questions connexes