这个控件其实是 .NET 1.1 新增的一个控件,可以用来浏览文件夹。
对于 1.0 我写过一片文章来介绍如何做这样的一个控件 http://dev.csdn.net/Develop/article/21/article/17/17635.shtm

今天一个同事碰到了一个奇怪的问题,很简单的代码

FolderBrowserdialog 的奇怪问题FolderBrowserDialog dlg=new FolderBrowserDialog();
FolderBrowserdialog 的奇怪问题dlg.ShowDialog();
FolderBrowserdialog 的奇怪问题
FolderBrowserdialog 的奇怪问题

结果 文件夹选择窗体,显示不正确。结果如图所示
FolderBrowserdialog 的奇怪问题

这个问题,其实很容易修复。只要把你当前进程的Appartment State 设置为 STA 就可以了,或者给 Main 函数加上一个属性

FolderBrowserdialog 的奇怪问题[STAThread]
FolderBrowserdialog 的奇怪问题
public static void Main()
{
FolderBrowserdialog 的奇怪问题}

出现这个问题,主要是跟 FolderBrowserDialog 的实现有关系,这个.NET 控件其实是 win32 Shell Ole 控件的一个重新包装,你可以通过reflector看到具体的代码
FolderBrowserdialog 的奇怪问题protected override bool RunDialog(IntPtr hWndOwner)
{
FolderBrowserdialog 的奇怪问题      IntPtr ptr1 
= IntPtr.Zero;
FolderBrowserdialog 的奇怪问题      
bool flag1 = false;
FolderBrowserdialog 的奇怪问题      UnsafeNativeMethods.Shell32.SHGetSpecialFolderLocation(hWndOwner, (
intthis.rootFolder, ref ptr1);
FolderBrowserdialog 的奇怪问题      
if (ptr1 == IntPtr.Zero)
{
FolderBrowserdialog 的奇怪问题            UnsafeNativeMethods.Shell32.SHGetSpecialFolderLocation(hWndOwner, 
0ref ptr1);
FolderBrowserdialog 的奇怪问题            
if (ptr1 == IntPtr.Zero)
{
FolderBrowserdialog 的奇怪问题                  
throw new Exception(SR.GetString("FolderBrowserDialogNoRootFolder"));
FolderBrowserdialog 的奇怪问题            }

FolderBrowserdialog 的奇怪问题      }

FolderBrowserdialog 的奇怪问题      
int num1 = 0x40;
FolderBrowserdialog 的奇怪问题      
if (!this.showNewFolderButton)
{
FolderBrowserdialog 的奇怪问题            num1 
+= 0x200;
FolderBrowserdialog 的奇怪问题      }

FolderBrowserdialog 的奇怪问题      Application.OleRequired();
FolderBrowserdialog 的奇怪问题      IntPtr ptr2 
= IntPtr.Zero;
FolderBrowserdialog 的奇怪问题      
try
{
FolderBrowserdialog 的奇怪问题            UnsafeNativeMethods.BROWSEINFO browseinfo1 
= new UnsafeNativeMethods.BROWSEINFO();
FolderBrowserdialog 的奇怪问题            IntPtr ptr3 
= Marshal.AllocHGlobal((int) (260 * Marshal.SystemDefaultCharSize));
FolderBrowserdialog 的奇怪问题            IntPtr ptr4 
= Marshal.AllocHGlobal((int) (260 * Marshal.SystemDefaultCharSize));
FolderBrowserdialog 的奇怪问题            UnsafeNativeMethods.BrowseCallbackProc proc1 
= new UnsafeNativeMethods.BrowseCallbackProc(this.FolderBrowserDialog_BrowseCallbackProc);
FolderBrowserdialog 的奇怪问题            browseinfo1.pidlRoot 
= ptr1;
FolderBrowserdialog 的奇怪问题            browseinfo1.hwndOwner 
= hWndOwner;
FolderBrowserdialog 的奇怪问题            browseinfo1.pszDisplayName 
= ptr3;
FolderBrowserdialog 的奇怪问题            browseinfo1.lpszTitle 
= this.descriptionText;
FolderBrowserdialog 的奇怪问题            browseinfo1.ulFlags 
= num1;
FolderBrowserdialog 的奇怪问题            browseinfo1.lpfn 
= proc1;
FolderBrowserdialog 的奇怪问题            browseinfo1.lParam 
= IntPtr.Zero;
FolderBrowserdialog 的奇怪问题            browseinfo1.iImage 
= 0;
FolderBrowserdialog 的奇怪问题            ptr2 
= UnsafeNativeMethods.Shell32.SHBrowseForFolder(browseinfo1);
FolderBrowserdialog 的奇怪问题            
if (ptr2 != IntPtr.Zero)
{
FolderBrowserdialog 的奇怪问题                  UnsafeNativeMethods.Shell32.SHGetPathFromIDList(ptr2, ptr4);
FolderBrowserdialog 的奇怪问题                  
this.selectedPathNeedsCheck = true;
FolderBrowserdialog 的奇怪问题                  
this.selectedPath = Marshal.PtrToStringAuto(ptr4);
FolderBrowserdialog 的奇怪问题                  Marshal.FreeHGlobal(ptr4);
FolderBrowserdialog 的奇怪问题                  Marshal.FreeHGlobal(ptr3);
FolderBrowserdialog 的奇怪问题                  flag1 
= true;
FolderBrowserdialog 的奇怪问题            }

FolderBrowserdialog 的奇怪问题      }

FolderBrowserdialog 的奇怪问题      
finally
{
FolderBrowserdialog 的奇怪问题            UnsafeNativeMethods.IMalloc malloc1 
= FolderBrowserDialog.GetSHMalloc();
FolderBrowserdialog 的奇怪问题            malloc1.Free(ptr1);
FolderBrowserdialog 的奇怪问题            
if (ptr2 != IntPtr.Zero)
{
FolderBrowserdialog 的奇怪问题                  malloc1.Free(ptr2);
FolderBrowserdialog 的奇怪问题            }

FolderBrowserdialog 的奇怪问题      }

FolderBrowserdialog 的奇怪问题      
return flag1;
FolderBrowserdialog 的奇怪问题}

FolderBrowserdialog 的奇怪问题 
FolderBrowserdialog 的奇怪问题


而shell32 的申明如下:

FolderBrowserdialog 的奇怪问题[SuppressUnmanagedCodeSecurity, ComVisible(false)]
FolderBrowserdialog 的奇怪问题
internal class Shell32
{
FolderBrowserdialog 的奇怪问题      
// Methods
FolderBrowserdialog 的奇怪问题
      public Shell32();
FolderBrowserdialog 的奇怪问题      [DllImport(
"shell32.dll", CharSet=CharSet.Auto)]
FolderBrowserdialog 的奇怪问题      
public static extern IntPtr SHBrowseForFolder([In] UnsafeNativeMethods.BROWSEINFO lpbi);
FolderBrowserdialog 的奇怪问题      [DllImport(
"shell32.dll")]
FolderBrowserdialog 的奇怪问题      
public static extern int SHGetMalloc([Out, MarshalAs(UnmanagedType.LPArray)] UnsafeNativeMethods.IMalloc[] ppMalloc);
FolderBrowserdialog 的奇怪问题      [DllImport(
"shell32.dll", CharSet=CharSet.Auto)]
FolderBrowserdialog 的奇怪问题      
public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);
FolderBrowserdialog 的奇怪问题      [DllImport(
"shell32.dll")]
FolderBrowserdialog 的奇怪问题      
public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);
FolderBrowserdialog 的奇怪问题}

FolderBrowserdialog 的奇怪问题 
FolderBrowserdialog 的奇怪问题
FolderBrowserdialog 的奇怪问题 
FolderBrowserdialog 的奇怪问题

相关文章: