Folderbrowser in .NET environment

zhaozj2021-02-17  56

I haven't been written for a long time (in fact, I didn't write anything ;-)), which may already have some seniors who have to write today. I don't dare to take out now ugly, the master can see the title and the above map can decide not to look. Do not waste everyone.

Customer Requirements: There is a WinForm program that can choose the location where the data file is stored. It is simple to say that you select a directory on the hard disk.

Original idea: There is a shbrowseforfolder API in Win32 SDK. This is also the most frequently used method usually using .NET developer, it is of course the managed code provided by .NET Framework.

Question: Check the MSDN, discover the same functionality as the SHBROWSer class, but help files prompt: FolderNameEditor.FolderBrowser type supports the .NET framework structure, so it does not apply to use directly from the code. MS does not seem to want the developer to directly take advantage of this class, there is no instructions on this class member in the document. The FolderBrowser class is as follows: [C #] protected ready, foldernameEditor.FolderBrowser: Component property is protected and sealed.

Workaround: FolderBrowser is defined in class FoldernameEditor, but the MS did not do it alone, which also made protected and Sealed, so by inheriting FoldernameEditor, then instantifying a FolderBrowser class in inheritance class. This dialog is called. . As for members of FolderBrowser, you can get all the members of the FolderBrowser, which you can use by other thanks to view .NET compilation, recommend Lutz Roader's .NET Reflector.

This class actually has only one method showdialog, and it will vomit a bit after the disassembly. Let's take a look at it below.

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_0115L_0000: ldsfld IntPtr.ZeroL_0005: stloc. 0 L_0006: ldarg.1 L_0007: brfalse.s L_0012L_0009: ldarg.1 L_000a: callvirt IWin32Window.get_HandleL_000f: stloc.1 L_0010: br.s L_0018L_0012: call UnsafeNativeMethods.GetActiveWindowL_0017: stloc.1 L_0018: ldloc.1 L_0019: ldarg. 0 L_001a: ldfld FolderBrowser.startLocationL_001f: ldloca.s V_0L_0021: call Shell32.SHGetSpecialFolderLocationL_0026: pop L_0027: ldloc.0 L_0028: ldsfld IntPtr.ZeroL_002d: call IntPtr.op_EqualityL_0032: brfalse.s L_0036L_0034: ldc.i4.2 L_0035: ret L_0036 : ldarg.0 L_0037: ldfld FolderBrowser.publicOptionsL_003c: ldarg.0 L_003d: ldfld FolderBrowser.privateOptionsL_0042: or L_0043: stloc.2 L_0044: ldloc.2 L_0045: ldc.i4.s 64L_0047: and L_0048: brfalse.s L_0050L_004a: call Application.olerequiredl_004f: ​​POP L_0050: ldsfld INTPTR.ZEROL_005 5: stloc.3 L_0056: newobj BROWSEINFO..ctorL_005b: stloc.s V_4L_005d: ldsfld FolderBrowser.MAX_PATHL_0062: call Marshal.AllocHGlobalL_0067: stloc.s V_5L_0069: ldloc.s V_4L_006b: ldloc.0 L_006c: stfld BROWSEINFO.pidlRootL_0071: ldloc. s V_4L_0073: ldloc.1 L_0074: stfld BROWSEINFO.hwndOwnerL_0079: ldloc.s V_4L_007b: ldloc.s V_5L_007d: stfld BROWSEINFO.pszDisplayNameL_0082: ldloc.s V_4L_0084: ldarg.0 L_0085: ldfld FolderBrowser.descriptionTextL_008a: stfld BROWSEINFO.lpszTitleL_008f: ldloc. s V_4L_0091: ldloc.2 L_0092: stfld BROWSEINFO.ulFlagsL_0097: ldloc.s V_4L_0099: ldsfld IntPtr.ZeroL_009e: stfld BROWSEINFO.lpfnL_00a3: ldloc.s V_4L_00a5: ldsfld IntPtr.ZeroL_00aa: stfld BROWSEINFO.lParamL_00af: ldloc.s V_4L_00b1: ldc. I4.0 L_00B2:

stfld BROWSEINFO.iImageL_00b7: ldloc.s V_4L_00b9: call Shell32.SHBrowseForFolderL_00be: stloc.3 L_00bf: ldloc.3 L_00c0: ldsfld IntPtr.ZeroL_00c5: call IntPtr.op_EqualityL_00ca: brfalse.s L_00d1L_00cc: ldc.i4.2 L_00cd: stloc.s V_7L_00cf: leave.s L_0117L_00d1: ldloc.3 L_00d2: ldloc.s V_5L_00d4: call Shell32.SHGetPathFromIDListL_00d9: pop L_00da: ldarg.0 L_00db: ldloc.s V_5L_00dd: call Marshal.PtrToStringAutoL_00e2: stfld FolderBrowser.directoryPathL_00e7: ldloc.s V_5L_00e9: call Marshal.FreeHGlobalL_00ee: leave.s L_0115L_00f0: call FolderBrowser.GetSHMallocL_00f5: stloc.s V_6L_00f7: ldloc.s V_6L_00f9: ldloc.0 L_00fa: callvirt IMalloc.FreeL_00ff: ldloc.3 L_0100: ldsfld IntPtr.ZeroL_0105: call IntPtr.op_InequalityL_010a: brfalse.s L_0114L_010c: ldloc.s V_6L_010e: ldloc.3 L_010f: callvirt IMalloc.FreeL_0114: endfinally L_0115: ldc.i4.1 L_0116: ret L_0117: ldloc.s V_7L_0119: ret spent so much effort had it myself by interop To call ShbrowseForfolder, it is better to call this API directly. Complete FolderBrowser class

using System; using System.Windows.Forms; using System.Diagnostics; using System.Runtime.InteropServices; using System.Collections; namespace FolderBrowser {///

/// Summary description for FolderBrowser /// ///

[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 PUBLIC 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,

/// 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 "; 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) {mathal.freehglobal (bi.pszdisplayname);}}}}} How to call this class:

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;

转载请注明原文地址:https://www.9cbs.com/read-28975.html

New Post(0)