FolderBrowserDialog 대화 상자가 선택한 폴더로 스크롤되지 않는 이유는 무엇입니까?
이 스크린샷에 나타나듯이 선택한 폴더는 보기에 없습니다.선택한 폴더를 보려면 아래로 스크롤해야 합니다.
동일한 대화 상자에 다른 컴퓨터에 표시되는 선택한 폴더 표시
윈도우 7이 있는 두 대의 컴퓨터에서 실행해 봤어요.1대에서는 정상적으로 동작하지만 2대째에서는 동작하지 않습니다.Windows 환경에서는 코드 문제가 아닌 것 같습니다.어떤 해결책을 제안할 수 있는 사람?
코드에 변경은 없습니다.다른 드라이브에서 더 긴 경로를 사용했지만 결과는 동일합니다.
private void TestDialog_Click ( object sender, EventArgs e )
{
//Last path store the selected path, to show the same directory as selected on next application launch.
//Properties.Settings.Default.LastPath
FolderBrowserDialog dlgFolder = new FolderBrowserDialog ();
dlgFolder.RootFolder = Environment.SpecialFolder.DesktopDirectory;
dlgFolder.SelectedPath = Properties.Settings.Default.LastPath;
if (dlgFolder.ShowDialog () == System.Windows.Forms.DialogResult.OK)
{
Properties.Settings.Default.LastPath = dlgFolder.SelectedPath;
Properties.Settings.Default.Save ();
}
}
입니다.FolderBrowserDialog
'아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.FolderBrowserDialog
.이지만, 오히려 NET 입니다.Common Dialog
Windows 의 windows windows windows windows windows windows windows windows windows.을 TreeView컨트롤로 했습니다.TVM_ENSUREVISIBLE
대화상자가 표시되고 초기 폴더가 선택된 후 메시지가 나타납니다.이 메시지에 의해 TreeView컨트롤이 스크롤되어 현재 선택된 항목이 창에 표시됩니다.
하려면 TreeView의 .FolderBrowserDialog
TVM_ENSUREVISIBLE
네? 네, 네, 네, 네, 네, 네, 네.이것이 해답이지만, 우리의 길을 가로막고 있는 것이 있다.
번째 는 '아예'가
FolderBrowserDialog
아니다가 아닙니다. 컨트롤, NET .Controls
집 、 、 、、 TreeView에서 하여 액세스할 수 .둘째, 의 설계자입니다. 물 net
FolderBrowserDialog
학급은 이 반을 봉인하기로 결정했다.이 부적절한 결정으로 인해 윈도 메시지핸들러를 덮어쓸 수 없게 됩니다.우리가 이걸 할 수 있었다면, 우리는 아마 그 게시물을 올리려고 했을 것이다.TVM_ENSUREVISIBLE
.WM_SHOWWINDOW
시시지핸핸핸핸메메메 메메메메메TVM_ENSUREVISIBLE
이 실제로 하며 Tree View 컨트롤이 Tree View를 하지 않습니다.ShowDialog
에 이 할 수 그러나 이 메서드는 차단되므로 이 메서드가 호출되면 메시지를 게시할 수 없습니다.
하나의 클래스는, 「스태틱 도우미」를 사용할 수.FolderBrowserDialog
이치노는 이것을 짧게 으로써 이 를 해결한다.Timer
ShowDialog
그 후 , , 추적, 하다.TreeView
Timer
및(대화상자 표시 후)을 합니다.TVM_ENSUREVISIBLE
★★★★★★★★★★★★★★★★★★.
은 이 문제에 에 완벽하지는 않습니다.왜냐하면 이 솔루션은 다음 정보에 대한 몇 가지 사전 지식에 의존하기 때문입니다.FolderBrowserDialog
구체적으로는 창 제목을 사용하여 대화를 찾을 수 있습니다.영어 이외의 설치에서는 중단됩니다.제목 텍스트나 클래스 이름이 아닌 대화 상자 항목 ID를 사용하여 대화에서 자녀 컨트롤을 추적합니다. 시간이 지남에 따라 자녀 컨트롤이 더 신뢰할 수 있을 것 같았기 때문입니다.
이 코드는 Windows 7(64비트) 및 Windows XP에서 테스트되고 있습니다.
과 같습니다.할 수 .using System.Runtime.InteropServices;
)
public static class FolderBrowserLauncher
{
/// <summary>
/// Using title text to look for the top level dialog window is fragile.
/// In particular, this will fail in non-English applications.
/// </summary>
const string _topLevelSearchString = "Browse For Folder";
/// <summary>
/// These should be more robust. We find the correct child controls in the dialog
/// by using the GetDlgItem method, rather than the FindWindow(Ex) method,
/// because the dialog item IDs should be constant.
/// </summary>
const int _dlgItemBrowseControl = 0;
const int _dlgItemTreeView = 100;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
/// <summary>
/// Some of the messages that the Tree View control will respond to
/// </summary>
private const int TV_FIRST = 0x1100;
private const int TVM_SELECTITEM = (TV_FIRST + 11);
private const int TVM_GETNEXTITEM = (TV_FIRST + 10);
private const int TVM_GETITEM = (TV_FIRST + 12);
private const int TVM_ENSUREVISIBLE = (TV_FIRST + 20);
/// <summary>
/// Constants used to identity specific items in the Tree View control
/// </summary>
private const int TVGN_ROOT = 0x0;
private const int TVGN_NEXT = 0x1;
private const int TVGN_CHILD = 0x4;
private const int TVGN_FIRSTVISIBLE = 0x5;
private const int TVGN_NEXTVISIBLE = 0x6;
private const int TVGN_CARET = 0x9;
/// <summary>
/// Calling this method is identical to calling the ShowDialog method of the provided
/// FolderBrowserDialog, except that an attempt will be made to scroll the Tree View
/// to make the currently selected folder visible in the dialog window.
/// </summary>
/// <param name="dlg"></param>
/// <param name="parent"></param>
/// <returns></returns>
public static DialogResult ShowFolderBrowser( FolderBrowserDialog dlg, IWin32Window parent = null )
{
DialogResult result = DialogResult.Cancel;
int retries = 10;
using (Timer t = new Timer())
{
t.Tick += (s, a) =>
{
if (retries > 0)
{
--retries;
IntPtr hwndDlg = FindWindow((string)null, _topLevelSearchString);
if (hwndDlg != IntPtr.Zero)
{
IntPtr hwndFolderCtrl = GetDlgItem(hwndDlg, _dlgItemBrowseControl);
if (hwndFolderCtrl != IntPtr.Zero)
{
IntPtr hwndTV = GetDlgItem(hwndFolderCtrl, _dlgItemTreeView);
if (hwndTV != IntPtr.Zero)
{
IntPtr item = SendMessage(hwndTV, (uint)TVM_GETNEXTITEM, new IntPtr(TVGN_CARET), IntPtr.Zero);
if (item != IntPtr.Zero)
{
SendMessage(hwndTV, TVM_ENSUREVISIBLE, IntPtr.Zero, item);
retries = 0;
t.Stop();
}
}
}
}
}
else
{
//
// We failed to find the Tree View control.
//
// As a fall back (and this is an UberUgly hack), we will send
// some fake keystrokes to the application in an attempt to force
// the Tree View to scroll to the selected item.
//
t.Stop();
SendKeys.Send("{TAB}{TAB}{DOWN}{DOWN}{UP}{UP}");
}
};
t.Interval = 10;
t.Start();
result = dlg.ShowDialog( parent );
}
return result;
}
}
VB.Net 코드의 경우는, 다이얼로그를 표시하기 전에 이 코드의 행을 입력합니다.
SendKeys.Send ("{TAB}{TAB}{RIGHT}")
이 스레드가 오래된 것은 알지만 확장 메서드를 사용하면 FolderBrowserDialog에 추가할 수 있습니다.ShowDialog 메서드를 사용한 후 필요에 따라 반복하여 사용합니다.
샘플(아래)은 간단한 SendKeys 메서드만 사용하고 있습니다(이 방법은 별로 좋아하지 않지만, 이 경우에는 잘 작동합니다).SendKeys 메서드를 사용하여 대화 상자에서 선택한 폴더로 이동할 때 Visual Studio에서 디버깅하는 경우 SendKeys 호출이 현재 창(활성 VS 창)에 적용됩니다.잘못된 창에서 SendKeys 메시지가 수신되지 않도록 확장 방식에는 마크 F가 게시한 것과 유사한 메시지를 C#으로 변환하는 외부 메서드 호출이 포함됩니다.
internal static class FolderBrowserDialogExtension
{
public static DialogResult ShowDialog(this FolderBrowserDialog dialog, bool scrollIntoView)
{
return ShowDialog(dialog, null, scrollIntoView);
}
public static DialogResult ShowDialog(this FolderBrowserDialog dialog, IWin32Window owner, bool scrollIntoView)
{
if (scrollIntoView)
{
SendKeys.Send("{TAB}{TAB}{RIGHT}");
}
return dialog.ShowDialog(owner);
}
}
이거면 돼
folderBrowserDialog1.Reset();
folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
folderBrowserDialog1.SelectedPath = WorkingFolder;
하지만 대화 상자를 두 번째로 사용한 후에만
https://www.daniweb.com/software-development/csharp/threads/300578/folderbrowserdialog-expanding-the-selected-directory-의 회피책을 사용하고 있습니다.
FolderBrowserDialog^ oFBD = gcnew FolderBrowserDialog;
oFBD->RootFolder = Environment::SpecialFolder::MyComputer;
oFBD->SelectedPath = i_sPathImport;
oFBD->ShowNewFolderButton = false; // use if appropriate in your application
SendKeys::Send ("{TAB}{TAB}{RIGHT}"); // <<-- Workaround
::DialogResult oResult = oFBD->ShowDialog ();
가장 좋은 방법은 아니지만, 나한테는 효과가 있어.
★RootFolder
첫 번째 콜에서는 동작하지 않지만 두 번째 콜 이후에는 동작하지 않습니다.★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
다른 사람들은 이 장애가 운영 체제에 따라 다르다고 보고 있습니다.
7 x SP1 Windows 7 Pro x 64 SP1 을 .
나는 다음과 같은 것을 발견했다.
- if
.SelectedPath
\"로 끝나면 대화상자가 아래로 스크롤하여 경로를 표시합니다. - if
.SelectedPath
로 ."'이렇게 하다.경로는 선택되지만 표시는 보증되지 않습니다.
이치노브랫 외스트라이처 TreeView에서 .SHBrowseForFolder
상자를 열고 .TVM_ENSUREVISIBLE
에서는 과 같이 합니다다음은 C에서 이 작업을 수행합니다.
#include <windows.h>
#include <objbase.h>
#include <objidl.h>
#include <Shlobj.h>
#include <Dsclient.h>
#include <wchar.h>
//
// EnumCallback - Callback function for EnumWindows
//
static BOOL CALLBACK EnumCallback(HWND hWndChild, LPARAM lParam)
{
char szClass[MAX_PATH];
HTREEITEM hNode;
if (GetClassName(hWndChild, szClass, sizeof(szClass))
&& strcmp(szClass,"SysTreeView32")==0) {
hNode = TreeView_GetSelection(hWndChild); // found the tree view window
TreeView_EnsureVisible (hWndChild, hNode); // ensure its selection is visible
return(FALSE); // done; stop enumerating
}
return(TRUE); // continue enumerating
}
//
// BrowseCallbackProc - Callback function for SHBrowseForFolder
//
static INT CALLBACK BrowseCallbackProc (HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
switch (uMsg)
{
case BFFM_INITIALIZED:
SendMessage (hWnd, BFFM_SETEXPANDED, TRUE, lpData); // expand the tree view
SendMessage (hWnd, BFFM_SETSELECTION, TRUE, lpData); // select the item
break;
case BFFM_SELCHANGED:
EnumChildWindows(hWnd, EnumCallback,0);
break;
}
return 0;
}
//
// SelectDirectory - User callable entry point
//
int SelectDirectory (HWND hWndParent, char *path, int pathSize)
{
BROWSEINFO bi = {0};
LPITEMIDLIST pidl = NULL;
wchar_t ws[MAX_PATH];
CoInitialize(0);
if (pathSize < MAX_PATH) return(FALSE);
swprintf(ws, MAX_PATH, L"%hs", path);
bi.hwndOwner = hWndParent;
bi.lpszTitle = "Select Directory";
bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
bi.lpfn = BrowseCallbackProc;
bi.lParam = (LPARAM) ws;
pidl = SHBrowseForFolder (&bi);
if (pidl != NULL)
{
LPMALLOC pMalloc = NULL;
SHGetPathFromIDList (pidl, path);
path[pathSize-1]= '\0';
SHGetMalloc(&pMalloc);
pMalloc->lpVtbl->Free(pMalloc,pidl); // deallocate item
pMalloc->lpVtbl->Release(pMalloc);
return (TRUE);
}
return (FALSE);
}
c++ /mfc에서도 같은 문제가 발생하였습니다.BFPM_INITIALIZED 콜백에서 ::가 아닌 ::PostMessage를 사용하여 TVM_ENSUREVISIBLE 메시지를 배치했습니다.
case BFFM_INITIALIZED:
{
// select something
::SendMessage(m_hDialogBox, BFFM_SETSELECTION, TRUE, (LPARAM) pszSelection);
// find tree control
m_hTreeCtrl = 0;
HWND hchild = GetWindow(hWnd, GW_CHILD) ;
while (hchild != NULL)
{
VS_TChar classname[200] ;
GetClassName(hchild, classname, 200) ;
if (VS_strcmp(classname, _T("SHBrowseForFolder ShellNameSpace Control")) == 0)
{
HWND hlistctrl = GetWindow(hchild, GW_CHILD) ;
do
{
GetClassName(hlistctrl, classname, 200) ;
if (lstrcmp(classname, _T("SysTreeView32")) == 0)
{
m_hTreeCtrl = hlistctrl;
break ;
}
hlistctrl = GetWindow(hlistctrl, GW_HWNDNEXT) ;
} while (hlistctrl != NULL);
}
if (m_hTreeCtrl)
break;
hchild = GetWindow(hchild, GW_HWNDNEXT);
}
if (m_hTreeCtrl)
{
int item = ::SendMessage(m_hTreeCtrl, TVM_GETNEXTITEM, TVGN_CARET, 0);
if (item != 0)
::PostMessage(m_hTreeCtrl, TVM_ENSUREVISIBLE,0,item);
}
break;
}
적어도 가장 신뢰할 수 있는 최선의 방법은 자신만의 브라우저 클래스 대화 상자를 만드는 것입니다.트리 스크롤 문제는 오랫동안 골칫거리였습니다.결코 해결되지 않을 것입니다!
그림 그리는 법을 안다면 할 수 있는 일이 많지 않다.페인트칠이 빠르다는 것은 또 다른 이야기다.
가장 먼저 살펴봐야 할 곳은 오픈 소스입니다.의 GitHub의 넷소스 코드.개선할 대화 상자 클래스에 대한 선택 가능한 넷 버전입니다.당신은 약간의 노력으로 무엇을 성취할 수 있고 끝까지 해낼 수 있는지 놀랄지도 모른다.컨트롤과 디버깅을 에러가 발생하는 지점까지 복제하여 패치를 적용하기만 하면 됩니다.이것은 Microsoft도 할 수 있습니다.
오래된 스레드이기 때문에 게시 샘플을 읽을 수 없습니다.부탁하면 투고하는 게 더 나을 것 같아.
다만, 「예상」디렉토리로의 트리 스크롤등의 문제를 해결하려고 하는 유저에게는, 여기 확실한 어드바이스가 있습니다.컨트롤 또는 라이브러리에서 즉각적인 해결 방법이 없는 문제가 발생할 경우, 가능한 한 원본을 확장하고 문제에 패치를 적용하십시오.Windows에서 모든 것을 개선했습니다.Form. 예측 가능하고 정확한 결과를 얻기 위해 클래스를 Win32 라이브러리로 제어합니다.
좋은 소식은 C#에서는 거의 모든 합리적인 목표를 달성하기 위해 많은 낮은 수준의 제어가 가능하며 C도 마찬가지라는 것입니다.
과거에 저는 작동하지 않는 것을 재현하기만 하면 많은 시간이 절약될 수 있는 문제에 대한 해결책을 찾는데 너무 많은 시간을 소비했습니다.
SelectedPath와 RootFolder는 서로 배타적이기 때문에 RootFolder가 원인일 수 있다는 것을 다른 포럼에서 읽었습니다.즉, 둘 다 공존할 수 없고 기본 RootFolder()를 사용합니다.바탕화면)을 통해 최소한 트리(드라이브/폴더 탐색)를 오를 수 있습니다.
그러나 RootFolder가 데스크톱이 아닌 다른 것으로 변경되면 UNC 경로로 이동할 수 없습니다.
Hans Passant에 대한 답변: TextBox가 있는 이 Dialog Extension을 시도했지만 성공하지 못했습니다.
경로를 표시하기 위해 폴더 찾아보기 대화 상자 사용자 정의
VB로 계산해 봤는데NET을 사용하면 C#으로 쉽게 변환할 수 있습니다.저는 프랑스인이고 VB는 초보입니다.어쨌든, 제 해결책을 시도해 보세요.
하는 것은 ''을 '비동기식 작업'을 ' 작업'을 입니다.folderBrowserDialog
.
내가 직접 찾았는데 브래드 포스트에서 영감을 얻었어제 코드는 다음과 같습니다.
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, <MarshalAs(UnmanagedType.LPWStr)> ByVal lParam As String) As IntPtr
Public Declare Function FindWindowExW Lib "user32.dll" (ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr, <MarshalAs(UnmanagedType.LPWStr)> ByVal lpszClass As String, <MarshalAs(UnmanagedType.LPWStr)> 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
당신의 제안을 기다리고 있겠습니다.그리고 제가 C#을 모르기 때문에 C#로 번역해 주실 수 있습니다.
dlg폴더RootFolder = 환경.특수 폴더데스크톱 디렉토리
같지 않다
dlg폴더RootFolder = 환경.특수 폴더데스크톱
Special Folder의 차이점은 무엇입니까?데스크톱 및 특수 폴더.데스크톱 디렉토리?
연결된 스레드는 경로와 동일한 결과를 얻음을 나타냅니다.그러나 하나는 논리적 경로이고 다른 하나는 물리적 경로이기 때문에 이 둘은 같지 않습니다.
열려 있는 폴더 대화상자의 RootFolder에 둘 중 하나가 할당되면 결과 동작이 달라질 수 있습니다.
.RootFolder 할당으로 win7과 같은 일부 버전의 창에서는 두 창 중 하나를 "데스크탑"으로 처리합니다.즉, "컴퓨터" 하위 항목을 보고 이를 열어 개별 드라이브 문자를 볼 수 있습니다..SelectedPath는 어느 쪽이든 선택되지만 선택한 경로는 데스크톱의 논리 경로가 할당되었을 때만 표시됩니다.루트 폴더
게다가 win10 프리릴리스에서 폴더 찾아보기 대화상자를 사용하면 "데스크탑 디렉토리"는 데스크톱 디렉토리의 내용만으로 표시되며 논리 데스크톱 디렉토리에 대한 링크는 전혀 없습니다.그리고 그 아래에 어떤 하위 항목도 나열하지 않습니다.win7용 앱이 win10에서 사용하려고 하면 매우 답답합니다.
OP가 안고 있는 문제는 논리 데스크톱을 채용했어야 했는데 물리 데스크톱을 루트로 채용했다는 것입니다.
OP의 두 가지 다른 기계가 왜 다르게 반응하는지 설명할 수 없습니다.두 가지 버전이 있을 것으로 추측됩니다.NET 프레임워크가 설치되어 있습니다.
win10 프리릴리스에서 브라우즈 폴더 대화상자에 "데스크탑에 고정" 문제가 발생하는 것은 보다 최근의 이 원인일 수 있습니다.Win10 프리 릴리즈에 부속된 NET 프레임워크.유감스럽게도, 저는 아직 업데이트를 하지 않았기 때문에, 이 (win10) 케이스의 모든 사실을 모르고 있습니다.
추신: win8에서도 "데스크탑에 막힘" 현상이 발생한다는 것을 알게 되었습니다.
회피책은 win8에서 대체 GUI를 선택하는 것이었습니다.win10 프리 릴리즈에서도 같은 작업을 수행할 수 있습니다.
Marc F의 투고에 대한 답변 - 나는 VB를 전환했다.넷에서 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.
}
}
이것을 테스트해, 올바르게 동작.시스템을 참조해 주세요.런타임상호 운용 서비스, 시스템.스레드화, 시스템.스레드화임무들
에는 나에게이 되는 ).8.1
)
FolderBrowserDialog: 선택한 디렉터리 확장
언급URL : https://stackoverflow.com/questions/6942150/why-folderbrowserdialog-dialog-does-not-scroll-to-selected-folder
'IT이야기' 카테고리의 다른 글
컴파일러 경고 - 할당 주위에 진실 값으로 사용되는 괄호를 제안합니다. (0) | 2022.06.17 |
---|---|
c에서 64비트 정수를 지정하는 방법 (0) | 2022.06.17 |
구성 요소 페이지 Vue로 푸시할 때 재귀 발생 (0) | 2022.06.17 |
vue-cli 앱의 node_modules에서 js 파일 가져오기 (0) | 2022.06.17 |
C/C++에서 임의의 비트를 읽고 쓰는 방법 (0) | 2022.06.17 |