I'm very (I repeat: very very  ;) ) new to programming in ASM, so forgive me if this is a very dumb question.

I'm playing around with the GetOpenFileName command. The following code (based on one of iczelion's tutorials) works fine. It shows an OpenDialog and then shows the filename of the selected file in a MessageBox.


.386
.model flat, stdcall
option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
include comdlg32.inc

includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib

OpenDialogShow proto

.data
ofn  OPENFILENAME <>  ; <--- GLOBAL ofn - this works fine!
FilterString db "All Files",0,"*.*",0
            db "Text Files",0,"*.txt",0,0
buffer db 260 dup(0)

.data?
hInstance dd ?

.const
APP_TITLE db "OpenDialog Test",0

.code
start:
invoke GetModuleHandle,NULL
mov hInstance, eax

invoke OpenDialogShow

invoke ExitProcess,eax

OpenDialogShow proc

mov ofn.lStructSize,SIZEOF ofn

mov ofn.hWndOwner,NULL

mov eax,hInstance
mov ofn.hInstance,eax

mov  ofn.lpstrFilter, OFFSET FilterString
mov  ofn.lpstrFile,OFFSET buffer
mov  ofn.nMaxFile,260

mov  ofn.Flags, OFN_FILEMUSTEXIST or \
                    OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                    OFN_EXPLORER or OFN_HIDEREADONLY

invoke GetOpenFileName, ADDR ofn

invoke MessageBox,NULL,ADDR buffer,ADDR APP_TITLE,MB_OK

Ret
OpenDialogShow EndP

end start


In the above code, the variable ofn (a OPENFILENAME structure) is global. I always try to use LOCAL variables as much as possible.

However, if I try to make the ofn variable LOCAL as follows, I get an error if I run the program:

(Changes are: removed ofn  OPENFILENAME <> in .data and added LOCAL ofn:OPENFILENAME to OpenDialogShow proc)

.386
.model flat, stdcall
option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
include comdlg32.inc

includelib user32.lib
includelib kernel32.lib
includelib comdlg32.lib

OpenDialogShow proto

.data
FilterString db "All Files",0,"*.*",0
            db "Text Files",0,"*.txt",0,0
buffer db 260 dup(0)

.data?
hInstance dd ?

.const
APP_TITLE db "OpenDialog Test",0

.code
start:
invoke GetModuleHandle,NULL
mov hInstance, eax

invoke OpenDialogShow

invoke ExitProcess,eax

OpenDialogShow proc

LOCAL ofn:OPENFILENAME ; < --- This does not work!

mov ofn.lStructSize,SIZEOF ofn

mov ofn.hWndOwner,NULL

mov eax,hInstance
mov ofn.hInstance,eax

mov  ofn.lpstrFilter, OFFSET FilterString
mov  ofn.lpstrFile,OFFSET buffer
mov  ofn.nMaxFile,260

mov  ofn.Flags, OFN_FILEMUSTEXIST or \
                    OFN_PATHMUSTEXIST or OFN_LONGNAMES or\
                    OFN_EXPLORER or OFN_HIDEREADONLY

invoke GetOpenFileName, ADDR ofn <--- ERROR!

invoke MessageBox,NULL,ADDR buffer,ADDR APP_TITLE,MB_OK

Ret
OpenDialogShow EndP

end start



Posted on 2007-12-31 11:26:36 by yEnc
With local structures you have to make sure that all structure members are initialized properly which means that you have to set the structure members you don't use to 0 as they may have random data in it.

Initialize the structure to 0 at the beginning of your ShowDialogProc with an


lea edi, ofn
xor eax, eax
mov ecx, sizeof ofn/4
rep stosd


or use RtlZeroMemory to clear the Structure.

To prevent weird bugs it's good to always clear buffers and structures before using them.
Posted on 2007-12-31 11:32:23 by JimmyClif
Thanks for your quick answer, it worked!

Just to be sure: is

invoke RtlZeroMemory,ADDR ofn,SIZEOF ofn


the correct way to clear ofn with RtlZeroMemory?

Posted on 2007-12-31 11:48:06 by yEnc
Absolutely :)
Posted on 2007-12-31 12:15:26 by JimmyClif