Zoom Icon

Tutorial 10: Il Dialog Box come Finestra Principale

From UIC

Tutorial 10: Il Dialog Box come Finestra Principale

Contents


Tutorial 10: Il Dialog Box come Finestra Principale
Author: Icezelion
Email: Traduttore: -NeuRaL_NoiSE
Website: Mirror
Date: 30/12/2008 (dd/mm/yyyy)
Level: Slightly hard
Language: Italian Flag Italian.gif
Comments: Formattazione Wiki: Antelox


Introduzione

Adesso arriva la parte davvero interessante riguardo alla GUI, il dialog box. In questo tutorial (e nel prossimo), impareremo come usare un dialog box come finestra principale.


Tools

Esempio 1
Esempio 2


Preliminari

Se analizzate ed usate piu' volte gli esempi del tutorial precedente, dopo un po' vi accorgerete che non potete passare l'input focus da un controllo di child window ad un altro con il tasto Tab. L'unico modo di farlo e' clickare sul controllo in cui volete l'input focus. La situazione e' piuttosto fastidiosa. Un'altra cosa che potreste notare e' che ho cambiato il colore dello sfondo della parent window da bianco normale, come nell'esempio precedente, in grigio. Con questo cambiamento, il colore dei controlli di child window possono mescolarsi in modo perfetto con il colore della client area della parent window. C'e' un modo per aggirare il problema ma non e' semplice. Dovete subclassare tutti i controlli di child window nella vostra parent window. Il motivo per cui esiste questo problema e' che i controlli di child window sono stati originariamente ideati per funzionare con un dialog box, non una finestra normale. Il colore predefinito dei controlli di child window (tipo il push button) e' grigio perche' la client area di un dialog box e' normalmente grigia, e pertanto i colori si mescolano senza nessun lavoro aggiuntivo da parte del programmatore. Prima di inoltrarci nei dettagli, dovremmo capire COS'E' un dialog box. Un dialog box e' semplicemente una finestra normale progettata per funzionare con i controlli di child window. Windows fornisce inoltre un "gestore di dialog box" interno che e' responsabile per la maggior parte delle operazioni da tastiera, come cambiare l'input focus se Tab viene premuto, premere un push button predefinito se viene premuto il tasto Enter, ecc. cosicche' i programmatori possono dedicarsi a compiti piu' importanti. I dialog boxes sono fondamentalmente usati come periferiche di input e output. Come tali, possono essere considerati "scatole nere" di input o di output, a significare che un programmatore non deve sapere come un dialog box funziona internamente per poterlo utilizzare, deve semplicemente sapere come interagire con esso. Questo e' uno dei principi dell'object oriented programming (OOP, programmazione orientata agli oggetti, NdT), chiamato information hiding (occultamento delle informazioni). Se la scatola nera e' *perfettamente* progettata, l'utente puo' farne uso senza avere la minima idea di come essa operi. Il problema e' che la scatola nera deve essere perfetta, e questa e' una cosa difficile da ottenere nel mondo reale. Anche la Win32 API e' progettata come una scatola nera. Beh, sembra che stiamo deviando dal nostro discorso. Ritorniamo al nostro argomento. I dialog boxes sono progettati per ridurre il carico di lavoro di un programmatore. Normalmente se mettete i controlli di child window in una finestra normale, dovete subclassarli e scrivere le risposte alle operazioni da tastiera da soli. Ma se li mettete in un dialog box, questo gestira' le operazioni da tastiera per voi. Dovrete in tal caso solo sapere come rilevare l'input dal dialog box o come mandarvi comandi. Un dialog box e' definito come una risorsa, proprio come un menu. Voi scrivete un "template" del dialog box descrivendo le caratteristiche dello stesso e i suoi controlli, e quindi compilate il resource script con un editor di risorse. Notate che tutte le risorse vanno messe assieme nello stesso resource script file. Potete usare qualsiasi editor di testo per scrivere il template di un dialog box ma ve lo sconsiglio. Fareste meglio ad usare un editor di risorse e fare il lavoro in modo "visivo", poiche' organizzare i controlli di child window in un dialog box e' difficile da fare manualmente. Esistono molti eccellenti editors di risorse. Molti dei piu' importanti compilatori includono il proprio editor di risorse nel package. Potete usarli per creare uno script di risorse per il vostro programma, e quindi rimuovere le righe inutili, come quelle inerenti il MFC. Ci sono due tipi principali di dialog box: modal e modeless. Un modeless dialog box vi permette di cambiare l'input focus alle altre finestre. Un esempio e' il dialog "Find" di MS Word. Esistono due sottotipi di modal dialog box: application modal e system modal. Un application modal dialog box non vi permette di spostare l'input focus su di un'altra finestra della stessa applicazione, ma vi permette di spostarlo su finestre di ALTRE applicazioni. Un system modal dialog box non vi permette di spostare l'input focus su nessun'altra finestra se non gli rispondete, prima. Un modeless dialog box viene creato tramite la funzione API CreateDialogParam. Un modal dialog box viene creato chiamando DialogBoxParam. L'unica distinzione tra un application modal dialog box e un system modal dialog box e' lo stile DS_SYSMODAL. Se includete lo stile DS_SYSMODAL nel template del dialog box, quel dialog box sara' system modal. Potete rilevare dati da un controllo di child window control o da un dialog box chiamando la funzione SendDlgItemMessage. La sua sintassi e' questa:

