Corso di Visual C++

Utilizzare i menu III

 

Iniziamo l’ultima puntata solo teorica sui menu, le prossime saranno tutte di pratica, promesso!
Avevamo chiuso la scorsa puntata parlando dei messaggi che il Windows spedisce quando si fa click su una voce di menu.
Avevamo detto che tra i primi messaggi che arrivano (oltre a quello di clic del mouse o di tasto premuto della tastiera) c’è WM_INITMENU. Questo messaggio notifica che è stata selezionata una voce e che sta per essere visualizzato un menu. Prima che questo appaia sullo schermo arriva un messaggio WM_INITMENUPOPUP.
Dopo di ciò il menu è ormai visualizzato e all’utente è possibile selezionare le voci. Quando questi vi sposta il mouse sopra compare una barra di selezione che si sposta con esso, e poco prima viene inviato il messaggio WM_MENUSELECT. Questo messaggio nell’antichità (sempre al tempo dei programmatori in C) veniva usato per visualizzare una guida sensibile al contesto della voce di menu su cui sta passando il mouse.
Quando l’utente si decide a cliccare una voce, viene inviato un messaggio che indica il verificarsi di tale evento: un messaggio WM_COMMAND.

Questo è un messaggio che incontrerete spesso durante la vostra carriera di programmatori Windows; è quasi sempre conseguenza di azioni invocate dall’utente e per il quale spesso il programmatore deve prendere provvedimenti (per l’azione, non per il programmatore).
Il messaggio WM_COMMAND è composto da due parole: quella di ordine basso (wParam) nel caso dei menu contiene l’identificatore della voce di menu ed è quella che per ora ci interessa maggiormente.
MFC mette a nostra disposizione la macro ON_COMMAND; grazie a questa è molto semplice associare agli indicatori delle voci di menu (o della barra degli strumenti) una funzione.
Windows ha alcuni identificatori predefiniti di voci di menu; ad esempio i comandi Salva e Apri hanno come identificatori rispettivamente IDM_FILE_SAVE e IDM_FILE_OPEN.
Per associare quindi al clic sulla voce di menu Apri (che ha l’identificatore IDM_FILE_OPEN), la funzione OnFileOpen, basterà aggiungere la seguente riga nella mappa dei messaggi della finestra:

ON_COMMAND (IDM_FILE_OPEN, OnFileOpen)

Se utilizzate il Wizard, non dovrete fare neanche questo, si preoccuperà di fare tutto lui.

In passato quando non c’era MFC bisognava utilizzare un struttura switch-case controllando wParam per poi richiamare la funzione giusta associata all’identificatore.
Ricordo che con MFC il FrameWork provvede a smistare i messaggi di selezione delle voci di menu a tutte le quattro classi principali: quella di applicazione, di documento, di vista e di finestra. Ciò consente di gestire le funzioni associate in tutte e quattro queste classi, tenendo sempre presente però dei criteri logici da rispettare. Ad esempio sembrerebbe opportuno gestire le funzioni relative ai file nel documento, quelle relative al disegno nella vista… anche se possono esserci casi particolari.

Vediamo adesso di approfondire l'aspetto della sincronizzazione dello stato delle voci di menu con lo stato dell'applicazione.

Spesso può servire mostrare lo stato del programma tramite un segno di spunta accanto ad una voce di menu: è il caso ad esempio della voce Barra degli strumenti nel menu Visualizza. Quando la barra degli strumenti è visibile, tale voce è spuntata, viceversa non lo è.
Per aggiornare tali voci, il momento più propizio è quello prima che vengano visualizzate. Il framework ci permette di gestire questa situazione grazie al messaggio UPDATE_COMMAND_UI.
Questo messaggio arriva appunto prima che venga visualizzata la voce e grazie al parametro passato alla funzione che lo mappa è possibile modificare lo stato della voce.

Ad esempio nel caso dell’esempio visto nella puntata precedente potremmo volere che la voce di menu ProvaMenu non sia spuntata fino a quando non la clicchiamo per la prima volta.

Mappiamo allora il messaggio UPDATE_COMMAND_UI con l'identificatore ID_VIEW_PROVAMENU; ricordo di usare ClassWizard per fare ciò e scorrere la lista degli identificatori fino a trovare quello in oggetto.

Se abbiamo seguito tutti i passi correttamente come avevamo fatto prima, dovremmo trovarci dinanzi lo scheletro della funzione creata dal Wizard:

void CMainFrame::OnUpdateViewProvamenu(CCmdUI* pCmdUI)
{
            // TODO: Add your command update UI handler code here
           
}


Se siete intraprendenti sfogliate elettronicamente la bibbia del VC++ (l’MSDN), cercate di capire come funziona la classe CCmdUI e cercate di fare quello che ci siamo proposti: spuntare la voce ProvaMenu non appena viene cliccata per la prima volta. Se non ci riuscite troverete la soluzione nella prossima puntata.

 

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