Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2373
  • Last Modified:

PItemIdList To String & String To PItemIdList


   Hi again,

   I need to convert a PItemIdList to a string and, of course, I need to do the back conversion from string to PItemIdList also.

   Something like that :

function PItemIdListToString (pidl : PItemIdList) : string;
function StringToPItemIdList (str : string) : PItemIdList;

   Thanks
0
ivan_llanas
Asked:
ivan_llanas
  • 6
  • 4
  • 3
  • +1
1 Solution
 
mocartsCommented:
you mean ShellObj itemidlist?
in what format in string you need?
mo.
0
 
ivan_llanasAuthor Commented:

   Yes, the ShellObj.PItemIdList.

   Well, I would like to use the Windows' notation (if possible) :

::{208D2C60-3AEA-1069-A2D7-08002B30309D}

for "single" PILD's and

::{208D2C60-3AEA-1069-A2D7-08002B30309D}\::{02004700-6F54-6164-206C-612072656400}\::{666F736F....

for PIDL's with parents.
0
 
MadshiCommented:
Well, you could use my package madShell, which is free for non-commercial purpose.

http://help.madshi.net/madShell.htm

To convert a pidl into a path you can use "IDList(pidl).Path". The other way round works by using "ShellObj(path).IDList.Pidl".

Regards, Madshi.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
ivan_llanasAuthor Commented:

   madShell.dcu is more than 100 Kb and if this module uses madBasic routines, this makes about 200 additional Kb's to the executable to just convert PIDL's to strings.

   Anyway, if these functions are using ShellFolder.GetDisplayNameOf (aItemIdList, SHGDN_FORPARSING, aString), they do not work with PIDL's like "Microsoft Network", "Network neighborhood"... as they return an special name (like "EntireNetwork") or the icon title instead the PIDL converted to string. This makes impossible to "go" back to this PIDL just having this description string.

   There must be a way to store a PIDL and restore it later as Windows Explorer lets create a shortcut from any icon it displays.

   Ivan :(
0
 
MadshiCommented:
>> they do not work with PIDL's like

madShell converts system PIDLs into "::{guid}" paths, it's exactly what you've asked for. You're right, though, madShell's footprint is quite big.

Regards, Madshi.
0
 
Slick812Commented:
hello ivan, you might try these 2 functions -


function GUIDToString(GUID1: TGUID): string;
var
Pwc: PWideChar;
begin
StringFromCLSID(GUID1, Pwc);
Result := WideCharToString(Pwc);
end;

function StringToGUID(IDstr: String): TGUID;
var
Pwc: PWideChar;
begin
Pwc := StringToOleStr(IDstr);
OleCheck(CLSIDFromString(Pwc, Result));
end;

 - - - - - - - - - - - - - - - - - - - -

var
ClsID1: TGUID;
begin
Label1.Caption := GUIDToString(IMalloc);
ClsID1 := StringToGUID(Label4.Caption);
Label2.Caption := GUIDToString(ClsID1);
end;
0
 
ivan_llanasAuthor Commented:

  This seems to almost be, but I don't have TGUID's; I have PItemIdList's, and I haven't found a way to convert them to TGUID or get a TGUID from a PItemIdList. Functions SHGetDataFromIDList has a "supicious" pointer-to-anything parameter...

var pp : TSHDescriptionID;

   SHGetDataFromIDList (Desktop, The_PIDL, SHGDFIL_DESCRIPTIONID, @pp, SizeOf(pp));
   TheString := GUIDToString (pp.Id);

but this hasn worked.
0
 
ivan_llanasAuthor Commented:

   The Control Panel GUID is ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{21EC2020-3AEA-1069-A2DD-08002B30309D} and running this piece of code,
........................................
var pp : TSHDescriptionID;

   SHGetDataFromIDList (Desktop, ControlPanelItemIdList, SHGDFIL_DESCRIPTIONID, @pp, SizeOf(pp));

   result := GUIDToString (pp.Id);
........................................

the only thing I get is the first part:

{20D04FE0-3AEA-1069-A2D8-08002B30309D}

so, there must be a way to iterate the GUID or the PItemIdList to get the rest of the GUID-path...
0
 
Slick812Commented:
I haven't had much time to work on this. . .  but I think the
SHGetDataFromIDList( ) might be for a single reference of the ItemList? ?, , , , since it has the   psf  parameter for the Parent folder. . . but I can't tell if you might use QueryInterface to get the rest of the list???, Here's a Thought - It seems you want to store the ItemList in a string, and then use that stored string to create that ItemList, Since you hve a pointer to the list you might just copy the Bytes from this pointer, into your own Pointer storage block and save that memory or save it to file. . . I have no Idea how the system may or may not have unique bytes for these ItemLists. . . but you would not need to convert them to strings
0
 
ivan_llanasAuthor Commented:

   Yes, SHGetDataFromIDList asks for a IShellFolder; may be the parent? May be, but if I use the real Parent IShellFolder I get a real strange string instead one of the portions of ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\::{21EC2020-3AEA-1069-A2DD-08002B30309D}. But if I use the Desktop IShellFolder I get the first portion of the string.

   Yes, the real matter is to store the ItemList and restore it previously. The conversion to string is not required (but I think it's somewhat "elegant", as long as a PItemIDList can be converted to a string like ::{nnn...}\::{n...}\::{nnn...). The real problem is to avoid creating manually a PItemIdList and fill it with a bunch of bytes. I have an object (TShellBrowser) with a published property (Folder). This folder is set using IShellFolder.ParseDisplayName, and this method "understands" this kind of strings I want to get.

   One reason more to get the PIDL's converted to strings is that they must be saved to the registry. Yes, the registry can host almost any data type, but you'll agree that strings is the most easy to manage, won't you?
0
 
Slick812Commented:
??. .  well, in this case No. . . I have seen many Delphi programmers here do code that converts EVERYTHING into strings. .  I used to try and do that , , but now I use the variable type or Pointers to memory blocks. . . Anyway, I took some time to try and store Item Lists in the Registry, here's something that seems to work - -



procedure TForm1.sbut_SavePItemListClick(Sender: TObject);
var
pFontsIDL: PItemIDList;
ShellMalloc: IMalloc;
ListSize: Integer;
Reg1: TRegistry;
AryChar: Array[0..1024] of Char;
begin
if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
  begin
  SHGetSpecialFolderLocation(Form1.Handle, CSIDL_FONTS, pFontsIDL);
  SHGetPathFromIDList(pFontsIDL, @AryChar);
  try
    ListSize := ShellMalloc.GetSize(pFontsIDL);
    Reg1 := TRegistry.Create;
    try
      Reg1.RootKey := HKEY_CURRENT_USER;
      if Reg1.OpenKey('\Software\Tbear2u', False) then
        begin
        Reg1.WriteBinaryData('PList1', pFontsIDL^, ListSize);
        Reg1.CloseKey;
        end;
      finally
      Reg1.Free;
      end;
    finally
    ShellMalloc.Free(pFontsIDL);
    end;
  ShowMessage(IntToStr(ListSize)+' '+AryChar);
  end;
end;

procedure TForm1.sbut_LoadPListRegClick(Sender: TObject);
var
ShellMalloc: IMalloc;
ListSize: Integer;
Reg1: TRegistry;
pNewIDL: PItemIDList;
AryChar: Array[0..1024] of Char;
begin
ListSize := 0;
Reg1 := TRegistry.Create;
try
  Reg1.RootKey := HKEY_CURRENT_USER;
  if Reg1.OpenKey('\Software\Tbear2u', False) then
    begin
    ListSize := Reg1.GetDataSize('PList1');
    if ListSize > 4 then
      begin
      if (ShGetMalloc(ShellMalloc) = S_OK) and (ShellMalloc <> nil) then
        begin
        pNewIDL := ShellMalloc.Alloc(ListSize);
        try
          Reg1.ReadBinaryData('PList1', pNewIDL^, ListSize);
          SHGetPathFromIDList(pNewIDL, @AryChar);
          finally
          ShellMalloc.Free(pNewIDL);
          end;
        end;
      end;
    Reg1.CloseKey;
    end;
  finally
  Reg1.Free;
  end;
ShowMessage(IntToStr(ListSize)+' '+AryChar);
end;
0
 
MadshiCommented:
One things that speaks pro strings in this case is that the pidl raw data will most probably not cross OS compatible, while the string representation might have better chances there.
0
 
ivan_llanasAuthor Commented:

   Sorry, I've been out for a while... It seems that recovering the whole PIDL in a single chunk works. Maybe it is not cross OS compatible, but in the same computer it does, so I'm not going to loose more time in this question... It would be nice using those "::{...}" strings but "my" "0xXXXXXXXXX..." strings are ok also. Thanks to everybody. Points fly to you, Slick812...
0
 
Slick812Commented:
I don't think the ItemLists would be transferable from one Computer to another anyway (regardless of the OS), , , except maybe the PIDL's which are windows constants, most are based on the File paths
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 6
  • 4
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now