├── docs └── img │ ├── drive1.png │ ├── drive2.png │ ├── demo_win8.1.png │ ├── compress_bar.png │ └── compress_form.png ├── TotalCommander ├── 7za.exe ├── Resources │ ├── Up-16.png │ ├── Copy-16.png │ ├── Add_File1.png │ ├── Add_Folder.png │ ├── Details-50.png │ ├── Rename-16.png │ ├── info_icon.png │ ├── Edit File-16.png │ ├── refresh_icon.png │ ├── icon-view-pane.png │ ├── icon-view-pane1.png │ ├── Show_Password_24.png │ ├── document_tree_icon.png │ ├── ic_cancel_black_48dp.png │ ├── ic_close_black_48dp.png │ ├── ic_search_black_48dp.png │ ├── ic_archive_black_48dp.png │ ├── ic_refresh_black_48dp.png │ ├── ic_unarchive_black_48dp.png │ ├── ic_arrow_upward_black_48dp.png │ ├── ic_chevron_left_black_48dp.png │ └── ic_chevron_right_black_48dp.png ├── totalCommander.ico ├── App.config ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── ComboBoxItem.cs ├── Program.cs ├── GUI │ ├── HtmlBrowser.cs │ ├── FormNewFolder.cs │ ├── DisksBrowser.cs │ ├── HtmlBrowser.Designer.cs │ ├── ListViewExtensions.cs │ ├── FormNewFolder.Designer.cs │ ├── FileBrowser.cs │ ├── ShellBrowser.resx │ ├── ListViewColumnSorter.cs │ ├── ShellBrowser.Designer.cs │ ├── FormFindFiles.cs │ ├── FormFindFiles.Designer.cs │ ├── NavigationPane.cs │ ├── FormPacking.cs │ └── FormPacking.Designer.cs ├── ShellHistory.cs ├── app.manifest ├── Keyboards.html ├── ShellInfoItem.cs ├── PropertiesDialog.cs ├── ShellIcon.cs ├── Form_TotalCommander.cs └── TotalCommander.csproj ├── FileBrowser.sln ├── README.md └── .gitignore /docs/img/drive1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/docs/img/drive1.png -------------------------------------------------------------------------------- /docs/img/drive2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/docs/img/drive2.png -------------------------------------------------------------------------------- /TotalCommander/7za.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/7za.exe -------------------------------------------------------------------------------- /docs/img/demo_win8.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/docs/img/demo_win8.1.png -------------------------------------------------------------------------------- /docs/img/compress_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/docs/img/compress_bar.png -------------------------------------------------------------------------------- /docs/img/compress_form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/docs/img/compress_form.png -------------------------------------------------------------------------------- /TotalCommander/Resources/Up-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/Up-16.png -------------------------------------------------------------------------------- /TotalCommander/totalCommander.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/totalCommander.ico -------------------------------------------------------------------------------- /TotalCommander/Resources/Copy-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/Copy-16.png -------------------------------------------------------------------------------- /TotalCommander/Resources/Add_File1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/Add_File1.png -------------------------------------------------------------------------------- /TotalCommander/Resources/Add_Folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/Add_Folder.png -------------------------------------------------------------------------------- /TotalCommander/Resources/Details-50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/Details-50.png -------------------------------------------------------------------------------- /TotalCommander/Resources/Rename-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/Rename-16.png -------------------------------------------------------------------------------- /TotalCommander/Resources/info_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/info_icon.png -------------------------------------------------------------------------------- /TotalCommander/Resources/Edit File-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/Edit File-16.png -------------------------------------------------------------------------------- /TotalCommander/Resources/refresh_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/refresh_icon.png -------------------------------------------------------------------------------- /TotalCommander/Resources/icon-view-pane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/icon-view-pane.png -------------------------------------------------------------------------------- /TotalCommander/Resources/icon-view-pane1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/icon-view-pane1.png -------------------------------------------------------------------------------- /TotalCommander/Resources/Show_Password_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/Show_Password_24.png -------------------------------------------------------------------------------- /TotalCommander/Resources/document_tree_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/document_tree_icon.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_cancel_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_cancel_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_close_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_close_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_search_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_search_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_archive_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_archive_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_refresh_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_refresh_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_unarchive_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_unarchive_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_arrow_upward_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_arrow_upward_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_chevron_left_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_chevron_left_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/Resources/ic_chevron_right_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tesuji/FileBrowser/HEAD/TotalCommander/Resources/ic_chevron_right_black_48dp.png -------------------------------------------------------------------------------- /TotalCommander/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /TotalCommander/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /TotalCommander/ComboBoxItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TotalCommander 8 | { 9 | /// 10 | /// Represents an item in System.Windows.Forms.ComboBox 11 | /// 12 | public class ComboBoxItem 13 | { 14 | public string Text { get; set; } 15 | public object Value { get; set; } 16 | 17 | public override string ToString() 18 | { 19 | return Text; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /TotalCommander/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace TotalCommander 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Form_TotalCommander()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /TotalCommander/GUI/HtmlBrowser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | 11 | namespace TotalCommander.GUI 12 | { 13 | public partial class HtmlBrowser : Form 14 | { 15 | string FullPath = string.Empty; 16 | 17 | public HtmlBrowser() 18 | { 19 | InitializeComponent(); 20 | this.KeyPreview = true; 21 | this.StartPosition = FormStartPosition.CenterParent; 22 | btnOK.Click += (s, _) => 23 | { 24 | this.DialogResult = System.Windows.Forms.DialogResult.OK; 25 | }; 26 | } 27 | 28 | public HtmlBrowser(string path) 29 | : this() 30 | { 31 | FullPath = path; 32 | wbDisplay.Url = new Uri(FullPath); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /FileBrowser.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.13 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TotalCommander", "TotalCommander\TotalCommander.csproj", "{8B3B6A1D-2373-42BD-9216-5E6265E9BB83}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {8B3B6A1D-2373-42BD-9216-5E6265E9BB83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {8B3B6A1D-2373-42BD-9216-5E6265E9BB83}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {8B3B6A1D-2373-42BD-9216-5E6265E9BB83}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {8B3B6A1D-2373-42BD-9216-5E6265E9BB83}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /TotalCommander/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TotalCommander.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /TotalCommander/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Total Commander")] 9 | [assembly: AssemblyDescription("A file browser in Beta Version")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("15520599")] 12 | [assembly: AssemblyProduct("Total Commander")] 13 | [assembly: AssemblyCopyright("TranCaoPhap-MIT ® License")] 14 | [assembly: AssemblyTrademark("15520599-TranCaoPhap")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bb050ffe-1d64-4a44-ac59-3fb51d860aa4")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.9.1.1")] 36 | [assembly: AssemblyFileVersion("0.9.1.1")] 37 | -------------------------------------------------------------------------------- /TotalCommander/GUI/FormNewFolder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Windows.Forms; 5 | 6 | namespace TotalCommander.GUI 7 | { 8 | public partial class FormNewFolder : Form 9 | { 10 | public string NewName { get; set; } 11 | 12 | public FormNewFolder() 13 | { 14 | NewName = string.Empty; 15 | this.StartPosition = FormStartPosition.CenterParent; 16 | InitializeComponent(); 17 | this.MinimizeBox = false; 18 | this.MaximizeBox = false; 19 | this.FormBorderStyle = FormBorderStyle.FixedDialog; 20 | this.ShowInTaskbar = false; 21 | } 22 | 23 | public void Init() 24 | { 25 | if (!String.IsNullOrWhiteSpace(NewName)) 26 | { 27 | txtNewName.Text = NewName; 28 | txtNewName.SelectionStart = 0; 29 | txtNewName.SelectionLength = NewName.Length; 30 | NewName = string.Empty; 31 | } 32 | 33 | txtNewName.KeyDown += txtNewName_KeyDown; 34 | btnOK.Click += btnOK_Click; 35 | btnCancel.Click += btnCancel_Click; 36 | } 37 | 38 | void btnCancel_Click(object sender, EventArgs e) 39 | { 40 | this.Close(); 41 | } 42 | 43 | void btnOK_Click(object sender, EventArgs e) 44 | { 45 | NewName = txtNewName.Text; 46 | if (String.IsNullOrEmpty(NewName)) 47 | { 48 | this.Close(); 49 | } 50 | else 51 | this.DialogResult = System.Windows.Forms.DialogResult.OK; 52 | } 53 | 54 | void txtNewName_KeyDown(object sender, KeyEventArgs e) 55 | { 56 | if (e.KeyData == Keys.Enter) 57 | { 58 | btnOK_Click(sender, EventArgs.Empty); 59 | } 60 | } 61 | 62 | 63 | 64 | 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /TotalCommander/ShellHistory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace TotalCommander 8 | { 9 | /// 10 | /// The history of the shell explorer 11 | /// 12 | public class ShellHistory 13 | { 14 | #region Local variables 15 | 16 | private List m_History; 17 | private int m_Current; 18 | 19 | #endregion 20 | 21 | internal ShellHistory() 22 | { 23 | m_Current = -1; 24 | m_History = new List(); 25 | } 26 | 27 | /// 28 | /// Clears the history. 29 | /// 30 | public void Clear() 31 | { 32 | if (m_History.Count > 0) 33 | { 34 | m_Current = -1; 35 | m_History.Clear(); 36 | } 37 | 38 | } 39 | 40 | internal void Add(string folder) 41 | { 42 | int count = m_History.Count - m_Current - 1; 43 | if (count > 0) 44 | { 45 | m_History.RemoveRange(m_Current + 1, count); 46 | } 47 | //while (_Current < _History.Count - 1) 48 | //{ 49 | // _History.RemoveAt(_Current + 1); 50 | //} 51 | 52 | m_History.Add(folder); 53 | m_Current = m_History.Count - 1; 54 | } 55 | 56 | internal string MoveBackward() 57 | { 58 | if (m_Current < 0) 59 | { 60 | throw new InvalidOperationException("Cannot navigate back"); 61 | } 62 | m_Current -= 1; 63 | return m_History[m_Current]; 64 | } 65 | 66 | internal string MoveForward() 67 | { 68 | if (m_Current == m_History.Count - 1) 69 | { 70 | throw new InvalidOperationException("Cannot navigate forward"); 71 | } 72 | m_Current += 1; 73 | return m_History[m_Current]; 74 | } 75 | 76 | internal bool CanNavigateBack 77 | { 78 | get { return m_Current > 0; } 79 | } 80 | 81 | internal bool CanNavigateForward 82 | { 83 | get { return m_Current != m_History.Count - 1; } 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /TotalCommander/GUI/DisksBrowser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Windows.Forms; 8 | 9 | namespace TotalCommander.GUI 10 | { 11 | public class DisksBrowser : ComboBox 12 | { 13 | public DisksBrowser() 14 | { 15 | this.DrawMode = DrawMode.OwnerDrawFixed; 16 | this.DrawItem += DrawDrivesImage; 17 | this.DropDownStyle = ComboBoxStyle.DropDownList; 18 | } 19 | 20 | public void Init() 21 | { 22 | this.Items.Clear(); 23 | AddDisks(); 24 | } 25 | 26 | private void AddDisks() 27 | { 28 | DriveInfo[] allDrives = DriveInfo.GetDrives().Where(d => d.IsReady).ToArray(); 29 | ComboBoxItem[] arrCbi = new ComboBoxItem[allDrives.Length]; 30 | for (int i = 0; i < allDrives.Length; i++) 31 | { 32 | arrCbi[i] = new ComboBoxItem(); 33 | arrCbi[i].Text = allDrives[i].Name; 34 | arrCbi[i].Value = allDrives[i]; 35 | } 36 | this.BeginUpdate(); 37 | this.Items.AddRange(arrCbi); 38 | this.EndUpdate(); 39 | } 40 | 41 | /// 42 | /// Updates disks when inserting new device or removing it. 43 | /// 44 | /// 45 | /// Returns a Boolean value indicates that the browsing disk is exists. 46 | /// 47 | public bool UpdateDisks() 48 | { 49 | string oldDisk = this.SelectedItem.ToString(); 50 | this.Items.Clear(); 51 | AddDisks(); 52 | 53 | bool oldDiskExists = false; 54 | for (int i = 0; i < this.Items.Count; i++) 55 | { 56 | if (this.Items[i].ToString().Equals(oldDisk, StringComparison.OrdinalIgnoreCase)) 57 | { 58 | oldDiskExists = true; 59 | this.SelectedIndex = i; 60 | } 61 | } 62 | return oldDiskExists; 63 | } 64 | 65 | private void DrawDrivesImage(object sender, DrawItemEventArgs e) 66 | { 67 | if (e.Index == -1) 68 | return; 69 | 70 | e.DrawBackground(); 71 | string path = this.Items[e.Index].ToString(); 72 | Icon icon = ShellIcon.GetIcon(path); 73 | e.Graphics.DrawIcon(icon, 3, e.Bounds.Top); 74 | e.Graphics.DrawString(path, this.Font, Brushes.Black, icon.Width + 2, e.Bounds.Top); 75 | e.DrawFocusRectangle(); 76 | } 77 | 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /TotalCommander/app.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /TotalCommander/Keyboards.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Keyboard shortcuts 6 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 |
KeyAction
F1 / Ctrl+CCopy selected items
F2Rename selected items
F3View selected files
F4Edit selected items
F5Refresh file browser.
F6 / Ctrl+XMove selected items
F7 / Ctrl+Shift+NCreate new folder
F8Delete selected items
Ctrl+VPaste files or folders.
Ctrl+QExit the application.
Alt+EnterOpen properties dialog for selected items.
Ctrl+FSearch for files and folders.
Alt+Go to parent folder
Backspace / Alt+Go to previous folder.
Alt+Go to the following folder.
EnterOpen file or folder.
DeleteSend files or folders to Recycle bin
Shift+DeletePermanently remove files or folders.
113 | 114 | -------------------------------------------------------------------------------- /TotalCommander/GUI/HtmlBrowser.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TotalCommander.GUI 2 | { 3 | partial class HtmlBrowser 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(HtmlBrowser)); 32 | this.wbDisplay = new System.Windows.Forms.WebBrowser(); 33 | this.btnOK = new System.Windows.Forms.Button(); 34 | this.SuspendLayout(); 35 | // 36 | // wbDisplay 37 | // 38 | this.wbDisplay.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 39 | | System.Windows.Forms.AnchorStyles.Left) 40 | | System.Windows.Forms.AnchorStyles.Right))); 41 | this.wbDisplay.Location = new System.Drawing.Point(4, 4); 42 | this.wbDisplay.MinimumSize = new System.Drawing.Size(23, 23); 43 | this.wbDisplay.Name = "wbDisplay"; 44 | this.wbDisplay.Size = new System.Drawing.Size(779, 507); 45 | this.wbDisplay.TabIndex = 0; 46 | // 47 | // btnOK 48 | // 49 | this.btnOK.Anchor = System.Windows.Forms.AnchorStyles.Bottom; 50 | this.btnOK.Location = new System.Drawing.Point(345, 517); 51 | this.btnOK.Name = "btnOK"; 52 | this.btnOK.Size = new System.Drawing.Size(87, 27); 53 | this.btnOK.TabIndex = 1; 54 | this.btnOK.Text = "OK"; 55 | this.btnOK.UseVisualStyleBackColor = true; 56 | // 57 | // HtmlBrowser 58 | // 59 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 60 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 61 | this.ClientSize = new System.Drawing.Size(784, 562); 62 | this.Controls.Add(this.btnOK); 63 | this.Controls.Add(this.wbDisplay); 64 | this.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 65 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 66 | this.Name = "HtmlBrowser"; 67 | this.Text = "HtmlBrowser"; 68 | this.ResumeLayout(false); 69 | 70 | } 71 | 72 | #endregion 73 | 74 | private System.Windows.Forms.WebBrowser wbDisplay; 75 | private System.Windows.Forms.Button btnOK; 76 | } 77 | } -------------------------------------------------------------------------------- /TotalCommander/GUI/ListViewExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel; 3 | using System.Runtime.InteropServices; 4 | using System.Windows.Forms; 5 | 6 | /// 7 | [EditorBrowsable(EditorBrowsableState.Never)] 8 | public static class ListViewExtensions 9 | { 10 | [StructLayout(LayoutKind.Sequential)] 11 | public struct HDITEM 12 | { 13 | public Mask mask; 14 | public int cxy; 15 | [MarshalAs(UnmanagedType.LPTStr)] 16 | public string pszText; 17 | public IntPtr hbm; 18 | public int cchTextMax; 19 | public Format fmt; 20 | public IntPtr lParam; 21 | // _WIN32_IE >= 0x0300 22 | public int iImage; 23 | public int iOrder; 24 | // _WIN32_IE >= 0x0500 25 | public uint type; 26 | public IntPtr pvFilter; 27 | // _WIN32_WINNT >= 0x0600 28 | public uint state; 29 | 30 | [Flags] 31 | public enum Mask 32 | { 33 | Format = 0x4, // HDI_FORMAT 34 | }; 35 | 36 | [Flags] 37 | public enum Format 38 | { 39 | SortDown = 0x200, // HDF_SORTDOWN 40 | SortUp = 0x400, // HDF_SORTUP 41 | }; 42 | }; 43 | 44 | public const int LVM_FIRST = 0x1000; 45 | public const int LVM_GETHEADER = LVM_FIRST + 31; 46 | 47 | public const int HDM_FIRST = 0x1200; 48 | public const int HDM_GETITEM = HDM_FIRST + 11; 49 | public const int HDM_SETITEM = HDM_FIRST + 12; 50 | 51 | [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 52 | public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam); 53 | 54 | [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 55 | public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 msg, IntPtr wParam, ref HDITEM lParam); 56 | 57 | public static void SetSortIcon(this ListView listViewControl, int columnIndex, SortOrder order) 58 | { 59 | IntPtr columnHeader = SendMessage(listViewControl.Handle, LVM_GETHEADER, IntPtr.Zero, IntPtr.Zero); 60 | for (int columnNumber = 0; columnNumber <= listViewControl.Columns.Count - 1; columnNumber++) 61 | { 62 | var columnPtr = new IntPtr(columnNumber); 63 | var item = new HDITEM 64 | { 65 | mask = HDITEM.Mask.Format 66 | }; 67 | 68 | if (SendMessage(columnHeader, HDM_GETITEM, columnPtr, ref item) == IntPtr.Zero) 69 | { 70 | throw new Win32Exception(); 71 | } 72 | 73 | if (order != SortOrder.None && columnNumber == columnIndex) 74 | { 75 | switch (order) 76 | { 77 | case SortOrder.Ascending: 78 | item.fmt &= ~HDITEM.Format.SortDown; 79 | item.fmt |= HDITEM.Format.SortUp; 80 | break; 81 | case SortOrder.Descending: 82 | item.fmt &= ~HDITEM.Format.SortUp; 83 | item.fmt |= HDITEM.Format.SortDown; 84 | break; 85 | } 86 | } 87 | else 88 | { 89 | item.fmt &= ~HDITEM.Format.SortDown & ~HDITEM.Format.SortUp; 90 | } 91 | 92 | if (SendMessage(columnHeader, HDM_SETITEM, columnPtr, ref item) == IntPtr.Zero) 93 | { 94 | throw new Win32Exception(); 95 | } 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FileBrowser 2 | 3 | A faked Total Commander in C# 4 | 5 | ### Features 6 | 7 | #### Support basic keyboard shortcuts on folder and file 8 | 9 | Function (Shortcut) | How to implement 10 | --------------------| ---------------- 11 | Copy (Ctrl+C) | Use Clipboard to create file list that needed to copy. In cut, use additional flag CanCut in order to delete file after Cut. 12 | Move (Ctrl+X) | Like above 13 | Paste (Ctrl+V) | Paste file and folder from list in Clipboard to target folder 14 | Delete (Delete or Shift+Delete) (Many file and folder) | Use `Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile` and `FileSystem.DeleteDirectory` to delete file and display familiar delete-file-prompt message box 15 | Rename (F2) (Many file and folder) | Set `LabelEdit` attritube of `ListView` and implement handler for `AfterLabelEdit` event 16 | Find (Ctrl+F) | Use seperate `FormFileFinds` form to search for files, where using `DirectoryInfo.GetFiles` and `DirectoryInfo.GetDirectories` 17 | View in detail or in list | Set `View.Details` or `View.List` 18 | Sort file in column | Implement handler for `ColumnClick` event with comparers such as `CompareFileName`, `CompareFileExtension`, `CompareFileSize`, etc 19 | Use `VirtualListView` for faster display | Set `VirtualMode = true`, handlers for `CacheVirtualItems`, `RetrieveVirtualItem`, `SearchForVirtualItem` 20 | Support Drop\&Drag | Implement handlers for `DragEnter`, `DragDrop`, `ItemDrag` 21 | Support file browser history | In `ShellHistory` class 22 | 23 | #### Clean user interface (UI) with 2 interactive windows 24 | 25 | In fact, each window is a `UserControl`, mostly including other controls like `ListView`, `TextBox`, `ComboBox`, `TreeView`. 26 | 27 | ![In Windows 8.1](docs/img/demo_win8.1.png) 28 | 29 | #### Browse in many local drives 30 | 31 | ![In sidepane](docs/img/drive1.png) 32 | ![In combobox](docs/img/drive2.png) 33 | 34 | #### Menu context and shortcuts to interact with file and folder 35 | 36 | Key | Action 37 | --- | ------ 38 | F1 / Ctrl+C | Copy selected items 39 | F2 | Rename selected items 40 | F3 | View selected files 41 | F4 | Edit selected items 42 | F5 | Refresh file browser. 43 | F6 / Ctrl+X | Move selected items 44 | F7 / Ctrl+Shift+N | Create new folder 45 | F8 | Delete selected items 46 | Ctrl+V | Paste files or folders. 47 | Ctrl+Q | Exit the application. 48 | Alt+Enter | Open properties dialog for selected items. 49 | Ctrl+F | Search for files and folders. 50 | Alt+ | Go to parent folder 51 | Backspace / Alt+ | Go to previous folder. 52 | Alt+ | Go to the following folder. 53 | Enter | Open file or folder. 54 | Delete | Send files or folders to Recycle bin 55 | Shift+Delete | Permanently remove files or folders. 56 | 57 | #### Edit, Run file directly with supported system formats such as MS Word, `.exe` 58 | 59 | #### Compress file and folder 60 | 61 | ![In menu bar](docs/img/compress_bar.png) 62 | ![In seperate form](docs/img/compress_form.png) 63 | 64 | ### TODO 65 | 66 | - [ ] Add handler for menu bar 67 | - [ ] Test suits 68 | - [ ] Add Travis CI build tests 69 | - [x] Beautify [Keyboards.html](TotalCommander/Keyboards.html) 70 | 71 | ### Meta 72 | 73 | - Written by @lzutao 74 | - Release under [GPLv3 License](LICENSE) 75 | - Software is as is - no warranty expressed or implied. 76 | -------------------------------------------------------------------------------- /TotalCommander/GUI/FormNewFolder.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TotalCommander.GUI 2 | { 3 | partial class FormNewFolder 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormNewFolder)); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.txtNewName = new System.Windows.Forms.TextBox(); 34 | this.btnOK = new System.Windows.Forms.Button(); 35 | this.btnCancel = new System.Windows.Forms.Button(); 36 | this.SuspendLayout(); 37 | // 38 | // label1 39 | // 40 | this.label1.AutoSize = true; 41 | this.label1.Location = new System.Drawing.Point(0, 0); 42 | this.label1.Name = "label1"; 43 | this.label1.Size = new System.Drawing.Size(121, 13); 44 | this.label1.TabIndex = 0; 45 | this.label1.Text = "New folder (directory):"; 46 | // 47 | // txtNewName 48 | // 49 | this.txtNewName.Location = new System.Drawing.Point(0, 22); 50 | this.txtNewName.Name = "txtNewName"; 51 | this.txtNewName.Size = new System.Drawing.Size(395, 22); 52 | this.txtNewName.TabIndex = 1; 53 | // 54 | // btnOK 55 | // 56 | this.btnOK.Location = new System.Drawing.Point(227, 48); 57 | this.btnOK.Name = "btnOK"; 58 | this.btnOK.Size = new System.Drawing.Size(75, 23); 59 | this.btnOK.TabIndex = 2; 60 | this.btnOK.Text = "OK"; 61 | this.btnOK.UseVisualStyleBackColor = true; 62 | // 63 | // btnCancel 64 | // 65 | this.btnCancel.Location = new System.Drawing.Point(308, 48); 66 | this.btnCancel.Name = "btnCancel"; 67 | this.btnCancel.Size = new System.Drawing.Size(75, 23); 68 | this.btnCancel.TabIndex = 3; 69 | this.btnCancel.Text = "Cancel"; 70 | this.btnCancel.UseVisualStyleBackColor = true; 71 | // 72 | // Form_NewFolder 73 | // 74 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 75 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 76 | this.ClientSize = new System.Drawing.Size(394, 77); 77 | this.Controls.Add(this.btnCancel); 78 | this.Controls.Add(this.btnOK); 79 | this.Controls.Add(this.txtNewName); 80 | this.Controls.Add(this.label1); 81 | this.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 82 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 83 | this.KeyPreview = true; 84 | this.Name = "Form_NewFolder"; 85 | this.Text = "Total Commander"; 86 | this.ResumeLayout(false); 87 | this.PerformLayout(); 88 | 89 | } 90 | 91 | #endregion 92 | 93 | private System.Windows.Forms.Label label1; 94 | private System.Windows.Forms.TextBox txtNewName; 95 | private System.Windows.Forms.Button btnOK; 96 | private System.Windows.Forms.Button btnCancel; 97 | } 98 | } -------------------------------------------------------------------------------- /TotalCommander/ShellInfoItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace TotalCommander 8 | { 9 | public sealed class ShellInfoItem 10 | { 11 | public string FileName { get; private set; } 12 | public string Ext { get; private set; } 13 | public string SizeFile { get; private set; } 14 | public string Date { get; private set; } 15 | public string Attr { get; private set; } 16 | 17 | #region Constructors 18 | public ShellInfoItem(FileInfo info): this((FileSystemInfo)info) { } 19 | 20 | public ShellInfoItem(DirectoryInfo info) : this((FileSystemInfo)info) { } 21 | 22 | public ShellInfoItem(FileSystemInfo info) 23 | { 24 | FileName = info.Name; 25 | Date = GetFavoriteDateString(info.CreationTime); 26 | Attr = GetFileAttributesString(info.Attributes); 27 | if (info.Attributes.HasFlag(FileAttributes.Directory)) 28 | { 29 | Ext = string.Empty; 30 | SizeFile = ""; 31 | } 32 | else 33 | { 34 | Ext = info.Extension; 35 | SizeFile = GetBytesReadable(((FileInfo)info).Length); 36 | } 37 | } 38 | #endregion Constructors 39 | 40 | public string[] ToArray() 41 | { 42 | string[] result = new string[] { 43 | FileName, 44 | Ext.Replace(".", "").ToLower(), /* No period */ 45 | SizeFile, 46 | Date, 47 | Attr }; 48 | return result; 49 | } 50 | 51 | #region Gets favorite results 52 | /// 53 | /// Returns the favorite time for an arbitrary file. 54 | /// Example: 23/03/2017 21:11:11 to 23/03/2017 21:11 55 | /// 56 | internal static string GetFavoriteDateString(DateTime myDateTime) 57 | { 58 | return myDateTime.ToString("dd/MM/yyyy hh:mm"); 59 | } 60 | /// 61 | /// Returns the human-readable file size for an arbitrary, 64-bit file size 62 | /// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB" 63 | /// 64 | internal static string GetBytesReadable(long i) 65 | { 66 | // Get absolute value 67 | long absolute_i = (i < 0 ? -i : i); 68 | // Determine the suffix and readable value 69 | string suffix; 70 | double readable; 71 | if (absolute_i >= 0x40000000) // Gigabyte 72 | { 73 | suffix = " GB"; 74 | readable = (i >> 20); 75 | } 76 | else if (absolute_i >= 0x100000) // Megabyte 77 | { 78 | suffix = " MB"; 79 | readable = (i >> 10); 80 | } 81 | else if (absolute_i >= 0x400) // Kilobyte 82 | { 83 | suffix = " KB"; 84 | readable = i; 85 | } 86 | else 87 | { 88 | return i.ToString("0 B"); // Byte 89 | } 90 | // Divide by 1024 to get fractional value 91 | readable = readable / 1024; 92 | // Return formatted number with suffix 93 | return readable.ToString("0.##") + suffix; 94 | } 95 | 96 | /// 97 | /// Returns the short format string file attribute 98 | /// 99 | internal static string GetFileAttributesString(FileAttributes fa) 100 | { 101 | string attr = string.Empty; 102 | if (fa.HasFlag(FileAttributes.ReadOnly)) attr += "r"; 103 | else attr += "-"; 104 | if (fa.HasFlag(FileAttributes.Archive)) attr += "a"; 105 | else attr += "-"; 106 | if (fa.HasFlag(FileAttributes.Hidden)) attr += "h"; 107 | else attr += "-"; 108 | if (fa.HasFlag(FileAttributes.System)) attr += "s"; 109 | else attr += "-"; 110 | return attr; 111 | } 112 | 113 | #endregion Gets favorite results 114 | 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /TotalCommander/GUI/FileBrowser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace TotalCommander.GUI 5 | { 6 | internal class FileBrowser : ListView 7 | { 8 | #region Fields 9 | //private ListViewColumnSorter m_ColumnSorter = new ListViewColumnSorter(); 10 | #endregion Fields 11 | 12 | #region Overrided functions 13 | 14 | protected override bool IsInputKey(Keys keyData) 15 | { 16 | switch (keyData) 17 | { 18 | case Keys.Right: 19 | case Keys.Left: 20 | case Keys.Up: 21 | case Keys.Down: 22 | return true; 23 | } 24 | return base.IsInputKey(keyData); 25 | } 26 | 27 | #region Cannot use ListViewItemSorter in virtual mode 28 | //protected override void OnColumnClick(ColumnClickEventArgs e) 29 | //{ 30 | // // Determine if clicked column is already the column that is being sorted. 31 | // if (e.Column == SortColumn) 32 | // { 33 | // // Reverse the current sort direction for this column. 34 | // if (Order == SortOrder.Ascending) 35 | // Order = SortOrder.Descending; 36 | // else 37 | // Order = SortOrder.Ascending; 38 | // } 39 | // else 40 | // { 41 | // // Set the column number that is to be sorted; default to ascending. 42 | // SortColumn = e.Column; 43 | // Order = SortOrder.Ascending; 44 | // } 45 | // // set the sort arrow to a particular column 46 | // this.SetSortIcon(e.Column, Order); 47 | // // Perform the sort with these new sort options. 48 | // //this.Sort(); 49 | // //this.ListViewItemSorter = m_ColumnSorter; 50 | // base.OnColumnClick(e); 51 | //} 52 | #endregion 53 | 54 | protected override void OnKeyDown(KeyEventArgs e) 55 | { 56 | switch (e.KeyData) 57 | { 58 | case Keys.Control | Keys.A: 59 | for (int i = 0; i < this.VirtualListSize; i++) 60 | { 61 | this.SelectedIndices.Add(i); 62 | } 63 | break; 64 | } 65 | base.OnKeyDown(e); 66 | } 67 | 68 | #endregion Overrided functions 69 | 70 | internal void Init() 71 | { 72 | this.HideSelection = false; 73 | this.MultiSelect = true; 74 | this.AllowDrop = true; 75 | this.ShowGroups = false; 76 | this.FullRowSelect = true; 77 | this.LabelEdit = true; 78 | this.DoubleBuffered = true; 79 | 80 | DefineColumn(); 81 | this.SetSortIcon(0, SortOrder.Ascending); 82 | 83 | this.Resize += FileBrowser_Resize; 84 | } 85 | 86 | private void DefineColumn() 87 | { 88 | this.View = View.Details; 89 | this.HeaderStyle = ColumnHeaderStyle.Clickable; 90 | this.Columns.Add("Name"); // 0 91 | this.Columns.Add("Ext", 40); // 1 92 | this.Columns.Add("Size", 60); // 2 93 | this.Columns.Add("Date", 100); // 3 94 | this.Columns.Add("Attr", 35); // 4 95 | int tmp = this.Width - 235; 96 | this.Columns[0].Width = (tmp > 60) ? tmp : 60; 97 | } 98 | 99 | public void ChangeViewMode(View view) 100 | { 101 | if (this.View == view) return; 102 | switch (view) 103 | { 104 | case View.List: 105 | this.HeaderStyle = ColumnHeaderStyle.None; 106 | this.Columns.Clear(); 107 | this.View = View.List; 108 | break; 109 | case View.Details: 110 | DefineColumn(); 111 | break; 112 | } 113 | } 114 | 115 | /// 116 | /// Sets to Name columns be the longest column 117 | /// 118 | void FileBrowser_Resize(object sender, EventArgs e) 119 | { 120 | if (this.View == View.Details) 121 | { 122 | int total = 0; 123 | for (int i = 1; i < 5; i++) 124 | { 125 | total += this.Columns[i].Width; 126 | } 127 | int tmp = this.Width - total; 128 | this.Columns[0].Width = (tmp > 60) ? tmp : 60; 129 | } 130 | } 131 | 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /TotalCommander/PropertiesDialog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.Specialized; 4 | using System.IO; 5 | using System.Runtime.InteropServices; 6 | using System.Windows.Forms; 7 | 8 | namespace TotalCommander 9 | { 10 | /// 11 | public static class PropertiesDialog 12 | { 13 | 14 | [DllImport("shell32.dll", CharSet = CharSet.Auto)] 15 | static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo); 16 | 17 | [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 18 | public struct SHELLEXECUTEINFO 19 | { 20 | public int cbSize; 21 | public uint fMask; 22 | public IntPtr hwnd; 23 | [MarshalAs(UnmanagedType.LPTStr)] 24 | public string lpVerb; 25 | [MarshalAs(UnmanagedType.LPTStr)] 26 | public string lpFile; 27 | [MarshalAs(UnmanagedType.LPTStr)] 28 | public string lpParameters; 29 | [MarshalAs(UnmanagedType.LPTStr)] 30 | public string lpDirectory; 31 | public int nShow; 32 | public IntPtr hInstApp; 33 | public IntPtr lpIDList; 34 | [MarshalAs(UnmanagedType.LPTStr)] 35 | public string lpClass; 36 | public IntPtr hkeyClass; 37 | public uint dwHotKey; 38 | public IntPtr hIcon; 39 | public IntPtr hProcess; 40 | } 41 | private const int SW_SHOW = 5; 42 | private const uint SEE_MASK_INVOKEIDLIST = 12; 43 | 44 | #region Import Methods 45 | 46 | [DllImport("shell32.dll", SetLastError = true)] 47 | static extern int SHMultiFileProperties(System.Windows.Forms.IDataObject pdtobj, int flags); 48 | 49 | [DllImport("shell32.dll", CharSet = CharSet.Auto)] 50 | public static extern IntPtr ILCreateFromPath(string path); 51 | 52 | [DllImport("shell32.dll", CharSet = CharSet.None)] 53 | public static extern void ILFree(IntPtr pidl); 54 | 55 | [DllImport("shell32.dll", CharSet = CharSet.None)] 56 | public static extern int ILGetSize(IntPtr pidl); 57 | 58 | #endregion 59 | 60 | #region Static Methods 61 | 62 | #region Private 63 | 64 | private static MemoryStream CreateShellIDList(StringCollection filenames) 65 | { 66 | // first convert all files into pidls list 67 | int pos = 0; 68 | byte[][] pidls = new byte[filenames.Count][]; 69 | foreach (var filename in filenames) 70 | { 71 | // Get pidl based on name 72 | IntPtr pidl = ILCreateFromPath(filename); 73 | int pidlSize = ILGetSize(pidl); 74 | // Copy over to our managed array 75 | pidls[pos] = new byte[pidlSize]; 76 | Marshal.Copy(pidl, pidls[pos++], 0, pidlSize); 77 | ILFree(pidl); 78 | } 79 | 80 | // Determine where in CIDL we will start pumping PIDLs 81 | int pidlOffset = 4 * (filenames.Count + 2); 82 | // Start the CIDL stream 83 | var memStream = new MemoryStream(); 84 | var sw = new BinaryWriter(memStream); 85 | // Initialize CIDL witha count of files 86 | sw.Write(filenames.Count); 87 | // Calcualte and write relative offsets of every pidl starting with root 88 | sw.Write(pidlOffset); 89 | pidlOffset += 4; // root is 4 bytes 90 | foreach (var pidl in pidls) 91 | { 92 | sw.Write(pidlOffset); 93 | pidlOffset += pidl.Length; 94 | } 95 | 96 | // Write the root pidl (0) followed by all pidls 97 | sw.Write(0); 98 | foreach (var pidl in pidls) sw.Write(pidl); 99 | // stream now contains the CIDL 100 | return memStream; 101 | } 102 | 103 | #endregion 104 | 105 | #region Public 106 | 107 | /// 108 | /// Opens a file properties dialog from windows explorer 109 | /// 110 | public static int Show(IEnumerable Filenames) 111 | { 112 | StringCollection Files = new StringCollection(); 113 | foreach (string s in Filenames) Files.Add(s); 114 | var data = new DataObject(); 115 | data.SetFileDropList(Files); 116 | data.SetData("Preferred DropEffect", true, new MemoryStream(new byte[] { 5, 0, 0, 0 })); 117 | data.SetData("Shell IDList Array", true, CreateShellIDList(Files)); 118 | return SHMultiFileProperties(data, 0); 119 | } 120 | 121 | /// 122 | /// Opens a file properties dialog from windows explorer 123 | /// 124 | public static int Show(string[] Filenames) 125 | { 126 | return Show(Filenames as IEnumerable); 127 | } 128 | 129 | /// 130 | /// Opens a file properties dialog from windows explorer 131 | /// 132 | public static bool Show(string fileName) 133 | { 134 | SHELLEXECUTEINFO info = new SHELLEXECUTEINFO(); 135 | info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info); 136 | info.lpVerb = "properties"; 137 | info.lpFile = fileName; 138 | info.nShow = SW_SHOW; 139 | info.fMask = SEE_MASK_INVOKEIDLIST; 140 | return ShellExecuteEx(ref info); 141 | } 142 | #endregion 143 | #endregion 144 | } 145 | } 146 | 147 | -------------------------------------------------------------------------------- /TotalCommander/GUI/ShellBrowser.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | -------------------------------------------------------------------------------- /TotalCommander/GUI/ListViewColumnSorter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Windows.Forms; 4 | 5 | namespace TotalCommander.GUI 6 | { 7 | /// 8 | /// This class is an implementation of the 'IComparer' interface. 9 | /// 10 | public class ListViewColumnSorter : IComparer 11 | { 12 | #region Fields 13 | /// 14 | /// Specifies the column to be sorted 15 | /// 16 | private int ColumnToSort; 17 | /// 18 | /// Specifies the order in which to sort (i.e. 'Ascending'). 19 | /// 20 | private SortOrder OrderOfSort; 21 | /// 22 | /// Case insensitive comparer object 23 | /// 24 | private CaseInsensitiveComparer ObjectCompare; 25 | #endregion 26 | 27 | /// 28 | /// Class constructor. Initializes various elements 29 | /// 30 | public ListViewColumnSorter() 31 | { 32 | // Initialize the column to '0' 33 | ColumnToSort = 0; 34 | 35 | // Initialize the sort order to 'none' 36 | OrderOfSort = SortOrder.None; 37 | 38 | // Initialize the CaseInsensitiveComparer object 39 | ObjectCompare = new CaseInsensitiveComparer(); 40 | } 41 | 42 | /// 43 | /// This method is inherited from the IComparer interface. It compares the two objects passed using a case insensitive comparison. 44 | /// 45 | /// First object to be compared 46 | /// Second object to be compared 47 | /// The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y' 48 | public int Compare(object x, object y) 49 | { 50 | int result = 1; 51 | string firstItem = ((ListViewItem)x).SubItems[ColumnToSort].Text; 52 | string secondItem = ((ListViewItem)y).SubItems[ColumnToSort].Text; 53 | switch (ColumnToSort) 54 | { 55 | case 0: // name column 56 | string size1 = ((ListViewItem)x).SubItems[2].Text; 57 | string size2 = ((ListViewItem)y).SubItems[2].Text; 58 | int flag = (IsFolder(size1) ? 1 : 0) + (IsFolder(size2) ? 2 : 0); 59 | switch (flag) 60 | { 61 | // Neither item is a folder => Compare names 62 | case 0: goto case 3; break; 63 | // A is a folder, but B isn't => A < B 64 | case 1: result = -1; break; 65 | // B is a folder, but A isn't => A > B 66 | case 2: result = 1; break; 67 | // Both items are folders => Compare names 68 | case 3: result = firstItem.CompareTo(secondItem); break; 69 | // Failsafe 70 | default: 71 | result = 0; 72 | break; 73 | } 74 | break; 75 | case 2: // size column 76 | // Both items have the same size or are folders 77 | if (String.Equals(firstItem, secondItem)) 78 | result = 0; 79 | // A is a folder, but B isn't => A < B 80 | else if (IsFolder(firstItem)) 81 | result = -1; 82 | // B is a folder, but A isn't => A > B 83 | else if (IsFolder(secondItem)) 84 | result = 1; 85 | // Both items are files with different sizes 86 | else 87 | { 88 | string[] firstSize = firstItem.Split(); 89 | string[] secondSize = secondItem.Split(); 90 | long firstByte = GetTotalBytes(firstSize[0], firstSize[1]); 91 | long secondByte = GetTotalBytes(secondSize[0], secondSize[1]); 92 | result = firstByte.CompareTo(secondByte); 93 | } 94 | break; 95 | case 3: // date column 96 | DateTime firstDate, secondDate; 97 | bool canConvert1 = DateTime.TryParse(firstItem, out firstDate); 98 | bool canConvert2 = DateTime.TryParse(secondItem, out secondDate); 99 | if (canConvert1 && canConvert2) 100 | { 101 | // Compare the two dates. 102 | result = firstDate.CompareTo(secondDate); 103 | } 104 | break; 105 | default: // other columns, compares as string 106 | result = firstItem.CompareTo(secondItem); 107 | break; 108 | } 109 | // Determine whether the sort order is descending. 110 | return (OrderOfSort == SortOrder.Descending) ? -result : result; 111 | } 112 | 113 | private bool IsFolder(string size) 114 | { 115 | return String.Equals("", size); 116 | } 117 | 118 | private long GetTotalBytes(string number, string suffix) 119 | { 120 | long result = 0; 121 | if (suffix == "B") 122 | { 123 | long.TryParse(number, out result); 124 | } 125 | else 126 | { 127 | double readable; 128 | if (double.TryParse(number, out readable)) 129 | { 130 | readable *= 1024; 131 | result = Convert.ToInt64(readable); 132 | if (suffix == "MB") 133 | { 134 | result = (result << 10); 135 | } 136 | else if (suffix == "GB") 137 | { 138 | result = (result << 20); 139 | } 140 | } 141 | } 142 | return result; 143 | } 144 | 145 | #region Properties 146 | /// 147 | /// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0'). 148 | /// 149 | public int SortColumn 150 | { 151 | set { ColumnToSort = value; } 152 | get { return ColumnToSort; } 153 | } 154 | 155 | /// 156 | /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending'). 157 | /// 158 | public SortOrder Order 159 | { 160 | set { OrderOfSort = value; } 161 | get { return OrderOfSort; } 162 | } 163 | #endregion 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /TotalCommander/ShellIcon.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Drawing; 3 | using System.Runtime.InteropServices; 4 | 5 | namespace TotalCommander 6 | { 7 | public class ShellIcon 8 | { 9 | #region Interop constants 10 | 11 | private static readonly uint FILE_ATTRIBUTE_NORMAL = 0x80; 12 | private static readonly uint FILE_ATTRIBUTE_DIRECTORY = 0x10; 13 | 14 | #endregion 15 | 16 | #region Interop data types 17 | 18 | [StructLayout(LayoutKind.Sequential)] 19 | private struct SHFILEINFO 20 | { 21 | public IntPtr hIcon; 22 | public IntPtr iIcon; 23 | public uint dwAttributes; 24 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 25 | public string szDisplayName; 26 | [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] 27 | public string szTypeName; 28 | } 29 | 30 | 31 | [Flags] 32 | public enum SHGFI : int 33 | { 34 | /// get icon 35 | Icon = 0x000000100, 36 | /// get display name 37 | DisplayName = 0x000000200, 38 | /// get type name 39 | TypeName = 0x000000400, 40 | /// get attributes 41 | Attributes = 0x000000800, 42 | /// get icon location 43 | IconLocation = 0x000001000, 44 | /// return exe type 45 | ExeType = 0x000002000, 46 | /// get system icon index 47 | SysIconIndex = 0x000004000, 48 | /// put a link overlay on icon 49 | LinkOverlay = 0x000008000, 50 | /// show icon in selected state 51 | Selected = 0x000010000, 52 | /// get only specified attributes 53 | Attr_Specified = 0x000020000, 54 | /// get large icon 55 | LargeIcon = 0x000000000, 56 | /// get small icon 57 | SmallIcon = 0x000000001, 58 | /// get open icon 59 | OpenIcon = 0x000000002, 60 | /// get shell size icon 61 | ShellIconSize = 0x000000004, 62 | /// pszPath is a pidl 63 | PIDL = 0x000000008, 64 | /// use passed dwFileAttribute 65 | UseFileAttributes = 0x000000010, 66 | /// apply the appropriate overlays 67 | AddOverlays = 0x000000020, 68 | /// Get the index of the overlay in the upper 8 bits of the iIcon 69 | OverlayIndex = 0x000000040, 70 | } 71 | 72 | #endregion 73 | 74 | private class Win32 75 | { 76 | [DllImport("shell32.dll")] 77 | public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags); 78 | 79 | /// 80 | /// Calls the Win32 API function DestroyIcon to release resources 81 | /// from Icon.FromHandle(IntPtr handle) 82 | /// 83 | /// Control handle of the icon 84 | [DllImport("user32.dll", CharSet = CharSet.Auto)] 85 | public static extern bool DestroyIcon(IntPtr handle); 86 | 87 | /// 88 | /// Creates an array of handles to large or small icons extracted 89 | /// from the specified executable file, DLL, or icon file. 90 | /// 91 | /// 92 | /// If the function succeeds, the return value is the handle to an icon. 93 | /// If the file specified was not an executable file, DLL, or icon file, 94 | /// the return value is 1. If no icons were found in the file, 95 | /// the return value is NULL. 96 | /// 97 | [DllImport("shell32.dll", EntryPoint = "ExtractIconExW", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 98 | public static extern int ExtractIconEx(string lpszFile, int nIconIndex, out IntPtr phiconLarge, out IntPtr phiconSmall, int nIcons); 99 | 100 | } 101 | 102 | /// 103 | /// Extracts icons from a DLL with known index of the image in the DLL 104 | /// 105 | /// NULL if icon not found 106 | public static Icon GetIconFromIndex(string file, int index) 107 | { 108 | IntPtr large; 109 | IntPtr small; 110 | Win32.ExtractIconEx(file, index, out large, out small, 1); 111 | Icon icon = null; 112 | if (small != IntPtr.Zero) 113 | { 114 | icon = (Icon)Icon.FromHandle(small).Clone(); 115 | Win32.DestroyIcon(large); 116 | Win32.DestroyIcon(small); 117 | } 118 | return icon; 119 | } 120 | 121 | /// 122 | /// Gets icon from file path 123 | /// 124 | /// Returns null if icon not found 125 | public static Icon GetIcon(string fileName) 126 | { 127 | return GetSmallIcon(fileName); 128 | } 129 | 130 | public static Icon GetIcon(string fileName, SHGFI flags, bool isFolder = false) 131 | { 132 | SHFILEINFO shinfo = new SHFILEINFO(); 133 | IntPtr hImgSmall = Win32.SHGetFileInfo( 134 | fileName, isFolder ? FILE_ATTRIBUTE_DIRECTORY : FILE_ATTRIBUTE_NORMAL, 135 | ref shinfo, (uint)Marshal.SizeOf(shinfo), (uint)(SHGFI.Icon | flags)); 136 | Icon icon = null; 137 | if (shinfo.hIcon != IntPtr.Zero) 138 | { 139 | icon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone(); 140 | Win32.DestroyIcon(shinfo.hIcon); 141 | } 142 | return icon; 143 | } 144 | 145 | public static Icon GetSmallFolderIcon() 146 | { 147 | return GetIcon("folder", SHGFI.SmallIcon | SHGFI.UseFileAttributes, true); 148 | } 149 | 150 | public static Icon GetLargeFolderIcon() 151 | { 152 | return GetIcon("folder", SHGFI.LargeIcon | SHGFI.UseFileAttributes, true); 153 | } 154 | 155 | public static Icon GetSmallIcon(string fileName) 156 | { 157 | return GetIcon(fileName, SHGFI.SmallIcon); 158 | } 159 | 160 | public static Icon GetLargeIcon(string fileName) 161 | { 162 | return GetIcon(fileName, SHGFI.LargeIcon); 163 | } 164 | 165 | /// 166 | /// Get small icon from specific file extension 167 | /// 168 | /// File extension such as '.exe', '.doc' 169 | public static Icon GetSmallIconFromExtension(string extension) 170 | { 171 | return GetIcon(extension, SHGFI.SmallIcon | SHGFI.UseFileAttributes); 172 | } 173 | 174 | /// 175 | /// Get large icon from specific file extension 176 | /// 177 | /// File extension such as '.exe', '.doc' 178 | public static Icon GetLargeIconFromExtension(string extension) 179 | { 180 | return GetIcon(extension, SHGFI.LargeIcon | SHGFI.UseFileAttributes); 181 | } 182 | } 183 | } -------------------------------------------------------------------------------- /TotalCommander/GUI/ShellBrowser.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TotalCommander.GUI 2 | { 3 | partial class ShellBrowser 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.lblBotStatus = new System.Windows.Forms.Label(); 32 | this.lblTopStorageStatus = new System.Windows.Forms.Label(); 33 | this.disksBrowser = new TotalCommander.GUI.DisksBrowser(); 34 | this.splMainView = new System.Windows.Forms.SplitContainer(); 35 | this.navigationPane = new TotalCommander.GUI.NavigationPane(); 36 | this.browser = new TotalCommander.GUI.FileBrowser(); 37 | this.txtPath = new System.Windows.Forms.TextBox(); 38 | ((System.ComponentModel.ISupportInitialize)(this.splMainView)).BeginInit(); 39 | this.splMainView.Panel1.SuspendLayout(); 40 | this.splMainView.Panel2.SuspendLayout(); 41 | this.splMainView.SuspendLayout(); 42 | this.SuspendLayout(); 43 | // 44 | // lblBotStatus 45 | // 46 | this.lblBotStatus.AutoSize = true; 47 | this.lblBotStatus.Dock = System.Windows.Forms.DockStyle.Bottom; 48 | this.lblBotStatus.Location = new System.Drawing.Point(0, 570); 49 | this.lblBotStatus.Name = "lblBotStatus"; 50 | this.lblBotStatus.Size = new System.Drawing.Size(82, 15); 51 | this.lblBotStatus.TabIndex = 22; 52 | this.lblBotStatus.Text = "Bottom Status"; 53 | // 54 | // lblTopStorageStatus 55 | // 56 | this.lblTopStorageStatus.AutoSize = true; 57 | this.lblTopStorageStatus.Location = new System.Drawing.Point(60, 6); 58 | this.lblTopStorageStatus.Name = "lblTopStorageStatus"; 59 | this.lblTopStorageStatus.Size = new System.Drawing.Size(79, 15); 60 | this.lblTopStorageStatus.TabIndex = 21; 61 | this.lblTopStorageStatus.Text = "StorageStatus"; 62 | this.lblTopStorageStatus.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 63 | // 64 | // disksBrowser 65 | // 66 | this.disksBrowser.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; 67 | this.disksBrowser.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 68 | this.disksBrowser.FormattingEnabled = true; 69 | this.disksBrowser.Location = new System.Drawing.Point(0, 0); 70 | this.disksBrowser.Name = "disksBrowser"; 71 | this.disksBrowser.Size = new System.Drawing.Size(60, 24); 72 | this.disksBrowser.TabIndex = 6; 73 | this.disksBrowser.TabStop = false; 74 | // 75 | // splMainView 76 | // 77 | this.splMainView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 78 | | System.Windows.Forms.AnchorStyles.Left) 79 | | System.Windows.Forms.AnchorStyles.Right))); 80 | this.splMainView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 81 | this.splMainView.FixedPanel = System.Windows.Forms.FixedPanel.Panel1; 82 | this.splMainView.Location = new System.Drawing.Point(0, 46); 83 | this.splMainView.Name = "splMainView"; 84 | // 85 | // splMainView.Panel1 86 | // 87 | this.splMainView.Panel1.Controls.Add(this.navigationPane); 88 | // 89 | // splMainView.Panel2 90 | // 91 | this.splMainView.Panel2.Controls.Add(this.browser); 92 | this.splMainView.Size = new System.Drawing.Size(524, 518); 93 | this.splMainView.SplitterDistance = 173; 94 | this.splMainView.SplitterWidth = 3; 95 | this.splMainView.TabIndex = 23; 96 | this.splMainView.TabStop = false; 97 | // 98 | // navigationPane 99 | // 100 | this.navigationPane.BorderStyle = System.Windows.Forms.BorderStyle.None; 101 | this.navigationPane.Dock = System.Windows.Forms.DockStyle.Fill; 102 | this.navigationPane.Location = new System.Drawing.Point(0, 0); 103 | this.navigationPane.Name = "navigationPane"; 104 | this.navigationPane.Size = new System.Drawing.Size(171, 516); 105 | this.navigationPane.TabIndex = 0; 106 | this.navigationPane.TabStop = false; 107 | // 108 | // browser 109 | // 110 | this.browser.BorderStyle = System.Windows.Forms.BorderStyle.None; 111 | this.browser.Dock = System.Windows.Forms.DockStyle.Fill; 112 | this.browser.Location = new System.Drawing.Point(0, 0); 113 | this.browser.Name = "browser"; 114 | this.browser.Size = new System.Drawing.Size(346, 516); 115 | this.browser.TabIndex = 0; 116 | this.browser.UseCompatibleStateImageBehavior = false; 117 | // 118 | // txtPath 119 | // 120 | this.txtPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 121 | | System.Windows.Forms.AnchorStyles.Right))); 122 | this.txtPath.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest; 123 | this.txtPath.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.FileSystemDirectories; 124 | this.txtPath.ImeMode = System.Windows.Forms.ImeMode.NoControl; 125 | this.txtPath.Location = new System.Drawing.Point(0, 23); 126 | this.txtPath.Name = "txtPath"; 127 | this.txtPath.Size = new System.Drawing.Size(524, 23); 128 | this.txtPath.TabIndex = 24; 129 | this.txtPath.TabStop = false; 130 | // 131 | // ShellBrowser 132 | // 133 | this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); 134 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; 135 | this.Controls.Add(this.txtPath); 136 | this.Controls.Add(this.splMainView); 137 | this.Controls.Add(this.lblBotStatus); 138 | this.Controls.Add(this.disksBrowser); 139 | this.Controls.Add(this.lblTopStorageStatus); 140 | this.DoubleBuffered = true; 141 | this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 142 | this.Name = "ShellBrowser"; 143 | this.Size = new System.Drawing.Size(524, 585); 144 | this.splMainView.Panel1.ResumeLayout(false); 145 | this.splMainView.Panel2.ResumeLayout(false); 146 | ((System.ComponentModel.ISupportInitialize)(this.splMainView)).EndInit(); 147 | this.splMainView.ResumeLayout(false); 148 | this.ResumeLayout(false); 149 | this.PerformLayout(); 150 | 151 | } 152 | 153 | #endregion 154 | 155 | private TotalCommander.GUI.DisksBrowser disksBrowser; 156 | private System.Windows.Forms.Label lblTopStorageStatus; 157 | private System.Windows.Forms.Label lblBotStatus; 158 | private FileBrowser browser; 159 | private System.Windows.Forms.SplitContainer splMainView; 160 | private NavigationPane navigationPane; 161 | private System.Windows.Forms.TextBox txtPath; 162 | 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /TotalCommander/Form_TotalCommander.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.IO; 5 | using System.Windows.Forms; 6 | 7 | namespace TotalCommander 8 | { 9 | public partial class Form_TotalCommander : Form 10 | { 11 | #region Fields 12 | private GUI.ShellBrowser m_PreviousFocus; 13 | #endregion 14 | 15 | public Form_TotalCommander() 16 | { 17 | InitializeComponent(); 18 | 19 | GUI.ShellBrowser.SmallImageList = smallImgList; 20 | 21 | shellBrowserLeft.Init(); 22 | shellBrowserRight.Init(); 23 | 24 | shellBrowserLeft.RecvFocus += Browser_GotFocus; 25 | shellBrowserRight.RecvFocus += Browser_GotFocus; 26 | 27 | m_PreviousFocus = shellBrowserLeft; 28 | Init(); 29 | } 30 | 31 | void Browser_GotFocus(object sender, EventArgs e) 32 | { 33 | GUI.ShellBrowser tmp = sender as GUI.ShellBrowser; 34 | if (tmp != null) 35 | { 36 | m_PreviousFocus = tmp; 37 | } 38 | } 39 | 40 | private void Init() 41 | { 42 | InitMenuItems(); 43 | InitBottomItems(); 44 | InitToolbarBtns(); 45 | } 46 | 47 | #region Bottom buttons 48 | void InitBottomItems() 49 | { 50 | this.KeyDown += Form_TotalCommander_KeyDown; 51 | btnF3View.Click += btnF3View_Click; 52 | btnF4Edit.Click += btnF4Edit_Click; 53 | btnF1Copy.Click += btnF1Copy_Click; 54 | btnF6Move.Click += btnF6Move_Click; 55 | btnF7NewFolder.Click += btnF7NewFolder_Click; 56 | btnF8Delete.Click += btnF8Delete_Click; 57 | btnExit.Click += btnExit_Click; 58 | } 59 | 60 | void Form_TotalCommander_KeyDown(object sender, KeyEventArgs e) 61 | { 62 | switch (e.KeyData) 63 | { 64 | case Keys.F3: 65 | btnF3View_Click(null, null); 66 | break; 67 | case Keys.F4: 68 | btnF4Edit_Click(null, null); 69 | break; 70 | case Keys.F1: 71 | btnF1Copy_Click(null, null); 72 | break; 73 | case Keys.F6: 74 | btnF6Move_Click(null, null); 75 | break; 76 | case Keys.F7: 77 | btnF7NewFolder_Click(null, null); 78 | break; 79 | case Keys.F8: 80 | btnF8Delete_Click(null, null); 81 | break; 82 | case Keys.Control | Keys.Q: 83 | btnExit_Click(null, null); 84 | break; 85 | } 86 | } 87 | 88 | void btnExit_Click(object sender, EventArgs e) 89 | { 90 | this.Close(); 91 | } 92 | 93 | void btnF8Delete_Click(object sender, EventArgs e) 94 | { 95 | m_PreviousFocus.DeleteSelectedItems(Microsoft.VisualBasic.FileIO.RecycleOption.SendToRecycleBin); 96 | } 97 | 98 | void btnF7NewFolder_Click(object sender, EventArgs e) 99 | { 100 | m_PreviousFocus.CreateNewFolder(); 101 | } 102 | 103 | void btnF6Move_Click(object sender, EventArgs e) 104 | { 105 | m_PreviousFocus.CutSelectedItems(); 106 | } 107 | 108 | void btnF1Copy_Click(object sender, EventArgs e) 109 | { 110 | m_PreviousFocus.CopySelectedItems(); 111 | } 112 | 113 | void btnF4Edit_Click(object sender, EventArgs e) 114 | { 115 | m_PreviousFocus.EditWithNotepad(); 116 | } 117 | 118 | void btnF3View_Click(object sender, EventArgs e) 119 | { 120 | m_PreviousFocus.EditWithNotepad(); 121 | } 122 | #endregion Bottom buttons 123 | 124 | #region Menu items 125 | void InitMenuItems() 126 | { 127 | tsmiViewProperties.Click += tsmiViewProperties_Click; 128 | tsmiExit.Click += tsmiExit_Click; 129 | tsmiKeyboards.Click += tsmiKeyboards_Click; 130 | tsmiAbout.Click += tsmiAbout_Click; 131 | } 132 | 133 | void tsmiAbout_Click(object sender, EventArgs e) 134 | { 135 | string caption = "About Total Commander"; 136 | string text = @"Total Commander Version 0.9.1.1 (2018-04-09) 137 | lzutao @ Github"; 138 | MessageBox.Show(text, caption, MessageBoxButtons.OK, MessageBoxIcon.Information); 139 | } 140 | 141 | void tsmiKeyboards_Click(object sender, EventArgs e) 142 | { 143 | string helpFile = "Keyboards.htm"; 144 | if (File.Exists(helpFile)) 145 | { 146 | FileInfo info = new FileInfo(helpFile); 147 | GUI.HtmlBrowser htmlBrowser = new GUI.HtmlBrowser(info.FullName); 148 | htmlBrowser.Text = "Keyboard shortcuts"; 149 | htmlBrowser.ShowDialog(this); 150 | } 151 | else 152 | { 153 | GUI.FormPacking.FatalError(this.FindForm(), "Keyboards.htm is missing."); 154 | } 155 | } 156 | 157 | void tsmiExit_Click(object sender, EventArgs e) 158 | { 159 | btnExit_Click(null, null); 160 | } 161 | 162 | void tsmiViewProperties_Click(object sender, EventArgs e) 163 | { 164 | m_PreviousFocus.OpenPropertiesWindowWithSelectedItems(); 165 | } 166 | #endregion Menu items 167 | 168 | #region Toolstrip buttons 169 | void InitToolbarBtns() 170 | { 171 | tsbtnGoParent.Click += tsbtnGoParent_Click; 172 | tsbtnGoBackward.Click += tsbtnGoBackward_Click; 173 | tsbtnGoForward.Click += tsbtnGoForward_Click; 174 | tsbtnDetailViewMode.Click += tsbtnDetailViewMode_Click; 175 | tsbtnListViewMode.Click += tsbtnListViewMode_Click; 176 | tsbtnTreeView.Click += tsbtnTreeView_Click; 177 | tsbtnPackFiles.Click += tsbtnPackFiles_Click; 178 | tsbtnRefreshWindows.Click += tsbtnRefreshWindows_Click; 179 | tsbtnAddNewFile.Click += tsbtnAddNewFile_Click; 180 | tsbtnAddNewFolder.Click += tsbtnAddNewFolder_Click; 181 | } 182 | 183 | void tsbtnAddNewFolder_Click(object sender, EventArgs e) 184 | { 185 | m_PreviousFocus.CreateNewFolder(); 186 | } 187 | 188 | void tsbtnAddNewFile_Click(object sender, EventArgs e) 189 | { 190 | m_PreviousFocus.CreateNewFile(); 191 | } 192 | 193 | void tsbtnTreeView_Click(object sender, EventArgs e) 194 | { 195 | m_PreviousFocus.HideNavigationPane = !(m_PreviousFocus.HideNavigationPane); 196 | } 197 | 198 | void tsbtnPackFiles_Click(object sender, EventArgs e) 199 | { 200 | m_PreviousFocus.PackFiles(); 201 | } 202 | 203 | void tsbtnRefreshWindows_Click(object sender, EventArgs e) 204 | { 205 | m_PreviousFocus.RefreshAll(); 206 | } 207 | 208 | private void tsbtnDetailViewMode_Click(object sender, EventArgs e) 209 | { 210 | m_PreviousFocus.ChangeViewMode(View.Details); 211 | } 212 | 213 | private void tsbtnListViewMode_Click(object sender, EventArgs e) 214 | { 215 | m_PreviousFocus.ChangeViewMode(View.List); 216 | } 217 | 218 | #region Navigation Clicks 219 | 220 | private void tsbtnGoBackward_Click(object sender, EventArgs e) 221 | { 222 | m_PreviousFocus.GoBackward(); 223 | } 224 | 225 | private void tsbtnGoForward_Click(object sender, EventArgs e) 226 | { 227 | m_PreviousFocus.GoForward(); 228 | } 229 | 230 | private void tsbtnGoParent_Click(object sender, EventArgs e) 231 | { 232 | m_PreviousFocus.GoParent(); 233 | } 234 | 235 | #endregion 236 | 237 | #endregion Toolstrip buttons 238 | 239 | #region Device detector constants and Structs 240 | 241 | const int WM_DEVICECHANGE = 0x219; 242 | const int DBT_DEVICEARRIVAL = 0x8000; 243 | const int DBT_DEVICEREMOVECOMPLETE = 0x8004; 244 | const int DBT_DEVTYP_VOLUME = 0x00000002; 245 | 246 | [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)] 247 | public struct DevBroadcastVolume 248 | { 249 | public int Size; 250 | public int DeviceType; 251 | public int Reserved; 252 | public int Mask; 253 | public Int16 Flags; 254 | } 255 | 256 | protected override void WndProc(ref Message m) 257 | { 258 | base.WndProc(ref m); 259 | switch (m.Msg) 260 | { 261 | case WM_DEVICECHANGE: 262 | switch ((int)m.WParam) 263 | { 264 | case DBT_DEVICEARRIVAL: 265 | case DBT_DEVICEREMOVECOMPLETE: 266 | shellBrowserLeft.OnDeviceDetected(null, null); 267 | shellBrowserRight.OnDeviceDetected(null, null); 268 | break; 269 | } 270 | break; 271 | } 272 | } 273 | 274 | #endregion Device detector constants and Structs 275 | 276 | } 277 | } 278 | -------------------------------------------------------------------------------- /TotalCommander/GUI/FormFindFiles.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Windows.Forms; 10 | using System.Threading; 11 | using System.Threading.Tasks; 12 | using System.Diagnostics; 13 | 14 | namespace TotalCommander.GUI 15 | { 16 | public partial class FormFindFiles : Form 17 | { 18 | public string Pattern { get; set; } 19 | 20 | public FormFindFiles() 21 | { 22 | InitializeComponent(); 23 | Init(); 24 | } 25 | 26 | public FormFindFiles(string directoryToFind, ImageList smallImageList) 27 | { 28 | InitializeComponent(); 29 | lvwViewer.SmallImageList = smallImageList; 30 | txtPath.Text = directoryToFind; 31 | Init(); 32 | } 33 | 34 | private void Init() 35 | { 36 | txtPattern.Focus(); 37 | txtPath.KeyDown += txtPath_KeyDown; 38 | txtPattern.KeyDown += txtPattern_KeyDown; 39 | lblStatus.Visible = false; 40 | 41 | btnBrowse.Click += btnBrowse_Click; 42 | btnCancel.Click += btnCancel_Click; 43 | btnSearch.Click += btnSearch_Click; 44 | 45 | InitListView(); 46 | } 47 | 48 | #region Listview 49 | 50 | void lvwViewer_Resize(object sender, EventArgs e) 51 | { 52 | lvwViewer.Columns[0].Width = lvwViewer.Width; 53 | } 54 | 55 | void InitListView() 56 | { 57 | lvwViewer.View = View.Details; 58 | lvwViewer.FullRowSelect = true; 59 | lvwViewer.Columns.Add("Name"); 60 | lvwViewer.Columns[0].Width = lvwViewer.Width; 61 | lvwViewer.Resize += lvwViewer_Resize; 62 | lvwViewer.HideSelection = false; 63 | lvwViewer.LabelEdit = false; 64 | lvwViewer.KeyDown += lvwViewer_KeyDown; 65 | lvwViewer.MouseDoubleClick += lvwViewer_MouseDoubleClick; 66 | } 67 | 68 | void lvwViewer_MouseDoubleClick(object sender, MouseEventArgs e) 69 | { 70 | if (e.Button == MouseButtons.Left) 71 | { 72 | ListView fBrowser = (ListView)sender; 73 | ListViewHitTestInfo info = fBrowser.HitTest(e.X, e.Y); 74 | ListViewItem item = info.Item; 75 | if (item != null) 76 | { 77 | string fullPath = item.Tag.ToString(); 78 | Process.Start(fullPath); 79 | } 80 | } 81 | } 82 | 83 | void lvwViewer_KeyDown(object sender, KeyEventArgs e) 84 | { 85 | switch (e.KeyData) 86 | { 87 | case Keys.Enter: 88 | if (lvwViewer.FocusedItem != null) 89 | { 90 | string fullPath = lvwViewer.FocusedItem.Tag.ToString(); 91 | Process.Start(fullPath); 92 | } 93 | break; 94 | } 95 | } 96 | 97 | void AddKeyToImageList(string key, Icon icon) 98 | { 99 | if (!lvwViewer.SmallImageList.Images.ContainsKey(key)) 100 | { 101 | lvwViewer.SmallImageList.Images.Add(key, icon); 102 | } 103 | } 104 | 105 | void UpdateResultView() 106 | { 107 | if (null == ArrDirsFound || null == ArrFilesFound) 108 | return; 109 | 110 | List lvwItems = new List(); 111 | ListViewItem lvwItem = null; 112 | foreach (DirectoryInfo dir in ArrDirsFound) 113 | { 114 | string[] row = { dir.FullName }; 115 | 116 | try 117 | { 118 | // check for accessing power through exception 119 | dir.GetAccessControl(); 120 | if (dir.Attributes.HasFlag(FileAttributes.Hidden)) 121 | lvwItem = new ListViewItem(row, "hidden_folder"); 122 | else 123 | lvwItem = new ListViewItem(row, "FolderIcon"); 124 | } 125 | catch (UnauthorizedAccessException) 126 | { 127 | lvwItem = new ListViewItem(row, "locked_folder"); 128 | } 129 | lvwItem.Tag = dir.FullName; // save fullpath to item 130 | 131 | lvwItems.Add(lvwItem); 132 | } 133 | 134 | foreach (FileInfo file in ArrFilesFound) 135 | { 136 | string[] row = { file.FullName }; 137 | 138 | // Check to see if the image collection contains an image 139 | // for this extension, using the extension as a key. 140 | Icon icon = ShellIcon.GetIcon(file.FullName); 141 | string ext = file.Extension.Replace(".", ""); 142 | if (icon != null) 143 | { 144 | AddKeyToImageList(file.FullName, icon); 145 | lvwItem = new ListViewItem(row, file.FullName); 146 | } 147 | else if (!String.IsNullOrEmpty(ext)) 148 | { 149 | //Icon iconExt = Icon.ExtractAssociatedIcon(file.FullName); 150 | Icon iconExt = ShellIcon.GetSmallIconFromExtension(ext); 151 | AddKeyToImageList(ext, iconExt); 152 | lvwItem = new ListViewItem(row, ext); 153 | } 154 | else 155 | lvwItem = new ListViewItem(row, "unknown"); // unknow file icon 156 | 157 | lvwItem.Tag = file.FullName; 158 | lvwItems.Add(lvwItem); 159 | } 160 | 161 | lvwViewer.Items.Clear(); 162 | lvwViewer.BeginUpdate(); 163 | lvwViewer.Items.AddRange(lvwItems.ToArray()); 164 | lvwViewer.EndUpdate(); 165 | } 166 | 167 | #endregion Listview 168 | 169 | #region Quick search when pressing enter key 170 | void txtPattern_KeyDown(object sender, KeyEventArgs e) 171 | { 172 | if (e.KeyData == Keys.Enter) 173 | btnSearch_Click(sender, null); 174 | } 175 | 176 | void txtPath_KeyDown(object sender, KeyEventArgs e) 177 | { 178 | if (e.KeyData == Keys.Enter) 179 | btnSearch_Click(sender, null); 180 | } 181 | #endregion Quick search when pressing enter key 182 | 183 | bool CanAccess(DirectoryInfo info) 184 | { 185 | bool canAccess = true; 186 | try 187 | { 188 | info.GetAccessControl(); 189 | } 190 | catch (UnauthorizedAccessException) { canAccess = false; } 191 | return canAccess; 192 | } 193 | 194 | async void btnSearch_Click(object sender, EventArgs e) 195 | { 196 | DirectoryInfo info = new DirectoryInfo(txtPath.Text); 197 | 198 | if (!info.Exists) 199 | { 200 | MessageBox.Show(this, "Directory not exists."); 201 | return; 202 | } 203 | if (!CanAccess(info)) 204 | { 205 | MessageBox.Show("Access denied on this directory."); 206 | return; 207 | } 208 | lblStatus.Visible = true; 209 | lblStatus.Text = "Searching ..."; 210 | btnSearch.Enabled = false; 211 | this.Cursor = Cursors.WaitCursor; 212 | 213 | 214 | Pattern = txtPattern.Text; 215 | await DoSearch(info); 216 | btnSearch.Enabled = true; 217 | int number = ArrFilesFound.Length + ArrDirsFound.Length; 218 | lblStatus.Text=number > 0 ? string.Format("{0} files, {1} directories", ArrFilesFound.Length, ArrDirsFound.Length): 219 | "No file or folder matches the pattern."; 220 | this.Cursor = Cursors.Default; 221 | UpdateResultView(); 222 | } 223 | 224 | void btnCancel_Click(object sender, EventArgs e) 225 | { 226 | this.Close(); 227 | } 228 | 229 | void btnBrowse_Click(object sender, EventArgs e) 230 | { 231 | using (var fbd = new FolderBrowserDialog()) 232 | { 233 | fbd.Description = "Choose directory to search!"; 234 | fbd.ShowNewFolderButton = false; 235 | //fbd.RootFolder = txtPath.Text; 236 | fbd.SelectedPath = txtPath.Text; 237 | if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK) 238 | { 239 | txtPath.Text = fbd.SelectedPath; 240 | } 241 | } 242 | } 243 | 244 | async Task DoSearch(DirectoryInfo info) 245 | { 246 | SearchOption option = chkFindSubDirs.Checked ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; 247 | FileInfo[] fileResult =null; 248 | DirectoryInfo[] dirResult=null; 249 | await Task.Run(() => 250 | { 251 | fileResult = info.GetFiles(Pattern, option); 252 | dirResult = info.GetDirectories(Pattern, option); 253 | }); 254 | ArrDirsFound = dirResult.Where(d => !(d.Attributes.HasFlag(FileAttributes.Temporary) && d.Attributes.HasFlag(FileAttributes.System))).ToArray(); 255 | ArrFilesFound = fileResult.Where(d => !(d.Attributes.HasFlag(FileAttributes.Temporary) && d.Attributes.HasFlag(FileAttributes.System))).ToArray(); 256 | } 257 | 258 | #region Properties 259 | public DirectoryInfo[] ArrDirsFound { get; set; } 260 | public FileInfo[] ArrFilesFound { get; set; } 261 | #endregion Properties 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /TotalCommander/GUI/FormFindFiles.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TotalCommander.GUI 2 | { 3 | partial class FormFindFiles 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormFindFiles)); 32 | this.btnSearch = new System.Windows.Forms.Button(); 33 | this.btnCancel = new System.Windows.Forms.Button(); 34 | this.label1 = new System.Windows.Forms.Label(); 35 | this.label2 = new System.Windows.Forms.Label(); 36 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 37 | this.lvwViewer = new System.Windows.Forms.ListView(); 38 | this.txtPattern = new System.Windows.Forms.TextBox(); 39 | this.txtPath = new System.Windows.Forms.TextBox(); 40 | this.btnBrowse = new System.Windows.Forms.Button(); 41 | this.chkFindSubDirs = new System.Windows.Forms.CheckBox(); 42 | this.lblStatus = new System.Windows.Forms.Label(); 43 | this.groupBox1.SuspendLayout(); 44 | this.SuspendLayout(); 45 | // 46 | // btnSearch 47 | // 48 | this.btnSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 49 | this.btnSearch.Location = new System.Drawing.Point(583, 12); 50 | this.btnSearch.Name = "btnSearch"; 51 | this.btnSearch.Size = new System.Drawing.Size(87, 27); 52 | this.btnSearch.TabIndex = 0; 53 | this.btnSearch.TabStop = false; 54 | this.btnSearch.Text = "Start Search"; 55 | this.btnSearch.UseVisualStyleBackColor = true; 56 | // 57 | // btnCancel 58 | // 59 | this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 60 | this.btnCancel.Location = new System.Drawing.Point(583, 46); 61 | this.btnCancel.Name = "btnCancel"; 62 | this.btnCancel.Size = new System.Drawing.Size(87, 27); 63 | this.btnCancel.TabIndex = 1; 64 | this.btnCancel.TabStop = false; 65 | this.btnCancel.Text = "Cancel"; 66 | this.btnCancel.UseVisualStyleBackColor = true; 67 | // 68 | // label1 69 | // 70 | this.label1.AutoSize = true; 71 | this.label1.Location = new System.Drawing.Point(0, 12); 72 | this.label1.Name = "label1"; 73 | this.label1.Size = new System.Drawing.Size(66, 15); 74 | this.label1.TabIndex = 3; 75 | this.label1.Text = "Search for :"; 76 | // 77 | // label2 78 | // 79 | this.label2.AutoSize = true; 80 | this.label2.Location = new System.Drawing.Point(0, 46); 81 | this.label2.Name = "label2"; 82 | this.label2.Size = new System.Drawing.Size(61, 15); 83 | this.label2.TabIndex = 4; 84 | this.label2.Text = "Search in :"; 85 | // 86 | // groupBox1 87 | // 88 | this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 89 | | System.Windows.Forms.AnchorStyles.Left) 90 | | System.Windows.Forms.AnchorStyles.Right))); 91 | this.groupBox1.Controls.Add(this.lvwViewer); 92 | this.groupBox1.Location = new System.Drawing.Point(3, 104); 93 | this.groupBox1.Name = "groupBox1"; 94 | this.groupBox1.Size = new System.Drawing.Size(667, 185); 95 | this.groupBox1.TabIndex = 5; 96 | this.groupBox1.TabStop = false; 97 | this.groupBox1.Text = "Search results :"; 98 | // 99 | // lvwViewer 100 | // 101 | this.lvwViewer.Dock = System.Windows.Forms.DockStyle.Fill; 102 | this.lvwViewer.Location = new System.Drawing.Point(3, 19); 103 | this.lvwViewer.Name = "lvwViewer"; 104 | this.lvwViewer.Size = new System.Drawing.Size(661, 163); 105 | this.lvwViewer.TabIndex = 0; 106 | this.lvwViewer.TabStop = false; 107 | this.lvwViewer.UseCompatibleStateImageBehavior = false; 108 | // 109 | // txtPattern 110 | // 111 | this.txtPattern.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 112 | | System.Windows.Forms.AnchorStyles.Right))); 113 | this.txtPattern.Location = new System.Drawing.Point(93, 12); 114 | this.txtPattern.Name = "txtPattern"; 115 | this.txtPattern.Size = new System.Drawing.Size(373, 23); 116 | this.txtPattern.TabIndex = 0; 117 | // 118 | // txtPath 119 | // 120 | this.txtPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 121 | | System.Windows.Forms.AnchorStyles.Right))); 122 | this.txtPath.BackColor = System.Drawing.SystemColors.Window; 123 | this.txtPath.Location = new System.Drawing.Point(93, 46); 124 | this.txtPath.Name = "txtPath"; 125 | this.txtPath.ReadOnly = true; 126 | this.txtPath.Size = new System.Drawing.Size(373, 23); 127 | this.txtPath.TabIndex = 1; 128 | // 129 | // btnBrowse 130 | // 131 | this.btnBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 132 | this.btnBrowse.Location = new System.Drawing.Point(488, 46); 133 | this.btnBrowse.Name = "btnBrowse"; 134 | this.btnBrowse.Size = new System.Drawing.Size(77, 27); 135 | this.btnBrowse.TabIndex = 9; 136 | this.btnBrowse.TabStop = false; 137 | this.btnBrowse.Text = "Browse ..."; 138 | this.btnBrowse.UseVisualStyleBackColor = true; 139 | // 140 | // chkFindSubDirs 141 | // 142 | this.chkFindSubDirs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 143 | | System.Windows.Forms.AnchorStyles.Right))); 144 | this.chkFindSubDirs.AutoSize = true; 145 | this.chkFindSubDirs.Location = new System.Drawing.Point(222, 81); 146 | this.chkFindSubDirs.Name = "chkFindSubDirs"; 147 | this.chkFindSubDirs.Size = new System.Drawing.Size(166, 19); 148 | this.chkFindSubDirs.TabIndex = 2; 149 | this.chkFindSubDirs.Text = "Search in all subdirectories"; 150 | this.chkFindSubDirs.UseVisualStyleBackColor = true; 151 | // 152 | // lblStatus 153 | // 154 | this.lblStatus.AutoSize = true; 155 | this.lblStatus.Location = new System.Drawing.Point(0, 300); 156 | this.lblStatus.Name = "lblStatus"; 157 | this.lblStatus.Size = new System.Drawing.Size(73, 15); 158 | this.lblStatus.TabIndex = 10; 159 | this.lblStatus.Text = "Result status"; 160 | // 161 | // FormFindFiles 162 | // 163 | this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F); 164 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi; 165 | this.ClientSize = new System.Drawing.Size(677, 325); 166 | this.Controls.Add(this.lblStatus); 167 | this.Controls.Add(this.chkFindSubDirs); 168 | this.Controls.Add(this.btnBrowse); 169 | this.Controls.Add(this.txtPath); 170 | this.Controls.Add(this.txtPattern); 171 | this.Controls.Add(this.groupBox1); 172 | this.Controls.Add(this.label2); 173 | this.Controls.Add(this.label1); 174 | this.Controls.Add(this.btnCancel); 175 | this.Controls.Add(this.btnSearch); 176 | this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 177 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 178 | this.Name = "FormFindFiles"; 179 | this.ShowInTaskbar = false; 180 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; 181 | this.Text = "Find Files"; 182 | this.groupBox1.ResumeLayout(false); 183 | this.ResumeLayout(false); 184 | this.PerformLayout(); 185 | 186 | } 187 | 188 | #endregion 189 | 190 | private System.Windows.Forms.Button btnSearch; 191 | private System.Windows.Forms.Button btnCancel; 192 | private System.Windows.Forms.Label label1; 193 | private System.Windows.Forms.Label label2; 194 | private System.Windows.Forms.GroupBox groupBox1; 195 | private System.Windows.Forms.TextBox txtPattern; 196 | private System.Windows.Forms.TextBox txtPath; 197 | private System.Windows.Forms.Button btnBrowse; 198 | private System.Windows.Forms.CheckBox chkFindSubDirs; 199 | private System.Windows.Forms.ListView lvwViewer; 200 | private System.Windows.Forms.Label lblStatus; 201 | } 202 | } -------------------------------------------------------------------------------- /TotalCommander/TotalCommander.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {8B3B6A1D-2373-42BD-9216-5E6265E9BB83} 8 | WinExe 9 | Properties 10 | TotalCommander 11 | TotalCommander 12 | v4.5 13 | 512 14 | publish\ 15 | true 16 | Disk 17 | false 18 | Foreground 19 | 7 20 | Days 21 | false 22 | false 23 | true 24 | 0 25 | 1.0.0.%2a 26 | false 27 | false 28 | true 29 | 30 | 31 | AnyCPU 32 | true 33 | full 34 | false 35 | bin\Debug\ 36 | DEBUG;TRACE 37 | prompt 38 | 4 39 | 40 | 41 | AnyCPU 42 | pdbonly 43 | true 44 | bin\Release\ 45 | TRACE 46 | prompt 47 | 4 48 | 49 | 50 | false 51 | 52 | 53 | totalCommander.ico 54 | 55 | 56 | app.manifest 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Component 76 | 77 | 78 | Component 79 | 80 | 81 | Form 82 | 83 | 84 | FormFindFiles.cs 85 | 86 | 87 | Form 88 | 89 | 90 | FormPacking.cs 91 | 92 | 93 | Form 94 | 95 | 96 | FormNewFolder.cs 97 | 98 | 99 | Form 100 | 101 | 102 | HtmlBrowser.cs 103 | 104 | 105 | 106 | 107 | Component 108 | 109 | 110 | UserControl 111 | 112 | 113 | ShellBrowser.cs 114 | 115 | 116 | True 117 | True 118 | Resources.resx 119 | 120 | 121 | 122 | 123 | 124 | Form 125 | 126 | 127 | Form_TotalCommander.cs 128 | 129 | 130 | 131 | 132 | 133 | 134 | Form_TotalCommander.cs 135 | 136 | 137 | FormFindFiles.cs 138 | 139 | 140 | FormPacking.cs 141 | 142 | 143 | FormNewFolder.cs 144 | 145 | 146 | HtmlBrowser.cs 147 | 148 | 149 | ShellBrowser.cs 150 | 151 | 152 | ResXFileCodeGenerator 153 | Designer 154 | Resources.Designer.cs 155 | 156 | 157 | 158 | SettingsSingleFileGenerator 159 | Settings.Designer.cs 160 | 161 | 162 | True 163 | Settings.settings 164 | True 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | False 227 | Microsoft .NET Framework 4.5 %28x86 and x64%29 228 | true 229 | 230 | 231 | False 232 | .NET Framework 3.5 SP1 Client Profile 233 | false 234 | 235 | 236 | False 237 | .NET Framework 3.5 SP1 238 | false 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | PreserveNewest 247 | 248 | 249 | PreserveNewest 250 | 251 | 252 | 253 | 254 | 255 | 256 | 263 | -------------------------------------------------------------------------------- /TotalCommander/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace TotalCommander.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TotalCommander.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized resource of type System.Drawing.Bitmap. 65 | /// 66 | internal static System.Drawing.Bitmap Add_File1 { 67 | get { 68 | object obj = ResourceManager.GetObject("Add_File1", resourceCulture); 69 | return ((System.Drawing.Bitmap)(obj)); 70 | } 71 | } 72 | 73 | /// 74 | /// Looks up a localized resource of type System.Drawing.Bitmap. 75 | /// 76 | internal static System.Drawing.Bitmap Add_Folder { 77 | get { 78 | object obj = ResourceManager.GetObject("Add_Folder", resourceCulture); 79 | return ((System.Drawing.Bitmap)(obj)); 80 | } 81 | } 82 | 83 | /// 84 | /// Looks up a localized resource of type System.Drawing.Bitmap. 85 | /// 86 | internal static System.Drawing.Bitmap copy_icon { 87 | get { 88 | object obj = ResourceManager.GetObject("copy_icon", resourceCulture); 89 | return ((System.Drawing.Bitmap)(obj)); 90 | } 91 | } 92 | 93 | /// 94 | /// Looks up a localized resource of type System.Drawing.Bitmap. 95 | /// 96 | internal static System.Drawing.Bitmap details_icon { 97 | get { 98 | object obj = ResourceManager.GetObject("details_icon", resourceCulture); 99 | return ((System.Drawing.Bitmap)(obj)); 100 | } 101 | } 102 | 103 | /// 104 | /// Looks up a localized resource of type System.Drawing.Bitmap. 105 | /// 106 | internal static System.Drawing.Bitmap document_tree_icon { 107 | get { 108 | object obj = ResourceManager.GetObject("document_tree_icon", resourceCulture); 109 | return ((System.Drawing.Bitmap)(obj)); 110 | } 111 | } 112 | 113 | /// 114 | /// Looks up a localized resource of type System.Drawing.Bitmap. 115 | /// 116 | internal static System.Drawing.Bitmap edit_icon { 117 | get { 118 | object obj = ResourceManager.GetObject("edit_icon", resourceCulture); 119 | return ((System.Drawing.Bitmap)(obj)); 120 | } 121 | } 122 | 123 | /// 124 | /// Looks up a localized resource of type System.Drawing.Bitmap. 125 | /// 126 | internal static System.Drawing.Bitmap ic_archive_black_48dp { 127 | get { 128 | object obj = ResourceManager.GetObject("ic_archive_black_48dp", resourceCulture); 129 | return ((System.Drawing.Bitmap)(obj)); 130 | } 131 | } 132 | 133 | /// 134 | /// Looks up a localized resource of type System.Drawing.Bitmap. 135 | /// 136 | internal static System.Drawing.Bitmap ic_arrow_upward_black_48dp { 137 | get { 138 | object obj = ResourceManager.GetObject("ic_arrow_upward_black_48dp", resourceCulture); 139 | return ((System.Drawing.Bitmap)(obj)); 140 | } 141 | } 142 | 143 | /// 144 | /// Looks up a localized resource of type System.Drawing.Bitmap. 145 | /// 146 | internal static System.Drawing.Bitmap ic_cancel_black_48dp { 147 | get { 148 | object obj = ResourceManager.GetObject("ic_cancel_black_48dp", resourceCulture); 149 | return ((System.Drawing.Bitmap)(obj)); 150 | } 151 | } 152 | 153 | /// 154 | /// Looks up a localized resource of type System.Drawing.Bitmap. 155 | /// 156 | internal static System.Drawing.Bitmap ic_chevron_left_black_48dp { 157 | get { 158 | object obj = ResourceManager.GetObject("ic_chevron_left_black_48dp", resourceCulture); 159 | return ((System.Drawing.Bitmap)(obj)); 160 | } 161 | } 162 | 163 | /// 164 | /// Looks up a localized resource of type System.Drawing.Bitmap. 165 | /// 166 | internal static System.Drawing.Bitmap ic_chevron_right_black_48dp { 167 | get { 168 | object obj = ResourceManager.GetObject("ic_chevron_right_black_48dp", resourceCulture); 169 | return ((System.Drawing.Bitmap)(obj)); 170 | } 171 | } 172 | 173 | /// 174 | /// Looks up a localized resource of type System.Drawing.Bitmap. 175 | /// 176 | internal static System.Drawing.Bitmap ic_close_black_48dp { 177 | get { 178 | object obj = ResourceManager.GetObject("ic_close_black_48dp", resourceCulture); 179 | return ((System.Drawing.Bitmap)(obj)); 180 | } 181 | } 182 | 183 | /// 184 | /// Looks up a localized resource of type System.Drawing.Bitmap. 185 | /// 186 | internal static System.Drawing.Bitmap ic_search_black_48dp { 187 | get { 188 | object obj = ResourceManager.GetObject("ic_search_black_48dp", resourceCulture); 189 | return ((System.Drawing.Bitmap)(obj)); 190 | } 191 | } 192 | 193 | /// 194 | /// Looks up a localized resource of type System.Drawing.Bitmap. 195 | /// 196 | internal static System.Drawing.Bitmap ic_unarchive_black_48dp { 197 | get { 198 | object obj = ResourceManager.GetObject("ic_unarchive_black_48dp", resourceCulture); 199 | return ((System.Drawing.Bitmap)(obj)); 200 | } 201 | } 202 | 203 | /// 204 | /// Looks up a localized resource of type System.Drawing.Bitmap. 205 | /// 206 | internal static System.Drawing.Bitmap icon_view_pane { 207 | get { 208 | object obj = ResourceManager.GetObject("icon_view_pane", resourceCulture); 209 | return ((System.Drawing.Bitmap)(obj)); 210 | } 211 | } 212 | 213 | /// 214 | /// Looks up a localized resource of type System.Drawing.Bitmap. 215 | /// 216 | internal static System.Drawing.Bitmap info_icon { 217 | get { 218 | object obj = ResourceManager.GetObject("info_icon", resourceCulture); 219 | return ((System.Drawing.Bitmap)(obj)); 220 | } 221 | } 222 | 223 | /// 224 | /// Looks up a localized resource of type System.Drawing.Bitmap. 225 | /// 226 | internal static System.Drawing.Bitmap refresh_icon { 227 | get { 228 | object obj = ResourceManager.GetObject("refresh_icon", resourceCulture); 229 | return ((System.Drawing.Bitmap)(obj)); 230 | } 231 | } 232 | 233 | /// 234 | /// Looks up a localized resource of type System.Drawing.Bitmap. 235 | /// 236 | internal static System.Drawing.Bitmap rename_icon { 237 | get { 238 | object obj = ResourceManager.GetObject("rename_icon", resourceCulture); 239 | return ((System.Drawing.Bitmap)(obj)); 240 | } 241 | } 242 | 243 | /// 244 | /// Looks up a localized resource of type System.Drawing.Bitmap. 245 | /// 246 | internal static System.Drawing.Bitmap Show_Password_24 { 247 | get { 248 | object obj = ResourceManager.GetObject("Show_Password_24", resourceCulture); 249 | return ((System.Drawing.Bitmap)(obj)); 250 | } 251 | } 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /TotalCommander/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\refresh_icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\Copy-16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\info_icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\document_tree_icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\Add_Folder.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | ..\Resources\ic_chevron_right_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | ..\Resources\Add_File1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | 143 | ..\Resources\Rename-16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 144 | 145 | 146 | ..\Resources\ic_unarchive_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 147 | 148 | 149 | ..\Resources\Edit File-16.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 150 | 151 | 152 | ..\Resources\ic_close_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 153 | 154 | 155 | ..\Resources\ic_search_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 156 | 157 | 158 | ..\Resources\icon-view-pane1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 159 | 160 | 161 | ..\Resources\Details-50.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 162 | 163 | 164 | ..\Resources\ic_archive_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 165 | 166 | 167 | ..\Resources\ic_arrow_upward_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 168 | 169 | 170 | ..\Resources\ic_cancel_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 171 | 172 | 173 | ..\Resources\ic_chevron_left_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 174 | 175 | 176 | ..\Resources\Show_Password_24.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 177 | 178 | -------------------------------------------------------------------------------- /TotalCommander/GUI/NavigationPane.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Runtime.InteropServices; 4 | using System.Windows.Forms; 5 | using System.Linq; 6 | using Microsoft.VisualBasic.FileIO; 7 | //using Microsoft 8 | 9 | namespace TotalCommander.GUI 10 | { 11 | internal class NavigationPane : System.Windows.Forms.TreeView 12 | { 13 | #region DLL import 14 | 15 | /// 16 | /// Causes a window to use a different set of visual style information than its class normally uses. 17 | /// 18 | /// Handle to the window whose visual style information is to be changed. 19 | /// Pointer to a string that contains the application name 20 | /// to use in place of the calling application's name. If this parameter is NULL, 21 | /// the calling application's name is used. 22 | /// Pointer to a string that contains a semicolon-separated 23 | /// list of CLSID names to use in place of the actual list passed by the window's class. 24 | /// If this parameter is NULL, the ID list from the calling class is used. 25 | /// If this function succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code. 26 | [DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)] 27 | private extern static int SetWindowTheme(IntPtr hWnd, string pszSubAppName, 28 | string pszSubIdList); 29 | #endregion DLL import 30 | 31 | #region Overrided 32 | protected override void OnKeyDown(KeyEventArgs e) 33 | { 34 | if (e.KeyData == Keys.Enter) 35 | { 36 | if (this.SelectedNode.IsExpanded) 37 | this.SelectedNode.Collapse(); 38 | else 39 | this.SelectedNode.Expand(); 40 | } 41 | else if (e.KeyData == Keys.F5) 42 | RefreshContents(); 43 | base.OnKeyDown(e); 44 | } 45 | #endregion 46 | 47 | internal void Init() 48 | { 49 | this.BeforeExpand += NativeTreeView_BeforeExpand; 50 | 51 | SetWindowTheme(this.Handle, "explorer", null); 52 | if (!this.ImageList.Images.ContainsKey("FolderIcon")) 53 | { 54 | this.ImageList.Images.Add("FolderIcon", ShellIcon.GetLargeFolderIcon()); 55 | this.ImageList.Images.Add("LockFolder", ShellIcon.GetIconFromIndex("shell32.dll", 47)); 56 | /// Detect icon base on Windows version 57 | var vs = Environment.OSVersion; 58 | switch (vs.Version.Major) 59 | { 60 | /// Windows vista, 7, 8, 8.1 61 | case 6: 62 | this.ImageList.Images.Add("ComputerIcon", ShellIcon.GetIconFromIndex("shell32.dll", 15)); 63 | this.ImageList.Images.Add("LibrariesIcon", ShellIcon.GetIconFromIndex("imageres.dll", 202)); 64 | this.ImageList.Images.Add("FavoritesIcon", ShellIcon.GetIconFromIndex("imageres.dll", 203)); 65 | break; 66 | /// Windows 10 67 | case 10: 68 | this.ImageList.Images.Add("ComputerIcon", ShellIcon.GetIconFromIndex("shell32.dll", 15)); 69 | this.ImageList.Images.Add("LibrariesIcon", ShellIcon.GetIconFromIndex("imageres.dll", 203)); 70 | this.ImageList.Images.Add("FavoritesIcon", ShellIcon.GetIconFromIndex("imageres.dll", 200)); 71 | break; 72 | default: 73 | throw new NotSupportedException("This windows version is not supported"); 74 | } 75 | } 76 | 77 | this.HideSelection = false; 78 | // FullRowSelect is ignored if ShowLines is set to true. 79 | this.ShowLines = false; 80 | this.FullRowSelect = true; 81 | 82 | AddFavorites(); 83 | AddLibraries(); 84 | AddComputer(); 85 | 86 | // change items height 87 | int nodeHeight = this.Nodes[0].Bounds.Height; 88 | this.ItemHeight = nodeHeight + 4; 89 | } 90 | 91 | #region Add to favorites folder 92 | private void AddDesktop(TreeNode parent) 93 | { 94 | string path = SpecialDirectories.Desktop; 95 | AddImageToList(this.ImageList, path, ShellIcon.GetIcon(path)); 96 | AddNodeToParent(parent, "Desktop", path, path); 97 | } 98 | 99 | private void AddDownloads(TreeNode parent) 100 | { 101 | string userPath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); 102 | string downloadPath = Path.Combine(userPath, "Downloads"); 103 | AddImageToList(this.ImageList, downloadPath, ShellIcon.GetIcon(downloadPath)); 104 | AddNodeToParent(parent, "Downloads", downloadPath, downloadPath); 105 | } 106 | 107 | void AddFavorites() 108 | { 109 | TreeNode favoritesNode = new TreeNode(); 110 | favoritesNode.Name = favoritesNode.Text = "Favorites"; 111 | favoritesNode.SelectedImageKey = favoritesNode.ImageKey = "FavoritesIcon"; 112 | favoritesNode.Tag = @"\\Favorites"; 113 | favoritesNode.Expand(); 114 | AddDesktop(favoritesNode); 115 | AddDownloads(favoritesNode); 116 | this.BeginUpdate(); 117 | this.Nodes.Add(favoritesNode); 118 | this.EndUpdate(); 119 | } 120 | #endregion Add to favorites folder 121 | 122 | #region Add to libraries 123 | private void AddDocuments(TreeNode parent) 124 | { 125 | string path = SpecialDirectories.MyDocuments; 126 | AddImageToList(this.ImageList, path, ShellIcon.GetIcon(path)); 127 | AddNodeToParent(parent, "Documents", path, path); 128 | } 129 | 130 | private void AddPictures(TreeNode parent) 131 | { 132 | string path = SpecialDirectories.MyPictures; 133 | AddImageToList(this.ImageList, path, ShellIcon.GetIcon(path)); 134 | AddNodeToParent(parent, "Pictures", path, path); 135 | } 136 | 137 | private void AddMusics(TreeNode parent) 138 | { 139 | string path = SpecialDirectories.MyMusic; 140 | AddImageToList(this.ImageList, path, ShellIcon.GetIcon(path)); 141 | AddNodeToParent(parent, "Musics", path, path); 142 | } 143 | 144 | private void AddVideos(TreeNode parent) 145 | { 146 | string path = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos); 147 | AddImageToList(this.ImageList, path, ShellIcon.GetIcon(path)); 148 | AddNodeToParent(parent, "Videos", path, path); 149 | } 150 | 151 | void AddLibraries() 152 | { 153 | TreeNode libsNode = new TreeNode(); 154 | libsNode.Name = libsNode.Text = "Libraries"; 155 | libsNode.SelectedImageKey = libsNode.ImageKey = "LibrariesIcon"; 156 | libsNode.Tag = @"\\Libraries"; 157 | libsNode.Expand(); 158 | AddDocuments(libsNode); 159 | AddPictures(libsNode); 160 | AddMusics(libsNode); 161 | AddVideos(libsNode); 162 | this.BeginUpdate(); 163 | this.Nodes.Add(libsNode); 164 | this.EndUpdate(); 165 | } 166 | 167 | #endregion Add to libraries 168 | 169 | public static void AddImageToList(ImageList list, string key, System.Drawing.Icon icon) 170 | { 171 | if (!list.Images.ContainsKey(key)) 172 | { 173 | list.Images.Add(key, icon); 174 | } 175 | } 176 | 177 | #region Add computer 178 | private void AddDrivesNode(TreeNode myComputerNode) 179 | { 180 | DriveInfo[] allDrives = System.IO.DriveInfo.GetDrives().Where(d => d.IsReady).ToArray(); 181 | System.Drawing.Icon iconForDrive = null; 182 | foreach (DriveInfo drive in allDrives) 183 | { 184 | TreeNode driveNode = new TreeNode(); 185 | driveNode.Name = drive.Name; 186 | string volumnName = String.IsNullOrEmpty(drive.VolumeLabel) ? GetDriveType(drive.DriveType) : drive.VolumeLabel; 187 | string name = String.Format("{0} ({1})", volumnName, drive.Name); 188 | driveNode.Text = name; 189 | iconForDrive = ShellIcon.GetIcon(drive.Name); 190 | AddImageToList(this.ImageList, drive.Name, iconForDrive); 191 | driveNode.ImageKey = drive.Name; 192 | driveNode.SelectedImageKey = drive.Name; 193 | driveNode.Tag = drive.Name; 194 | if (drive.IsReady) 195 | driveNode.Nodes.Add(String.Empty); 196 | myComputerNode.Nodes.Add(driveNode); 197 | } 198 | } 199 | 200 | public static string GetDriveType(DriveType type) 201 | { 202 | string result = ""; 203 | switch (type) 204 | { 205 | case DriveType.CDRom: 206 | result = "CDRom Disk"; 207 | break; 208 | case DriveType.Fixed: 209 | result = "Local Disk"; 210 | break; 211 | case DriveType.Network: 212 | result = "Network Disk"; 213 | break; 214 | case DriveType.NoRootDirectory: 215 | result = "Mounted Disk"; 216 | break; 217 | case DriveType.Removable: 218 | result = "Removable Disk"; 219 | break; 220 | default: 221 | result = type.ToString(); 222 | break; 223 | } 224 | return result; 225 | } 226 | 227 | private void AddComputer() 228 | { 229 | TreeNode computerNode = new TreeNode(); 230 | computerNode.Name = computerNode.Text = "Computer"; 231 | computerNode.SelectedImageKey = computerNode.ImageKey = "ComputerIcon"; 232 | computerNode.Tag = @"\\Computer"; 233 | computerNode.Expand(); 234 | AddDrivesNode(computerNode); 235 | this.BeginUpdate(); 236 | this.Nodes.Add(computerNode); 237 | this.EndUpdate(); 238 | } 239 | #endregion Add computer 240 | 241 | internal void AddToDirectory(TreeNode parent) 242 | { 243 | DirectoryInfo dirs = new DirectoryInfo(parent.Tag.ToString()); 244 | DirectoryInfo[] subDirs = dirs.GetDirectories().Where(x => !x.Attributes.HasFlag(FileAttributes.System)).ToArray(); 245 | foreach (DirectoryInfo subDir in subDirs) 246 | { 247 | this.AddNodeToParent(parent, subDir.Name, "FolderIcon", subDir.FullName); 248 | } 249 | } 250 | 251 | public static bool BannedAttrExists(FileSystemInfo x) 252 | { 253 | return x.Attributes.HasFlag(FileAttributes.System) || 254 | x.Attributes.HasFlag(FileAttributes.Hidden) || 255 | x.Attributes.HasFlag(FileAttributes.Temporary); 256 | } 257 | 258 | void AddSubNodes(TreeNode parent) 259 | { 260 | DirectoryInfo dirs = new DirectoryInfo(parent.Tag.ToString()); 261 | 262 | DirectoryInfo[] subDirs = dirs.GetDirectories().Where(x => !BannedAttrExists(x)).ToArray(); 263 | 264 | foreach (DirectoryInfo subDir in subDirs) 265 | { 266 | TreeNode node = new TreeNode(subDir.Name); 267 | try 268 | { 269 | //keep the directory's full path in the tag for use later 270 | node.Name = subDir.Name; 271 | node.Tag = subDir.FullName; 272 | if (subDir.Attributes.HasFlag(FileAttributes.Hidden)) 273 | { 274 | node.ImageKey = "hidden_folder"; 275 | node.SelectedImageKey = "hidden_folder"; 276 | } 277 | else 278 | { 279 | node.ImageKey = "FolderIcon"; 280 | node.SelectedImageKey = "FolderIcon"; 281 | } 282 | 283 | //if the directory has sub directories add the place holder 284 | int dirCount = subDir.GetDirectories().Where(x => !BannedAttrExists(x)).Count(); 285 | if (dirCount > 0) 286 | { 287 | node.Nodes.Add(null, String.Empty, "FolderIcon", "FolderIcon"); 288 | } 289 | } 290 | catch (UnauthorizedAccessException) 291 | { 292 | //display a locked folder icon 293 | node.ImageKey = "LockFolder"; 294 | node.SelectedImageKey = "locked_folder"; 295 | } 296 | finally 297 | { 298 | this.BeginUpdate(); 299 | parent.Nodes.Add(node); 300 | this.EndUpdate(); 301 | } 302 | } 303 | } 304 | 305 | private void AddNodeToParent(TreeNode parent, string strName, string imageKey, string tag) 306 | { 307 | TreeNode node = new TreeNode(); 308 | node.Name = strName; 309 | node.Text = strName; 310 | node.ImageKey = imageKey; 311 | node.SelectedImageKey = imageKey; 312 | node.Tag = tag; 313 | if (HasChildNode(node)) 314 | node.Nodes.Add(null, String.Empty, "FolderIcon", "FolderIcon"); 315 | parent.Nodes.Add(node); 316 | } 317 | 318 | internal bool HasChildNode(TreeNode node) 319 | { 320 | string pathParent = node.Tag.ToString(); 321 | try 322 | { 323 | DirectoryInfo dir = new DirectoryInfo(pathParent); 324 | bool result = false; 325 | try 326 | { 327 | int dirLenght = dir.GetDirectories().Where(d => !d.Attributes.HasFlag(FileAttributes.System)).Count(); 328 | if (dirLenght > 0) 329 | { 330 | result = true; 331 | } 332 | } 333 | catch (UnauthorizedAccessException) 334 | { 335 | result = false; 336 | } 337 | return result; 338 | } 339 | catch (Exception ex) { MessageBox.Show(ex.Message); } 340 | return false; 341 | } 342 | 343 | static internal bool IsSpecialFolders(string path) 344 | { 345 | bool val = (path == @"\\Computer") || (path == @"\\Libraries") || (path == @"\\Favorites"); 346 | return val; 347 | } 348 | 349 | internal void UpdateDisks() 350 | { 351 | TreeNode computerNode = this.Nodes[2]; 352 | computerNode.Nodes.Clear(); 353 | AddDrivesNode(computerNode); 354 | } 355 | 356 | internal void RefreshContents() 357 | { 358 | TreeNode currentNode = this.SelectedNode; 359 | currentNode.Nodes.Clear(); 360 | string currentPath = currentNode.Tag.ToString(); 361 | if (currentPath == @"\\Computer") 362 | AddDrivesNode(currentNode); 363 | else if (currentPath == @"\\Libraries") 364 | { 365 | AddDocuments(currentNode); 366 | AddPictures(currentNode); 367 | AddMusics(currentNode); 368 | AddVideos(currentNode); 369 | } 370 | else if (currentPath == @"\\Favorites") 371 | { 372 | AddDesktop(currentNode); 373 | AddDownloads(currentNode); 374 | } 375 | else 376 | { 377 | AddSubNodes(currentNode); 378 | } 379 | currentNode.Expand(); 380 | } 381 | 382 | void NativeTreeView_BeforeExpand(object sender, TreeViewCancelEventArgs e) 383 | { 384 | if (e.Node.Nodes.Count > 0) 385 | { 386 | if (String.IsNullOrEmpty(e.Node.Nodes[0].Text) && e.Node.Nodes[0].Tag == null) 387 | { 388 | e.Node.Nodes.Clear(); 389 | AddSubNodes(e.Node); 390 | } 391 | } 392 | } 393 | } 394 | } 395 | -------------------------------------------------------------------------------- /TotalCommander/GUI/FormPacking.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Drawing; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | using System.Windows.Forms; 11 | 12 | namespace TotalCommander.GUI 13 | { 14 | public partial class FormPacking : Form 15 | { 16 | string[] arrPaths; 17 | static readonly string Path7za = @"7za.exe"; 18 | static readonly string SevenZipHash256 = "E6855553350FA6FB23E05839C7F3EF140DAD29D9A0E3495DE4D1B17A9FBF5CA4"; 19 | static bool Is7zaExistAndTrusted = false; 20 | 21 | public static string GetSha256HexString(string fullPath) 22 | { 23 | string hexString; 24 | using (var fs = new FileStream(fullPath, FileMode.Open)) 25 | using (BufferedStream bs = new BufferedStream(fs)) 26 | { 27 | using (var sha256 = new System.Security.Cryptography.SHA256Managed()) 28 | { 29 | byte[] hash = sha256.ComputeHash(bs); 30 | hexString = BitConverter.ToString(hash).Replace("-", String.Empty); 31 | } 32 | } 33 | return hexString; 34 | } 35 | 36 | public static bool Check7zaTrusted() 37 | { 38 | FileInfo info = new FileInfo(Path7za); 39 | if (info.Exists && !Is7zaExistAndTrusted) 40 | { 41 | string hash = GetSha256HexString(info.FullName); 42 | Is7zaExistAndTrusted = hash.Equals(SevenZipHash256); 43 | } 44 | return Is7zaExistAndTrusted; 45 | } 46 | 47 | public FormPacking() 48 | { 49 | if (File.Exists(Path7za)) 50 | Check7zaTrusted(); 51 | 52 | if (!Is7zaExistAndTrusted) 53 | { 54 | FatalError(this.FindForm(), "The packer is broken."); 55 | this.Close(); 56 | } 57 | 58 | InitializeComponent(); 59 | Init(); 60 | } 61 | 62 | public FormPacking(IEnumerable paths): this() 63 | { 64 | arrPaths = paths.ToArray(); 65 | if (arrPaths == null) return; 66 | string directory = Path.GetDirectoryName(arrPaths[0]); 67 | lblSaveFilePath.Text = directory; 68 | 69 | string archiveName; 70 | if (arrPaths.Length == 1) 71 | { 72 | archiveName = Path.GetFileNameWithoutExtension(arrPaths[0]); 73 | } 74 | else 75 | { 76 | archiveName = Path.GetFileName(directory); 77 | if (String.IsNullOrEmpty(archiveName)) 78 | archiveName = Path.GetPathRoot(directory).Replace(@":\", ""); 79 | } 80 | txtFileName.Text = archiveName + ".zip"; 81 | } 82 | 83 | void Init() 84 | { 85 | this.StartPosition = FormStartPosition.CenterParent; 86 | this.ShowInTaskbar = false; 87 | 88 | txtPass1.UseSystemPasswordChar = txtPass2.UseSystemPasswordChar = true; 89 | btnOpenSaveDialog.Click += BtnOpenSaveDialog_Click; 90 | btnOK.Click += BtnOK_Click; 91 | btnCancel.Click += BtnCancel_Click; 92 | btnShowPassword.MouseDown += BtnShowPassword_MouseDown; 93 | btnShowPassword.MouseUp += BtnShowPassword_MouseUp; 94 | 95 | InitArchiveFormat(); 96 | InitCompressionLevel(ArchiveFormat.p7z); 97 | InitUpdateMode(); 98 | InitPathMode(); 99 | InitEncryptionMethod(ArchiveFormat.zip); 100 | } 101 | 102 | #region Button events 103 | void BtnShowPassword_MouseUp(object sender, MouseEventArgs e) 104 | { 105 | txtPass1.UseSystemPasswordChar = txtPass2.UseSystemPasswordChar = true; 106 | } 107 | 108 | void BtnShowPassword_MouseDown(object sender, MouseEventArgs e) 109 | { 110 | txtPass1.UseSystemPasswordChar = txtPass2.UseSystemPasswordChar = false; 111 | } 112 | 113 | void BtnCancel_Click(object sender, EventArgs e) 114 | { 115 | this.Close(); 116 | } 117 | 118 | async void BtnOK_Click(object sender, EventArgs e) 119 | { 120 | string archiveName = Path.Combine(lblSaveFilePath.Text, txtFileName.Text); 121 | if (String.IsNullOrWhiteSpace(archiveName)) return; 122 | 123 | string command = "a"; 124 | 125 | StringBuilder sbSwitches = new StringBuilder("-y"); // assume yes on all commands 126 | #region Archive format 127 | sbSwitches.Append(" -t"); 128 | var format = (ArchiveFormat)cboArchiveFormat.SelectedItem; 129 | switch (format) 130 | { 131 | case ArchiveFormat.p7z: 132 | sbSwitches.Append("7z"); 133 | break; 134 | default: 135 | sbSwitches.Append(format.ToString()); 136 | break; 137 | } 138 | #endregion Archive format 139 | 140 | #region Encryption 141 | bool useEncrypt = !String.IsNullOrEmpty(txtPass1.Text) && gbEncryption.Enabled; 142 | string password = ""; 143 | if (useEncrypt) 144 | { 145 | password = txtPass1.Text; 146 | if (!password.Equals(txtPass2.Text)) 147 | { 148 | FatalError(this.FindForm(), "Password does not match."); 149 | return; 150 | } 151 | sbSwitches.AppendFormat(" -p{0}", password); 152 | } 153 | #endregion Encryption 154 | 155 | /// Compression level 156 | var level = (CompressionLevel)((ComboBoxItem)cboCompressionLevel.SelectedItem).Value; 157 | sbSwitches.AppendFormat(" -mx{0}", (int)level); 158 | 159 | var updateMode = (UpdateMode)((ComboBoxItem)cboUpdateMode.SelectedItem).Value; 160 | #region Update mode 161 | switch (updateMode) 162 | { 163 | case UpdateMode.AddAndReplace: 164 | break; 165 | case UpdateMode.UpdateAndAdd: 166 | command = "u "; 167 | break; 168 | case UpdateMode.FreshenExisting: 169 | sbSwitches.Append(" -up1q1r0x1y2z1w2"); 170 | break; 171 | case UpdateMode.Synchronize: 172 | sbSwitches.Append(" -up1q0r2x1y2z1w2"); 173 | break; 174 | } 175 | #endregion Update mode 176 | 177 | #region Path mode 178 | 179 | #endregion Path mode 180 | 181 | #region combobox 182 | if (chkSFX.Checked) 183 | sbSwitches.Append(" -spf"); 184 | if (chkDeleteAfterCompression.Checked) 185 | sbSwitches.Append(" -sdel"); 186 | #endregion combobox 187 | 188 | #region Run 7za.exe 189 | 190 | var fileLists = String.Concat(Path.GetTempFileName(), Guid.NewGuid().ToString(), ".txt"); 191 | File.WriteAllLines(fileLists, arrPaths); 192 | 193 | var pInfo = new System.Diagnostics.ProcessStartInfo() 194 | { 195 | FileName = Path7za, 196 | Arguments = String.Format("{0} \"{1}\" @\"{2}\" {3}", command, archiveName, fileLists, sbSwitches.ToString()), 197 | WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden 198 | }; 199 | System.Diagnostics.Process x = null; 200 | try 201 | { 202 | btnOK.Enabled = false; 203 | x = System.Diagnostics.Process.Start(pInfo); 204 | 205 | Task task = Task.Run(() => x.WaitForExit()); 206 | await task; 207 | if (task.IsCompleted) 208 | { 209 | switch (x.ExitCode) 210 | { 211 | case 0: break; 212 | case 1: FatalError(this.FindForm(), @"Warning (Non fatal error(s)). 213 | For example, one or more files were locked by some other application, so they were not compressed.", 214 | MessageBoxIcon.Information); 215 | break; 216 | case 2: FatalError(this.FindForm(), "Some errors occur"); break; 217 | case 7: FatalError(this.FindForm(), "Arguments errors occur" + Environment.NewLine + 218 | pInfo.Arguments ); 219 | break; 220 | case 8: FatalError(this.FindForm(), "Not enough sufficient memory for operation"); break; 221 | case 255: FatalError(this.FindForm(), "User stops the operation"); break; 222 | } 223 | } 224 | } 225 | finally 226 | { 227 | if (null != x) x.Close(); 228 | this.DialogResult = DialogResult.OK; 229 | File.Delete(fileLists); 230 | } 231 | 232 | #endregion Run 7za.exe 233 | } 234 | 235 | void BtnOpenSaveDialog_Click(object sender, EventArgs e) 236 | { 237 | string directory = Path.GetDirectoryName(arrPaths[0]); 238 | using (var ofd = new SaveFileDialog() 239 | { 240 | CheckPathExists = true, 241 | ValidateNames = true, 242 | InitialDirectory = directory, 243 | FileName = txtFileName.Text 244 | }) 245 | { 246 | var dResult = ofd.ShowDialog(this.FindForm()); 247 | if (dResult == DialogResult.OK) 248 | { 249 | txtFileName.Text = Path.GetFileName(ofd.FileName); 250 | lblSaveFilePath.Text = Path.GetDirectoryName(ofd.FileName); 251 | } 252 | } 253 | } 254 | #endregion Button events 255 | 256 | #region Init combobox contents 257 | void InitArchiveFormat() 258 | { 259 | cboArchiveFormat.DataSource = Enum.GetValues(typeof(ArchiveFormat)); 260 | cboArchiveFormat.SelectionChangeCommitted += CboArchiveFormat_SelectionChangeCommitted; 261 | } 262 | 263 | void CboArchiveFormat_SelectionChangeCommitted(object sender, EventArgs e) 264 | { 265 | var format = (ArchiveFormat)cboArchiveFormat.SelectedItem; 266 | if (Enum.IsDefined(typeof(ArchiveFormat), format)) 267 | { 268 | InitCompressionLevel(format); 269 | bool is7zipOrZip = format == ArchiveFormat.zip || format == ArchiveFormat.p7z; 270 | if (is7zipOrZip) 271 | { 272 | InitEncryptionMethod(format); 273 | gbEncryption.Enabled = true; 274 | } 275 | else 276 | { 277 | gbEncryption.Enabled = false; 278 | } 279 | string name = txtFileName.Text; 280 | if (format == ArchiveFormat.p7z) 281 | { 282 | name = Path.ChangeExtension(name, ".7z"); 283 | } 284 | else 285 | { 286 | name = Path.ChangeExtension(name, "." + format.ToString()); 287 | } 288 | 289 | txtFileName.Text = name; 290 | } 291 | } 292 | 293 | void InitCompressionLevel(ArchiveFormat format) 294 | { 295 | cboCompressionLevel.Items.Clear(); 296 | ComboBoxItem item = null; 297 | if (format == ArchiveFormat.p7z || format == ArchiveFormat.zip) 298 | { 299 | ComboBoxItem[] arrItems = new ComboBoxItem[6]; 300 | 301 | #region Add items 302 | item = new ComboBoxItem() 303 | { 304 | Text = CompressionLevel.Fast.ToString(), 305 | Value = CompressionLevel.Fast 306 | }; 307 | arrItems[0] = item; 308 | 309 | item = new ComboBoxItem() 310 | { 311 | Text = CompressionLevel.Fastest.ToString(), 312 | Value = CompressionLevel.Fastest 313 | }; 314 | arrItems[1] = item; 315 | 316 | item = new ComboBoxItem() 317 | { 318 | Text = CompressionLevel.Maximum.ToString(), 319 | Value = CompressionLevel.Maximum 320 | }; 321 | arrItems[2] = item; 322 | 323 | item = new ComboBoxItem() 324 | { 325 | Text = CompressionLevel.Normal.ToString(), 326 | Value = CompressionLevel.Normal 327 | }; 328 | arrItems[3] = item; 329 | 330 | item = new ComboBoxItem() 331 | { 332 | Text = CompressionLevel.Store.ToString(), 333 | Value = CompressionLevel.Store 334 | }; 335 | arrItems[4] = item; 336 | 337 | item = new ComboBoxItem() 338 | { 339 | Text = CompressionLevel.Ultra.ToString(), 340 | Value = CompressionLevel.Ultra 341 | }; 342 | arrItems[5] = item; 343 | #endregion Add items 344 | 345 | cboCompressionLevel.BeginUpdate(); 346 | cboCompressionLevel.Items.AddRange(arrItems); 347 | cboCompressionLevel.SelectedIndex = 3; 348 | cboCompressionLevel.EndUpdate(); 349 | } 350 | else 351 | { 352 | item = new ComboBoxItem() 353 | { 354 | Text = CompressionLevel.Store.ToString(), 355 | Value = CompressionLevel.Store 356 | }; 357 | cboCompressionLevel.Items.Add(item); 358 | cboCompressionLevel.SelectedIndex = 0; 359 | } 360 | } 361 | 362 | void InitUpdateMode() 363 | { 364 | ComboBoxItem[] cboItems = new ComboBoxItem[4]; 365 | 366 | ComboBoxItem item = new ComboBoxItem() 367 | { 368 | Text = "Add and replace files", 369 | Value = UpdateMode.AddAndReplace 370 | }; 371 | cboItems[0] = item; 372 | 373 | item = new ComboBoxItem() 374 | { 375 | Text = "Freshen Existing files", 376 | Value = UpdateMode.FreshenExisting 377 | }; 378 | cboItems[1] = item; 379 | 380 | item = new ComboBoxItem() 381 | { 382 | Text = "Synchronize files", 383 | Value = UpdateMode.Synchronize 384 | }; 385 | cboItems[2] = item; 386 | 387 | item = new ComboBoxItem() 388 | { 389 | Text = "Update and add files", 390 | Value = UpdateMode.UpdateAndAdd 391 | }; 392 | cboItems[3] = item; 393 | 394 | cboUpdateMode.BeginUpdate(); 395 | cboUpdateMode.Items.AddRange(cboItems); 396 | cboUpdateMode.EndUpdate(); 397 | cboUpdateMode.SelectedIndex = 0; 398 | } 399 | 400 | void InitPathMode() 401 | { 402 | ComboBoxItem[] cboItems = new ComboBoxItem[3]; 403 | 404 | ComboBoxItem item = new ComboBoxItem() 405 | { 406 | Text = "Relative pathnames", 407 | Value = PathMode.Relative 408 | }; 409 | cboItems[0] = item; 410 | 411 | item = new ComboBoxItem() 412 | { 413 | Text = "Full pathnames", 414 | Value = PathMode.Full 415 | }; 416 | cboItems[1] = item; 417 | 418 | item = new ComboBoxItem() 419 | { 420 | Text = "Absolute pathnames", 421 | Value = PathMode.Absolute 422 | }; 423 | cboItems[2] = item; 424 | 425 | cboPathMode.BeginUpdate(); 426 | cboPathMode.Items.AddRange(cboItems); 427 | cboPathMode.EndUpdate(); 428 | cboPathMode.SelectedIndex = 0; 429 | } 430 | 431 | void InitEncryptionMethod(ArchiveFormat format) 432 | { 433 | cboEncryptMethod.Items.Clear(); 434 | ComboBoxItem item = null; 435 | switch (format) 436 | { 437 | case ArchiveFormat.zip: 438 | item = new ComboBoxItem() 439 | { 440 | Text = EncryptionMethod.ZipCrypto.ToString(), 441 | Value = EncryptionMethod.ZipCrypto 442 | }; 443 | cboEncryptMethod.Items.Add(item); 444 | item = new ComboBoxItem() 445 | { 446 | Text = EncryptionMethod.AES256.ToString(), 447 | Value = EncryptionMethod.AES256 448 | }; 449 | cboEncryptMethod.Items.Add(item); 450 | break; 451 | case ArchiveFormat.p7z: 452 | item = new ComboBoxItem() 453 | { 454 | Text = EncryptionMethod.AES256.ToString(), 455 | Value = EncryptionMethod.AES256 456 | }; 457 | cboEncryptMethod.Items.Add(item); 458 | break; 459 | } 460 | cboEncryptMethod.SelectedIndex = 0; 461 | } 462 | 463 | #endregion Init combobox contents 464 | 465 | public static void FatalError(IWin32Window handle, string text, MessageBoxIcon icon = MessageBoxIcon.Error) 466 | { 467 | string caption = "Total Commander"; 468 | MessageBox.Show(handle, text, caption, MessageBoxButtons.OK, icon); 469 | } 470 | } 471 | 472 | #region Enum Structures 473 | enum ArchiveFormat { zip = 0, p7z, wim, tar } 474 | 475 | enum CompressionLevel { Normal = 5, Fastest = 1, Fast = 3, Store = 0, Maximum = 7, Ultra = 9 } 476 | 477 | enum UpdateMode { AddAndReplace = 0, UpdateAndAdd, FreshenExisting, Synchronize } 478 | 479 | enum PathMode { Relative = 0, Full, Absolute } 480 | 481 | enum EncryptionMethod { ZipCrypto = 0, AES256 } 482 | #endregion Enum Structures 483 | } 484 | -------------------------------------------------------------------------------- /TotalCommander/GUI/FormPacking.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace TotalCommander.GUI 2 | { 3 | partial class FormPacking 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormPacking)); 32 | this.label1 = new System.Windows.Forms.Label(); 33 | this.lblSaveFilePath = new System.Windows.Forms.Label(); 34 | this.txtFileName = new System.Windows.Forms.TextBox(); 35 | this.label2 = new System.Windows.Forms.Label(); 36 | this.label3 = new System.Windows.Forms.Label(); 37 | this.cboArchiveFormat = new System.Windows.Forms.ComboBox(); 38 | this.cboCompressionLevel = new System.Windows.Forms.ComboBox(); 39 | this.cboPathMode = new System.Windows.Forms.ComboBox(); 40 | this.cboUpdateMode = new System.Windows.Forms.ComboBox(); 41 | this.label4 = new System.Windows.Forms.Label(); 42 | this.label5 = new System.Windows.Forms.Label(); 43 | this.groupBox1 = new System.Windows.Forms.GroupBox(); 44 | this.gbEncryption = new System.Windows.Forms.GroupBox(); 45 | this.txtPass1 = new System.Windows.Forms.TextBox(); 46 | this.txtPass2 = new System.Windows.Forms.TextBox(); 47 | this.label6 = new System.Windows.Forms.Label(); 48 | this.label7 = new System.Windows.Forms.Label(); 49 | this.panel1 = new System.Windows.Forms.Panel(); 50 | this.chkSFX = new System.Windows.Forms.CheckBox(); 51 | this.chkDeleteAfterCompression = new System.Windows.Forms.CheckBox(); 52 | this.btnShowPassword = new System.Windows.Forms.Button(); 53 | this.cboEncryptMethod = new System.Windows.Forms.ComboBox(); 54 | this.label8 = new System.Windows.Forms.Label(); 55 | this.btnOK = new System.Windows.Forms.Button(); 56 | this.btnCancel = new System.Windows.Forms.Button(); 57 | this.btnOpenSaveDialog = new System.Windows.Forms.Button(); 58 | this.panel2 = new System.Windows.Forms.Panel(); 59 | this.groupBox1.SuspendLayout(); 60 | this.gbEncryption.SuspendLayout(); 61 | this.panel1.SuspendLayout(); 62 | this.panel2.SuspendLayout(); 63 | this.SuspendLayout(); 64 | // 65 | // label1 66 | // 67 | this.label1.AutoSize = true; 68 | this.label1.Location = new System.Drawing.Point(4, 16); 69 | this.label1.Name = "label1"; 70 | this.label1.Size = new System.Drawing.Size(50, 15); 71 | this.label1.TabIndex = 0; 72 | this.label1.Text = "Archive:"; 73 | // 74 | // lblSaveFilePath 75 | // 76 | this.lblSaveFilePath.AutoSize = true; 77 | this.lblSaveFilePath.Location = new System.Drawing.Point(60, 4); 78 | this.lblSaveFilePath.Name = "lblSaveFilePath"; 79 | this.lblSaveFilePath.Size = new System.Drawing.Size(31, 15); 80 | this.lblSaveFilePath.TabIndex = 1; 81 | this.lblSaveFilePath.Text = "Path"; 82 | // 83 | // txtFileName 84 | // 85 | this.txtFileName.Location = new System.Drawing.Point(60, 22); 86 | this.txtFileName.Name = "txtFileName"; 87 | this.txtFileName.Size = new System.Drawing.Size(518, 23); 88 | this.txtFileName.TabIndex = 2; 89 | // 90 | // label2 91 | // 92 | this.label2.AutoSize = true; 93 | this.label2.Location = new System.Drawing.Point(4, 61); 94 | this.label2.Name = "label2"; 95 | this.label2.Size = new System.Drawing.Size(89, 15); 96 | this.label2.TabIndex = 4; 97 | this.label2.Text = "Archive format:"; 98 | // 99 | // label3 100 | // 101 | this.label3.AutoSize = true; 102 | this.label3.Location = new System.Drawing.Point(4, 89); 103 | this.label3.Name = "label3"; 104 | this.label3.Size = new System.Drawing.Size(107, 15); 105 | this.label3.TabIndex = 5; 106 | this.label3.Text = "Compression level:"; 107 | // 108 | // cboArchiveFormat 109 | // 110 | this.cboArchiveFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 111 | this.cboArchiveFormat.FormattingEnabled = true; 112 | this.cboArchiveFormat.Location = new System.Drawing.Point(119, 58); 113 | this.cboArchiveFormat.Name = "cboArchiveFormat"; 114 | this.cboArchiveFormat.Size = new System.Drawing.Size(121, 23); 115 | this.cboArchiveFormat.TabIndex = 6; 116 | this.cboArchiveFormat.TabStop = false; 117 | // 118 | // cboCompressionLevel 119 | // 120 | this.cboCompressionLevel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 121 | this.cboCompressionLevel.FormattingEnabled = true; 122 | this.cboCompressionLevel.Location = new System.Drawing.Point(119, 89); 123 | this.cboCompressionLevel.Name = "cboCompressionLevel"; 124 | this.cboCompressionLevel.Size = new System.Drawing.Size(121, 23); 125 | this.cboCompressionLevel.TabIndex = 7; 126 | this.cboCompressionLevel.TabStop = false; 127 | // 128 | // cboPathMode 129 | // 130 | this.cboPathMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 131 | this.cboPathMode.FormattingEnabled = true; 132 | this.cboPathMode.Location = new System.Drawing.Point(434, 89); 133 | this.cboPathMode.Name = "cboPathMode"; 134 | this.cboPathMode.Size = new System.Drawing.Size(180, 23); 135 | this.cboPathMode.TabIndex = 11; 136 | this.cboPathMode.TabStop = false; 137 | // 138 | // cboUpdateMode 139 | // 140 | this.cboUpdateMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 141 | this.cboUpdateMode.FormattingEnabled = true; 142 | this.cboUpdateMode.Location = new System.Drawing.Point(434, 58); 143 | this.cboUpdateMode.Name = "cboUpdateMode"; 144 | this.cboUpdateMode.Size = new System.Drawing.Size(180, 23); 145 | this.cboUpdateMode.TabIndex = 10; 146 | this.cboUpdateMode.TabStop = false; 147 | // 148 | // label4 149 | // 150 | this.label4.AutoSize = true; 151 | this.label4.Location = new System.Drawing.Point(319, 89); 152 | this.label4.Name = "label4"; 153 | this.label4.Size = new System.Drawing.Size(68, 15); 154 | this.label4.TabIndex = 9; 155 | this.label4.Text = "Path mode:"; 156 | // 157 | // label5 158 | // 159 | this.label5.AutoSize = true; 160 | this.label5.Location = new System.Drawing.Point(319, 61); 161 | this.label5.Name = "label5"; 162 | this.label5.Size = new System.Drawing.Size(82, 15); 163 | this.label5.TabIndex = 8; 164 | this.label5.Text = "Update mode:"; 165 | // 166 | // groupBox1 167 | // 168 | this.groupBox1.Controls.Add(this.chkDeleteAfterCompression); 169 | this.groupBox1.Controls.Add(this.chkSFX); 170 | this.groupBox1.Location = new System.Drawing.Point(7, 128); 171 | this.groupBox1.Name = "groupBox1"; 172 | this.groupBox1.Size = new System.Drawing.Size(301, 80); 173 | this.groupBox1.TabIndex = 12; 174 | this.groupBox1.TabStop = false; 175 | this.groupBox1.Text = "Options"; 176 | // 177 | // gbEncryption 178 | // 179 | this.gbEncryption.Controls.Add(this.panel2); 180 | this.gbEncryption.Controls.Add(this.cboEncryptMethod); 181 | this.gbEncryption.Controls.Add(this.label8); 182 | this.gbEncryption.Controls.Add(this.panel1); 183 | this.gbEncryption.Controls.Add(this.label6); 184 | this.gbEncryption.Controls.Add(this.label7); 185 | this.gbEncryption.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 186 | this.gbEncryption.Location = new System.Drawing.Point(314, 128); 187 | this.gbEncryption.Name = "gbEncryption"; 188 | this.gbEncryption.Size = new System.Drawing.Size(311, 158); 189 | this.gbEncryption.TabIndex = 13; 190 | this.gbEncryption.TabStop = false; 191 | this.gbEncryption.Text = "Encryption"; 192 | // 193 | // txtPass1 194 | // 195 | this.txtPass1.BorderStyle = System.Windows.Forms.BorderStyle.None; 196 | this.txtPass1.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 197 | this.txtPass1.Location = new System.Drawing.Point(0, 3); 198 | this.txtPass1.Margin = new System.Windows.Forms.Padding(0); 199 | this.txtPass1.Name = "txtPass1"; 200 | this.txtPass1.Size = new System.Drawing.Size(290, 22); 201 | this.txtPass1.TabIndex = 14; 202 | // 203 | // txtPass2 204 | // 205 | this.txtPass2.BorderStyle = System.Windows.Forms.BorderStyle.None; 206 | this.txtPass2.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 207 | this.txtPass2.Location = new System.Drawing.Point(0, 3); 208 | this.txtPass2.Margin = new System.Windows.Forms.Padding(0); 209 | this.txtPass2.Name = "txtPass2"; 210 | this.txtPass2.Size = new System.Drawing.Size(256, 22); 211 | this.txtPass2.TabIndex = 15; 212 | // 213 | // label6 214 | // 215 | this.label6.AutoSize = true; 216 | this.label6.Location = new System.Drawing.Point(6, 65); 217 | this.label6.Name = "label6"; 218 | this.label6.Size = new System.Drawing.Size(103, 15); 219 | this.label6.TabIndex = 15; 220 | this.label6.Text = "Reenter password:"; 221 | // 222 | // label7 223 | // 224 | this.label7.AutoSize = true; 225 | this.label7.Location = new System.Drawing.Point(6, 19); 226 | this.label7.Name = "label7"; 227 | this.label7.Size = new System.Drawing.Size(90, 15); 228 | this.label7.TabIndex = 14; 229 | this.label7.Text = "Enter password:"; 230 | // 231 | // panel1 232 | // 233 | this.panel1.BackColor = System.Drawing.SystemColors.Window; 234 | this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 235 | this.panel1.Controls.Add(this.btnShowPassword); 236 | this.panel1.Controls.Add(this.txtPass2); 237 | this.panel1.Location = new System.Drawing.Point(9, 83); 238 | this.panel1.Margin = new System.Windows.Forms.Padding(0); 239 | this.panel1.Name = "panel1"; 240 | this.panel1.Size = new System.Drawing.Size(290, 30); 241 | this.panel1.TabIndex = 16; 242 | // 243 | // chkSFX 244 | // 245 | this.chkSFX.AutoSize = true; 246 | this.chkSFX.Location = new System.Drawing.Point(6, 22); 247 | this.chkSFX.Name = "chkSFX"; 248 | this.chkSFX.Size = new System.Drawing.Size(123, 19); 249 | this.chkSFX.TabIndex = 0; 250 | this.chkSFX.TabStop = false; 251 | this.chkSFX.Text = "Create SFX archive"; 252 | this.chkSFX.UseVisualStyleBackColor = true; 253 | // 254 | // chkDeleteAfterCompression 255 | // 256 | this.chkDeleteAfterCompression.AutoSize = true; 257 | this.chkDeleteAfterCompression.Location = new System.Drawing.Point(5, 47); 258 | this.chkDeleteAfterCompression.Name = "chkDeleteAfterCompression"; 259 | this.chkDeleteAfterCompression.Size = new System.Drawing.Size(181, 19); 260 | this.chkDeleteAfterCompression.TabIndex = 2; 261 | this.chkDeleteAfterCompression.TabStop = false; 262 | this.chkDeleteAfterCompression.Text = "Delete files after compression"; 263 | this.chkDeleteAfterCompression.UseVisualStyleBackColor = true; 264 | // 265 | // btnShowPassword 266 | // 267 | this.btnShowPassword.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 268 | this.btnShowPassword.Image = global::TotalCommander.Properties.Resources.Show_Password_24; 269 | this.btnShowPassword.Location = new System.Drawing.Point(259, -1); 270 | this.btnShowPassword.Margin = new System.Windows.Forms.Padding(0); 271 | this.btnShowPassword.Name = "btnShowPassword"; 272 | this.btnShowPassword.Size = new System.Drawing.Size(30, 30); 273 | this.btnShowPassword.TabIndex = 16; 274 | this.btnShowPassword.TabStop = false; 275 | this.btnShowPassword.UseVisualStyleBackColor = true; 276 | // 277 | // cboEncryptMethod 278 | // 279 | this.cboEncryptMethod.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; 280 | this.cboEncryptMethod.FormattingEnabled = true; 281 | this.cboEncryptMethod.Location = new System.Drawing.Point(126, 125); 282 | this.cboEncryptMethod.Name = "cboEncryptMethod"; 283 | this.cboEncryptMethod.Size = new System.Drawing.Size(121, 23); 284 | this.cboEncryptMethod.TabIndex = 15; 285 | this.cboEncryptMethod.TabStop = false; 286 | // 287 | // label8 288 | // 289 | this.label8.AutoSize = true; 290 | this.label8.Location = new System.Drawing.Point(9, 128); 291 | this.label8.Name = "label8"; 292 | this.label8.Size = new System.Drawing.Size(112, 15); 293 | this.label8.TabIndex = 14; 294 | this.label8.Text = "Encryption method:"; 295 | // 296 | // btnOK 297 | // 298 | this.btnOK.Anchor = System.Windows.Forms.AnchorStyles.Bottom; 299 | this.btnOK.AutoSize = true; 300 | this.btnOK.BackColor = System.Drawing.Color.Green; 301 | this.btnOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 302 | this.btnOK.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 303 | this.btnOK.ForeColor = System.Drawing.SystemColors.Window; 304 | this.btnOK.Location = new System.Drawing.Point(24, 246); 305 | this.btnOK.Margin = new System.Windows.Forms.Padding(0); 306 | this.btnOK.Name = "btnOK"; 307 | this.btnOK.Size = new System.Drawing.Size(55, 27); 308 | this.btnOK.TabIndex = 17; 309 | this.btnOK.Text = "OK"; 310 | this.btnOK.UseVisualStyleBackColor = false; 311 | // 312 | // btnCancel 313 | // 314 | this.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom; 315 | this.btnCancel.AutoSize = true; 316 | this.btnCancel.BackColor = System.Drawing.Color.Red; 317 | this.btnCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 318 | this.btnCancel.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 319 | this.btnCancel.ForeColor = System.Drawing.SystemColors.Window; 320 | this.btnCancel.Location = new System.Drawing.Point(132, 246); 321 | this.btnCancel.Margin = new System.Windows.Forms.Padding(0); 322 | this.btnCancel.Name = "btnCancel"; 323 | this.btnCancel.Size = new System.Drawing.Size(55, 27); 324 | this.btnCancel.TabIndex = 18; 325 | this.btnCancel.Text = "Cancel"; 326 | this.btnCancel.UseVisualStyleBackColor = false; 327 | // 328 | // btnOpenSaveDialog 329 | // 330 | this.btnOpenSaveDialog.Anchor = System.Windows.Forms.AnchorStyles.Bottom; 331 | this.btnOpenSaveDialog.AutoSize = true; 332 | this.btnOpenSaveDialog.BackColor = System.Drawing.Color.Green; 333 | this.btnOpenSaveDialog.FlatStyle = System.Windows.Forms.FlatStyle.Flat; 334 | this.btnOpenSaveDialog.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 335 | this.btnOpenSaveDialog.ForeColor = System.Drawing.SystemColors.Window; 336 | this.btnOpenSaveDialog.Location = new System.Drawing.Point(582, 19); 337 | this.btnOpenSaveDialog.Margin = new System.Windows.Forms.Padding(0); 338 | this.btnOpenSaveDialog.Name = "btnOpenSaveDialog"; 339 | this.btnOpenSaveDialog.Size = new System.Drawing.Size(28, 27); 340 | this.btnOpenSaveDialog.TabIndex = 19; 341 | this.btnOpenSaveDialog.TabStop = false; 342 | this.btnOpenSaveDialog.Text = "..."; 343 | this.btnOpenSaveDialog.UseVisualStyleBackColor = false; 344 | // 345 | // panel2 346 | // 347 | this.panel2.BackColor = System.Drawing.SystemColors.Window; 348 | this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 349 | this.panel2.Controls.Add(this.txtPass1); 350 | this.panel2.Location = new System.Drawing.Point(9, 36); 351 | this.panel2.Margin = new System.Windows.Forms.Padding(0); 352 | this.panel2.Name = "panel2"; 353 | this.panel2.Size = new System.Drawing.Size(290, 30); 354 | this.panel2.TabIndex = 20; 355 | // 356 | // FormPacking 357 | // 358 | this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); 359 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 360 | this.ClientSize = new System.Drawing.Size(624, 309); 361 | this.Controls.Add(this.btnOpenSaveDialog); 362 | this.Controls.Add(this.btnCancel); 363 | this.Controls.Add(this.btnOK); 364 | this.Controls.Add(this.gbEncryption); 365 | this.Controls.Add(this.groupBox1); 366 | this.Controls.Add(this.cboPathMode); 367 | this.Controls.Add(this.cboUpdateMode); 368 | this.Controls.Add(this.label4); 369 | this.Controls.Add(this.label5); 370 | this.Controls.Add(this.cboCompressionLevel); 371 | this.Controls.Add(this.cboArchiveFormat); 372 | this.Controls.Add(this.label3); 373 | this.Controls.Add(this.label2); 374 | this.Controls.Add(this.txtFileName); 375 | this.Controls.Add(this.lblSaveFilePath); 376 | this.Controls.Add(this.label1); 377 | this.DoubleBuffered = true; 378 | this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); 379 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 380 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 381 | this.KeyPreview = true; 382 | this.MaximizeBox = false; 383 | this.MinimizeBox = false; 384 | this.Name = "FormPacking"; 385 | this.Text = "Pack Files"; 386 | this.groupBox1.ResumeLayout(false); 387 | this.groupBox1.PerformLayout(); 388 | this.gbEncryption.ResumeLayout(false); 389 | this.gbEncryption.PerformLayout(); 390 | this.panel1.ResumeLayout(false); 391 | this.panel1.PerformLayout(); 392 | this.panel2.ResumeLayout(false); 393 | this.panel2.PerformLayout(); 394 | this.ResumeLayout(false); 395 | this.PerformLayout(); 396 | 397 | } 398 | 399 | #endregion 400 | 401 | private System.Windows.Forms.Label label1; 402 | private System.Windows.Forms.Label lblSaveFilePath; 403 | private System.Windows.Forms.TextBox txtFileName; 404 | private System.Windows.Forms.Label label2; 405 | private System.Windows.Forms.Label label3; 406 | private System.Windows.Forms.ComboBox cboArchiveFormat; 407 | private System.Windows.Forms.ComboBox cboCompressionLevel; 408 | private System.Windows.Forms.ComboBox cboPathMode; 409 | private System.Windows.Forms.ComboBox cboUpdateMode; 410 | private System.Windows.Forms.Label label4; 411 | private System.Windows.Forms.Label label5; 412 | private System.Windows.Forms.GroupBox groupBox1; 413 | private System.Windows.Forms.GroupBox gbEncryption; 414 | private System.Windows.Forms.Panel panel1; 415 | private System.Windows.Forms.TextBox txtPass2; 416 | private System.Windows.Forms.Label label6; 417 | private System.Windows.Forms.Label label7; 418 | private System.Windows.Forms.TextBox txtPass1; 419 | private System.Windows.Forms.CheckBox chkDeleteAfterCompression; 420 | private System.Windows.Forms.CheckBox chkSFX; 421 | private System.Windows.Forms.ComboBox cboEncryptMethod; 422 | private System.Windows.Forms.Label label8; 423 | private System.Windows.Forms.Button btnShowPassword; 424 | private System.Windows.Forms.Button btnOK; 425 | private System.Windows.Forms.Button btnCancel; 426 | private System.Windows.Forms.Panel panel2; 427 | private System.Windows.Forms.Button btnOpenSaveDialog; 428 | } 429 | } --------------------------------------------------------------------------------