Corso di Visual C++

La clessidra e miscellanea di mouse

 

Visto nella precedente puntata come cambiare la forma del mouse, vediamo in questa come nascondere il cursore, come attivare la clessidra e come rilevare alcune informazioni sul nostro caro topo.

Per nascondere il mouse non basta che richiamare ShowCursor con parametro FALSE, per ripristinarlo invece occorre richiamare la medesima funzione con parametro TRUE; es:

// nasconde il mouse

::ShowCursor(FALSE);

// riattiva il mouse

::ShowCursor(TRUE);

Ricordo che il SO tiene un conteggio interno del numero di volte che si nasconde e ripristina il mouse. Il conteggio parte da 0 e ogni volta che si nasconde il mouse viene decrementato il relativo contatore, viceversa viene incrementato quando lo si ripristina. Il puntatore verrà visualizzato solo quando il valore del contatore è maggiore o uguale a zero.

 

E' opportuno quindi, visto che il mouse è una risorsa condivisa, verificare che il numero di ShowCursor(FALSE) sia esattamente al numero di ShowCursor(TRUE).

Visualizzare il cursore a clessidra solitamente serve per notificare all'utente delle attese dovute a computazioni molto lunghe.

Personalmente io in questo caso, ove possibile, cerco di inserire dette computazioni in un thread separato in modo da non costringere l'utente ad attendere.

Se ciò non fosse possibile è possibile richiamare le funzioni BeginWaitCursor() ed EndWaitCursor() per visualizzare e nascondere la clessidra.

Come per il caso precedente Windows tiene una variabile interna per conteggiare il numero di volte che vengono richiamate queste funzioni. La clessidra viene visualizzata quando questa variabile assume un valore maggiore di zero (è inizializzata a zero). La solita raccomandazione è di tenere traccia del numero di volte che viene richiamata una funzione o l'altra perché il cursore è una risorsa condivisa.

Per non incorrere in questo problema si può creare una variabile di tipo CWaitCursor sullo stack; quando si uscirà dallo scope della variabile il cursore verrà automaticamente ripristinato; es:

CWaitCursor clessidra;

In questo caso dopo la creazione dell'oggetto clessidra il cursore si trasforma in una clessidra e verrà ripristinato quando si esce dallo scope; se lo si vuol fare prima si può utilizzare il metodo Restore, es:

clessidra.Restore();

Questo è utile in particolare quando si sa che potrebbe essere lanciato un messaggio WM_SETCURSOR che distruggerebbe la clessidra; questo potrebbe ad esempio avvenire se sta per essere visualizzata una finestra di dialogo o una MessageBox.

Se volete sostituire la clessidra utilizzata da CWaitCursor o BeginWaitCursor potete scavalcare la funzione virtuale DoWaitCursor di CWinApp. L'implementazione di default di questa funzione ( da utilizzare come modello per il vostro override ) si trova nel file sorgente Appui.cpp di MFC.

Per sapere se sul vostro sistema è presente un mouse, potete utilizzare GetSistemMetrics:

int ret=::GetSistemMetrics (SM_MOUSE_PRESENT);

ret varrà 0 se il mouse non è presente, un valore diverso da zero in caso contrario.

Se invece di SM_MOUSE_PRESENT mettete la costante SM_CMOUSEBUTTONS, il valore di ritorno sarà il numero di pulsanti del mouse ( 0 nel caso in cui il mouse non sia presente ).

Se tale funzione è richiamata con la costante SM_SWAPBUTTON, il valore di ritorno sarà diversoda 0 se i pulsanti destro e sinistro sono stati scambiati, 0 in caso contrario.

Per conoscere il tempo di doppio click utilizzare ::GetDoubleClickTime(), che ritorna appunto tale valore espresso in millisecondi. Per settare tale intervallo utilizzare la corrispondente funzione API: ::SetDoubleClickTime(xyz), dove xyz è l'intervallo in ms.

Nella prossima puntata vedremo come rilevare lo stato dei pulsanti del mouse e la sua posizione da qualsiasi funzione.

 

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