LONG SendDlgItemMessage(

        HWND  hwndDlg, // handle del dialog box
        int  idControl, // id del controllo
        UINT  uMsg, // messaggio da mandare
        WPARAM  wParam, // primo parametro del messaggio
        LPARAM  lParam  // secondo parametro del messaggio
       );

Questa funzione API e' l'unica che dovete conoscere per essere in grado di rilevare e inviare messaggi e dati A e DA un controllo di child window. Ad esempio, se volete rilevare il testo da un edit control, potete farlo cosi':

call SendDlgItemMessage, hDlg, ID_EDITBOX, WM_GETTEXT, 256, ADDR buffer_per_testo

Per sapere quale messaggio inviare, dovreste consultare la vostra Win32 API reference. Comunque, Windows fornisce anche molte funzioni API controllo-specifiche per prendere e mandare dati velocemente, ad esempio CheckRadioButton, CheckDlgButton ecc. Queste funzioni controllo-specifiche sono state create per la comodita' dei programmatori, di modo che essi non si trovino a dover cercare il significato di wParam ed lParam per ogni messaggio. Normalmente, dovreste usare funzioni API controllo-specifiche quando disponibili, perche' rendono la gestione del codice piu' semplice. Ricorrete a SendDlgItemMessage solo se non disponete di una funzione API controllo-specifica. Un dialog box manda i suoi messaggi ad una funzione di callback specializzata, chiamata dialog box procedure che ha il seguente formato:

BOOL DlgProc  
         
            (HWND hDlg,         // handle della finestra del dialog
            UINT iMsg,          // Messaggio
            WPARAM wParam ,
            LPARAM lParam);

Come potete vedere, una dialog box procedure e' molto simile ad una window procedure, eccetto per il tipo di valore di ritorno, che e' BOOL anziche' LRESULT. Il gestore di dialog boxes interno di Windows E' la vera window procedure per i dialog boxes. Esso chiama la nostra dialog box procedure con i molti messaggi che riceve. Percio' la regola generale e' questa: se la dialog box procedure elabora un messaggio, DEVE restituire il valore TRUE in eax e se non lo elabora, deve restituire FALSE in eax. Notate che una dialog box procedure non passa i messaggi che non elabora alla call a DefWindowProc, poiche' non e' una vera window procedure. Potete fare due usi distinti di un dialog box. Potete usarlo come finestra principale della vostra applicazione o usarlo come periferica di input. Esamineremo il primo approccio in questo tutorial. La frase "usare un dialog box come finestra principale" puo' essere interpretata in due modi diversi.

  1. Potete usare il template del dialog box come un template di class che registrate con la funzione RegisterClassEx. In questo caso, il dialog box si comporta come una finestra "normale": riceve messaggi tramite la window procedure riferita dal membro lpfnWndProc della window class, non tramite una dialog box procedure. Il vantaggio di questo approccio sta nel fatto che non dovete creare i controlli di child window da soli, poiche' Windows li crea per voi quando viene creato il dialog box. Inoltre Windows gestisce la keyboard logic (Tab, Enter ecc.) per voi. In piu' potete specificare cursore ed icona della vostra finestra nella struttura della window class.
  2. Il vostro programma crea semplicemente il dialog box senza creare nessuna parent window. Questo approccio rende un message loop inutile poiche' i messaggi sono inviati direttamente alla dialog box procedure. Non dovete nemmeno preoccuparvi di registrare una window class! Solitamente la prima linea nel codice e' la call che crea il dialog box che verra' usato come finestra principale. Questo approccio e' generalmente il migliore ed il piu' semplice per creare una finestra principale con molti controlli di child window. Poiche' il gestore interno di dialog box e' funzionante, non dovrete preoccuparvi della keyboard logic.

