windows.inc does not have the OFNOTIFY structure defined:
typedef struct _OFNOTIFY {
NMHDR hdr;
LPOPENFILENAME lpOFN;
LPTSTR pszFile;
} OFNOTIFY, *LPOFNOTIFY;
also, the associated notification code constants are incorrectly defined as:
CDN_INITDONE equ 0000h
CDN_SELCHANGE equ 0001h
CDN_FOLDERCHANGE equ 0002h
CDN_SHAREVIOLATION equ 0003h
CDN_HELP equ 0004h
CDN_FILEOK equ 0005h
CDN_TYPECHANGE equ 0006h
CDN_INCLUDEITEM equ 0007h
should be:
CDN_INITDONE equ CDN_FIRST-0000h
CDN_SELCHANGE equ CDN_FIRST-0001h
CDN_FOLDERCHANGE equ CDN_FIRST-0002h
CDN_SHAREVIOLATION equ CDN_FIRST-0003h
CDN_HELP equ CDN_FIRST-0004h
CDN_FILEOK equ CDN_FIRST-0005h
CDN_TYPECHANGE equ CDN_FIRST-0006h
CDN_INCLUDEITEM equ CDN_FIRST-0007h
EDIT: CDN_FIRST is correctly defined as 0-601 (decimal, not hex)
And as a check against the Microsoft header files:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
void main( void )
{
printf("CDN_FIRST %d\n",CDN_FIRST);
printf("CDN_LAST %d\n\n",CDN_LAST);
printf("sizeof(OFNOTIFY) %d\n\n", sizeof(OFNOTIFY));
printf("CDN_INITDONE %d\n",CDN_INITDONE);
printf("CDN_SELCHANGE %d\n",CDN_SELCHANGE);
printf("CDN_FOLDERCHANGE %d\n",CDN_FOLDERCHANGE);
printf("CDN_SHAREVIOLATION %d\n",CDN_SHAREVIOLATION);
printf("CDN_HELP %d\n",CDN_HELP);
printf("CDN_FILEOK %d\n",CDN_FILEOK);
printf("CDN_TYPECHANGE %d\n",CDN_TYPECHANGE);
printf("CDN_INCLUDEITEM %d\n\n",CDN_INCLUDEITEM);
getch();
}
CDN_FIRST -601
CDN_LAST -699
sizeof(OFNOTIFY) 20
CDN_INITDONE -601
CDN_SELCHANGE -602
CDN_FOLDERCHANGE -603
CDN_SHAREVIOLATION -604
CDN_HELP -605
CDN_FILEOK -606
CDN_TYPECHANGE -607
CDN_INCLUDEITEM -608
This is my attempt at a definition that will work with windows.inc, along with a simple test app.
;==============================================================================
include \masm32\include\masm32rt.inc
;==============================================================================
LPOPENFILENAMEW TYPEDEF PTR OPENFILENAMEW
LPOPENFILENAMEA TYPEDEF PTR OPENFILENAMEA
IFDEF __UNICODE__
LPOPENFILENAME equ <LPOPENFILENAMEW>
ELSE
LPOPENFILENAME equ <LPOPENFILENAMEA>
ENDIF
;typedef struct _OFNOTIFY {
; NMHDR hdr;
; LPOPENFILENAME lpOFN;
; LPTSTR pszFile;
;} OFNOTIFY, *LPOFNOTIFY;
OFNOTIFY STRUCT
hdr NMHDR <>
lpOFN LPOPENFILENAME ?
pszFile LPTSTR ?
OFNOTIFY ENDS
;==============================================================================
.data
ofno OFNOTIFY <>
ofn OPENFILENAME <>
strFile db 100 dup(0)
.code
;==============================================================================
OFNHookProc proc hdlg:HWND, uiMsg:UINT, wParam:WPARAM, lParam:LPARAM
SWITCH uiMsg
CASE WM_NOTIFY
mov eax, lParam
mov eax, [eax].OFNOTIFY.lpOFN
printf("%Xh\n\n",eax)
ENDSW
ret
OFNHookProc endp
;==============================================================================
start:
;==============================================================================
printf("%d\n",SIZEOF OFNOTIFY)
printf("%Xh\n\n",ADDR ofn)
mov ofn.lStructSize, SIZEOF OPENFILENAME
mov ofn.lpstrFilter, chr$("All Files (*.*)",0,"*.*",0,0)
mov ofn.lpstrFile, OFFSET strFile
mov ofn.nMaxFile, SIZEOF strFile
mov ofn.Flags, OFN_EXPLORER or OFN_ENABLEHOOK or OFN_FILEMUSTEXIST
mov ofn.lpfnHook, OFNHookProc
invoke GetOpenFileName, ADDR ofn
inkey
exit
;==============================================================================
end start
20
403014h
403014h
403014h
403014h
nice Michael
i wanted my app to accept filenames with no extension
then - append the extension, according to the drop-down box selection and test to see if the file exists
in this case, i only had 2 different file types for SaveAs
but, something like Paint may have several
my final OfnHookProc looks like this
;***********************************************************************************************
OfnHookProc PROC hwndDlg:HWND,uiMsg:UINT,wParam:WPARAM,lParam:LPARAM
_CDN_INITDONE EQU -601
_CDN_SELCHANGE EQU -602
_CDN_FOLDERCHANGE EQU -603
_CDN_SHAREVIOLATION EQU -604
_CDN_HELP EQU -605
_CDN_FILEOK EQU -606
_CDN_TYPECHANGE EQU -607
_CDN_INCLUDEITEM EQU -608
.if uiMsg==WM_NOTIFY
mov edx,lParam
.if [edx].OFNOTIFY.hdr.code==_CDN_FILEOK
push ebx
push esi
push edi
push hwndDlg
push ebp
mov ebx,[edx].OFNOTIFY.lpOFN ;EBX = lpOFN
mov ebp,esp
mov esi,[ebx].OPENFILENAME.lpstrFile
INVOKE GetStrLen,esi
lea ecx,[eax+1]
add eax,sizeof szExists+7
mov edi,esp
and al,-4
sub edi,eax
ASSUME FS:Nothing
.repeat
push edx
mov esp,fs:[8]
.until edi>=esp
ASSUME FS:ERROR
mov esp,edi
rep movsb
movzx edx,word ptr [ebx].OPENFILENAME.nFileExtension
INVOKE SetSaveAsExt,edx,[ebx].OPENFILENAME.nFilterIndex,esp
xor eax,eax
mov ebx,esp
push ecx
push eax
push eax
sub esp,sizeof WIN32_FILE_ATTRIBUTE_DATA-8
INVOKE GetFileAttributesEx,ebx,eax,esp
add esp,sizeof WIN32_FILE_ATTRIBUTE_DATA-8
pop edx
pop eax
or eax,edx
pop ecx
.if !ZERO?
lea edi,[ebx+ecx]
mov esi,offset szExists
mov ecx,sizeof szExists
rep movsb
INVOKE MessageBox,[ebp+4],ebx,offset szSaveAs,MB_YESNO or MB_ICONEXCLAMATION
.if eax==IDNO
INVOKE SetWindowLong,[ebp+4],DWL_MSGRESULT,TRUE
mov eax,TRUE
.else
xor eax,eax
.endif
.endif
leave
pop edx
pop edi
pop esi
pop ebx
.else
xor eax,eax
.endif
.else
xor eax,eax
.endif
ret
OfnHookProc ENDP
;***********************************************************************************************
notice that, if the file exists but has 0 size, i treat it as "ok to overwrite"
i use a support routine that sets the "test" extension, according to the nFilterIndex value
then, in the SaveAs dialog proc, i use the same SetSaveAsExt function to set the final extension
i also used an "extended" version of the OPENFILENAME structure
;EX_OPENFILENAME STRUCT
; lStructSize DWORD ?
; hwndOwner HWND ?
; hInstance HINSTANCE ?
; lpstrFilter LPCTSTR ?
; lpstrCustomFilter LPTSTR ?
; nMaxCustFilter DWORD ?
; nFilterIndex DWORD ?
; lpstrFile LPTSTR ?
; nMaxFile DWORD ?
; lpstrFileTitle LPTSTR ?
; nMaxFileTitle DWORD ?
; lpstrInitialDir LPCTSTR ?
; lpstrTitle LPCTSTR ?
; Flags DWORD ?
; nFileOffset WORD ?
; nFileExtension WORD ?
; lpstrDefExt LPCTSTR ?
; lCustData LPARAM ?
; lpfnHook LPOFNHOOKPROC ?
; lpTemplateName LPCTSTR ?
; pvReserved LPVOID ?
; dwReserved DWORD ?
; FlagsEx DWORD ?
the last 3 members are not present in the OPENFILENAME structure defined in windows.inc
if you hook a new style dialog, and want it to have the places bar, you will need to use the longer structure
because i had to "discover" the windows.inc discrepancies as i went along,
it took me 2 days of farting around to get what i wanted :lol:
There is no need to search anything
All this is perfectly defined in the commdlg.sdk and perhaps in some others translated file
Extract from commdlg.sdk
Quote
OFNOTIFYA STRUCT DEFALIGNMASM
hdr NMHDR <>
lpOFN DWORD ?
pszFile DWORD ? ; May be NULL
OFNOTIFYA ENDS
CDN_FIRST equ < 0 - 601>
CDN_LAST equ < 0 - 699>
; Notifications from Open or Save dialog
CDN_INITDONE equ < CDN_FIRST - 00000h>
CDN_SELCHANGE equ < CDN_FIRST - 00001h>
CDN_FOLDERCHANGE equ < CDN_FIRST - 00002h>
CDN_SHAREVIOLATION equ < CDN_FIRST - 00003h>
CDN_HELP equ < CDN_FIRST - 00004h>
CDN_FILEOK equ < CDN_FIRST - 00005h>
CDN_TYPECHANGE equ < CDN_FIRST - 00006h>
IF ( NTDDI_VERSION GE NTDDI_WIN2K)
CDN_INCLUDEITEM equ < CDN_FIRST - 00007h>
ENDIF ; (NTDDI_VERSION >= NTDDI_WIN2K)
CDM_FIRST equ < WM_USER + 100>
CDM_LAST equ < WM_USER + 200>
;-------- and more -------------------