Comment windows a programmé le shbrowseforfolder?

0/5 (4 avis)

Vue 8 819 fois - Téléchargée 600 fois

Description

Ce programme affiche une boite de dialogue pour choisir un répertoire tout comme la fonction SHBrowseForFolder le fait. Mais je n'utilise pas ce dernier, j'utilise les fonctions comme SHGetDesktopFolder, SHGetSpecialFolderLocation, SHGetPathFromIDList, WNetOpenEnum, WNetEnumResource, etc. Ainsi que l'interface ISHellFolder et ses fonctions(EnumObjects, BindToObject, GetDisplayNameOf, CompareIDs, etc.)

Source / Exemple :


// Echantillon du programme : la fonction SetPath

procedure TForm1.SetPath;
const
     Flags = SHCONTF_FOLDERS and SHCONTF_NONFOLDERS;
     Flg   = SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or SHCONTF_INCLUDEHIDDEN;
var
   Sfi        : TSHFileInfo;
   Root,
   NodeTemp   : TTreenode;
   FullID, ID, idRoot : PItemIDList;
   NewShellFolder : IShellFolder;
   EnumList    : IEnumIDList;
   NumIDs      : DWORD;
   Disque, szChaine : string;
   szpPath     : array[0..MAX_PATH] of Char;
   SaveCursor : TCursor;
   Liste : TList;
   i : Integer;
   ShellItem : PShellItem;