Questo tutorial sara' lungo. Presentero' qui il primo approccio seguito dal secondo.


Essay 1


Dialog.asm

include windows.inc
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib

.data
ClassName db "DLGCLASS",0
MenuName db "MyMenu",0
DlgName db "MyDialog",0
AppName db "Our First Dialog Box",0
TestString db "Wow! I'm in an edit box now",0

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
buffer db 512 dup(?),0

.const
IDC_EDIT       equ 3000
IDC_BUTTON     equ 3001
IDC_EXIT       equ 3002
IDM_GETTEXT     equ 32000
IDM_CLEAR       equ 32001
IDM_EXIT       equ 32002

.code
start:
    invoke GetModuleHandle, NULL
    mov    hInstance,eax
    invoke GetCommandLine
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hDlg:HWND
    mov   wc.cbSize,SIZEOF WNDCLASSEX
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,DLGWINDOWEXTRA
    push  hInstance
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_BTNFACE+1
    mov   wc.lpszMenuName,OFFSET MenuName
    mov   wc.lpszClassName,OFFSET ClassName
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,0
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
    invoke RegisterClassEx, addr wc
    invoke CreateDialogParam,hInstance,ADDR DlgName,NULL,NULL,NULL
    mov   hDlg,eax
    invoke ShowWindow, hDlg,SW_SHOWNORMAL
    invoke UpdateWindow, hDlg
   invoke GetDlgItem,hDlg,IDC_EDIT
   invoke SetFocus,eax
   .WHILE TRUE
        invoke GetMessage, ADDR msg,NULL,0,0
        .BREAK .IF (!eax)
        invoke IsDialogMessage, hDlg, ADDR msg
        .IF eax ==FALSE
            invoke TranslateMessage, ADDR msg
            invoke DispatchMessage, ADDR msg
        .ENDIF
    .ENDW
    mov     eax,msg.wParam
    ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    mov   eax,uMsg
    .IF eax==WM_DESTROY
        invoke PostQuitMessage,NULL
    .ELSEIF eax==WM_COMMAND
        mov eax,wParam
        .IF lParam==0
            .IF ax==IDM_GETTEXT
                invoke GetDlgItemText,hWnd,IDC_EDIT,ADDR buffer,512
                invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK
            .ELSEIF ax==IDM_CLEAR
                invoke SetDlgItemText,hWnd,IDC_EDIT,NULL
            .ELSE
                invoke DestroyWindow,hWnd
            .ENDIF
        .ELSE
            .IF ax==IDC_BUTTON
                shr eax,16
                .IF ax==BN_CLICKED
                    invoke SetDlgItemText,hWnd,IDC_EDIT,ADDR TestString
                .ENDIF
            .ELSEIF ax==IDC_EXIT
                shr eax,16
                .IF ax==BN_CLICKED
                    invoke SendMessage,hWnd,WM_COMMAND,IDM_EXIT,0
                .ENDIF
            .ENDIF
        .ENDIF
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam
        ret
 .ENDIF
        xor    eax,eax
 ret
WndProc endp
end start

Dialog.rc

#include "c:\masm\include\winuser.h"

#define IDC_EDIT                                       3000
#define IDC_BUTTON                                3001
#define IDC_EXIT                                       3002

#define IDM_GETTEXT                             32000
#define IDM_CLEAR                                  32001
#define IDM_EXIT                                      32003
 

MyDialog DIALOG 10, 10, 205, 60
STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
CAPTION "Our First Dialog Box"
CLASS "DLGCLASS"
BEGIN
    EDITTEXT         IDC_EDIT,   15,17,111,13, ES_AUTOHSCROLL | ES_LEFT
    DEFPUSHBUTTON   "Say Hello", IDC_BUTTON,    141,10,52,13
    PUSHBUTTON      "E&xit", IDC_EXIT,  141,26,52,13, WS_GROUP
END
 

MyMenu  MENU
BEGIN
    POPUP "Test Controls"
    BEGIN
        MENUITEM "Get Text", IDM_GETTEXT
        MENUITEM "Clear Text", IDM_CLEAR
        MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
        MENUITEM "E&xit", IDM_EXIT
    END
