分享
 
 
 

.net环境中使用FolderBrowser

王朝c#·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

好久没有动手写东西了(其实以前什么也没写过;-)),今天要写的可能已经有哪位前辈完成了。拙作实在不敢拿出来现丑,高手看标题和上面的贴图就可以决定要不要看下去。不浪费大家时间。

客户的要求:有一个winform程序,用户要求可以自己选择数据文件存放的位置,简单点说就是在硬盘上选择一个目录。

最初的想法:Win32 SDK中有一个SHBrowseForFolder API,这也是平时使用最频繁的方法,既然用.net开发程序当然想尽量用.net framework提供的managed代码。

问题:查阅MSDN,发现FolderBrowser类与SHBrowseForFolder的一样的功能,但是帮助文件提示:FolderNameEditor.FolderBrowser 类型支持 .NET 框架结构,因此不适用于直接从代码中使用。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,反汇编以后差一点吐血。大家看看下面的就明白了。

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_00cc: 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;

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有