none
FolderBrowserDialog et Environment.SpecialFolder.MyDocuments - C#

    Discussion générale

  • Bonjour, 

    Je rencontre une difficulté en développant une appli Windows Forms:  Je mets en oeuvre FolderBrowserDialog pour séléctionner un répertoire, dans une séquence très simple, mais je rencontre un obstacle à propos du RootFolder 

    le script est:

    FolderBrowserDialog fbd = new FolderBrowserDialog();

              fbd.Reset();

              string path="";

              // sélection du dossier racine

                fbd.Description = "Choisissez un dossier " + path;

    OK       fbd.RootFolder = Environment.SpecialFolder.Desktop;   Dans ces 2 cas, la fenetre de dialogue affiche l'arborescence des dossiers

    OK       fbd.RootFolder = Environment.SpecialFolder.MyComputer;

    MAIS:

    BAD     fbd.RootFolder = Environment.SpecialFolder.MyDocuments;  => seul le dossier Documents est affiché dans la boite de sélection on ne peut voir l'arborescence (même problème avec MyMusic, MyPicturesou MyVideos )

                 fbd.ShowNewFolderButton = false;

                 if ( fbd.ShowDialog()==DialogResult.OK)

                {

                    toolStripTextBoxDirectory.Text = fbd.SelectedPath;

                }

    Merci de votre aide, je voudrais comprendre!

    jeudi 14 décembre 2017 13:26

Toutes les réponses

  • J'ai le même "bug" sur mon OS (Windows 10), en C#, C++, ...

    ça fonctionne correctement si je ne mets pas le flag BIF_USENEWUI

    lors de l'appel de SHBrowseForFolder()

    jeudi 14 décembre 2017 16:44
  • Bonjour,

    Je n'ai pas eu de réponse argumentée de cette erreur de Microsoft ! N'étant pas suffise ment expert   je ne comprends pas comment faire pour tester le flag BIF_USENEWUI ? 

    A quel niveau ? Dans mon programme ? 

    Merci si je peux utiliser tes connaissances !

    mardi 6 février 2018 13:36
  • Par exemple :

    HRESULT hr = HRESULT.E_FAIL;
    IntPtr pidl = IntPtr.Zero, pidlRet = IntPtr.Zero;
    hr = SHGetFolderLocation(IntPtr.Zero, CSIDL_PERSONAL, IntPtr.Zero, 0, out pidl);
    if (hr == HRESULT.S_OK)
    {
        BROWSEINFO bi = new BROWSEINFO();
        bi.pidlRoot = pidl;
        bi.hwndOwner = this.Handle;
        bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_SHAREABLE |  BIF_VALIDATE;
        bi.lpszTitle = "Title";
        pidlRet = SHBrowseForFolder(bi);
        if (pidlRet != IntPtr.Zero)
        {
            IntPtr pszSelectedPath = IntPtr.Zero;
            pszSelectedPath = Marshal.AllocHGlobal((MAX_PATH + 1) * Marshal.SystemDefaultCharSize);
            SHGetPathFromIDList(pidlRet, pszSelectedPath);
            string sSelectedPath = null;
            sSelectedPath = Marshal.PtrToStringAuto(pszSelectedPath);
            Marshal.FreeHGlobal(pszSelectedPath);
        }
    }

    Avec les declarations :

    public enum HRESULT : int
    {          
        S_OK = 0,
        S_FALSE = 1,
        E_NOINTERFACE = unchecked((int)0x80004002),
        E_NOTIMPL = unchecked((int)0x80004001),           
        E_FAIL = unchecked((int)0x80004005)            
    }
    
    public delegate int BrowseCallbackProc(IntPtr hwnd, int msg, IntPtr lParam, IntPtr lpData);
    
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public class BROWSEINFO
    {
        public IntPtr hwndOwner;
        public IntPtr pidlRoot;
        public IntPtr pszDisplayName;
        public string lpszTitle;
        public int ulFlags;
        public BrowseCallbackProc lpfn;
        public IntPtr lParam;
        public int iImage;
    }
    
    [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr SHBrowseForFolder([In] BROWSEINFO lpbi);
    
    [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern HRESULT SHGetFolderLocation(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwReserved, out IntPtr ppidl);
    
    public const int CSIDL_DESKTOP = 0x0000;
    public const int CSIDL_PERSONAL = 0x0005;
    
    // Browsing for directory.
    public const int BIF_RETURNONLYFSDIRS = 0x00000001;  // For finding a folder to start document searching
    public const int BIF_DONTGOBELOWDOMAIN = 0x00000002;  // For starting the Find Computer
    public const int BIF_STATUSTEXT = 0x00000004;   // Top of the dialog has 2 lines of text for BROWSEINFO.lpszTitle and one line if
                                                    // this flag is set.  Passing the message BFFM_SETSTATUSTEXTA to the hwnd can set the
                                                    // rest of the text.  This is not used with BIF_USENEWUI and BROWSEINFO.lpszTitle gets
                                                    // all three lines of text.
    public const int BIF_RETURNFSANCESTORS = 0x00000008;
    public const int BIF_EDITBOX = 0x00000010;   // Add an editbox to the dialog
    public const int BIF_VALIDATE = 0x00000020;   // insist on valid result (or CANCEL)
    
    public const int BIF_NEWDIALOGSTYLE = 0x00000040;   // Use the new dialog layout with the ability to resize
                                                        // Caller needs to call OleInitialize() before using this API
    
    public const int BIF_USENEWUI = (BIF_NEWDIALOGSTYLE | BIF_EDITBOX);
    
    public const int BIF_BROWSEINCLUDEURLS = 0x00000080;   // Allow URLs to be displayed or entered. (Requires BIF_USENEWUI)
    public const int BIF_UAHINT = 0x00000100;   // Add a UA hint to the dialog, in place of the edit box. May not be combined with BIF_EDITBOX
    public const int BIF_NONEWFOLDERBUTTON = 0x00000200;   // Do not add the "New Folder" button to the dialog.  Only applicable with BIF_NEWDIALOGSTYLE.
    public const int BIF_NOTRANSLATETARGETS = 0x00000400;   // don't traverse target as shortcut
    
    public const int BIF_BROWSEFORCOMPUTER = 0x00001000;  // Browsing for Computers.
    public const int BIF_BROWSEFORPRINTER = 0x00002000;  // Browsing for Printers
    public const int BIF_BROWSEINCLUDEFILES = 0x00004000;  // Browsing for Everything
    public const int BIF_SHAREABLE = 0x00008000;  // sharable resources displayed (remote shares, requires BIF_USENEWUI)
    public const int BIF_BROWSEFILEJUNCTIONS = 0x00010000;  // allow folder junctions like zip files and libraries to be browsed
    
    public const int MAX_PATH = 260;
    
    [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true, EntryPoint = "SHGetPathFromIDListW")]
    public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);


    mardi 6 février 2018 14:10
  • Bonjour,

    En 2011 j'ai eu à développer une application sous ... le Windows de l'époque, et en effet les variables de répertoires spéciaux ne renvoyaient pas au même répertoire sur toutes les machines.

    Heureusement il n'y avait qu'une demi-douzaine de machines à gérer, alors j'ai fait le tour et j'ai trouvé une syntaxe lourdingue qui permettait de faire ce que j'avais à faire. Peut-être bien que j'enregistrais une configuration sur chaque machine, je ne saurais plus être catégorique.

    Bon, comment dire ... on espère que sous Windows 11 ça sera d'équerre.

    vendredi 9 février 2018 15:33