Una volta inoltrati i messaggi, questi devono essere recuperati da una coda di priorità (ciò viene fatto dalla funzione GetMessage), tradotti (dalla funzione TranslateMessage) e quindi smistati tramite la funzione WndProc.
Come ciò avvenga non ci interessa, ma è importante sapere che i messaggi accodati ‘aspettano’ finche non vengono richiamati; è per questo motivo che talvolta, mentre il computer è molto occupato in qualche operazione, risponde in ritardo ai nostri input (clic del mouse, digitazione da tastiera).
I messaggi che non vengono direttamente gestiti dalla nostra applicazione finiscono in una funzione che si occupa della gestione di default (questa si chiama DefWindowProc); il processo termina quando nella coda arriva il messaggio speciale WM_QUIT (solitamente in seguito alla pressione, da parte dell’utente, del pulsante Chiudi).
Windows ci mette a disposizione circa 200 tipi di messaggi diversi, e a questi se ne aggiungono circa una ventina ad ogni nuova versione. Essi solitamente hanno un formato standard, cioè vengono accompagnati da due parametri a 32 bit che sono wParam e lParam, che descrivono il comportamento da tenere durante la loro gestione. Ad esempio il messaggio WM_LBUTTONDOWN viene mandato in seguito al clic sul pulsante sinistro del mouse e nei parametri di accompagnamento ci sono le sue coordinate al momento della pressione del tasto e anche altre informazioni che identificano l’eventuale pressione di CTRL s MAIUSC durante l’evento.
I messaggi che ora prenderemo più in considerazione sono quelli relativi all’aggiornamento dello schermo, al mouse e alla tastiera.
Quando una finestra ha bisogno di effettuare delle operazione sullo schermo deve gestire il messaggio WM_PAINT, che con MFC è fatto in automatico utilizzando come abbiamo già visto la funzione OnDraw; questa è una delle poche eccezioni, ma non iniziamo a parlare adesso del perché (se i più esperti di C++ stanno già pensando al virtualismo delle funzioni pure, stanno sulla buona strada).
Per avere una lista di tutti i messaggi possibili ed immaginabili con cui potremmo avere a che fare, andate nell’help del VC++ e nell’indice scrivete WM_ e vedrete un bella lista interminabile, con tutte le descrizioni del proprio significato e dei parametri associati.
Vediamo adesso come sia possibile effettuare la gestione dei messaggi (handling): se avete voglia di farlo manualmente, vi consiglio di vedere prima cosa fa il Wizard, in modo da ripensarci subito dopo!
Prima di tutto aprite un progetto (ad esempio prg2 di due puntate scorse), poi richiamate ClassWizard dal menu View.
Ora avete davanti una finestra a schede (sarà una vostra fedele amica!) e sulla prima compare la voce Message Maps e sarà quella che useremo più di frequente. Qui abbiamo varie opzioni: Projects, Class name, Object IDs, Messages e Member functions. L’Help ci spiega tutto, ma vediamo anche noi il loro significato:
- Projects indica il progetto correntemente attivo, ci è utile solo nel caso di applicazioni multi-progetto, utili in casi particolari come il testing di classi da esportare e di Dll.
- Class name ci permette di selezionare la classe del nostro progetto in cui vogliamo mappare il messaggio che andremo a selezionare; vi ricordate l’architettura Doc-View con le classi vista, applicazione, documento e finestra principale? È proprio ora che vedremo di capirne meglio il funzionamento, perché sarà assolutamente necessaria la loro comprensione.
- Object IDs permette di selezionare l’oggetto della finestra a cui si riferisce il messaggio (ad esempio un controllo di testo di modifica o un controllo a lista).
- Messages è l’elenco dei messaggi che supporta l’oggetto selezionato tramite Object IDs.
- Member functions è l’elenco delle funzioni membro della classe attualmente selezionata.
Proviamo ad esempio a gestire il già citato clic sinistro del mouse: primo, in Class name selezionate CPrg2View perché i messaggi vogliamo siano diretti alla classe vista e selezionate quindi l’oggetto CPrg2View.A questo punto tra la lista dei messaggi cercate WM_LBUTTONDOWN e fate doppio clic su tale voce e cliccate poi sul bottone Edit code.
Ora il Wizard ha fatto tutto per voi ed ogni volta che verrà cliccato il pulsante sinistro del mouse verrà richiamata la funzione appena creata.
Provate a sostituire il commento // Todo… con il comando seguente:
MessageBox(“Ciao!”);