2014-05-21 5 views
8

Questa domanda potrebbe avere già una risposta, ma non sono riuscito a trovare la risposta corretta. Sto cercando di attivare o disattivare un interruttore di debug quando viene premuto il tasto F12 in un modulo. Non riesco a utilizzare l'evento onkeydown poiché dovrei configurare una funzione separata per ogni campo insieme al modulo. Quindi ho studiato e ho trovato la funzione SetWindowsHookEx per impostare un hook della tastiera. Questo funziona bene tranne che sto ottenendo due indicazioni il tasto F12 è premuto ogni volta che viene premuto:Gancio tastiera per cercare F12 con delphi

2014/05/21 14:16:43.334 
Code: 0 
Key: 123 
KeyStroke: 5767169 
KeyStroke to Hex: 00580001 
2014/05/21 14:16:43.446 
Code: 0 
Key: 123 
KeyStroke: -1067974655 
KeyStroke to Hex: C0580001 Note: this should be the keystroke that reflects KEYDOWN 

vedo la combinazione di tasti è un possibile metodo per verificare la presenza di keydown (WM_KEYDOWN $ 0100). La mia domanda è: come posso testare Keystroke per WM_KEYDOWN?

Qui è la mia funzione di callback:

function KeyboardHookProc(Code: Integer; Key: Word; KeyStroke: LongInt) : LongInt; 
begin 
    Result := 0; 
    if Code = HC_NOREMOVE then exit; 
    Result := CallNextHookEx(FkbHook, Code,Key,KeyStroke); 
    if Code < 0 then exit; 

{ 
WM_KEYDOWN 

} 
    if (KeyStroke and WM_KEYDOWN) = 0 then { this is where I need to test but this doesn't work! } 
    begin 
    if Code = HC_ACTION then 
    begin 
    case Key of 
     vk_F12: begin 
      TKPMF.Memo1.Lines.Add(FormatDatetime('yyyy/mm/dd hh:nn:ss.zzz',now)); 
      TKPMF.Memo1.Lines.Add('Code: ' + IntToStr(Code)); 
      TKPMF.Memo1.Lines.Add('Key: ' + IntToStr(Key)); 
      TKPMF.Memo1.Lines.Add('KeyStroke: ' + IntToStr(KeyStroke)); 
      TKPMF.Memo1.Lines.Add('KeyStroke to Hex: ' + LongToHex(KeyStroke)); 
     end; 
    end; {case} 

    end; 
    end; 

end; 
+1

Quale versione di Delphi stai usando? Perché non utilizzare KeyPreview del modulo? http://stackoverflow.com/questions/6509242/how-does-delphis-keypreview-work – Frazz

+2

Nel peggiore dei casi utilizzare ApplicationEvents. Non c'è bisogno di agganciare la tua applicazione. –

+3

Non sono sicuro del motivo per cui qualcuno farebbe un downvote qui. L'OP ha mostrato prove di ricerca e codice di esempio. Anche l'OP è nuovo (rep = 1), quindi l'incapacità di chiarire la versione di Delphi è scusabile. – Argalatyr

risposta

12

Non è necessario assegnare un gestore diverso per ogni singolo evento del controllo OnKeyDown. Puoi assegnarle tutte per utilizzare lo stesso singolo gestore. Se si abilita la proprietà KeyPreview del modulo, non sarà necessario assegnare alcun gestore a nessuno dei controlli, è possibile utilizzare l'evento OnKeyDown del modulo da solo. Se è necessario rilevare la pressione del tasto quando sono aperti più moduli, è possibile utilizzare l'evento TApplication.OnMessage o TApplicationEvents.OnMessage. In entrambi i casi, non è necessario utilizzare un gancio della tastiera tramite SetWindowsHooKEx().

Il motivo per cui il tuo hook non funziona è perché WM_KEYDOWN è un messaggio di finestra, non un flag di sequenza di tasti. Read the documentation. La sequenza di tasti dei due messaggi visualizzati differisce solo nei bit 30 (stato chiave precedente) e 31 (stato transizione).

+0

Remy, sì è stato così, come al solito, cerco di rendere le cose troppo complicate. Posso sempre contare su di te per conoscere la risposta corretta. –

+1

Quando qualcuno ti dà una risposta corretta, devi fare clic sul pulsante per accettarlo (funziona solo per uno se c'è più di una risposta). In questo modo, il rispondente ottiene un piccolo aumento di reputazione, come hai fatto quando alcuni di noi hanno upvoted la tua domanda, e la risposta acquisisce un segno di spunta verde, che aiuta gli altri utenti. – MartynA

+5

MartynA - fatto! –