• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • .net環境中使用FolderBrowser

    發表于:2007-05-25來源:作者:點擊數: 標簽:好久.NET環境使用
    好久沒有動手寫東西了(其實以前什么也沒寫過;-)),今天要寫的可能已經有哪位前輩完成了。拙作實在不敢拿出來現丑,高手看標題和上面的貼圖就可以決定要不要看下去。不浪費大家時間。 客戶的要求 :有一個winform程序,用戶要求可以自己選擇數據文件存放的位

    好久沒有動手寫東西了(其實以前什么也沒寫過;-)),今天要寫的可能已經有哪位前輩完成了。拙作實在不敢拿出來現丑,高手看標題和上面的貼圖就可以決定要不要看下去。不浪費大家時間。

    客戶的要求:有一個winform程序,用戶要求可以自己選擇數據文件存放的位置,簡單點說就是在硬盤上選擇一個目錄。

    最初的想法: Win32 SDK中有一個SHBrowseForFolder API,這也是平時使用最頻繁的方法,既然用.net開發程序當然想盡量用.net framework提供的managed代碼。

    問題:  查閱MSDN,發現FolderBrowser類與SHBrowseForFolder的一樣的功能,但是幫助文件提示:FolderNameEditor.FolderBrowser 類型支持 .NET 框架結構,因此不適用于直接從代碼中使用?!?/FONT>ms似乎并不希望開發人員直接利用這個類,文檔中沒有關于這個類成員的任何說明。FolderBrowser類的申明如下:[C#]
    protected sealed class FolderNameEditor.FolderBrowser : Component 屬性是protected和sealed. 

    解決方法:FolderBrowser嵌套地定義在類FolderNameEditor中,還好ms沒有做絕把它也做成protected和sealed,這樣通過繼承FolderNameEditor,再在繼承類中實例化一個FolderBrowser類就可以調用這個對話框了。至于FolderBrowser的成員可以通過其它查看.net匯編的小工具獲得,推薦 使用lutz Roader's .net reflector,在下面的截圖可以看到FolderBrowser的所有成員。


    該類實際上只有一個方法ShowDialog,反匯編以后差一點吐血。大家看看下面的就明白了。

    Windows.Forms.Design.FolderNameEditor+FolderBrowser href="urn:object:0">FolderBrowser.ShowDialog

    .maxstack 3
    .locals (IntPtr V_0, IntPtr V_1, int V_2, IntPtr V_3, BROWSEINFO V_4, IntPtr V_5, IMalloc V_6, DialogResult V_7)
    .try L_0056 to L_00f0 finally L_00f0 to L_0115
    L_0000: ldsfld IntPtr.Zero
    L_0005: stloc.0
    L_0006: ldarg.1
    L_0007: brfalse.s L_0012
    L_0009: ldarg.1
    L_000a: callvirt IWin32Window.get_Handle
    L_000f: stloc.1
    L_0010: br.s L_0018
    L_0012: call UnsafeNativeMethods.GetActiveWindow
    L_0017: stloc.1
    L_0018: ldloc.1
    L_0019: ldarg.0
    L_001a: ldfld FolderBrowser.startLocation
    L_001f: ldloca.s V_0
    L_0021: call Shell32.SHGetSpecialFolderLocation
    L_0026: pop
    L_0027: ldloc.0
    L_0028: ldsfld IntPtr.Zero
    L_002d: call IntPtr.op_Equality
    L_0032: brfalse.s L_0036
    L_0034: ldc.i4.2
    L_0035: ret
    L_0036: ldarg.0
    L_0037: ldfld FolderBrowser.publicOptions
    L_003c: ldarg.0
    L_003d: ldfld FolderBrowser.privateOptions
    L_0042: or
    L_0043: stloc.2
    L_0044: ldloc.2
    L_0045: ldc.i4.s 64
    L_0047: and
    L_0048: brfalse.s L_0050
    L_004a: call Application.OleRequired
    L_004f: pop
    L_0050: ldsfld IntPtr.Zero
    L_0055: stloc.3
    L_0056: newobj BROWSEINFO..ctor
    L_005b: stloc.s V_4
    L_005d: ldsfld FolderBrowser.MAX_PATH
    L_0062: call Marshal.AllocHGlobal
    L_0067: stloc.s V_5
    L_0069: ldloc.s V_4
    L_006b: ldloc.0
    L_006c: stfld BROWSEINFO.pidlRoot
    L_0071: ldloc.s V_4
    L_0073: ldloc.1
    L_0074: stfld BROWSEINFO.hwndOwner
    L_0079: ldloc.s V_4
    L_007b: ldloc.s V_5
    L_007d: stfld BROWSEINFO.pszDisplayName
    L_0082: ldloc.s V_4
    L_0084: ldarg.0
    L_0085: ldfld FolderBrowser.descriptionText
    L_008a: stfld BROWSEINFO.lpszTitle
    L_008f: ldloc.s V_4
    L_0091: ldloc.2
    L_0092: stfld BROWSEINFO.ulFlags
    L_0097: ldloc.s V_4
    L_0099: ldsfld IntPtr.Zero
    L_009e: stfld BROWSEINFO.lpfn
    L_00a3: ldloc.s V_4
    L_00a5: ldsfld IntPtr.Zero
    L_00aa: stfld BROWSEINFO.lParam
    L_00af: ldloc.s V_4
    L_00b1: ldc.i4.0
    L_00b2: stfld BROWSEINFO.iImage
    L_00b7: ldloc.s V_4
    L_00b9: call Shell32.SHBrowseForFolder
    L_00be: stloc.3
    L_00bf: ldloc.3
    L_00c0: ldsfld IntPtr.Zero
    L_00c5: call IntPtr.op_Equality
    L_00ca: brfalse.s L_00d1
    L_00clearcase/" target="_blank" >cc: ldc.i4.2
    L_00cd: stloc.s V_7
    L_00cf: leave.s L_0117
    L_00d1: ldloc.3
    L_00d2: ldloc.s V_5
    L_00d4: call Shell32.SHGetPathFromIDList
    L_00d9: pop
    L_00da: ldarg.0
    L_00db: ldloc.s V_5
    L_00dd: call Marshal.PtrToStringAuto
    L_00e2: stfld FolderBrowser.directoryPath
    L_00e7: ldloc.s V_5
    L_00e9: call Marshal.FreeHGlobal
    L_00ee: leave.s L_0115
    L_00f0: call FolderBrowser.GetSHMalloc
    L_00f5: stloc.s V_6
    L_00f7: ldloc.s V_6
    L_00f9: ldloc.0
    L_00fa: callvirt IMalloc.Free
    L_00ff: ldloc.3
    L_0100: ldsfld IntPtr.Zero
    L_0105: call IntPtr.op_Inequality
    L_010a: brfalse.s L_0114
    L_010c: ldloc.s V_6
    L_010e: ldloc.3
    L_010f: callvirt IMalloc.Free
    L_0114: endfinally
    L_0115: ldc.i4.1
    L_0116: ret
    L_0117: ldloc.s V_7
    L_0119: ret
    費了那么多勁原來它自己也是通過interop調用SHBrowseForFolder,那還不如直接調用這個API。

    完整的FolderBrowser類

    using System;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Collections;
    namespace FolderBrowser 
    {
     /// <summary>
     /// Summary description for FolderBrowser.
     /// </summary>
     ///

     [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
     [ComVisible(true)]
     public class BROWSEINFO {
      public IntPtr hwndOwner;
      public IntPtr pidlRoot;
      public IntPtr pszDisplayName;
      public string lpszTitle;
      public int ulFlags;
      public IntPtr lpfn;
      public IntPtr lParam;
      public int iImage;
     }

     [Flags, Serializable]
     public enum BrowseFlags {
      BIF_DEFAULT    = 0x0000,

      BIF_BROWSEFORCOMPUTER = 0x1000,

      BIF_BROWSEFORPRINTER = 0x2000,

      BIF_BROWSEINCLUDEFILES = 0x4000,

      BIF_BROWSEINCLUDEURLS = 0x0080,

      BIF_DONTGOBELOWDOMAIN = 0x0002,

      BIF_EDITBOX    = 0x0010,

      BIF_NEWDIALOGSTYLE  = 0x0040,

      BIF_NONEWFOLDERBUTTON = 0x0200,

      /// </summary>
      BIF_RETURNFSANCESTORS = 0x0008,

      BIF_RETURNONLYFSDIRS = 0x0001,

      BIF_SHAREABLE   = 0x8000,

      BIF_STATUSTEXT   = 0x0004,

      BIF_UAHINT    = 0x0100,

      BIF_VALIDATE   = 0x0020,

      BIF_NOTRANSLATETARGETS = 0x0400,
     }

     


     public class API {
      [DllImport("shell32.dll", PreserveSig=true, CharSet=CharSet.Auto)]
      public static extern IntPtr SHBrowseForFolder(BROWSEINFO bi);

      [DllImport("shell32.dll", PreserveSig=true, CharSet=CharSet.Auto)]
      public static extern bool SHGetPathFromIDList(IntPtr pidl, IntPtr pszPath);

      [DllImport("shell32.dll", PreserveSig=true, CharSet=CharSet.Auto)]
      public static extern int SHGetSpecialFolderLocation(IntPtr hwnd, int csidl, ref IntPtr ppidl);
     }


     public class FolderBrowser
     {
      private string m_strDirectoryPath;
      private string m_strTitle;
      private string m_strDisplayName;
      private BrowseFlags m_Flags;
      public FolderBrowser()
      {
       //
       // TODO: Add constructor logic here
       //
       m_Flags = BrowseFlags.BIF_DEFAULT;
       m_strTitle = "";

      }

      public string DirectoryPath {
       get{return this.m_strDirectoryPath;}
      }


      public string DisplayName {
       get{return this.m_strDisplayName;}
      }


      public string Title {
       set{this.m_strTitle = value;}
      }


      public BrowseFlags Flags {
       set{this.m_Flags = value;}
      }
      public DialogResult ShowFolderBrowser() {
       
       BROWSEINFO bi = new BROWSEINFO();
       bi.pszDisplayName = IntPtr.Zero;
       bi.lpfn = IntPtr.Zero;
       bi.lParam = IntPtr.Zero;
       bi.lpszTitle = "Select Folder";
       IntPtr idListPtr = IntPtr.Zero;
       IntPtr pszPath = IntPtr.Zero;
       try {
        if (this.m_strTitle.Length != 0) {
         bi.lpszTitle = this.m_strTitle;
        }
        bi.ulFlags = (int)this.m_Flags;
        bi.pszDisplayName = Marshal.AllocHGlobal(256);
       
        idListPtr = API.SHBrowseForFolder(bi);
      
        if (idListPtr == IntPtr.Zero) {
         return DialogResult.Cancel;
        }

      
        pszPath = Marshal.AllocHGlobal(256);
      
        bool bRet = API.SHGetPathFromIDList(idListPtr, pszPath);
      
        m_strDirectoryPath = Marshal.PtrToStringAuto(pszPath);
        this.m_strDisplayName = Marshal.PtrToStringAuto(bi.pszDisplayName);
       }
       catch (Exception ex) {
        Trace.WriteLine(ex.Message);
        return DialogResult.Abort;
       }
       finally {
       
        if (idListPtr != IntPtr.Zero) {
         Marshal.FreeHGlobal(idListPtr);
        }
        if (pszPath != IntPtr.Zero) {
         Marshal.FreeHGlobal(pszPath);
        }
        if (bi != null) {
         Marshal.FreeHGlobal(bi.pszDisplayName);
        }
       }
       return DialogResult.OK;
             }
     }
    }

    如何調用這個類:

    FolderBrowser aFolderBrowser = new FolderBrowser();
       aFolderBrowser.Title = "Select a Folder";
       aFolderBrowser.Flags = BrowseFlags.BIF_NEWDIALOGSTYLE|BrowseFlags.BIF_EDITBOX|BrowseFlags.BIF_STATUSTEXT;
       DialogResult result = aFolderBrowser.ShowFolderBrowser();
       if (result == DialogResult.OK ) {
       textBox1.Text = aFolderBrowser.DirectoryPath;

    原文轉自:http://www.kjueaiud.com

    評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>