Downloadez les exemples de DialogBox ici et ici. Downloadez l'exemple de DialogBox couramment utilisée ici.
GetOpenFileName proto lpofn:DWORDVous pouvez voir qu'il ne reçoit qu'un seul paramètre, un pointeur sur la structure OPENFILENAME. La valeur de retour TRUE(VRAI) signifie que l'utilisateur vient de choisi un fichier pour l'ouvrir, sinon la valeur en retour est FALSE(FAUX). Voyons la structurent d'OPENFILENAME maintenant.
OPENFILENAME STRUCTOn va voir la signification des membres fréquemment employés.lStructSize DWORD ?OPENFILENAME ENDS
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 ?
lStructSize | Taille de la structure d'OPENFILENAME, en octets. |
hwndOwner | handle de la boîte de dialogue qui sert à ouvrir des fichiers. |
hInstance | Instance Handle de l'application qui crée la 'boîte de dialogue qui sert à ouvrir des fichiers'. |
lpstrFilter | Sert à filtrer le type de chaînes de caractères à ouvrir. Il faut 2 NULL pour terminer cette instruction. La première chaîne de caractères est la description (donc le texte). La deuxième c'est le type de filtre. Par exemple, dans un répertoire on peut sélectionner tous les dossiers ou bien que les .exe ou bien seulement les .zip……etc:
FilterString db "All Files (*.*)",0, "*.*",0 db "Text Files (*.txt)",0,"*.txt",0,0 Remarquez bien que c'est la deuxième chaîne de caractères (pour chaque ligne) qui en réalité sert à Windows à filtrer les fichiers. Donc vous êtes obligés de mettre un 0 supplémentaire à la fin de la chaîne de caractères du filtre pour en indiquer sa fin. |
nFilterIndex | Indique quelle [paire de chaîne de caractères de] filtre sera utilisée par défaut dans la DialogBox qui sert à ouvrir les fichiers. Ce sera le 1, pour la première paire "All Files (*.*)", le 2 pour la deuxième paire "Text Files (*.txt)" etc. Ainsi dans notre exemple, si nous spécifions nFilterIndex en tant que 2, le deuxième modèle, "*.txt" sera employé. |
lpstrFile | Le pointeur du buffer qui contient le nom de fichier qu'on a l'habitude d'initialiser dans la boîte d'édition de notre DialogBox (ici c'est le pointeur qui pointe sur le texte " ALL FILES ". Le pointeur doit avoir une longueur d'au moins 260 octets.
Après que l'utilisateur ait choisit un fichier pour l'ouvrir, le nom de ce fichier ainsi que le chemin (Patch) complète où il est stocké, sont gardés dans ce buffer pstrFile. Vous pourrez en extraire l'information plus tard. |
nMaxFile | La taille de buffer lpstrFile. |
lpstrTitle | Pointeur du titre de la DialogBox qui sert à ouvrir les fichiers. (donc c'est le titre). |
Flags | Détermine le style et les caractéristiques de la boîte de dialogue. |
nFileOffset | Après que l'utilisateur ait choisi un fichier pour l'ouvrir, ce membre contient le n° du premier caractère du nom du fichier réel. Par exemple, si le nom complète avec son chemin est "c:\Windows\system\lz32.dll", ce membre contiendra la valeur 18. |
nFileExtension | Après que l'utilisateur ait choisi un fichier pour l'ouvrir, ce membre contient le numéro du premier caractère de l'extension du fichier. Ici c'est 23 |
.386
.model
flat,stdcall
option
casemap:none
WinMain
proto :DWORD,:DWORD,:DWORD,:DWORD
include
\masm32\include\windows.inc
include
\masm32\include\user32.inc
include
\masm32\include\kernel32.inc
include
\masm32\include\comdlg32.inc
includelib
\masm32\lib\user32.lib
includelib
\masm32\lib\kernel32.lib
includelib
\masm32\lib\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
mov CommandLine,eax
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT
invoke ExitProcess,eax
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
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 hInst
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,eax
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
.IF uMsg==WM_DESTROY
invoke PostQuitMessage,NULL
.ELSEIF uMsg==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 RtlZeroMemory,offset OutputString,OUTPUTSIZE
.endif
.else
invoke DestroyWindow, hWnd
.endif
.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF
xor eax,eax
ret
WndProc
endp
end
start
Nous remplaçons les membres ordinaires par des structures ofn.
mov ofn.lpstrFilter, OFFSET FilterString
Ce FilterString est le filtre du nom de fichier que nous définissons comme suit :
FilterString db "All Files",0,"*.*",0Remarquez que les quatre chaînes de caractères sont terminées par un Zéro. La première chaîne est la description de la chaîne suivante (EX : ''ALL FILES est la description de *.*''). Le modèle réel est la 2e chaîne de caractères, dans notre cas ce sont *. * et *.txt. En réalité nous pouvons prendre n'importe quel modèle d'extension. exemple : *.wavwav . Nous DEVONS mettre un zéro supplémentaire après la dernière chaîne de caractères pour à montrer que c'est la fin de la chaîne du filtre. N'oubliez surtout pas ça, sinon votre DialogBox se comportera étrangement.
db "Text Files",0,"*.txt",0,0
mov ofn.lpstrFile, OFFSET buffer
mov ofn.nMaxFile,MAXSIZE
Nous indiquons où la boîte de dialogue mettra le nom du fichier que l'utilisateur vient de choisir. Notez que nous devons spécifier sa taille dans le membre nMaxFile. Plus tard, nous pourrons extraire le nom du fichier contenu dans ce buffer.
mov ofn.Flags, OFN_FILEMUSTEXIST or \
OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
OFN_EXPLORER or OFN_HIDEREADONLY
Flags indique les caractéristiques de la boîte de dialogue.
Les 'flags' (les drapeaux) OFN_FILEMUSTEXIST et OFN_PATHMUSTEXIST exigent que le nom du fichier et le chemin que l'utilisateur tape dans la zone d'édition DOIVENT exister.
le 'flag' OFN_LONGNAMES dit à la boîte de dialogue de montrer des noms de fichier longs. (et non pas des trucs du genre 'nomtropl~1.exe')
Le flag OFN_EXPLORER indique que l'apparition de la boîte de dialogue doit être semblable à celle de l'Explorer Windows.
Le flag OFN_HIDEREADONLY cache la 'case à cocher : read-only ' de la boîte de dialogue.
Il y a beaucoup encore d'autres flags que vous pouvez employer. Consultez votre référence Win32 API.
mov ofn.lpstrTitle, OFFSET OurTitle
C'est le titre de la boîte de dialogue qui sert à ouvrir des fichiers.
invoke GetOpenFileName, ADDR ofn
Appelle la fonction GetOpenFileName. Il passage le pointer à la structure 'ofn' en tant que son paramètre.
À partir d'ici, la boîte de dialogue qui ouvre les fichiers, est affichée à l'écran. La fonction ne retournera pas avant que l'utilisateur ne choisisse un fichier pour l'ouvrir ou bien qu'il ne presse le bouton ANNULER ou FERMER de la boîte de dialogue.
Il renverra la valeur TRUE(VRAI) dans eax si l'utilisateur choisit un fichier pour l'ouvrir. Sinon, il retournera FALSE(FAUX).
.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
Dans le cas où l'utilisateur choisit un fichier pour l'ouvrir, nous préparons une chaîne de caractère pour qu'elle soit affichée dans une MessageBox. Nous réservons un bloc de mémoire dans la variable OutputString puis ensuite nous employons la fonction API, lstrcat, pour enchaîner ensembles les chaîne de caractères . Pour faire apparaître les chaînes sur plusieurs lignes, nous devons séparer chaque ligne avec un retour chariot.
mov eax,ofn.lpstrFile
push ebx
xor ebx,ebx
mov bx,ofn.nFileOffset
add eax,ebx
pop ebx
invoke lstrcat,offset OutputString,eax
Les susdites lignes exigent quelques explications. nFileOffset contient le n° dans l'ofn.lpstrFile (ce n° c'est son positionnement). Mais vous ne pouvez pas les ajouter ensemble directement puisque nFileOffset est une variable de TAILLE 'WORD' et lpstrFile est de TAILLE 'DWORD'. Il faut donc mettre la valeur de nFileOffset dans le mot bas (le mot de poids faible) de ebx et l'ajouter à la valeur de lpstrFile.
invoke MessageBox,hWnd,OFFSET OutputString,ADDR AppName,MB_OK
Nous affichons la chaîne de caractères dans la MessageBox (boîte de message).
invoke RtlZerolMemory,offset OutputString,OUTPUTSIZE
Nous devons *effacer* l'OutputString avant que nous ne puissions remplir une autre chaîne de caractères. Donc nous employons la fonction RtlZeroMemory pour faire le travail.