2010-03-12 10 views
5

Sto riscontrando il seguente problema in un'app WinForms. Sto cercando di implementare i tasti di scelta rapida e devo elaborare i messaggi chiave ogni volta che il controllo è attivo, non importa se il focus è su una casella di testo all'interno di quel controllo, ecc.ProcessCmdKey - attendere KeyUp?

Override ProcessCmdKey funziona magnificamente per questo e fa esattamente ciò che Voglio con una sola eccezione:

Se un utente preme un tasto e lo tiene premuto, ProcessCmdKey continua ad attivare gli eventi WM_KEYDOWN.

Tuttavia, ciò che voglio ottenere è che l'utente debba rilasciare nuovamente il pulsante prima che venga avviata un'altra azione hotkey (quindi, se qualcuno si siede sulla tastiera non causerebbe eventi di hotkey continui).
Tuttavia, non riesco a trovare dove rilevare gli eventi WM_KEYUP, quindi posso impostare un flag se deve elaborare nuovamente i messaggi ProcessCmdKey?

Chiunque può dare una mano qui?

Grazie,

Tom

risposta

9

ho pensato che sarebbe stato facile, basta guardare numero di ripetizioni della chiave. Non ha funzionato anche se sono usati modificatori. Avrai bisogno di vedere la chiave salire, che richiede l'implementazione di IMessageFilter. Questo ha funzionato:

public partial class Form1 : Form, IMessageFilter { 
    public Form1() { 
     InitializeComponent(); 
     Application.AddMessageFilter(this); 
     this.FormClosed += (s, e) => Application.RemoveMessageFilter(this); 
    } 
    bool mRepeating; 
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { 
     if (keyData == (Keys.Control | Keys.F) && !mRepeating) { 
      mRepeating = true; 
      Console.WriteLine("What the Ctrl+F?"); 
      return true; 
     } 
     return base.ProcessCmdKey(ref msg, keyData); 
    } 
    public bool PreFilterMessage(ref Message m) { 
     if (m.Msg == 0x101) mRepeating = false; 
     return false; 
    } 
} 
+0

Hm, che non sembra funzionare per me, PreProcessMessage non sembra ottenere innescato. – TJF

+0

Arf, funziona solo se il modulo ha lo stato attivo. Abbiamo bisogno del piano B, lascia che ci pensi. –

+0

@ Tom: ok, IMessageFilter può farlo. Ho aggiornato il mio post. –

3
const int WM_KEYDOWN = 0x100; 
const int WM_KEYUP = 0x101; 

protected override bool ProcessKeyPreview(ref Message m) 
{ 
    if (m.Msg == WM_KEYDOWN && (Keys)m.WParam == Keys.NumPad6) 
    { 
     //Do something 
    } 
    else if (m.Msg == WM_KEYUP && (Keys)m.WParam == Keys.NumPad6) 
    { 
     //Do something 
    } 

    return base.ProcessKeyPreview(ref m); 
} 
+1

WM_KEYUP non funziona qui. – Paul