Click here to Skip to main content
15,867,141 members
Articles / Programming Languages / C#

Dual Pane File Manager

Rate me:
Please Sign up or sign in to vote.
4.64/5 (28 votes)
21 Dec 2010CPOL8 min read 140K   2.2K   119   37
A dual pane file manager for Windows XP.

Dual Pane File Manager

Introduction

I know where the scissors are kept, where the spare light bulbs are, and where my first aid box is. I also know where I keep files on my computer.

I don't find Windows Explorer very useful for managing files. To me, a file manager has a "source" on the left and a "destination" on the right, with the ability to quickly copy or move files from source to destination, and to create shortcuts.

Jeff's File Manager (a dual pane file manager) is my attempt to produce a tool that lets me manage my files. It does many of the things that Windows Explorer does; it has a context menu (in fact, the Explorer context menu), and I can drag and drop files/folders. In some respects, it goes a bit further than Explorer in that it shows ghosted icons for empty CD/DVD drives. If you accidentally click on an empty CD/DVD drive, it won't open it and crash it into the door on your computer (I imagine Microsoft Vista/Win7 programmers don't have computers with doors on), it will just beep at you and tell you access is denied.

It doesn't show "My Documents" or the control panel, nor does it show the network - although it will show mapped network drives, in fact it will show anything with a drive letter.

NET and Files/Folders

There are several classes in .NET relating to file/folder handling, and the DriveInfo class has been added in version 2. However, there is still no .NET way to find the correct icon for any of these, or to find the proper mask for the icon – so that shares and system folders show up properly. There is also no .NET way to show the Explorer context menu. What I have done is to use the .NET classes as far as possible, and fallen back on the API where I couldn't find a .NET solution. In fact, it makes quite extensive use of the Windows API, and we can only hope that eventually Microsoft will extend the .NET Framework to give us easier access to the various interfaces that are needed for an app like this.

Application Structure

At the top level, there is a Windows Form: FormFileManager. This has the main menu and a Splitter control. Within the Splitter control sits two instances of a User Control called JExplorerFS, the one on the left is the source and the one on the right, the destination.

In turn, the JExplorerFS control contains further controls - a JCrumbToolBar (inherited from System.Windows.Forms.ToolStrip), a JTreeViewFS (inherited from System.Windows.Forms.TreeView), and a JListViewFS (inherited from System.Windows.Forms.ListView). Each of these controls is self contained so the JExplorerFS brings them all together and communicates between them.

The main from contains a standard ToolBar for quick access to functions, and each of the JExplorerFS controls has its own ToolBar.

Using the Application

If you treat it like two instances of Windows Explorer running side by side, you won't go far wrong - except there are buttons to allow you to copy/move files from the source to destination.

The main toolbar allows you to change the layout, compare file names between folders, compare files between folders, copy, move, and create shortcuts, copy and move with a rename, flip panes, and map/unmap network drives.

The toolbars in the source and destination panes are fairly self explanatory. There is an option to "Save File Icon" in the Tools menu. Ironically, it works with most things except file icons, and the various solutions I found on the Internet to save icons don't seem to work. However, it will save other graphics formats. The options I use most frequently are duplicated in toolbar buttons.

The two buttons that might need explaining are:

  • Favourites
  • This has nothing to do with Windows Favourites; it is a place to keep a note of the folders you use most. Click the main button to add the current folder, use the drop down to go to any listed folder.

  • External Applications
  • The program uses Windows file associations, so double clicking a file will open it in accordance with its file association (double clicking an executable will run it). If you want to open a file with a different application, you can add the application path (click the main button) and then use the drop down to pass whatever parameters are needed. You can pass no parameters (the application will just open), a working directory, the currently selected directory, or the full path of the currently selected file.

Speed of Application

I was anxious to ensure the program ran at a reasonable speed.

The first obvious bottleneck was getting the drive information which is used three times in each of the JExplorerFS controls, making six times for the two controls. What I did was to set up all the information that was needed in a class called JDriveData which a List<DriveInfo> and a List<JTagData>. These are set up the first time they are called – and can be refreshed when needed. The class is static and I found it easier to use a List<T> than a Collections class.

The second bottleneck was setting the JTreeViewFS to a new path. Because, information is only added to a node when it is expanded (and deleted when it is collapsed).

I decided to keep a Dictionary<string, TreeNode> to link file paths to a TreeNode. This Dictionary is updated each time a TreeNode is expanded or collapsed. Finding a specific folder is a case of finding its root in the Dictionary, then expanding it and looking again until the required path is found. It can be slow; setting the JTreeViewFS to a directory from, say, the favourites list means it has to start at the lowest common denominator (which in the worst case might be the root node) and work through expanding nodes as it goes. It's currently as quick as I can make it. It is certainly quicker to navigate by selecting the appropriate directory in the TreeView than any other means.

Acknowledgements

Programming is a hobby for me. I have had a lot of help from various people over the years, generously and freely given, for which I am grateful.

I have acknowledged specific contributions in the source code.

Using the Code

I have tried to document the code as completely as possible; as it stands, this is a complete application, but there may be useful bits that can be pulled out and used in other projects. There is a basic readme, called JGFileManager.txt, included.

Class Example

This is the JDriveData class:

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace JGFSControls
{
    //    Try and speed things up by using the same Drive Array for all controls
    internal class JDriveData
    {
        private static List<DriveInfo> m_DriveList = null;
        private static List<JTagData> m_TagDataList = null;

        private static void GetDriveData(bool refresh)
        {     
            if (refresh || m_DriveList == null)
            {
                m_DriveList = new List<DriveInfo>();
                DriveInfo[] driveArray = DriveInfo.GetDrives();
                foreach (DriveInfo current in driveArray)
                {
                    m_DriveList.Add(current);
                }
            }
        }

        private static void GetDriveTagDataList(bool refresh)
        {
            if (refresh || m_TagDataList == null)
            {
                GetDriveData(refresh); 
                JTagData tagData;
                m_TagDataList = new List<JTagData>();
                List<DriveInfo> driveArray = DriveList;
            
                foreach (DriveInfo current in driveArray)
                {
                    tagData = new JTagData(current);
                    m_TagDataList.Add(tagData);
                }
            }
        }

        internal static List<DriveInfo> DriveList
        {
            get
            {
                if (m_DriveList == null)
                    GetDriveData(true);
            
                return m_DriveList;
            }
        }

        internal static void RefreshDriveData()
        {
            GetDriveData(true);
            GetDriveTagDataList(true);
        }

        internal static List<JTagData> DriveTagDataList
        {
            get
            {
                if (m_TagDataList == null)
                    GetDriveTagDataList(true);
                return m_TagDataList;
            }
        }
    }
}

Memory Leaks

Using the API means moving out of the shelter of .NET’s memory management. I learnt (not quickly, I have to confess) to read the help that comes with Visual Studio, especially when using the API! Early versions of this program had massive memory leaks, and so I read the help file for every API call I used, and found the following relating to SHGetFileInfo:

If SHGetFileInfo returns an icon handle in the hIcon member of the SHFILEINFO structure pointed to by psfi, you are responsible for freeing it with DestroyIcon when you no longer need it.

Whoops!

My fault, I really should read the help more closely. I hope that I have picked up all the memory issues now.

History

  • 7th July, 2006
    • This is version 3.1, the latest version in a project I have been working on for a few years on and off. It is getting there, but I would certainly appreciate any feedback.
  • 28th July, 2006
    • I have called this version 3.3 just to differentiate it from the earlier version.
    • I have updated this article to try and make it more readable.
    • I have dropped the earlier cJDirectoryInfo and cJFileInfo classes in the interest of optimization. The information is now set up directly in the cTNode and cLVItem classes.
    • I have set up the classes cFilerTS, cFilerTV, and cFilerLV to be self contained and to sit in cFiler.
    • I have corrected a couple of errors, such as shortcuts picking up the wrong icons, along with some silly mistakes, some of which were pointed out in emails (I do appreciate that, I think it is impossible to produce a program without bugs unless somebody else tries it).
    • I added a try/catch block when reading LastWriteTime as it seems to have problems with some of my CD-Rs.
    • I wanted to pick up changes to removable media, and tried a variety of approaches - WM_DEVICECHANGE is not propagated if you have CD AutoPlay off. I tried timers, but was worried about resource issues. In the end, I decided to check removable devices when you hover over them (in the TreeView or ListView). I'd be interested in feedback on this approach. I've just realized that I don't update the dropdown with the fresh information; I will have a look at that for a later version.
    • I have done a general clean up, and tried to make sure that functions are not duplicated.
    • I have added a class cUserFileAccessRights to indicate the user's access rights to folders (used in drag and drop). This class was written by Bruce Hatt here. It's an enormously useful class, and has no equivalent in .NET.
  • 2nd December, 2008
    • The source has been updated to version 5. It now incorporates favourites and runs faster.
    • I have removed the note keeping functions. If you use them, you will need to add them back from the old source.
  • 20th December, 2010
    • This is quite a major re-write which I have been doing over the last couple of years, so it is difficult to make a direct comparison with previous versions.
    • I have added a Crumb-Bar, which seems to be the modern trend.
    • I have done everything I can think of to make it as quick as possible, including the use of a Dictionary<string, TreeNode> in the JTreeViewFS class.
    • I have added a thumbnail view.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Retired
United Kingdom United Kingdom
I have been a keen hobbyist programmer since getting my first computer - a Vic 20 (you had to be able to write programs then since few programs were available and all were expensive).
Retired and now living in Pewsey, Wiltshire, where I spend (far too much of) my time writing computer programs to keep my mind active.

Comments and Discussions

 
QuestionCompiling in VS2019 Pin
altronics16-Jan-22 14:54
altronics16-Jan-22 14:54 
QuestionStart Directory Pin
Member 1073468511-Sep-20 16:51
Member 1073468511-Sep-20 16:51 
QuestionBoth panes' display synchronization Pin
transoft23-Jun-11 3:47
transoft23-Jun-11 3:47 
Generaldual panel file manager Pin
farszan10-Sep-10 11:02
farszan10-Sep-10 11:02 
GeneralBeen There Pin
thund3rstruck5-Dec-08 9:58
thund3rstruck5-Dec-08 9:58 
QuestionLooks like good work, But could not find EXE (or application) to run Pin
Harshdeep Mehta (4700787)4-Dec-08 5:58
Harshdeep Mehta (4700787)4-Dec-08 5:58 
GeneralIt's a cool project, but Pin
Oleksii Prosiankin4-Dec-08 1:31
Oleksii Prosiankin4-Dec-08 1:31 
GeneralRe: It's a cool project, but Pin
Jeff Gaines4-Dec-08 1:52
Jeff Gaines4-Dec-08 1:52 
GeneralRe: It's a cool project, but Pin
Oleksii Prosiankin4-Dec-08 2:36
Oleksii Prosiankin4-Dec-08 2:36 
GeneralRe: It's a cool project, but Pin
Oleksii Prosiankin4-Dec-08 3:37
Oleksii Prosiankin4-Dec-08 3:37 
GeneralRe: It's a cool project, but Pin
Jeff Gaines4-Dec-08 22:29
Jeff Gaines4-Dec-08 22:29 
GeneralRe: It's a cool project, but Pin
Oleksii Prosiankin5-Dec-08 0:17
Oleksii Prosiankin5-Dec-08 0:17 
GeneralWindows Explorer Context Menu Pin
Doncp27-Nov-08 16:25
Doncp27-Nov-08 16:25 
GeneralRe: Windows Explorer Context Menu Pin
Doncp28-Nov-08 5:54
Doncp28-Nov-08 5:54 
GeneralRe: Windows Explorer Context Menu Pin
Jeff Gaines29-Nov-08 0:09
Jeff Gaines29-Nov-08 0:09 
GeneralSuggestion [modified] Pin
faroo2819-Aug-06 23:23
faroo2819-Aug-06 23:23 
GeneralRe: Suggestion Pin
Jeff Gaines20-Aug-06 6:34
Jeff Gaines20-Aug-06 6:34 
GeneralGreat Works !! But a bit slow ... Pin
buster2232-Aug-06 8:17
buster2232-Aug-06 8:17 
GeneralRe: Great Works !! But a bit slow ... Pin
Jeff Gaines2-Aug-06 9:10
Jeff Gaines2-Aug-06 9:10 
GeneralRe: Great Works !! But a bit slow ... Pin
faroo2813-Jun-08 6:11
faroo2813-Jun-08 6:11 
GeneralPowerDesk Pin
Ted Ferenc29-Jul-06 22:10
Ted Ferenc29-Jul-06 22:10 
GeneralDirectory Opus Pin
Leo Davidson31-Jul-06 1:41
Leo Davidson31-Jul-06 1:41 
GeneralRe: Directory Opus Pin
Ted Ferenc31-Jul-06 3:38
Ted Ferenc31-Jul-06 3:38 
GeneralRe: Directory Opus Pin
simon.proctor31-Jul-06 3:53
simon.proctor31-Jul-06 3:53 
GeneralRe: Directory Opus Pin
MAP Tiger31-Jul-06 23:25
MAP Tiger31-Jul-06 23:25 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.