Corso di Visual C++

Eventi legati al mouse II

 

Nella scorsa puntata abbiamo iniziato ad esaminare gli eventi legati al mouse, riprendiamo e facciamo adesso una osservazione sull'evento WM_MOUSEMOVE.

Tale evento non viene semplicemente segnalato inserendo un messaggio nella coda: infatti si rischierebbe di sovraffollarla di messaggi che poi non possono essere smaltiti in modo tempestivo a causa del loro numero solitamente elevato. L'accorgimento utilizzato è di segnalare la loro presenza tramite un flag nella coda messaggi ed inserirli successivamente solo quando Windows cerca di prelevare un messaggio. In tal modo si evita l'accumulo nei periodi in cui l'applicazione non è in grado di prelevare i messaggi dalla coda ( a causa di altre elaborazioni o a causa di altri scheduling ).

Per la gestione dei messaggi del mouse ci possiamo benissimo appoggiare al Wizard che crea i prototipi e li inserisce nella mappa dei messaggi; se però siamo un po' sadomaso e vogliamo farlo naturalmente ( da veri esperti, anche se non troppo furbi ) dobbiamo seguire alcuni semplici passi:

 

Dobbiamo inserire il prototipo ( i parametri ed il tipo di ritorno sono uguali per tutte le funzioni di gestione del mouse ) nella file .h della classe e prima della macro DECLARE_MESSAGE_MAP (), es: afx_msg void OnLButtonDown (UINT nFlags, CPoint point)

Poi nel file di implementazione della classe dobbiamo inserire, con prefissa la sigla ON_, il nome del messaggio nella definizione della mappa dei messaggi ( tra le macro BEGIN_MESSAGE_MAP ed END_MESSAGE_MAP ), ad esempio ON_WM_LBUTTONDOWN().

A questo punto non resta che inserire il corpo della funzione nello stesso file, es:

void CmyView::OnLButtonDown (UINT nFlags, CPoint point)

{

//elaborazione del clic sul pulsante sinistro del mouse

}

Vediamo il significato dei parametri del prototipo:

afx_msg void OnMsgName (UINT nFlags, CPoint point)

nFlags è un intero senza segno che indica lo stato di pressione dei pulsanti del mouse al momento della generazione dell'evento ed in più anche lo stato dei tasti MAIUSC e CTRL.

Per effettuare delle verifiche su nFlags possono essere utilizzate le seguenti maschere:

MK_LBUTTON indica che il pulsante sinistro del mouse è premuto

MK_MBUTTON indica che il pulsante centrale del mouse è premuto

MK_RBUTTON indica che il pulsante destro del mouse è premuto

MK_CONTROL il tasto CTRL è premuto

MK_SHIFT il tasto MAIUSC è premuto

Ad esempio il seguente enunciato

nFlags & MK_LBUTTON & MK_SHIFT

restituisce un valore diverso da zero se e solo se è premuto sia il pulsante sinistro del mouse che il tasto MAIUSC della tastiera.

Il parametro di tipo CPoint ritorna invece informazioni sulla posizione del cursore del mouse al momento della generazione dell'evento. Tali informazioni sono proprio le coordinate x ed y del mouse, reperibili nelle variabili point.x e point.y, e nel formato di coordinate di dispositivo.
Ad esempio se in seguito alla ricezione di un messaggio WM_MOUSEMOVE, point vale ( 13,16 ) ciò significa che il mouse, dopo l'ultimo movimento, si trovava a 13 pixel a destra e 16 pixel in basso dall'angolo in alto a sinistra dell'area client della finestra.

Quindi ricordate bene: le coordinate del mouse sono sempre in coordinate di dispositivo, in qualunque caso. Se le si vuole convertire in coordinate logiche, utilizzare la funzione di CDC DptoLP.

Vediamo ora come fare a cambiare il cursore del mouse.

A tale scopo possiamo o utilizzare la funzione CWinApp::LoadCursor oppure ::LoadCursor. Entrambe permettono di caricare risorse cursore memorizzate nel file .exe della nostra applicazione e create o esternamente o con l'editor di risorse del Visual C++.

Ad esempio per caricare una risorsa cursore che abbiamo chiamato IDC_MIOCURSORE, utilizzare la seguente sintassi:

AfxGetApp()->LoadCursor(IDC_MIOCURSORE);

Se alla risorsa abbiamo assegnato anche un identificatore stringa, l'uso di questo al posto dell'identificatore intero non cambia molto:

AfxGetApp()->LoadCursor("NomeDellaRisorsa");

Se volessimo caricare, invece di cursori personalizzati, alcuni dei cursori standard del Windows, possiamo utilizzare o la funzione CWinApp::LoadStandardCursor o la solita ::LoadCursor.

Gli identificatori dei cursori predefiniti più utilizzati sono IDC_ARROW, IDC_BEAM e IDC_CROSS.

Ecco un semplice esempio d'uso con questi:

AfxGetApp()->LoadStandardCursor (IDC_ARROW);

AfxGetApp()->LoadCursor(NULL,IDC_ARROW);

Nella prossima puntata vedremo la gestione del mouse nell'area non client.

 

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