Corso di Visual C++

I range di comandi

 

Impostare dei range di comandi WM_COMMAND da associare ad un’unica 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 un’applicazione 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 dell’IDE 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