- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Link kopiert
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
According to the MSDN documentation SHILCreateFromPath is also available on Windows 2000. Maybe you need to install some service pack or a newer version of Internet Explorer. I would not copy over the dll.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
There's something fishy about MSDN description:
There is a similar one, ILCreateFromPath, so you might try your luck with it instead.NoteThis function is available through Microsoft Windows XPService Pack 2 (SP2) and Windows Server 2003. It might be altered or unavailable in subsequent versions of Windows. It is not available in Windows Millennium Edition (Windows Me)....Minimum operating systems Windows2000, Windows XP
But, what exactly you're doing with it? BROWSEINFO.pszDisplayName is an "intent(inout)" parameter -- it specifies the initial input folder. Setting up an arbitrary pidlRoot perhaps?
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Thanks, Jugoslav, for spotting the ILCreateFromPath function, which I had missed and I will look at it.
Yes, I want to open the browse tree at a particular folder which is not necessarily a 'special folder', for which CSIDL's are available. So I need to generate a pointer to a list (PIDL) for a folder I wish to specify. Maybe ILCreateFromPath will return what I want. I need to generate an interface block for it of course.
If this fails, perhaps I could extract the SHILCreateFromPath object code from the XP shell32.dll and add it to the 2000 shell32.dll using EDITBIN?
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
On the other hand, ParseDisplayName is a COM object method, so it takes a bit of cludge to get hold of it (take the pointer returned by SHGetDesktopFolder, then walk a bit through it to get to the VTable, ParseDisplayName being the first method, see Shlobj.h). Do you need an example?
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
I've got an (almost) working sample for you... The "almost" part is due to COM of course, as I got an error in return value, but I can't deduce what's wrong, and I gotta run now. Tomorrow...
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
![Smiley with tongue out [:-P]](/isn/Community/en-US/emoticons/emotion-4.gif)
There you go (attached). Once you get an address of a COM object (in this case, an IShellFolder through SHGetDesktopFolder; most often, through CoCreateInstance), you should call DEREFERENCE_PROC to get the address of the method you want. (See the comments in DEREFERENCE_PROC how a COM object looks like on a "low-level" ). The first argument of COM methods is always a "this" pointer (i.e. that's the additional one as compared to documentation, which I forgot last night). The "magic number" 3 is the method's ordinal in the object's VTable... to know it, you have to dig out the original source (MSDN usually lists them in alphabetical order), Google for it, or in despair, try the hit-and-miss method. (The first three are IUnknown::QueryInterface, IUnknown::AddRef, and IUnknown::Release for all objects).
(The example is derived from my original XFTFile::XBrowse routine, so there is some extra stuff which doesn't work due to trimming)
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Thanks, but as I said, COM gives me the horrors. I downloaded the MS platform SDK and found SHELL32.LIB, which I included in my project. I used the attached interface block for SHILCreateFromFolder. I am not sure what to use for the third argument attributeiflagson input (it is defined as in:out in the MSDN library reference for SHILCreateFromFolder), so just stuck in a value I found that seemed reasonable.
The program compiled and linked OK. When I run it on my WIN2000 system, I get the result
PIDL= 0, IRET= 80070002
whatever I use for the Start path. That is, the PIDL value for the desktop. When compiled and run on my XP system, it crashes out with an access error. Any ideas?
interface
logical(4) function SHILCreateFromPath (pszPath, pidl, iflags)
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_SHILCreateFromPath@12' :: SHILCreateFromPath
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS: 'SHILCreateFromPath' :: SHILCreateFromPath
!DEC$ ENDIF
!DEC$ ATTRIBUTES REFERENCE :: pidl
!DEC$ ATTRIBUTES REFERENCE :: iflags
!DEC$ ATTRIBUTES REFERENCE :: pszPath
integer:: pidl, iflags
character*(*):: pszPath
end function SHILCreateFromPath
end interface
CHARACTER(256) STARTPATH
integer IRET, PIDL, FLAGS
integer, parameter :: CSIDL_PROGRAM_FILES = '0026'x
integer, parameter :: SFGAO_FILESYSTEM = '40000000'x
! 'Special' folder PIDL value
PIDL=CSIDL_PROGRAM_FILES
startpath='c:program files'
startpath=trim(adjustl(startpath))//char(0)
IRET=SHILCREATEFROMPATH(STARTPATH, PIDL, SFGAO_FILESYSTEM)
WRITE(*,1000) PIDL,IRET
1000 FORMAT(1H ,'PIDL= ',Z10,', IRET= ',Z10)
PIDL= 0, IRET= 80070002
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
But, according to MSDN, the first argument is a LPCWSTR, thus you need to declare the first argument as an INTEGER(2) array and convert the input string to wide char using MultiByteToWideChar?
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
Thanks, I didn't spot that. Do I understand correctly that I need to
1) Set a character string for the path that I want
2) determine how many characters it contains (including a terminating null?)
3) allocate an INTEGER(2) array of the correct size to contain the converted string (twice the number of characters?)
4) use MultiByteToWideChar to convert the null-terminated character string to the Unicode equivalent using, for example
MultiByteToWideChar(CP_APC, MB_PRECOMPOSED, MYPATH, SIZEOF(MYPATH), MYUNICODEARRAY, SIZEOF(MYUNICODEARRAY) )
Can you tell me where to find values for CP_APC, MB_PRECOMPOSED?
Again, many thanks for your suggestions.
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
![Surprised smiley [:-O]](/isn/Community/en-US/emoticons/emotion-3.gif)
If MyPath is zero-terminated, you can set -1 for the length and you'll get the zero-terminated output array back.
If MyPath is not zero-terminated, set the length to LEN_TRIM(MyPath), and manually append 0 to the output array (like I did).
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
I did look at your file (thanks again) but missed the MultiByte bit. I have added the code to convert the character string to unicode, changed the interface to SHILCreateFromPath as shown, added a call to CoInitialize (after getting an error message from SHILCreateFromPath that it hadn't been initialised) and repeated the program with the result shown below. I now get error code 8x0004005.
! For interfaces to GetACP and MultiByteToWideChar functions
USE kernel32
interface
logical(4) function SHILCreateFromPath (pszPath, pidl, iflags)
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_SHILCreateFromPath@12' :: SHILCreateFromPath
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS: 'SHILCreateFromPath' :: SHILCreateFromPath
!DEC$ ENDIF
!DEC$ ATTRIBUTES REFERENCE :: pidl
!DEC$ ATTRIBUTES REFERENCE :: iflags
!DEC$ ATTRIBUTES REFERENCE :: pszPath
integer:: pidl, iflags
INTEGER(2) :: pszPath(*)
end function SHILCreateFromPath
end interface
CHARACTER(256) STARTPATH
INTEGER(2) UCPATH(256)
integer IRET, PIDL, FLAGS, IACP, IWIDE, IBYTESNEED, IBYTESWRITTEN, I
integer, parameter :: CSIDL_PROGRAM_FILES = '0026'x
integer, parameter :: SFGAO_FILESYSTEM = '40000000'x
! had to add this because of previous error message from SHILCreateFromPath
iret=CoInitialize(0)
PIDL=CSIDL_PROGRAM_FILES
startpath='c:program fileszemax'
startpath=trim(adjustl(startpath))//char(0)
UCPATH=0
IACP=GetACP()
print *, 'IACP= ', IACP
IWIDE=0
IBYTESNEED=MultiByteToWideChar(IACP, 0, STARTPATH,-1,UCPATH, IWIDE)
PRINT *,'Number of wide characters needed= ', IBYTESNEED
IBYTESWRITTEN=MultiByteToWideChar(IACP, 0, STARTPATH,-1,UCPATH, IBYTESNEED)
PRINT *, 'IBYTESWRITTEN= ', IBYTESWRITTEN
PRINT *, 'UCPATH= ',(UCPATH(I),I=1,IBYTESWRITTEN)
IATTRIBUTES=0
IRET=SHILCREATEFROMPATH(UCPATH, PIDL, IATTRIBUTES)
WRITE(*,1000) PIDL,IRET, IATTRIBUTES
1000 FORMAT(1H 'PIDL= ',Z10,', IRET= ',Z10,', ATTRIBUTES= ',I8)
The output I get is:
IACP= 1252
Number of wide characters needed= 24
IBYTESWRITTEN= 24
UCPATH= 99 58 47 112 114 111 103 114 97 109
32 102 105 108 101 115 47 122 101 109 97
120 47 0
PIDL= 0, IRET= 80004005, ATTRIBUTES= 0
So something is still amiss..maybe it's because I have Win2000 and there are things missing from itthat I need?
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
0x80004005: "Unspecified error" (there's Error Lookup program in your CVF folder)
For what it's worth, your code works for me on CVF under XP SP2. I only had to dynamically bind the shell32.dll because I used the CVF's default (oldish) shell32.lib. Maybe it's a safer bet -- if there's no SHILCreateFromPath in the system's Shell32.dll, you'll get a null pscfp right away:
end interface
pointer (pscfp, SHILCreateFromPath)
...
hShell = GetModuleHandle("shell32.dll"C)
pscfp = GetProcAddress(hShell, "SHILCreateFromPath"C)
If you still won't have anything with COM, it is suggested here that undocumented
IRET=SHILCREATEFROMPATH(UCPATH, PIDL, IATTRIBUTES)
SHSimpleIDListFromPath works everywhere (but without promise as to the future).
- Als neu kennzeichnen
- Lesezeichen
- Abonnieren
- Stummschalten
- RSS-Feed abonnieren
- Kennzeichnen
- Anstößigen Inhalt melden
You may not believe this, but after trying everything else, when I changed
startpath='c:/Program Files/ZEMAX/'
to
startpath='c:Program FilesEMAX'
(i.e. forward slashes to back slashes in the folder name) it worked! Unbelievable!
I found that just one forward slash is enough to cause the function to reject the path as unacceptable!
However, I can't getSHILCreateFromPathto create a folder using the CSIDL_FLAG_CREATE attributes though, it returns with error 80070002
I Found 3 versions of ILCreateFromPath in the SHELL32LIB in the SDK and I got both the ASCII (ILCreateFromPathA) and Wide character (ILCreateFromPathW) versions to work as well.
Again, thanks for your help, it was much appreciated.

- RSS-Feed abonnieren
- Thema als neu kennzeichnen
- Thema als gelesen kennzeichnen
- Diesen Thema für aktuellen Benutzer floaten
- Lesezeichen
- Abonnieren
- Drucker-Anzeigeseite