Jump to content
limelect

A directory translate

Recommended Posts

I am trying to translate "Libraries\Pictures\My Pictures\" for example
to the directory "C:\Users\LimElect\Pictures"
I am using 

var
  LShellItem: IShellItem;
   LPlace: TFavoriteLinkItem;
begin
    if Succeeded(SHCreateItemFromParsingName(PWideChar('Libraries\Pictures\My Pictures\'),
             nil, StringToGUID(SID_IShellItem), LShellItem)) then
             begin
              Label1.Caption:= ShellItemFileSystemPath(LShellItem); //<<  here LShellItem is nil !!
             end;

This dose not work , any idea?
I took the above from VCL.dialogs

 

P.S Using FileOpenDialog and return FileOpenDialog1.ShellItem this works. BUT I DO NOT WANT TO EXECUTE.

I just want the directory NOT a file !!

 

 

Share this post


Link to post
Posted (edited)

NO because picture is only an example.

However you gave me an idea to decode (i do not like it)

a WORD in the explorer address to TPath.Get....

However i would like a nicer approach 

Edited by limelect

Share this post


Link to post
Posted (edited)

 

6 hours ago, limelect said:

I am trying to translate "Libraries\Pictures\My Pictures\" for example
to the directory "C:\Users\LimElect\Pictures"

When working with Libraries, you should use the IShellLibrary interface to query them.  However, in this particular example, the correct way to get the path to the user's Pictures folder is to use SHGetFolderPath(CSIDL_MYPICTURES) or SHGetKnownFolderPath(FOLDERID_Pictures) instead.

Quote

 

I am using 


if Succeeded(SHCreateItemFromParsingName(PWideChar('Libraries\Pictures\My Pictures\'),
  nil, StringToGUID(SID_IShellItem), LShellItem)) then
begin
  Label1.Caption:= ShellItemFileSystemPath(LShellItem); //<<  here LShellItem is nil !!
end;

 

LShellItem can't be nil if SHCreateItemFromParsingName() returns success.

 

Edited by Remy Lebeau

Share this post


Link to post

@Remy Lebeau  I know most of the answer. It seem i did not ask the right way.

The library section on the drive is only TEXT referring to c:/users/....

what i want is a way to translate this TEXT to c:/users/...

 

My picture is just an EXAMPLE of my NEED.

 

I tried  Using FileOpenDialog that returns FileOpenDialog1.ShellItem this works.

!!!!!   BUT I DO NOT WANT TO EXECUTE.

I just want the directory NOT a file !!!!

I need the software behind FileOpenDialog ON A DIRECTORY (not a file)

without the FileOpenDialog.execute. this is why i tried  SHCreateItemFromParsingName

 

I hop it clarified my need.

Share this post


Link to post
7 hours ago, limelect said:

@Remy Lebeau  I know most of the answer. It seem i did not ask the right way.

The library section on the drive is only TEXT referring to c:/users/....

what i want is a way to translate this TEXT to c:/users/...

Like I said, use the Shell Library API for that.  See Windows Libraries and Using Libraries in your Program for more details.

7 hours ago, limelect said:

I tried  Using FileOpenDialog that returns FileOpenDialog1.ShellItem this works.

!!!!!   BUT I DO NOT WANT TO EXECUTE.

I just want the directory NOT a file !!!!

I need the software behind FileOpenDialog ON A DIRECTORY (not a file)

without the FileOpenDialog.execute. this is why i tried  SHCreateItemFromParsingName

You don't need to repeat yourself.  You made yourself perfectly clear the first time you said that.

 

Share this post


Link to post
On 3/19/2019 at 10:21 AM, limelect said:

I am trying to translate "Libraries\Pictures\My Pictures\" for example
to the directory "C:\Users\LimElect\Pictures"
I am using 


var
  LShellItem: IShellItem;
   LPlace: TFavoriteLinkItem;
begin
    if Succeeded(SHCreateItemFromParsingName(PWideChar('Libraries\Pictures\My Pictures\'),
             nil, StringToGUID(SID_IShellItem), LShellItem)) then
             begin
              Label1.Caption:= ShellItemFileSystemPath(LShellItem); //<<  here LShellItem is nil !!
             end;

This dose not work , any idea?
I took the above from VCL.dialogs

 

P.S Using FileOpenDialog and return FileOpenDialog1.ShellItem this works. BUT I DO NOT WANT TO EXECUTE.

I just want the directory NOT a file !!

 

 

I don't have a ready implementation right now, but

  • Start with SHGetDesktopFolder. This returns an IShellFolder.
  • Use IShellFolder.ParseDisplayName and see if you can get it to parse your directory. That should provide an ItemIDList.
  • Now you can use those two to get the proper name.

Share this post


Link to post
Posted (edited)
21 hours ago, Rudy Velthuis said:

I don't have a ready implementation right now, but

  • Start with SHGetDesktopFolder. This returns an IShellFolder.
  • Use IShellFolder.ParseDisplayName and see if you can get it to parse your directory. That should provide an ItemIDList.
  • Now you can use those two to get the proper name.

That last step does not require the IShellFolder as the returned ItemIDList will be an absolute PIDL that can be passed to SHGetPathFromIDList().

 

But, this solution really isn't much different than using SHCreateItemFromParsingName() and ShellItemFileSystemPath() with an IShellItem instead of an ItemIDList.

Edited by Remy Lebeau

Share this post


Link to post
Posted (edited)
1 hour ago, Remy Lebeau said:

That last step does not require the IShellFolder as the returned ItemIDList will be an absolute PIDL that can be passed to SHGetPathFromIDList().

 

But, this solution really isn't much different than using SHCreateItemFromParsingName() and ShellItemFileSystemPath() with an IShellItem instead of an ItemIDList.

My solution already worked in Delphi 4. Then, there was no SHGetPathFromIDList() yet. And the other solution was not possible at all. <g>

Edited by Rudy Velthuis

Share this post


Link to post
Posted (edited)

@Rudy Velthuis I tried very simple 2 line of your suggestion

var

 Attr, Eaten: ULONG;
  PathIdList: PItemIdList;
  DesktopFolder: IShellFolder;

 

if Succeeded(SHGetDesktopFolder(DesktopFolder)) then begin    //Libraries\Pictures\
     if Succeeded(DesktopFolder.ParseDisplayName(0, nil, 'c:\', Eaten, PathIdList, Attr)) then begin

     end;
If i use 'Libraries\Pictures\' for path i get PathIdList=nil

If i use 'c:\' for path i get PathIdList <>nil

i am stuck again

Can you put your suggestion source here ?

With what dir librery text did you try your solution?

 

Edited by limelect

Share this post


Link to post
12 minutes ago, limelect said:

@Rudy Velthuis I tried very simple 2 line of your suggestion

var

 Attr, Eaten: ULONG;
  PathIdList: PItemIdList;
  DesktopFolder: IShellFolder;

 

if Succeeded(SHGetDesktopFolder(DesktopFolder)) then begin    //Libraries\Pictures\
     if Succeeded(DesktopFolder.ParseDisplayName(0, nil, 'c:\', Eaten, PathIdList, Attr)) then begin

     end;
If i use 'Libraries\Pictures\' for path i get PathIdList=nil

If i use 'c:\' for path i get PathIdList <>nil

i am stuck again

Can you put your suggestion source here ?

With what dir librery text did you try your solution?

 

What happens if you use 'C:\Libraries\Pictures' or 'C:\Windows' as path? You need a full path and the PItemIDList for C:\ is, AFAIK, indeed nil.

Share this post


Link to post
Posted (edited)

@Rudy Velthuis Libraries\Pictures\My Pictures    is OK

I tried C:\Libraries\Pictures NOT OK. this is not logical since there in NO such directory.

Just go to explorer and see how Explorer open 'libraries' and more

Edited by limelect

Share this post


Link to post
Posted (edited)
14 minutes ago, limelect said:

@Rudy Velthuis Libraries\Pictures\My Pictures    is OK

I tried C:\Libraries\Pictures NOT OK. this is not logical since there in NO such directory.

Just go to explorer and see how Explorer open 'libraries' and more

'C:\Libraries\Pictures' does not work for me either, but 'C:\Users\Rudy\Pictures' does. Note that a folder is not necessarily a physical directory on a physical medium, and that a display name can differ from the exact directory name as well.

 

Libraries is such a virtual folder. It does not exist as such on disk and does not have a PItemIDList, AFAIK.

Edited by Rudy Velthuis

Share this post


Link to post

@Rudy Velthuis   sure no problem for that C:\Users\Rudy\Pictures.

 

Since this is your directory for pictures . But that where i started

to GET !!! from libraries\pictures to C:\Users\Rudy\Pictures

THIS IS MY PROBLEM !!!

 

Share this post


Link to post
28 minutes ago, limelect said:

@Rudy Velthuis   sure no problem for that C:\Users\Rudy\Pictures.

 

Since this is your directory for pictures . But that where i started

to GET !!! from libraries\pictures to C:\Users\Rudy\Pictures

THIS IS MY PROBLEM !!!

 

Ok, your problem was not entirely clear to me.

Share this post


Link to post
Posted (edited)
2 hours ago, Rudy Velthuis said:

Libraries is such a virtual folder. It does not ... have a PItemIDList, AFAIK.

EVERYTHING in the Shell has a PIDL, relative to the Shell root.  In this case, Libraries is not part of the file system, so you can't get its PIDL from parsing a file system path.  The correct way to get the Libraries PIDL is to use SHGetKnownFolderIDList(FOLDERID_Libraries) instead.

Edited by Remy Lebeau
  • Thanks 1

Share this post


Link to post
Posted (edited)
2 hours ago, limelect said:

Since this is your directory for pictures . But that where i started

to GET !!! from libraries\pictures to C:\Users\Rudy\Pictures

THIS IS MY PROBLEM !!!

I've already answered this for you.  You need to use the IShellLibrary interface to get the filesystem path(s) that a given Library points to.  Why do you keep ignoring me on this?

 

You need to obtain the IShellLibrary interface for "Libraries\Pictures" first,

Then you can call the IShellLibrary::GetFolders() method asking it for an IShellItemArray interface,

Then you can the IShellItemArray::EnumItems() method to get an IEnumShellItems interface,

Then you can enumerate it to access the individual IShellItem interfaces,

And finally call IShellItem::GetDisplayName() asking for SIGDN_FILESYSPATH.

 

This is all documented on MSDN.

Edited by Remy Lebeau
  • Like 1

Share this post


Link to post

@Remy Lebeau I will see how to apply your idea.

 

Let me (if you allow ) how i got to this situation.

I have a free program  http://limelect.com/downloads/explorer-list/

which you can go to any EXPLORER address fast.

I am adding to it explore HISTORY.

(why ? because some time i forget where i was in explorer). 

when i go into a directory i get the TEXT in the explorer bar

And then if i need it letter i use it.

If i have an address as "c:\...." that not a problem.

However libraries... this where my problem start.

Thanks in any case

Share this post


Link to post
Posted (edited)

@limelect In this case you could cache as a lookup table the entries from:

 

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions

 

and fire the explorer for example with:

 

start shell:PicturesLibrary

 

or

 

explorer shell:PicturesLibrary

 

where PicturesLibrary is the example, one element from the FolderDescriptions

 

Then you will land there where you was and not in its translated dir.

Edited by Attila Kovacs

Share this post


Link to post
Posted (edited)

@Attila Kovacs your solution mite work but in my case

i cannot use .

http://limelect.com/downloads/explorer-list/

My software opens the same ! explorer page to a new location  !!

i do NOT open a new page unless i want it. 

I need the real address

 

P.S Try my software it is very useful to us programmers

 and many people downloaded it.

 

I will try Remy solution

Edited by limelect

Share this post


Link to post
Posted (edited)

@limelect ok, sorry but I'm not operating with explorer at all. I'm using Far Manager.

 

btw. you could lookup libraries/pictures from the mentioned list and fire the same location in a new explorer window without knowing its real location.

Edited by Attila Kovacs

Share this post


Link to post

@Remy Lebeau Thank you very much every body.

From Remy who gave me a starting point i found what i NEED.

It is MustangpeakVirtualShell-2.7.0\Demos\Namespace Browser

It dose exactly my need.

Thanks again

Share this post


Link to post
Posted (edited)
22 hours ago, Remy Lebeau said:

EVERYTHING in the Shell has a PIDL, relative to the Shell root.  In this case, Libraries is not part of the file system, so you can't get its PIDL from parsing a file system path.  The correct way to get the Libraries PIDL is to use SHGetKnownFolderIDList(FOLDERID_Libraries) instead.

Ok, but exactly that (get a PIDL from a file system path) seems to be what OP wants.

Edited by Rudy Velthuis

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×