Why FolderBrowserDialog dialog does not scroll to selected folder?

前端 未结 14 1598
失恋的感觉
失恋的感觉 2020-11-30 02:28

As show in this screen shot, the selected folder is not in the view. It needs to be scrolled down to view the selected folder.

14条回答
  •  春和景丽
    2020-11-30 03:00

    In response to Marc F's post - I've converted the VB.Net to C#

        public enum GW
        {
            HWNDFIRST = 0,
            HWNDLAST = 1,
            HWNDNEXT = 2,
            HWNDPREV = 3,
            OWNER = 4,
            CHILD = 5,
            ENABLEDPOPUP = 6
        }
    
        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "SendMessageW", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern IntPtr SendMessageW(IntPtr hWnd, uint msg, int wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);
        [System.Runtime.InteropServices.DllImport("user32.dll", EntryPoint = "FindWindowExW", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern IntPtr FindWindowExW(IntPtr hWndParent, IntPtr hWndChildAfter, [MarshalAs(UnmanagedType.LPWStr)] string lpszClass, [MarshalAs(UnmanagedType.LPWStr)] string lpszWindow);
        [System.Runtime.InteropServices.DllImport("user32", EntryPoint = "GetWindow", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern UInt32 GetWindow(IntPtr hwnd, UInt32 wCmd);
        [System.Runtime.InteropServices.DllImport("user32", EntryPoint = "GetDesktopWindow", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern IntPtr GetDesktopWindow();
        [System.Runtime.InteropServices.DllImport("user32", EntryPoint = "GetClassNameA", ExactSpelling = true, CharSet = System.Runtime.InteropServices.CharSet.Ansi, SetLastError = true)]
        public static extern int GetClassName(IntPtr hwnd, System.Text.StringBuilder lpClassName, int nMaxCount);
    
        private void FolderBrowserDialog_EnsureVisible(FolderBrowserDialog FB, IntPtr _Owner)
        {
            IntPtr hwnd = System.IntPtr.Zero;
            System.Text.StringBuilder sClassname = new System.Text.StringBuilder(256);
            Thread.Sleep(50); //necessary to let FolderBrowserDialog construct its window
            hwnd = GetDesktopWindow(); //Desktop window handle.
            hwnd = (System.IntPtr)GetWindow(hwnd, (UInt32)GW.CHILD); //We will find all children.
            while (!(hwnd == (System.IntPtr)0))
            {
                if (GetWindow(hwnd, (UInt32)GW.OWNER) == (UInt32)_Owner) //If one window is owned by our main window...
                {
                    GetClassName(hwnd, sClassname, 255);
                    if (sClassname.ToString() == "#32770") //Check if the class is FolderBrowserDialog.
                    {
                        break; //Then we found it.
                    }
                }
                hwnd = (System.IntPtr)GetWindow(hwnd, (UInt32)GW.HWNDNEXT); //Next window.
            } //If no found then exit.
            if (hwnd == (System.IntPtr)0)
            {
                return;
            }
            IntPtr hChild = (System.IntPtr)0;
            IntPtr hTreeView = (System.IntPtr)0;
            int i = 0;
            do
            {
                i += 1;
                if (i > 1000) //Security to avoid infinite loop.
                {
                    return;
                }
                hChild = FindWindowExW(hwnd, hChild, null, null); //Look for children windows of FolderBrowserDialog.
                hTreeView = FindWindowExW(hChild, (System.IntPtr)0, "SysTreeView32", null); //Look for treeview of FolderBrowserDialog.
                Thread.Sleep(5); //delay necessary because FolderBrowserDialog is in construction, then treeview maybe not yet exist.
            } while (hTreeView == (System.IntPtr)0);
            if (SendMessageW(hwnd, 0x46A, 1, FB.SelectedPath) == (System.IntPtr)0) //Send message BFFM_SETEXPANDED to FolderBrowserDialog.
            {
                SendMessageW(hTreeView, 0x7, 0, null); //Send message WM_SETFOCUS to the treeeview.
            }
        }
    

    Tested this and it works fine. Make sure you reference System.Runtime.InteropServices, System.Threading, an System.Threading.Tasks

提交回复
热议问题