Tutorial 11: Altre informazioni riguardanti il Dialog Box
From UIC
Tutorial 11: Altre Informazioni Riguardanti il Dialog Box
Contents |
| Tutorial 11: Altre informazioni riguardanti il Dialog Box | |
|---|---|
| Author: | Iczelion |
| Email: | Traduttore: -NeuRaL_NoiSE |
| Website: | Mirror |
| Date: | 30/12/2008 (dd/mm/yyyy) |
| Level: |
|
| Language: | Italian |
| Comments: | Formattazione Wiki: Antelox |
Introduzione
In questo tutorial impareremo altre cose riguardo al dialog box. Specificamente, ci inoltreremo nel modo di usare i dialog boxes come periferiche di input-output. Se avete letto il tutorial precedente, questo sara' una passeggiata, poiche' e' necessaria solo una piccola modifica per poter usare i dialog boxes come aggiunte alla nostra finestra principale. Inoltre, in questo tutorial, impareremo come usare i dialog boxes comuni.
Tools
Preliminari
C'e' molto poco da dire su come usare i dialog boxes come periferiche di input-output per un programma. Il vostro programma crea la finestra principale come al solito, e quando volete mostrare il dialog box, semplicemente chiama CreateDialogParam o DialogBoxParam. Con la chiamata a DialogBoxParam, non dovete fare piu' niente, ma semplicemente elaborare i messaggi nella dialog box procedure. Con CreateDialogParam, dovete inserire la chiamata a IsDialogMessage nel message loop per far si che il gestore di dialog box gestisca automaticamente la navigazione da tastiera nel vostro dialog box. Poiche' i due casi sono triviali, non inseriro' il codice qui. Potete scaricare gli esempi e dare un'occhiata voi stessi, qui e qui (sono i 2 esempi del tutorial precedente NdT).
Passiamo ai dialog boxes comuni. Windows contiene alcuni dialog boxes predefiniti che potete usare nelle vostre applicazioni. Questi dialog boxes esistono per fornire una interfaccia utente standardizzata. Essi sono i dialog boxes file, print (stampa, NdT), color, font, e search (trova, NdT). Dovreste usarli quanto piu' possibile. I dialog boxes sono contenuti in commdlg.dll. Per poterli usare, dovete linkare anche commdlg.lib. Creerete questi dialog boxes chiamando funzioni appropriate nella common dialog library. Per il dialog "Apri File" la funzione e' GetOpenFileName, per il dialog "salva con nome" e' GetSaveFileName, per il dialog "stampa" e' PrintDlg e cosi' via. Ognuna di queste funzioni supporta un puntatore ad una struttura come parametro. Dovreste studiarle nella Win32 API reference. In questo tutorial, dimostrero' come creare ed usare un dialog "Apri File". Qui di seguito c'e' il prototipo di funzione di GetOpenFileName:
LPOPENFILENAME lpofn //indirizzo della struttura con i dati di inizializzazione
);
Potete vedere che necessita di un solo parametro, un puntatore ad una struttura OPENFILENAME. Il valore di ritorno TRUE indica che l'utente ha scelto un file da aprire, altrimenti e' FALSE. Esamineremo ora la struttura OPENFILENAME.
lStructSize DWORD ?
hwndOwner HWND ?
hInstance HINSTANCE ?
lpstrFilter LPCSTR ?
lpstrCustomFilter LPSTR ?
nMaxCustFilter DWORD ?
nFilterIndex DWORD ?
lpstrFile LPSTR ?
nMaxFile DWORD ?
lpstrFileTitle LPSTR ?
nMaxFileTitle DWORD ?
lpstrInitialDir LPCSTR ?
lpstrTitle LPCSTR ?
Flags DWORD ?
nFileOffset WORD ?
nFileExtension WORD ?
lpstrDefExt LPCSTR ?
lCustData LPARAM ?
lpfnHook DWORD ?
lpTemplateName LPCSTR ?
OPENFILENAME ENDS
Vediamo qual'e' il significato dei membri usati frequentemente.
| lStructSize | La dimensione della struttura OPENFILENAME, in bytes |
|---|---|
| hwndOwner | Il window handle del dialog box "Apri File" |
| hInstance | L'instance handle dell'applicazione che crea il dialog box "Apri File" |
| lpstrFilter | Le stringhe-filtro in formato di coppie di stringhe null-terminated. La prima stringa in ciascuna coppia e' la descrizione. La seconda stringa e' il pattern per il filtro. Ad esempio:
FilterString db "Tutti i file (*.*)",0, "*.*",0 db "File di testo (*.txt)",0,"*.txt",0,0 Notate che solo il pattern nella seconda stringa e' effettivamente usato da Windows per filtrare i files. Notate inoltre che dovete mettere uno zero in piu' alla fine delle stringhe-filtro per denotarne la conclusione. |
| nFilterIndex | Specifca quale coppia di stringhe-filtro sara' utilizzata inzialmente, quando il dialog box "Apri File" viene mostrato per la prima volta. L'indice e' in base 1, vale a dire che la prima coppia e' 1, la seconda coppia e' 2 e cosi via. Percio', dato l'esempio precedente, se dichiariamo nFilterIndex come 2, il secondo pattern, "*.txt", sara' usato. |
| lpstrFile | Puntatore al buffer che contiene il nome del file che viene usato per inizializzare l'edit control "Nome File" nel dialog box. Il buffer dovrebbe essere lungo almeno 260 bytes.
Dopo che l'utente seleziona un file da aprire, il nome di tale file con la path completa viene salvato in questo buffer. Potete estrarne le informazioni successivamente. |
| nMaxFile | La grandezza del buffer lpstrFile. |
| lpstrTitle | Puntatore al titolo del dialog box "Apri File". |
| Flags | Determina gli stili e le caratteristiche del dialog box. |
| nFileOffset | Dopo che l'utente ha selezionato un file da aprire, questo membro contiene l'indice al primo carattere del nome effettivo del file. Ad esempio, se il nome completo con la path intera e' "c:\windows\system\lz32.dll", questo membro conterra' il valore 18. |
| nFileExtension | Dopo che l'utente ha selezionato un file da aprire, questo membro contiene l'indice al primo carattere dell'estensione del file. |
Essay
Il programma che segue mostra un dialog box "Apri File" quando l'utente seleziona File-> Open dal menu. Quando l'utente seleziona un file nel dialog box, il programma mostra una message box con il nome intero, il nome del file e l'estensione del file selezionato.
includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib
includelib comdlg32.lib
.const
IDM_OPEN equ 1
IDM_EXIT equ 2
MAXSIZE equ 260
OUTPUTSIZE equ 512
.data
ClassName db "SimpleWinClass",0
AppName db "Our Main Window",0
MenuName db "FirstMenu",0
ofn OPENFILENAME <>
FilterString db "All Files",0,"*.*",0
db "Text Files",0,"*.txt",0,0
buffer db MAXSIZE dup(0)
OurTitle db "-=Our First Open File Dialog Box=-: Choose the file to open",0
FullPathName db "The Full Filename with Path is: ",0
FullName db "The Filename is: ",0
ExtensionName db "The Extension is: ",0
OutputString db OUTPUTSIZE dup(0)
CrLf db 0Dh,0Ah,0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
.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 hwnd: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,NULL
push hInstance
pop wc.hInstance
mov wc.hbrBackground,COLOR_WINDOW+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 CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,300,200,NULL,NULL,\
hInst,NULL
mov hwnd,eax
invoke ShowWindow, hwnd,SW_SHOWNORMAL
invoke UpdateWindow, hwnd
.WHILE TRUE
invoke GetMessage, ADDR msg,NULL,0,0
.BREAK .IF (!eax)
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
.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 ax==IDM_OPEN
mov ofn.lStructSize,SIZEOF ofn
push hWnd
pop ofn.hwndOwner
push hInstance
pop ofn.hInstance
mov ofn.lpstrFilter, OFFSET FilterString
mov ofn.lpstrFile, OFFSET buffer
mov ofn.nMaxFile,MAXSIZE
mov ofn.Flags, OFN_FILEMUSTEXIST or \
OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
OFN_EXPLORER or OFN_HIDEREADONLY
mov ofn.lpstrTitle, OFFSET OurTitle
invoke GetOpenFileName, ADDR ofn
.if eax==TRUE
invoke lstrcat,offset OutputString,OFFSET FullPathName
invoke lstrcat,offset OutputString,ofn.lpstrFile
invoke lstrcat,offset OutputString,offset CrLf
invoke lstrcat,offset OutputString,offset FullName
mov eax,ofn.lpstrFile
push ebx
xor ebx,ebx
mov bx,ofn.nFileOffset
add eax,ebx
pop ebx
invoke lstrcat,offset OutputString,eax
invoke lstrcat,offset OutputString,offset CrLf
invoke lstrcat,offset OutputString,offset ExtensionName
mov eax,ofn.lpstrFile
push ebx
xor ebx,ebx
mov bx,ofn.nFileExtension
add eax,ebx
pop ebx
invoke lstrcat,offset OutputString,eax
invoke MessageBox,hWnd,OFFSET OutputString,ADDR AppName,MB_OK
invoke FillMemory,offset OutputString,OUTPUTSIZE,0
.endif
.else
invoke DestroyWindow, hWnd
.endif
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc endp
end start
Analisi
push hWnd
pop ofn.hwndOwner
push hInstance
pop ofn.hInstance
Riempiamo i membri necessari delle strutture ofn.
Questa Stringa-Filtro e' il filtro per il nome del file che dichiariamo come segue:
db "Text Files",0,"*.txt",0,0
Notate che TUTTE E QUATTRO le stringhe sono zero-terminated. La prima stringa e' la descrizione della stringa successiva. I patterns reali possono anche essere stringhe numeriche, in questo caso sono "*.*" e "*.txt". In realta' possiamo specificare qualsiasi pattern qui. DOBBIAMO mettere uno zero in piu' alla fine dell'ultima stringa-pattern per denotare la fine della stringa-filtro. Non dimenticatevi questo dettaglio o il vostro dialog box si comportera' in modo strano.
mov ofn.nMaxFile,MAXSIZE
Qui specifichiamo il buffer in cui il dialog box salvera' il nome del file che l'utente seleziona. Notate che dovete specificarne la grandezza nel membro nMaxFile. Possiamo poi estrarre il nome del file da questo buffer.
OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
OFN_EXPLORER or OFN_HIDEREADONLY
Flags specifica le caratteristiche del dialog box. Le flags OFN_FILEMUSTEXIST e OFN_PATHMUSTEXIST impongono che il nome del file la path che l'utente digita nell'edit control "Nome File" DEVONO esistere. La flag OFN_LONGNAMES indica al dialog box di mostrare i nomi dei file lunghi (in stile Windows per intenderci, NdT). La flag OFN_EXPLORER specifica che l'apparenza del dialog box deve assomigliare a quella di Explorer (=Gestione Risorse, o Esplora Risorse in italiano, NdT). La flag OFN_HIDEREADONLY nasconde la checkbox sola-lettura dal dialog box. Ci sono molte altre flags utilizzabili. Consultate la vostra Win32 API reference.
Specifica il titolo del dialog box.
Chiama la funzione GetOpenFileName, passando il puntatore alla struttura ofn come parametro. A questo punto, il dialog box "Apri File" viene mostrato sullo schermo. La funzione non ritornera' a meno che l'utente non selezioni un file da aprire, prema il tasto cancel o chiuda il dialog box. Essa restituira' il valore TRUE in eax se l'utente selziona un file da aprire. Altrimenti, restituira' FALSE.
invoke lstrcat,offset OutputString,OFFSET FullPathName
invoke lstrcat,offset OutputString,ofn.lpstrFile
invoke lstrcat,offset OutputString,offset CrLf
invoke lstrcat,offset OutputString,offset FullName
Se l'utente ha selezionato un file da aprire, prepariamo un stringa che verra' mostrata in una message box. Allochiamo un blocco di memoria nella variabile OutputString e quindi usiamo una funzione API, lstrcat, per concatenare le stringhe insieme. Per mettere le stringhe su piu' linee, dobbiamo separare ogni linea con una coppia carriage return-line feed.
push ebx
xor ebx,ebx
mov bx,ofn.nFileOffset
add eax,ebx
pop ebx
invoke lstrcat,offset OutputString,eax
Queste righe richiedono qualche spiegazione. nFileOffset contiene l'indice ad ofn.lpstrFile. Ma non potete addizionarli direttamente perche' nFileOffset e' una variabile di dimensioni WORD e lpstrFile e' invece una DWORD. Percio' bisogna mettere il valore di nFileOffset nella low word di ebx e aggiungerlo al valore di lpstrFile.
Mostriamo la stringa in una message box.
Dobbiamo *svuotare* la OutputString prima di potervi inserire un'altra stringa. Percio' usiamo la funzione FillMemory per eseguire il lavoro.
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.