Iniziamo lultima 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 allutente è 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 nellantichità
(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 lutente 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 dallutente e per il quale spesso il programmatore
deve prendere provvedimenti (per lazione, non per il programmatore).
Il messaggio WM_COMMAND è composto da due parole: quella di ordine
basso (wParam) nel caso dei menu contiene lidentificatore
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 lidentificatore
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 cera MFC bisognava utilizzare un struttura
switch-case controllando wParam per poi richiamare la funzione giusta
associata allidentificatore.
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 dellesempio 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++ (lMSDN), 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