Impostare dei range di comandi WM_COMMAND da associare ad ununica
funzione può contribuire ad alleggerire e a semplificare il codice
in molte circostanze. Solitamente questa particolare implementazione
nella mappa dei messaggi è utilizzata per le voci di menu, ma può
essere utilizzata per qualsiasi altra risorsa che utilizzi le MACRO
ON_COMMAND E ON_UPDATE_COMMAND_UI.
Pensate ad esempio di dover scrivere unapplicazione di disegno
e che in questa i colori si scelgono tramite delle voci di menu.
Se avete 10 colori, dovete avere 10 voci di menu e per ognuna di
queste un gestore ON_COMMAND ed uno ON_UPDATE_COMMAND_UI; ognuno
di questi gestori chiaramente fa quasi lo stesso lavoro.
Sembrerebbe ragionevole cercare di utilizzare qualche scorciatoia,
e lo faremo.
Prendiamo per prima cosa l'esempio Prg36, creiamo una nuova voce
di menu superiore e chiamiamola Color, a questa aggiungiamo
tre voci di livello inferiore: Rosso, Verde e Blu.
Inserite anche il testo che comparirà sulla barra di stato e gli
acceleratori da tastiera (usando le combinazioni Shift+ prima lettera
del colore).
Ora nella dichiarazione della classe CMainFrame (nella dichiarazione
della mappa dei messaggi) aggiungiamo
afx_msg void OnColor(UINT nID);
Questa è la funzione che sarà chiamata in risposta ai clic sulle
tre voci di menu Rosso,Verde e Blu.
Ora nella mappa dei messaggi aggiungiamo la MACRO ON_COMMAND_RANGE
che si occupa di effettuare tutto il lavoro:
ON_COMMAND_RANGE(ID_COLOR_ROSSO,ID_COLOR_BLU,OnColor)
Naturalmente, per funzionare tutto correttamente, gli identificatori
specificati dai primi due parametri alla MACRO devono essere consecutivi;
nel nostro caso lo sono perché le voci di menu le abbiamo create
consecutivamente, ma in tutti i casi lo possiamo verificare cliccando
sulla voce Resource Symbols del menu View dellIDE
del VC++.
Scriviamo ora la vera e propria funzione OnColor:
void CMainFrame::OnColor(UINT
nID)
{
m_nCurColor=nID-ID_COLOR_ROSSO;
switch (m_nCurColor)
{
case 0: AfxMessageBox("Rosso");
break;
case 1: AfxMessageBox("Verde");
break;
case 2: AfxMessageBox("Blu");
break;
}
}
m_nCurColor è un membro di dati pubblico di CMainFrame
e inizializzato a 0 nel costruttore. (lo zero, per nostra convenzione,
indica il primo colore: rosso),
Come potete osservare mandando in esecuzione l'esempio, con una
sola funzione gestiamo tutte e tre le voci di menu (ma potrebbero
essere state anche 1 o 30).
Ora allo stesso modo aggiungiamo la MACRO ON_UPDATE_COMMAND_UI_RANGE
per sincronizzare lo stato dell'applicazione con le voci di menu.
Aggiungiamo per prima cosa la dichiarazione della funzione che gestirà
la sincronizzazione: (questo sempre nella dichiarazione della mappa
dei messaggi nel file di header).
afx_msg void OnUpdateColor(CCmdUI* pCmdUI);
E quindi l'implementazione della funzione:
void CMainFrame::OnUpdateColor(CCmdUI*
pCmdUI)
{
pCmdUI->SetRadio(pCmdUI->m_nID==(ID_COLOR_ROSSO+m_nCurColor));
}
Questo stratagemma non fa altro che verificare che il colore corrente
(memorizzato nel membro di dati m_nCurColor) corrisponda
alla voce che sta per essere visualizzata (il valore dell'identificatore
è contenuto nel membro di dati pCmdUI->m_nID); se lo è
l'uguaglianza sarà vera e darà come risultato 1 il che farà selezionare
la voce con un pallino.
Questo è per quanto riguarda i range di comandi, come avete visto,
sono molto facili da utilizzare e semplificano molto la stesura
e la comprensibilità del codice.
Clicca sull'icona del floppy per scaricare il progetto Prg36. ![]()
Clicca sull'icona del floppy per scaricare direttamente l'eseguibile
Prg36.exe ![]()
Nella prossima puntata inizieremo a trattare la gestione dinamica
dei menu.
Torna all'indice Generale del corso di Corso di Visual C++ di Software Planet