END


Analisi 1

Analizziamo questo primo esempio.

Questo esempio mostra come registrare il template di un dialog come window class e creare una "finestra" da quella class. Il risultato e' molto simile alla finestra nel tutorial n.9 e cioe': non potete passare l'input focus ad altri controlli con il tasto tab. Ma semplifica il vostro programma poiche' non dovete creare i controlli di child window da soli. Analizziamo prima il template del dialog.

MyDialog DIALOG 10, 10, 205, 60

Dichiara il nome di un dialog, in questo caso "MyDialog", seguito dalla keyword "DIALOG". I quattro numeri successivi sono: x, y , larghezza, e altezza del dialog box in unita' di misura del dialog box (non uguali ai pixels).

STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK

Dichiara gli stili del dialog box.

CAPTION "Our First Dialog Box"

Questo e' il testo che apparira' nella barra del titolo del dialog box.

CLASS "DLGCLASS"

Questa linea e' importantissima. E' questa keyword CLASS che ci permette di usare il template del dialog box come una window class. Dopo la keyword c'e' il nome della "window class".

BEGIN
    EDITTEXT         IDC_EDIT,   15,17,111,13, ES_AUTOHSCROLL | ES_LEFT
    DEFPUSHBUTTON   "Say Hello", IDC_BUTTON,    141,10,52,13
    PUSHBUTTON      "E&xit", IDC_EXIT,  141,26,52,13
END

La parte sovrastante definisce i controlli di child window nel dialog box. Essi sono definiti tra le keywords BEGIN e END. Generalmente la sintassi e' questa:


tipi-di-controlli "testo" ,controlID, x, y, larghezza,altezza,[,stili]

tipi-di-controlli sono costanti del compilatore di risorse pertanto dovete consultare il manuale. Adesso analizziamo il codice assembly. La parte interessante sta nella struttura della window class:

mov   wc.cbWndExtra,DLGWINDOWEXTRA
      mov   wc.lpszClassName,OFFSET ClassName

Normalmente, questo membro e' settato a NULL, ma se vogliamo registrare il template di un dialog box come window class, dobbiamo settare questo membro con il valore DLGWINDOWEXTRA. Notate che il nome della class deve essere identico a quello che segue la keyword CLASS nel template del dialog box. I membri rimanenti sono inizializzati nel solito modo. Una volta riempita la struttura della window class, registratela con RegisterClassEx. Vi sembra familiare ? Questa e' la stessa routine che dovete seguire per registrare una normale window class.

invoke CreateDialogParam,hInstance,ADDR DlgName ,NULL,NULL,NULL

Una volta registrata la "window class", creeremo il nostro dialog box. In questo esempio, io creo un modeless dialog box con la funzione CreateDialogParam. Questa funzione supporta 5 parametri ma voi dovrete riempire solo i primi due: l'instance handle e il puntatore al nome del template del dialog box. Notate che il secondo parametro non e' un puntatore al nome della class. A questo punto, Windows crea il dialog box e i suoi controlli di child window. La vostra window procedure ricevera', come al solito, il messaggo WM_CREATE.

invoke GetDlgItem,hDlg,IDC_EDIT
      invoke SetFocus,eax

Una volta creato il dialog box, volete spostare l'input focus sull'edit control. Se scrivete questa parte di codice nella sezione WM_CREATE, la call a GetDlgItem fallira' poiche' in quel momento i controlli di child window non sono stati ancora creati. L'unico modo in cui potete farlo e' inserendola dopo che il dialog box e tutte i suoi controlli di child window sono stati creati. Percio' ho messo queste due righe dopo la chiamata ad UpdateWindow. La funzione GetDlgItem ottiene l'ID del controllo e restituisce l'handle della finestra associata al controllo. E' cosi' che potete trovare l'handle di una finestra se conoscete una sua control ID.

invoke IsDialogMessage, hDlg, ADDR msg
        .IF eax ==FALSE
            invoke TranslateMessage, ADDR msg
            invoke DispatchMessage, ADDR msg
        .ENDIF

