Why FolderBrowserDialog dialog does not scroll to selected folder?

前端 未结 14 1592
失恋的感觉
失恋的感觉 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条回答
  •  -上瘾入骨i
    2020-11-30 02:39

    I computed something in VB.NET, so it would be easy to transform it into C#. I'm French, and I'm beginner in VB. Anyway, you can try my solution.

    My idea is to launch an asynchronous task just before showing the folderBrowserDialog.

    I found this myself, but I was inspired by Brad post. Here's my code:

    Imports System.Threading.Tasks
    Imports Microsoft.VisualBasic.FileIO.FileSystem
    
    Public Enum GW
        HWNDFIRST = 0
        HWNDLAST = 1
        HWNDNEXT = 2
        HWNDPREV = 3
        OWNER = 4
        CHILD = 5
        ENABLEDPOPUP = 6
    End Enum
    
    Public Declare Function SendMessageW Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As UInteger, ByVal wParam As Integer,  ByVal lParam As String) As IntPtr
    Public Declare Function FindWindowExW Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr,  ByVal lpszClass As String,  ByVal lpszWindow As String) As IntPtr
    Public Declare Function GetWindow Lib "user32" (ByVal hwnd As IntPtr, ByVal wCmd As Long) As Long
    Public Declare Function GetDesktopWindow Lib "user32" () As IntPtr
    Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    
    Private Sub FolderBrowserDialog_EnsureVisible(FB As FolderBrowserDialog, _Owner As IntPtr)
        Dim hwnd As IntPtr
        Dim sClassname As New System.Text.StringBuilder(256)
        Thread.Sleep(50)                                     'necessary to let FolderBrowserDialog construct its window
        hwnd = GetDesktopWindow()                            'Desktop window handle.
        hwnd = GetWindow(hwnd, GW.CHILD)                     'We will find all children.
        Do Until hwnd = 0
            If GetWindow(hwnd, GW.OWNER) = _Owner Then       'If one window is owned by our main window...
                GetClassName(hwnd, sClassname, 255)
                If sClassname.ToString = "#32770" Then       'Check if the class is FolderBrowserDialog.
                    Exit Do                                  'Then we found it.
                End If
            End If
            hwnd = GetWindow(hwnd, GW.HWNDNEXT)              'Next window.
        Loop                                                 'If no found then exit.
        If hwnd = 0 Then Exit Sub
        Dim hChild As IntPtr = 0
        Dim hTreeView As IntPtr = 0
        Dim i As Integer = 0
        Do
            i += 1
            If i > 1000 Then Exit Sub                                       'Security to avoid infinite loop.
            hChild = FindWindowExW(hwnd, hChild, Nothing, Nothing)          'Look for children windows of FolderBrowserDialog.
            hTreeView = FindWindowExW(hChild, 0, "SysTreeView32", Nothing)  'Look for treeview of FolderBrowserDialog.
            Thread.Sleep(5)                                                 'delay necessary because FolderBrowserDialog is in construction, then treeview maybe not yet exist.
        Loop While hTreeView = 0
        If SendMessageW(hwnd, &H46A, 1, FB.SelectedPath) = 0 Then           'Send message BFFM_SETEXPANDED to FolderBrowserDialog.
            SendMessageW(hTreeView, &H7, 0, Nothing)                        'Send message WM_SETFOCUS to the treeeview.
        End If
    End Sub
    
    
    Dim My_save_dir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) & "\My-Saves"
    
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim FolderBrowserDialog1 As New FolderBrowserDialog
        FolderBrowserDialog1.Description = "Choose your save files path."
        If Directory.Exists(My_save_dir) Then
            FolderBrowserDialog1.SelectedPath = My_save_dir
        Else
            FolderBrowserDialog1.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
        End If
    
        Dim Me_handle = Me.Handle         'Store the main handle to compare after with each windows owner.
        Task.Run(Sub() FolderBrowserDialog_EnsureVisible(FolderBrowserDialog1, Me_handle))      'Here's the trick, run an asynchronous task to modify the folderdialog.
        If FolderBrowserDialog1.ShowDialog(Me) = System.Windows.Forms.DialogResult.OK Then
            My_save_dir = FolderBrowserDialog1.SelectedPath
        End If
    End Sub
    

    I'm waiting for your suggestions. And someone can translate it into C# because I don't know C#.

提交回复
热议问题