Hello,
I try to start the directory common dialog box at a choosen path
The fonction receive:
Handle of window,Pointer to the start path,pointer where to write the choosen path
The starting path is translate in a pidl using the IShellFolder interface.
All works ok,except that SHBrowseForFolder don't accept the adress of the created pidl?.
What is Wrong ?
ToutEnMasm
Choisir_Creer_Repertoire PROC Hfen:DWORD,pStart_Path:DWORD,pChoose_Path:DWORD
local bri :BROWSEINFO
Local itemidlist:ITEMIDLIST
Local unicode[MAX_PATH+1]:WORD
Local chEaten:DWORD,psfgaoOut,ppvIShellFolder,ppvIMalloc
Local retour:DWORD
ZEROLOCALES retour
.if pStart_Path != 0
invoke SHGetDesktopFolder,addr ppvIShellFolder ;IShellFolder pointer
.if eax != S_OK
jmp PathEchec
.endif
;translate the path where to begin in unicode
invoke MultiByteToWideChar,CP_ACP,MB_PRECOMPOSED,pStart_Path,-1,addr unicode,LENGTHOF unicode
.if eax != 0
;invoke SHParseDisplayName,addr unicode,NULL,addr itemidlist,sfgaoIn,addr psfgaoOut
;translate the unicode path in a pidl
IShellFolder ParseDisplayName,Hfen,NULL,addr unicode,addr chEaten,addr itemidlist,NULL
.if eax == S_OK
;get the adress of pidl to put in the root pidl
lea eax,itemidlist
mov bri.pidlRoot,eax ;point de depart NULL poste de travail,ou p ITEMIDLIST
.endif
.endif
IShellFolder Release
;If failed bri.pidlRoot == NULL ;pidl to begin the search
.endif
PathEchec:
;---------- search a directory ---------------------
PuPo bri.hwndOwner,Hfen
PuPo bri.pszDisplayName,pChoose_Path ;
mov bri.lpszTitle, SOFF("Choisir un Répertoire")
mov bri.ulFlags, BIF_RETURNONLYFSDIRS or BIF_DONTGOBELOWDOMAIN or BIF_USENEWUI
mov bri.lpfn, 0
mov bri.lParam, 0
mov bri.iImage, 0
INVOKE SHBrowseForFolder, addr bri
;eax choosen pidl
mov ebx,eax
mov edx,pChoose_Path
;------- translate pidl in path in reponse
INVOKE SHGetPathFromIDList, ebx, addr reponse ; conserver
.if eax == TRUE
invoke lnstr,addr reponse
mov retour,eax
invoke CoTaskMemFree,ebx ;free the pidl
;failed retour == 0
.endif
FindeChoisir_Creer_Repertoire:
mov eax,retour
ret
Choisir_Creer_Repertoire endp
;################################################################
Samples (in SDK) wasn't very clear.
Follow the correction
Returned by the function is a pointer (pidl) on a ITEMIDLIST structure
The declarations for IShellFolder are given by the translator
;################################################################
Choisir_Creer_Repertoire PROC Hfen:DWORD,pStart_Path:DWORD,pChoose_Path:DWORD
local bri :BROWSEINFO
Local pidl:DWORD
Local unicode[MAX_PATH+1]:WORD
Local chEaten:DWORD,psfgaoOut,ppvIShellFolder,ppvIMalloc,dwAttributes
Local retour:DWORD
ZEROLOCALES retour
.if pStart_Path != 0
invoke SHGetDesktopFolder,addr ppvIShellFolder ;IShellFolder pointer
.if eax != S_OK
jmp PathEchec
.endif
;translate the path where to begin in unicode
invoke MultiByteToWideChar,CP_ACP,MB_PRECOMPOSED,pStart_Path,-1,addr unicode,LENGTHOF unicode
.if eax != 0
;only XP invoke SHParseDisplayName,addr unicode,NULL,addr pidl,sfgaoIn,addr psfgaoOut
;translate the unicode path in a pidl
IShellFolder ParseDisplayName,Hfen,NULL,addr unicode,addr chEaten,addr pidl,addr dwAttributes
.if eax == S_OK
;get the adress of pidl to put in the root pidl
mov eax,pidl ;
mov bri.pidlRoot,eax ;point de depart NULL poste de travail,ou p pidl
.endif
.endif
IShellFolder Release
;If failed bri.pidlRoot == NULL ;pidl to begin the search
.endif
PathEchec:
;---------- search a directory ---------------------
PuPo bri.hwndOwner,Hfen
PuPo bri.pszDisplayName,pChoose_Path ;
mov bri.lpszTitle, SOFF("Choisir un Répertoire")
mov bri.ulFlags, BIF_RETURNONLYFSDIRS or BIF_DONTGOBELOWDOMAIN or BIF_USENEWUI
mov bri.lpfn, 0
mov bri.lParam, 0
mov bri.iImage, 0
INVOKE SHBrowseForFolder, addr bri
;eax choosen pidl
mov ebx,eax
mov edx,pChoose_Path
;------- translate pidl in path in reponse
INVOKE SHGetPathFromIDList, ebx, addr reponse ; conserver
.if eax == TRUE
invoke lnstr,addr reponse
mov retour,eax
invoke CoTaskMemFree,ebx ;free the pidl
;failed retour == 0
.endif
.if edx != 0
invoke CoTaskMemFree,pidl
.endif
FindeChoisir_Creer_Repertoire:
mov eax,retour
ret
Choisir_Creer_Repertoire endp
Ishellfolder interface,if you haven't it
Quote
pcomethod1 TYPEDEF PROTO :DWORD
pcomethod2 TYPEDEF PROTO :DWORD, :DWORD
pcomethod3 TYPEDEF PROTO :DWORD, :DWORD, :DWORD
pcomethod4 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD
pcomethod5 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD , :DWORD
pcomethod6 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD , :DWORD ,:DWORD
pcomethod7 TYPEDEF PROTO :DWORD, :DWORD, :DWORD, :DWORD , :DWORD ,:DWORD ,:DWORD
comethod1 TYPEDEF PTR pcomethod1
comethod2 TYPEDEF PTR pcomethod2
comethod3 TYPEDEF PTR pcomethod3
comethod4 TYPEDEF PTR pcomethod4
comethod5 TYPEDEF PTR pcomethod5
comethod6 TYPEDEF PTR pcomethod6
comethod7 TYPEDEF PTR pcomethod7
STIShellFolder STRUCT
QueryInterface comethod3 ?
AddRef comethod1 ?
Release comethod1 ?
ParseDisplayName comethod7 ?
EnumObjects comethod4 ?
BindToObject comethod5 ?
BindToStorage comethod5 ?
CompareIDs comethod4 ?
CreateViewObject comethod4 ?
GetAttributesOf comethod4 ?
GetUIObjectOf comethod7 ?
GetDisplayNameOf comethod4 ?
SetNameOf comethod6 ?
STIShellFolder ENDS
IShellFolder MACRO Function:REQ, args:VARARG
; definition de la macro locale InvokeInterface
LOCAL InvokeInterface, arg
FOR arg, <args> ;verifier que edx n'est pas dans la liste d'arguments args
IFIDNI <&arg>, <edx> ;
.ERR <edx is not allowed as a coinvoke parameter>
ENDIF
ENDM
IFIDNI <&pInterface>, <edx>
.ERR <edx is not allowed as a coinvoke parameter>
ENDIF
;InvokeInterface = concatene ...CATSTR(concatene) MACRO instruction MASM32
;---------- on doit mettre ppv en premier argument -----------------------------------
InvokeInterface CATSTR <invoke (STIShellFolder PTR[edx]).>,<&Function,ppvIShellFolder>
IFNB <args> ; add the list of parameter arguments if any
InvokeInterface CATSTR InvokeInterface, <, >, <&args>
ENDIF
; forme les lignes de codes
mov edx, ppvIShellFolder
mov edx, [edx]
InvokeInterface
ENDM