Il programma entra nel message loop e prima di chiamare TranslateMessage e DispatchMessage, chiamiamo la funzione IsDialogMessage per far si che il gestore di dialog box gestisca la keyboard logic del nostro dialog box al posto nostro. Se questa funzione restituisce TRUE, significa che il messaggio e' destinato al dialog box ed e' elaborato dal gestore di dialog box. Notate un'altra differenza dal tutorial precedente. Quando la window procedure vuole rilevare del testo dall'edit control, chiama la funzione GetDlgItemText invece di GetWindowText. GetDlgItemText accetta l'ID di un controllo al posto dell'handle di una finestra. Cio' rende la chiamata piu' semplice nel caso usiate un dialog box.


Adesso passiamo al secondo approccio su come usare un dialog box come finestra principale. Nel prossimo esempio, creero' un application modal dialog box. Non troverete un message loop o una window procedure perche' non sono necessari!



Essay 2


Dialog.asm

include windows.inc
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib

.data
DlgName db "MyDialog",0
AppName db "Our Second Dialog Box",0
TestString db "Wow! I'm in an edit box now",0

.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
buffer db 512 dup(?),0

.const
IDC_EDIT           equ 3000
IDC_BUTTON     equ 3001
IDC_EXIT           equ 3002
IDM_GETTEXT equ 32000
IDM_CLEAR       equ 32001
IDM_EXIT           equ 32002
 

.code
start:
    invoke GetModuleHandle, NULL
    mov    hInstance,eax
    invoke GetCommandLine
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
    invoke ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:SDWORD
    mov  eax, OFFSET DlgProc
    invoke DialogBoxParam, hInst, ADDR DlgName,NULL, eax,NULL
    ret
WinMain endp

DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    mov   eax,uMsg
    .IF eax==WM_INITDIALOG
        invoke GetDlgItem, hWnd,IDC_EDIT
        invoke SetFocus,eax
    .ELSEIF eax==WM_CLOSE
        invoke SendMessage,hWnd,WM_COMMAND,IDM_EXIT,0
    .ELSEIF eax==WM_COMMAND
        mov eax,wParam
        .IF lParam==0
            .IF ax==IDM_GETTEXT
                invoke GetDlgItemText,hWnd,IDC_EDIT,ADDR buffer,512
                invoke MessageBox,NULL,ADDR buffer,ADDR AppName,MB_OK
            .ELSEIF ax==IDM_CLEAR
                invoke SetDlgItemText,hWnd,IDC_EDIT,NULL
            .ELSEIF ax==IDM_EXIT
                invoke EndDialog, hWnd,NULL
            .ENDIF
        .ELSE
            .IF ax==IDC_BUTTON
                shr eax,16
                .IF ax==BN_CLICKED
                    invoke SetDlgItemText,hWnd,IDC_EDIT,ADDR TestString
                .ENDIF
            .ELSEIF ax==IDC_EXIT
                shr eax,16
                .IF ax==BN_CLICKED
                    invoke SendMessage,hWnd,WM_COMMAND,IDM_EXIT,0
                .ENDIF
            .ENDIF
        .ENDIF
    .ELSE
        mov eax,FALSE
        ret
    .ENDIF
    mov eax,TRUE
    ret
DlgProc endp
end start

Dialog.rc

#include "c:\masm\include\winuser.h"

#define IDC_EDIT                                       3000
#define IDC_BUTTON                                3001
#define IDC_EXIT                                       3002

#define IDR_MENU1                                  3003

#define IDM_GETTEXT                              32000
#define IDM_CLEAR                                   32001
#define IDM_EXIT                                       32003
 

MyDialog DIALOG 10, 10, 205, 60
STYLE 0x0004 | DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX |
WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK
CAPTION "Our Second Dialog Box"
MENU IDR_MENU1
BEGIN
    EDITTEXT         IDC_EDIT,   15,17,111,13, ES_AUTOHSCROLL | ES_LEFT
    DEFPUSHBUTTON   "Say Hello", IDC_BUTTON,    141,10,52,13
    PUSHBUTTON      "E&xit", IDC_EXIT,  141,26,52,13
END
 

IDR_MENU1  MENU
BEGIN
    POPUP "Test Controls"
    BEGIN
        MENUITEM "Get Text", IDM_GETTEXT
        MENUITEM "Clear Text", IDM_CLEAR
        MENUITEM "", , 0x0800 /*MFT_SEPARATOR*/
        MENUITEM "E&xit", IDM_EXIT
    END
END


Analisi 2

Segue l'analisi:

mov  eax, OFFSET DlgProc
    invoke DialogBoxParam, hInst, ADDR DlgName,NULL, eax,NULL
    ret

