Comment windows a programmé le shbrowseforfolder?

Soyez le premier à donner votre avis sur cette source.

Vue 8 361 fois - Téléchargée 555 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

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

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
1237
Date d'inscription
samedi 8 novembre 2003
Statut
Membre
Dernière intervention
3 septembre 2006
12
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

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.