Corso di Visual C++

La gestione degli eventi di tastiera

 

Le notifiche della pressione dei tasti arrivano alla vostra applicazione tramite messaggi, proprio come per il mouse.
Alla pressione di un tasto Windows invia alla vostra applicazione un messaggio WM_KEYDOWN, mentre al suo rilascio invia il corrispondente WM_KEYUP.
Questa è la regola generale per tutti i tasti tranne ALT ed F10. Questi infatti, essendo tasti di sistema speciali, provocano l'invio di messaggi WM_SYSKEYDOWN e WM_SYSKEYUP. Questi ultimi vengono inviati anche nel caso in cui si premano altri tasti, nel frattempo che il tasto ALT è tenuto premuto.

Se la vostra applicazione non ha bisogno di gestire tutti i tasti, ma solo quelli stampabili, allora va più che bene rispondere solo ai messaggi WM_CHAR. Questo vi semplificherà molto la vita, visto che sarà Windows a gestire le circostanze più disparate come quando è premuto il tasto ALT o MAIUSC, oppure la tastiera ha un layout non standard.
Se un tasto di carattere stampabile è premuto insieme al tasto di sistema ALT, viene inviato il messaggio WM_SYSCHAR.

La tastiera è come il mouse, è una risorsa condivisa e quindi i suoi messaggi non vengono inviati indistintamente a tutte le applicazioni. Mentre per il mouse i messaggi vengono inviati alla finestra che si trova sotto il suo puntatore, per la tastiera i messaggi vengono inviati alla finestra che ha l' "input focus". L'input focus è una proprietà che appartiene alla finestra che ha acquisito il controllo dell'input, magari cliccando su di essa o grazie a qualche altro stratagemma; solitamente è quella che è al momento attiva. L'input focus però potrebbe non appartenere alla finestra in questione, ma ad una sua finestra figlia, come un controllo di edit o una combo box. Nel caso in cui il focus appartenga ad una finestra figlia è bene ricordare che il flusso di messaggi non passa anche per il genitore, ma solo per la finestra in questione.

Una finestra al momento di ricevere l'input focus riceve un messaggio WM_SETFOCUS, mentre appena dopo che l'ha perso riceve un WM_KILLFOCUS.
Per 'regalare' l'input focus ad una finestra si può usare la funzione membro CWnd::SetFocus, oppure la funzione API ::SetFocus(hWnd). Se ad esempio pWnd è il puntatore al controllo di una finestra, se scriviamo:
pWnd->SetFocus();
succede che l'input focus passa a questo controllo. Automaticamente la finestra che aveva precedentemente l'input focus riceve un messaggio WM_KILLFOCUS.
Per avere un puntatore alla finestra che ha l'input focus, si può usare la funzione GetFocus di CWnd o ::GetFocus(hWnd) dell'API. In entrambi i casi il valore di ritorno sarà NULL se la finestra che possiede il focus non è stata creata dal thread da cui è stata richiamata tale funzione.

I messaggi dei tasti (key stroke) vengono inseriti nella coda dei messaggi nell'esatto ordine in cui vengono premuti e rilasciati i tasti. Ad esempio se si preme il tasto A, poi non rilasciando quest'ultimo si preme il tasto B, poi si rilascia quest'ultimo e poi il tasto A, si ha una sequenza di due messaggi WM_KEYDOWN e quindi due messaggi WM_KEYUP. Non è assolutamente vero che in seguito ad un messaggio WM_KEYDOWN deve giungere un messaggio WM_KEYUP.

Nello stesso momento in cui la funzione TranslateMessage traduce i due messaggi WM_KEYDOWN dell'esempio precedente, invia alla finestra con il focus due messaggi WM_CHAR con contenenti i codici dei tasti premuti.

I gestori per i messaggi WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN e WM_SYSKEYUP hanno il seguente prototipo:

afx_msg void OnMsgName (UINT nChar, UINT nRepCnt, UINT nFlags)

dove OnMsgName è la solita trasformazione dell'identificatore (costante numerica) del messaggio. Si elimina il prefisso WM_ e lo si sostituisce con On e quindi si trasforma tutto in minuscolo tranne le iniziali di parola; WM_KEYDOWN diventa ad esempio OnKeyDown.

Per una descrizione dei parametri di questo prototipo vi rimando alla prossima puntata.

 

Torna all'indice Generale del corso di Corso di Visual C++ di Software Planet