Introduzione alle API Win32, Parte 4/6
di Mastersgn, del 30 gennaio 2007 C/C++
Dopo aver creato una finestra di dialogo, introduciamo il concetto di evento e sviluppiamo la gestione di un particolare evento: la chiusura del dialogo. Infine, inseriamo un controllo nel dialogo come premessa alla lezione successiva.
Procedura del dialogo
Nell'articolo precedente abbiamo lasciato una domanda in sospeso: Perché non è possibile chiudere la finestra di dialogo? Prima di rispondere dobbiamo comprendere un particolare importante:
Quando interagiamo con un dialogo - ovvero lo ridimensioniamo, chiudiamo o clicchiamo su un controllo in esso presente - compiamo azioni chiamate eventi.
Ogni finestra possiede i propri eventi e, a fronte dell'attivazione di questi, può rispondere in determinati modi, che ovviamente saremo noi a decidere. Di conseguenza, quando chiudiamo il nostro dialogo in realtà inviamo un messaggio di chiusura della finestra alla procedura di gestione dell'evento: ogni dialogo dispone di una procedura per gestire i possibili eventi.
A questo punto è facile intuire che il dialogo creato nel precedente articolo non si chiudeva perchè non possedeva una propria procedura di gestione degli eventi, compreso la chiusura della finestra stessa.
Dunque, modificamo il codice del file
main.c
, come segue:#include <windows.h>
BOOL CALLBACK dlgProc(HWND hwndDlg,UINT dlgMsg,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
DialogBoxParam(0,"MioDialogo",0,dlgProc,0);
return 0;
}
BOOL CALLBACK dlgProc(HWND hwndDlg,UINT dlgMsg,WPARAM wParam,LPARAM lParam)
{
switch(dlgMsg)
{
case WM_CLOSE:
EndDialog(hwndDlg,0);
return TRUE;
break;
}
return 0;
}
Compiliamo nuovamente l'applicazione: ora la finestra è in grado di chiudersi correttamente.
Procedure e messaggi
Incontriamo una funzione utilizzata, appunto, come procedura del dialogo per la gestione degli eventi. Analizziamone il prototipo:
BOOL CALLBACK dlgProc(HWND hwndDlg,UINT dlgMsg,WPARAM wParam,LPARAM lParam);
- La funzione restituisce un tipo
BOOL
(valore 0 oppure 1) che può essere usato per conoscere l'esito della procedura.
dlgProc
è il nome che abbiamo scelto per la propcedura.
- Il parametro di tipo
HWND
(che chiamiamohwndDlg
) riceve l'handle del dialogo. Ci servirà nella procedura stessa (come primo parametro nella chiamata aEndDialog()
).
UINT dlgMsg
è il codice del messaggio. Viene passato alla procedura al verificarsi di un determinato evento (nel nostro casoWM_CLOSE
per chiudere la finestra).
WPARAM
edLPARAM
per ora li ingoriamo; li analizzeremo più avanti.
Adesso analizziamo il corpo della procedura:
switch(dlgMsg)
{
case WM_CLOSE:
EndDialog(hwndDlg,0);
return TRUE;
break;
}
Troviamo uno switch sulla variabile
dlgMsg
: nel caso in cui il codice del messaggio corrisponda aWM_CLOSE
, la procedura chiude il dialogo utilizzando la funzioneEndDialog()
. Dunque, a fronte dell'evento di chiusura del dialogo, il sistema spedisce un messaggioWM_CLOSE
alla procedura di gestione, "chiedendo" al dialogo di chiudersi.
Funzione EndDialog()
BOOL EndDialog(
HWND hDlg,
int nResult
);
- Al parametro di tipo
HWND
passiamo l'handle del dialogo da chiudere. Nel nostro casohwndDlg
(se stesso).
- A
int nResult
passiamo 0 (zero), e non ce ne interessiamo ulteriormente.
Osserviamo nuovamente la funzione di creazione del dialogo:
DialogBoxParam(0,"MioDialogo",0,dlgProc,0);
Al quarto parametro (
DLGPROC lpDialogFunc
), passiamo il nome della procudura del dialogo,dlgProc
appunto.
Riassumendo
Ogni dialogo possiede una procedura interna per gestire gli eventi che si possono verificare, tra cui anche la chiusura del dialogo stesso.
- Abbiamo visto che al verificarsi di un evento, il sistema invia alla procedura del dialogo il messaggio corrispondente a questo evento. Nel nostro caso si è trattato della chiusura della finestra, ma potrebbe trattarsi di qualsiasi altro evento, come il click su un controllo.
- Osserviamo il corpo della procedura: nel caso in cui (istruzione
switch
) il codice del messaggio (in questa procedura l'abbiamo chiamatodlgMsg
) corrisponda aWM_CLOSE
(evento di chiusura), allora chiudiamo il dialogo attraverso la chiamata alla funzioneEndDialog()
.
- La costante
WM_CLOSE
è un valore predefinito dell'ambiente. Ne esite uno per definire ciascun evento.
- Nell'istruzione di creazione del dialogo
DialogBoxParam(0,"MioDialogo",0,dlgProc,0)
, il secondo parametro indica il dialogo così come è stato definito nel nostro fileresource.rc
, mentre il quarto parametro identifica la procedura dello stesso.
Come esercizio per consolidare il tutto vi consiglio di riscrivere un'altro progetto uguale a questo, ma con nome di variabili, funzioni, costanti e parametri diversi (ad eccezione, ovviamente, delle costanti di ambiente!).
Aggiungiamo un controllo static
A questo punto, per concludere l'esercizio, inseriamo un semplice controllo nel nostro dialogo. Modifichiamo il file
resource.rc
in questo modo:
#include <windows.h>
MioDialogo DIALOG 20, 30, 180, 100
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialogo vuoto"
FONT 10, "Ms Sans Serif"
BEGIN
CTEXT "Sono un esempio di controllo static",101,16,18,144,33
END
Compilate il programma e vedrete il nuovo controllo all'interno della finestra. Nel prossimo appuntamento, vedremo come inviare e ricevere messaggi verso il controllo.
Nessun commento:
Posta un commento