I would like to call the fn. SHGetFolderPath() located in the shell32.lib with the following code snippet:
!DEC$ OBJCOMMENT LIB:"shell32.lib"
INTERFACE
FUNCTION SHGetFolderPath(hwndOwner, nFolder, hToken, dwFlags, pszPath)
use ifwinty
integer(LONG) :: SHGetFolderPath ! HRESULT, LONG = 4
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'SHGetFolderPathA' :: SHGetFolderPath
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: hwndOwner
integer(HANDLE) :: hwndOwner ! HANDLE = 4
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: nFolder
integer(LONG) :: nFolder ! LONG = 4
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: hToken
integer(HANDLE) :: hToken ! HANDLE = 4
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: dwFlags
integer(DWORD) :: dwFlags ! DWORD is unsigned 32 bit integer in C++
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: pszPath
character*(*) pszPath
END FUNCTION
END INTERFACE
! found these constants in shlobj.hINTEGER(4), PARAMETER :: CSIDL_APPDATA = Z'001a' ! 0x001a in shlobj.h
INTEGER(4), PARAMETER :: SHGFP_TYPE_CURRENT = 0
INTEGER(4), PARAMETER :: CSIDL_LOCAL_APPDATA = Z'001c' ! 0x001c in shlobj.h
INTEGER(4) iret
CHARACTER(Max_Path+1) szFileNameStr
! iret here is HRESULT
iret = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, szFileNameStr)
! get error code in low word
iret = LOWORD(iret)
Code links OK but when SHGetFolderPath() exexutes it returns a negative value or error. LOWORD(iret) returns
the value 87 which is ERROR_INVALID_PARAMETER in winerror.h.I believe the problem is in the Inerface Block, but not sure.
Any comments would be appreciated. Thanks in advance.
链接已复制
Finally figured out what the correct Interface Block should look like by examining code in shell32.f90.With the following interface and Win32 constants defined in first post, call to SHGetFolderPath() works fine.
!DEC$ OBJCOMMENT LIB:"shell32.lib"
INTERFACE
FUNCTION SHGetFolderPath(hwndOwner, nFolder, hToken, dwFlags, pszPath)use ifwintyinteger(LONG) :: SHGetFolderPath ! HRESULT, LONG = 4!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS:'SHGetFolderPathA' :: SHGetFolderPathinteger(HANDLE) :: hwndOwner ! HANDLE = 4integer(LONG) :: nFolder ! LONG = 4integer(HANDLE) :: hToken ! HANDLE = 4integer(DWORD) :: dwFlags ! DWORD is unsigned 32 bit integer in C++ !DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: pszPathcharacter*(*) pszPathEND FUNCTIONEND INTERFACE
I encountered a very weird issue by following your code up above.
The pszPath will be assigned value "...\My Documents ", that means bunches of space holders will be following "...\My Documents". I use TRIM, AJUSTR, but no use. There are still lots of spaces.
Did you have this issue too? If yes, how did you solve this issue?
