Corso di Visual C++

Eventi legati al mouse

 

Uno dei dispositivi di input maggiormente utilizzati, oltre alla tastiera, è il mouse.

Questo, come potrete immaginare, viene gestito da un apposito driver del Windows che elabora i suoi interrupt generando degli eventi di input. Tali eventi verranno immagazzinati in una particolare coda di messaggi nota come coda di input grezzi e sono identificati dal suffisso VM_ ( Windows Message ) come gli altri comuni messaggi del Windows. A questo punto un thread dedicato del S.O. provvede a trasferire i messaggi da questa coda a quelle delle singole applicazioni che si occupano di questo genere di eventi. Dopo di ciò i dati grezzi vengono elaborati dall'applicazione che li mette a disposizione per le comuni elaborazioni.

Questo modello è differente da quello del Windows 3.1 nel quale veniva utilizzata un'unica coda di messaggi in modo sincrono. La conseguenza era che se un'applicazione non riusciva a gestire l'input in maniera abbastanza veloce, ne risentivano le prestazioni di tutto il sistema.

 

La gestione asincrona dei messaggi del nuovo sistema a 32 bit utilizzando più code per ogni applicazione ed un thread di smistamento ha risolto brillantemente il problema.

Gli eventi legati al mouse si suddividono in due categorie principali: messaggi dell'area client e messaggi dell'area non client; in tutto sono circa 20 e sono generati da pressioni o rilasci dei pulsanti, da doppi clic o da movimenti del mouse.

Per ora esamineremo solo i messaggi relativi all'area client visto che gli altri hanno un comportamento leggermente diverso; questi sono i seguenti:

WM_LBUTTONDOWN

WM_MBUTTONDOWN

WM_RBUTTONDOWN

WM_LBUTTONUP

WM_MBUTTONUP

WM_RBUTTONUP

WM_LBUTTONDBLCLK

WM_MBUTTONDBLCLK

WM_RBUTTONDBLCLK

WM_MOUSEMOVE

I primi tre si riferiscono alle pressioni sui tasti sinistro, centrale e destro del mouse, i successivi tre ai corrispettivi rilasci dei pulsanti, mente gli ultimi tre ai doppi clic sui medesimi.

Nel caso in cui il pulsante centrale del mouse non esista, i pulsanti WM_Mx non arriveranno mai.

Per controllare il numero di pulsanti del mouse di sistema, basta controllare il valore di ritorno della seguente chiamata a funzione: ::GetSystemMetrics ( SM_CMOUSEBUTTONS ) ; se 0 significa che non è installato alcun mouse.

Riguardo ai messaggi WM_xBUTTONUP, c'è da fare qualche piccola osservazione: cosa succede se cliccate all'interno dell'area client della finestra e poi rilasciate il pulsante cliccato al suo esterno? Probabilmente starete immaginando che vi arriverà prima un messaggio WM_xBUTTONDOWN, poi una serie di WM_MOUSEMOVE senza un WM_xBUTTONUP finale come ci si potrebbe normalmente attendere.

Ecco quindi che bisogna non fare troppo affidamento sulla ricezione di questi ultimi messaggi, se proprio se ne ha bisogno si può utilizzare un piccolo trucchetto chiamato cattura del mouse e che affronteremo in seguito.

Grazie a quest'ultimo, dopo la cattura, tutti i messaggi generati dal mouse, anche all'esterno dell'area client, giungeranno alla nostra applicazione per una successiva elaborazione fino a quando non rilasceremo la cattura. In questo modo potremo essere sicuri che ad un messaggio WM_xBUTTONDOWN corrisponderà sempre un WM_xBUTTONUP.

Altra osservazione da fare è quella sulla notifica dei messaggi di doppio click.

Questo messaggio viene ricevuto quando due clic sullo stesso bottone del mouse si susseguono dopo un certo intervallo di tempo prefissato. Si può presto intuire che quindi giungerà prima una coppia WM_xBUTTONDOWN e WM_xBUTTONUP e poi un'altra coppia WM_xBUTTONDBLCLK e WM_xBUTTONUP.

Per ricevere tali tipi di messaggi la finestra deve però essere registrata per i doppi clic, quindi impostando lo stile CS_DBLCLKS della WNDCLASS ( già fatto di default ); in caso contrario si riceveranno semplicemente due coppie di eventi di notifica di pressione e rilascio.

Solitamente la prima coppia ricevuta viene utilizzata per selezionare l'oggetto sotto il mouse e poi la seconda per effettuare qualche operazione su di esso.

Nella prossima puntata continueremo a vedere gli eventi legati al mouse e come gestire questi messaggi.

 

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