Nella funzione WinMain, ci sono solo queste tre linee di codice. La prima linea salva l'offset della dialog box procedure in eax. La linea successiva e' la chiamata alla funzione DialogBoxParam che supporta 5 parametri: l'instance handle, il nome del template del dialog box, l'handle della parent window, l'indirizzo della dialog box procedure, e i dati specifici del dialog. DialogBoxParam crea un modal dialog box. Non si ritornera' fino a che il dialog box non viene distrutto.

.IF eax==WM_INITDIALOG
        invoke GetDlgItem, hWnd,IDC_EDIT
        invoke SetFocus,eax
    .ELSEIF eax==WM_CLOSE
        invoke SendMessage,hWnd,WM_COMMAND,IDM_EXIT,0

La dialog box procedure sembra una window procedure tranne per il fatto che non riceve il messaggio WM_CREATE. Il primo messaggio che riceve e' WM_INITDIALOG. Normalmente potete inserire qui il codice relativo all'inizializzazione. Notate che dovete restituire il valore TRUE in eax se elaborate il messaggio. Il gestore interno di dialog box non manda il messaggio WM_DESTROY alla nostra dialog box procedure. Percio' se vogliamo reagire quando l'utente preme il tasto di chiusura del nostro dialog box, dobbiamo elaborare il messaggio WM_CLOSE. Nel nostro esempio, mandiamo un messaggio WM_COMMAND con il valore IDM_EXIT in wParam. Cio' ha lo stesso effetto di quando l'utente sceglie il menu item Exit. L'elaborazione dei messaggi WM_COMMAND rimane invariata. Quando volete distruggere il dialog box, l'unico modo e' chiamare la funzione EndDialog. Non provate con DestroyWindow! Adesso esaminiamo il resource file. Il cambiamento degno di nota e' che invece di usare una stringa testuale come nome di menu usiamo un valore, IDR_MENU1. Cio' e' necessario se volete incollare un menu ad un dialog box creato con DialogBoxParam. Notate che nel template del dialog box, dovete aggiungere la keyword MENU seguita dalla resource ID del menu. Una differenza tra i due esempi in questo tutorial che potete immediatamente osservare e' la mancanza di un'icona nell'ultimo esempio. Comunque, potete settare un'icona mandando il messaggio WM_SETICON al dialog box durante WM_INITDIALOG.


Disclaimer

I documenti qui pubblicati sono da considerarsi pubblici e liberamente distribuibili, a patto che se ne citi la fonte di provenienza. Tutti i documenti presenti su queste pagine sono stati scritti esclusivamente a scopo di ricerca, nessuna di queste analisi è stata fatta per fini commerciali, o dietro alcun tipo di compenso. I documenti pubblicati presentano delle analisi puramente teoriche della struttura di un programma, in nessun caso il software è stato realmente disassemblato o modificato; ogni corrispondenza presente tra i documenti pubblicati e le istruzioni del software oggetto dell'analisi, è da ritenersi puramente casuale. Tutti i documenti vengono inviati in forma anonima ed automaticamente pubblicati, i diritti di tali opere appartengono esclusivamente al firmatario del documento (se presente), in nessun caso il gestore di questo sito, o del server su cui risiede, può essere ritenuto responsabile dei contenuti qui presenti, oltretutto il gestore del sito non è in grado di risalire all'identità del mittente dei documenti. Tutti i documenti ed i file di questo sito non presentano alcun tipo di garanzia, pertanto ne è sconsigliata a tutti la lettura o l'esecuzione, lo staff non si assume alcuna responsabilità per quanto riguarda l'uso improprio di tali documenti e/o file, è doveroso aggiungere che ogni riferimento a fatti cose o persone è da considerarsi PURAMENTE casuale. Tutti coloro che potrebbero ritenersi moralmente offesi dai contenuti di queste pagine, sono tenuti ad uscire immediatamente da questo sito.

Vogliamo inoltre ricordare che il Reverse Engineering è uno strumento tecnologico di grande potenza ed importanza, senza di esso non sarebbe possibile creare antivirus, scoprire funzioni malevole e non dichiarate all'interno di un programma di pubblico utilizzo. Non sarebbe possibile scoprire, in assenza di un sistema sicuro per il controllo dell'integrità, se il "tal" programma è realmente quello che l'utente ha scelto di installare ed eseguire, né sarebbe possibile continuare lo sviluppo di quei programmi (o l'utilizzo di quelle periferiche) ritenuti obsoleti e non più supportati dalle fonti ufficiali.