Corso di Visual C++

Sincronizzare le voci di menu

 

Nell’ultima puntata stavamo lavorando sul progetto di esempio Prg36. Ci eravamo proposti di spuntare la voce ProvaMenu non appena questa veniva cliccata per la prima volta.
Avevamo agganciato il messaggio UPDATE_COMMAND_UI all'identificatore ID_VIEW_PROVAMENU e avevamo fatto creare al Wizard lo scheletro del suo handler:

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


Come possiamo notare alla funzione viene passato un parametro di tipo CCmdUI
La classe CCmdUI è una classe che non ha nessun'altra classe base e viene utilizzata unicamente con il messaggio UPDATE_COMMAND_UI nelle classi derivate da CCmdTarget.

Come già detto quando un utente apre un menu, l'applicazione ha bisogno di sapere come dovrà apparire ogni voce: abilitata, disabilitata, spuntata... e per sapere ciò controlla la mappa dei messaggi per cercare degli handler ad UPDATE_COMMAND_UI. Grazie a questi handler viene passato un oggetto di tipo CCmdUI attraverso il quale, usando le sue funzioni membro, è possibile settare lo stato della voce.
Le funzioni membro principali di CCmdUI sono 4: SetText, SetRadio, SetCheck ed Enable; i loro nomi sembrano abbastanza autoesplicativi. Queste possono essere usate sia con voci di menu, che con pulsanti di toolbar che con pannelli delle barre di stato; ovviamente possono non sortire alcun effetto se non applicate al giusto contesto (es. settare il testo di un bottone di una toolbar).
SetText prende come parametro una stringa, mentre tutti gli altri un valore booleano (0 o 1) che imposta quella caratteristica. Ad esempio SetCheck imposta un segno di spunta, mentre SetRadio affianca alla voce un pallino. Questa seconda possibilità è poco usata, ma io la preferisco in situazioni in cui si devono selezionare voci che stanno tra loro in rapporto di mutua esclusione.

Il membro di dati più importante è sicuramente m_nID, cioè l'identificatore numerico della voce di cui si sta per settare lo stato, è utile in un caso che vedremo in seguito (ok, lo so siete curiosi, ma abbiate pazienza).

Modifichiamo la precedente funzione in questo modo:

void CMainFrame::OnUpdateViewProvamenu(CCmdUI* pCmdUI)
{
            static BOOL primaVolta=TRUE;
           
            if (primaVolta)
            {
                        primaVolta=FALSE;
            }
            else
            pCmdUI->SetCheck(TRUE);
}

Con queste due righe di codice facciamo si che la funzione pCmdUI->SetCheck(TRUE) venga richiamata solo se non è la prima volta che viene richiamato l’handler OnUpdateViewProvamenu. Per ‘ricordare’ se è la prima volta o meno, come vedete utilizziamo una variabile statica. Come tutti i programmatori abbastanza esperti sanno, le variabili statiche conservano il loro valore anche quando escono dallo scope (il loro campo di utilizzo) e vengono inizializzate solo la prima volta che vengono utilizzate; hanno anche altre caratteristiche molto importanti, ma ora non ci interessano.

Questo è il più per quanto concerne la sincronizzazione delle voci di menu con lo stato dell’applicazione, diamo ora brevemente qualche accenno sugli acceleratori di menu.
Come già detto in una puntata precedente, per specificarli occorre utilizzare l’editor delle risorse. Qui si associa ad ogni identificatore di voce di menu o di barra degli strumenti una combinazione di tasti. Alla pressione di questa combinazione di tasti viene inviato un messaggio WM_COMMAND con l’ID specificato per quell’acceleratore ed è come se fosse stata selezionata quella voce di menu (o quel pulsante della barra degli strumenti) a tutti gli effetti.
Gli acceleratori di tastiera si possono però specificare anche per ID non associati a nessuna voce ne di menu, ne di barra degli strumenti; in questo caso sarà solo una scorciatoia per un comando particolare.
Nello scegliere le combinazioni di tasti è preferibile non scegliere le combinazioni con il tasto ALT, questo tasto è infatti per lo più utilizzato dal S.O. e si potrebbe rischiare di creare confusione negli utenti che sono soliti utilizzare queste combinazioni standard; si consiglia quindi, per evitare problemi, di utilizzare le combinazioni con MAIUSC e CTRL.

Quanto esposto basta nel 90% dei casi, mi sento però obbligato a parlare, nelle prossime puntate, anche dell’uso dei range di comandi e del caricamento e creazione dinamica dei menu.
Per ora volontariamente non parlo delle bitmap nelle voci di menu perché presuppongono conoscenze di programmazione molto avanzate, e rischieremmo solo di fare una grande confusione; per tale motivo rimanderò questo argomenti molto più in la, dopo che avremo parlato dei controlli, delle DLL e di varie altre cosette.

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 parleremo sempre dei menu ed in particolare dei range di comandi.

 

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