📄 frmdirpicker.cs
字号:
//////////////////////////////////////////////////////////////////////
// General Purpose Dir/folder picker, 100% .NET, not relying on Internet Explorer's
// shell extensions.
//////////////////////////////////////////////////////////////////////
// COPYRIGHTS:
// Copyright (c)2002 Solutions Design. All rights reserved.
//
// Released under the following license: (BSD2)
// -------------------------------------------
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// 1) Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
// 2) Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials
// provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY SOLUTIONS DESIGN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOLUTIONS DESIGN OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The views and conclusions contained in the software and documentation are those of the authors
// and should not be interpreted as representing official policies, either expressed or implied,
// of Solutions Design.
//
//////////////////////////////////////////////////////////////////////
// Contributers to the code:
// - Frans Bouma [FB]
//////////////////////////////////////////////////////////////////////
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Management;
using System.IO;
using System.Runtime.InteropServices;
namespace LLBLGen
{
/// <summary>
/// Purpose: general purpose folder/dir picker.
/// </summary>
public class frmDirPicker : System.Windows.Forms.Form
{
#region Class Member Declarations
private System.Windows.Forms.Label lblDescription;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox tbxCurrentPath;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnOK;
private System.Windows.Forms.TreeView tvMain;
private System.ComponentModel.IContainer components;
private System.Windows.Forms.ImageList ilMain;
private bool m_bCancelClicked = false;
#endregion
// For extracting the icons from the Shell DLL, so we get native icons in every OS version.
// XP and up should use a manifest file.
[DllImport("Shell32.dll",EntryPoint="ExtractIconExW",CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern int ExtractIconEx(string sFile,int iIndex, out IntPtr piLargeVersion, out IntPtr piSmallVersion, int iAmountIcons);
public frmDirPicker()
{
IntPtr piLarge, piSmall;
Icon icExtracted;
InitializeComponent();
// Add the icons to the image list.
// Extract Normal folder
ExtractIconEx("Shell32.dll", 3, out piLarge,out piSmall, 1);
icExtracted= Icon.FromHandle(piSmall);
ilMain.Images.Add(icExtracted);
// Extract Open folder
ExtractIconEx("Shell32.dll", 4, out piLarge,out piSmall, 1);
icExtracted= Icon.FromHandle(piSmall);
ilMain.Images.Add(icExtracted);
// Extract A drive
ExtractIconEx("Shell32.dll", 6, out piLarge,out piSmall, 1);
icExtracted= Icon.FromHandle(piSmall);
ilMain.Images.Add(icExtracted);
// Extract Harddisk
ExtractIconEx("Shell32.dll", 8, out piLarge,out piSmall, 1);
icExtracted= Icon.FromHandle(piSmall);
ilMain.Images.Add(icExtracted);
// Extract Network drive
ExtractIconEx("Shell32.dll", 9, out piLarge,out piSmall, 1);
icExtracted= Icon.FromHandle(piSmall);
ilMain.Images.Add(icExtracted);
// Extract CDROM drive
ExtractIconEx("Shell32.dll", 11, out piLarge,out piSmall, 1);
icExtracted= Icon.FromHandle(piSmall);
ilMain.Images.Add(icExtracted);
InitTreeAndFillRoot();
}
/// <summary>
/// Purpose: Initializes the tree and fill the root node with the initial nodes.
/// </summary>
private void InitTreeAndFillRoot()
{
// Add all devices in this machine. Get them from WMI. See for
// detailed WMI information the WMI Platform SDK Documentation.
SelectQuery sqLogicalDrives = new SelectQuery ("SELECT * FROM Win32_LogicalDisk");
ManagementObjectSearcher mosSearcher = new ManagementObjectSearcher(sqLogicalDrives);
ManagementObjectCollection mocLogicalDrives = mosSearcher.Get();
tvMain.BeginUpdate();
foreach (ManagementObject moDrive in mocLogicalDrives)
{
// add a node. Select an image for the drive type.
TreeNode tnNode = tvMain.Nodes.Add(moDrive.Properties["DeviceID"].Value.ToString());
int iDriveType = int.Parse(moDrive.Properties["DriveType"].Value.ToString());
if(iDriveType < 2 || iDriveType > 5)
{
tnNode.ImageIndex = 0;
tnNode.SelectedImageIndex = 0;
}
else
{
tnNode.ImageIndex = iDriveType;
tnNode.SelectedImageIndex = iDriveType;
}
// add dummy node so the user can browse fast through the directories.
// add an empty string, a directory can't be an empty string.
TreeNode tnDummy = tnNode.Nodes.Add("");
}
tvMain.EndUpdate();
}
/// <summary>
/// Purpose: checks if the selected node has childs. if not, the 'directory' the node
/// represents is read and added as childnodes (1 node per directory entry).
/// Each node will have a dummy node, so the treeview will show a [+] for fast browsing.
/// This dummy node is removed with the first call to this routine.
/// </summary>
/// <param name="tvSelectedNode">The node selected by the user.</param>
private void GetSubDirectoryNodes(TreeNode tnSelectedNode)
{
try
{
this.Cursor = Cursors.AppStarting;
tvMain.BeginUpdate();
// first strip off dummy node IF it's present
if(tnSelectedNode.Nodes.Count == 1)
{
// check if it's the dummy
TreeNode tnChild = tnSelectedNode.Nodes[0];
if(tnChild.Text.Length==0)
{
// it's the dummy
tnSelectedNode.Nodes.Remove(tnChild);
}
}
if(tnSelectedNode.Nodes.Count <= 0)
{
// not expanded before. read subdirs
string sFullPath = tnSelectedNode.FullPath + @"\";
DirectoryInfo diCurrentDir = new DirectoryInfo(sFullPath);
foreach(DirectoryInfo diDirectory in diCurrentDir.GetDirectories())
{
// add new node to current node
TreeNode tnNode = tnSelectedNode.Nodes.Add(diDirectory.Name);
tnNode.ImageIndex = 0;
tnNode.SelectedImageIndex = 0;
FileAttributes faAttributes = diDirectory.Attributes;
// check the attributes, set foreground color.
if(((faAttributes & FileAttributes.System) > 0) || ((faAttributes & FileAttributes.Hidden) > 0))
{
tnNode.ForeColor = Color.Gray;
}
if((faAttributes & FileAttributes.Compressed)>0)
{
tnNode.ForeColor = Color.Blue;
}
// add dummy node to new node created
TreeNode tnDummy = tnNode.Nodes.Add("");
}
}
}
catch(Exception ex)
{
// View exception
frmException wExceptionViewer = new frmException(ex);
wExceptionViewer.ShowDialog();
}
finally
{
tvMain.EndUpdate();
this.Cursor = Cursors.Default;
}
}
/// <summary>
/// Purpose: when the property for the current path is set, this path should be reflected
/// in the tree visible. The complete path is searched in the tree, and per directory element in
/// the passed path, that directory is added to the tree.
/// </summary>
private void ReflectCurrentPathInTree()
{
TreeNode tnPrevious, tnCurrent;
string[] arrsDirsInCurrentPath = tbxCurrentPath.Text.Split('\\');
if(arrsDirsInCurrentPath.Length<=0)
{
// invalid split.
return;
}
tnCurrent = FindNodeInNodes(arrsDirsInCurrentPath[0],tvMain.Nodes);
if(tnCurrent==null)
{
// not found. directory path is nonexisting.
// select the first root node
tnCurrent = tvMain.Nodes[0];
}
for(int i = 1; i < arrsDirsInCurrentPath.Length;i++)
{
tnPrevious = tnCurrent;
// for this directory, first get all the subdirectories.
GetSubDirectoryNodes(tnCurrent);
// Get the node of the current directory.
tnCurrent = FindNodeInNodes(arrsDirsInCurrentPath[i], tnPrevious.Nodes);
if(tnCurrent!=null)
{
// found
tnCurrent.Expand();
}
else
{
// not valid. quit for loop
tnCurrent = tnPrevious;
break;
}
}
// select tnCurrent.
tvMain.SelectedNode = tnCurrent;
tnCurrent.EnsureVisible();
Application.DoEvents();
}
/// <summary>
/// Purpose: finds the node with the given sNodetext in the collection tncNodes. If found,
/// a reference to the nodeobject is returned, otherwise null is returned
/// </summary>
/// <param name="sNodeText">Labeltext of TreeNode to find</param>
/// <param name="tncNodes">Collection of TreeNode objects to search</param>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -