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