begin

     Root := nil;

     SaveCursor := Screen.Cursor;
     Treeview1.Items.BeginUpdate;

     try

        Screen.Cursor := crHourGlass;
        Treeview1.Items.Clear;

        {Bureau}
        if SHGetSpecialFolderLocation(Treeview1.Handle, CSIDL_DESKTOP, idRoot) = NOERROR then
        begin
             if SHGetFileInfo(PChar(idRoot), 0, Sfi, SizeOf(TSHFileInfo), SHGFI_PIDL or
                       SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_DISPLAYNAME) <> 0 then
             begin
                  Root                := Treeview1.Items.AddChild(nil, Sfi.szDisplayName);
                  Root.HasChildren    := True;
                  Root.ImageIndex     := Sfi.iIcon;
                  Root.SelectedIndex  := Root.ImageIndex;
                  Root.Data           := idRoot;
             end;
        end;

        {Poste de travail, tous les disques}
        if SHGetSpecialFolderLocation(Treeview1.Handle, CSIDL_DRIVES, idRoot) = NOERROR then
        begin
             if SHGetFileInfo(PChar(idRoot), 0, Sfi, SizeOf(TSHFileInfo), SHGFI_PIDL or
               SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_DISPLAYNAME) <> 0 then
             begin
                  Root := Treeview1.Items.AddChild(Root, Sfi.szDisplayName);
                  Root.ImageIndex := Sfi.iIcon;
                  Root.SelectedIndex := Sfi.iIcon;
             end;

             IDesktopFolder.BindToObject(idRoot,
                                          nil,
                                          IID_IShellFolder,
                                          Pointer(NewShellFolder));

             ShellFolder := NewShellFolder;

             NewShellFolder.EnumObjects(Application.Handle,
                                        Flg,
                                        EnumList);

             Liste := TList.Create;
             while EnumList.Next(1, ID, NumIDs) = S_OK do
             begin
                  ShellItem := New(PShellItem);

                  ShellItem.DisplayName := GetDisplayName(NewShellFolder, ID, False);
                  ShellItem.ID          := ID;
                  FullID := ConcatPIDLs(idRoot, ID);
                  ShellItem.ImageIndex  := GetShellImage(FullID, False);
                  ShellItem.SelectedIndex  := GetShellImage(FullID, True);
                  Liste.Add(ShellItem);
                  //Dispose(ShellItem);
             end;

             //Liste.Sort(ListSortFunc);

             if (Liste.List <> nil) and (Liste.Count > 0) then
                QuickSort(Liste.List, 0, Liste.Count - 1);

             
             for i := 0 to Liste.Count - 1 do
             begin
                  with Treeview1.Items do
                  begin
                       szChaine := PShellItem(Liste[i]).DisplayName;
                       Disque := Copy(szChaine, Pos(':', szChaine) - 1, 1) + ':\';
                       NodeTemp := AddChild(Root, szChaine);

                       if HasSubFolder(NewShellFolder, PShellItem(Liste[i]).ID) then
                          NodeTemp.HasChildren    := True;
                       
                       NodeTemp.ImageIndex     := PShellItem(Liste[i]).ImageIndex;
                       NodeTemp.SelectedIndex  := PShellItem(Liste[i]).SelectedIndex;
                  end;
             end;

             for i := 0 to Liste.Count - 1 do
             begin
                  {Supprimer le ID de chque élément}
                  DisposePIDL(PShellItem(Liste[i]).ID);
                  {Supprimer l'élément}
                  Dispose(PShellItem(Liste[i]));
             end;

             Liste.Free;

             
             {Etendre le Bureau, le premier noeud}
             TreeView1.Items.GetFirstNode.Expand(False);
             {Etendre le Poste de travail}
             Root.Expand(False);

             Treeview1.Selected := Root;

        end;

        {Voisinage réseau}
        if SHGetSpecialFolderLocation(Treeview1.Handle, CSIDL_NETWORK, idRoot) = NOERROR then
        begin
             if SHGetFileInfo(PChar(idRoot), 0, Sfi, SizeOf(TSHFileInfo), SHGFI_PIDL or
                  SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_DISPLAYNAME) <> 0 then
             begin
                  Root := Treeview1.Items.AddChild(Treeview1.Items.GetFirstNode, Sfi.szDisplayName);
                  Root.SelectedIndex := Sfi.iIcon;
                  Root.ImageIndex := Sfi.iIcon;
                  Root.HasChildren := True;
                  Root.Data := PChar(lpVoisinage);
             end;
        end;

        {Corbeille}
        if SHGetSpecialFolderLocation(Treeview1.Handle, CSIDL_BITBUCKET, idRoot) = NOERROR then
        begin
             if SHGetFileInfo(PChar(idRoot), 0, Sfi, SizeOf(TSHFileInfo), SHGFI_PIDL or
                  SHGFI_SYSICONINDEX or SHGFI_SMALLICON or SHGFI_DISPLAYNAME) <> 0 then
             begin
                  Root := Treeview1.Items.AddChild(Treeview1.Items.GetFirstNode, Sfi.szDisplayName);
                  Root.SelectedIndex := Sfi.iIcon;
                  Root.ImageIndex := Sfi.iIcon;
                  //Root.HasChildren := True;
                  //Root.Data := PChar(lpVoisinage);
             end;
        end;

        {Ajouter les dossiers du bureau}

        if SHGetSpecialFolderLocation(Treeview1.Handle, CSIDL_DESKTOPDIRECTORY , idRoot) = NOERROR then
        begin

             IDesktopFolder.BindToObject (idRoot,
                                          nil,
                                          IID_IShellFolder,
                                          Pointer(NewShellFolder));

             NewShellFolder.EnumObjects(Application.Handle,
                                        Flg,
                                        EnumList);

             while EnumList.Next(1, ID, NumIDs) = S_OK do
             begin
                  with Treeview1.Items do
                  begin
                       SHGetPathFromIDList(PItemIDList(GetFirstNode.Data), @szpPath);
                       szChaine := GetDisplayName(NewShellFolder, ID, False);
                       StrCat(szpPath, PChar('\' + szChaine));
                       if SHGetFileInfo(szpPath, 0, Sfi, SizeOf(TSHFileInfo),
                          SHGFI_ATTRIBUTES or SHGFI_DISPLAYNAME) <> 0 then
                       begin
                            // Si c'est un répertoire
                            if (Sfi.dwAttributes and FILE_ATTRIBUTE_DIRECTORY > 0) then
                            begin
                                 if Pos('.', szpPath) = 0 then
                                 begin
                                 Root := AddChild(GetFirstNode, Sfi.szDisplayName);
                                 Root.HasChildren    := HasSubs(szpPath);
                                 Root.ImageIndex     := GetNormalIcon(szpPath);
                                 Root.SelectedIndex  := GetSelectedIcon(szpPath);
                                 end;
                            end;
                       end;
                  end;
             end;
        end;
     finally
        Treeview1.Items.EndUpdate;
        Screen.Cursor := SaveCursor;
     end;

end;

Codes Sources

A voir également

Ajouter un commentaire Commentaires
cs_badjinmb Messages postés 6 Date d'inscription dimanche 23 avril 2006 Statut Membre Dernière intervention 5 mai 2006
5 mai 2006 à 22:55
salut kanto ton programe est supper , mais je n'y comprend rien enfin 1/10 ; j'ai cherché sur le net de la documentation mais je n'ai rien trouvé si tu peut me donner une adresse ou n'importe quoi pour comprendre ca serais supper ,appart ca il ya un petit problème,les dossiers du bureau ne s'ouvres pas ...
S.T.P si t'as quelquechose contacte moi Merci inffiniment a+
GregPL Messages postés 1 Date d'inscription mercredi 13 août 2003 Statut Membre Dernière intervention 7 février 2006
7 févr. 2006 à 15:38
Salut,

J'ai trouvé un problème ligne 182 (ou Unit1.pas ligne 976), le test ne doit pas être fait avec ?FILE_ATTRIBUTE_DIRECTORY? mais avec ?SFGAO_FOLDER?.

A+ Greg
cs_grandvizir Messages postés 1106 Date d'inscription samedi 8 novembre 2003 Statut Membre Dernière intervention 3 septembre 2006 22
21 mai 2005 à 10:42
TFolderTree réagit face aux actions...
cs_Zynox Messages postés 11 Date d'inscription vendredi 4 octobre 2002 Statut Membre Dernière intervention 2 mars 2004
2 avril 2003 à 20:48
Salut j'ai testé ton code il marche tres bien, ms il y a un petit pb, en effet si on creer un nouvo dossier le code ne reactualsie pas la structure :) dc il faut fermer l'aplication et la rouvrir.
Si tu pouvais arrangé ca ca seré cool :)
A+ Zynox
PS: Ton code couplé avec un pti bou de code c'est genial ^^

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.