FolderBrowserdialog 的奇怪问题

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

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

None.gif FolderBrowserDialog dlg = new  FolderBrowserDialog();
None.gifdlg.ShowDialog();
None.gif
None.gif

结果 文件夹选择窗体,显示不正确。结果如图所示
folderbrowser.JPG

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

None.gif [STAThread]
None.gif
public   static   void  Main()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedBlockEnd.gif}

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

ExpandedSubBlockEnd.gif      }

InBlock.gif      
int num1 = 0x40;
InBlock.gif      
if (!this.showNewFolderButton)
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif            num1 
+= 0x200;
ExpandedSubBlockEnd.gif      }

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

ExpandedSubBlockEnd.gif      }

InBlock.gif      
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif      
dot.gif{
InBlock.gif            UnsafeNativeMethods.IMalloc malloc1 
= FolderBrowserDialog.GetSHMalloc();
InBlock.gif            malloc1.Free(ptr1);
InBlock.gif            
if (ptr2 != IntPtr.Zero)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                  malloc1.Free(ptr2);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif      }

InBlock.gif      
return flag1;
ExpandedBlockEnd.gif}

None.gif 
None.gif


而shell32 的申明如下:

None.gif [SuppressUnmanagedCodeSecurity, ComVisible( false )]
None.gif
internal   class  Shell32
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif      
// Methods
InBlock.gif
      public Shell32();
InBlock.gif      [DllImport(
"shell32.dll", CharSet=CharSet.Auto)]
InBlock.gif      
public static extern IntPtr SHBrowseForFolder([In] UnsafeNativeMethods.BROWSEINFO lpbi);
InBlock.gif      [DllImport(
"shell32.dll")]
InBlock.gif      
public static extern int SHGetMalloc([Out, MarshalAs(UnmanagedType.LPArray)] UnsafeNativeMethods.IMalloc[] ppMalloc);
InBlock.gif      [DllImport(
"shell32.dll", CharSet=CharSet.Auto)]
InBlock.gif      
public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);
InBlock.gif      [DllImport(
"shell32.dll")]
InBlock.gif      
public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);
ExpandedBlockEnd.gif}

None.gif 
None.gif
None.gif 
None.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值