Introduction
This article shows the technique of creating a Windows-Explorer like interface using the Shell Folders for this purpose. Instead of the disk file structure, you also have the usual Windows-Explorer like features, Shell pop-up menu and to some extend drag-and-drop features. After having written articles on system file browsing which used Disk-Directory structures for processing information, I felt the need to write some article, true Windows-Explorer like articles using the same type of icons. I explored MSDN and found that it contained references to a similar interface named Enumdesk
, but the article was providing very sketchy information spread over 4 pages and even that information was incomplete (I thank them for it, at least I could search for information and write this article). The article referred to some structure, what was the full composition of the structure, how do they allocate memory to the structure before passing it to the tree /list items. Information about processing ITEMIDLIST
(like copy, concatenate) were also likewise not easy to find or not available. I persisted and managed to find some information in the .NET version of Visual Studio which helped me find the bare minimum necessary information to complete this article. Subsequently just for fun sake I added an ATL/WTL and Win32 version.
This article consists of the following 3 projects:
- ShellExplorer (MFC Version)
- ATLWindowsExplorer (ATL/WTL Version)
- Win32Explorer (Win32 Version)
- Classes
ShellViewClasses
ShellCtrlClasses
ShellExplorer
This is a MFC version having 3 views, a Tree or Folders view at the left-top, a Files or List view at left-bottom and another ListView
/Webbrowser
view at the right.
This version has an interesting feature, if in the Listview
at the left-bottom you double-click on files of type GIF, text, C, CPP, H the file is displayed in the ListView
at the right.
The list view at right also doubles as files browser or web-page browser, you can open a web-page from the menu or browse files by expanding the Tree view at the left-top.
The right-top view when used under Windows2000 has sort facility and also additional columns not available under Windows98 (a pop-up menu displays when you right click on a column header). It also has drag-n-drop features. If you have short-cuts for OLE-aware applications like Paintbrush, Excel, NotePad etc., you can drag-n-drop a file of these types on these applications short-cut from this view or create short-cuts on the desktop. But not in the TreeView
at the left-top, but if you drag an item from the right-top view and move to cursor on the plus sign of the TreeView
, you do get a feeling of drag-n-drop but code for drop has been commented out due to errors, likewise you can also fake drag-n-drop from the left-bottom view to the TreeView
above.
ATLWindowsExplorer
This project was created using an Appwizard downloaded from Microsoft's website, you can create Bitmaps on window menus and also pop-up menu with the least amount of effort in this environment, it uses a Win32 like programming style but you will note that most of the source code written by me is in the Header file (.H) not .cpp files. When used under Windows 98 the menus have a sliding effect. All necessary header files which come with the wizard have been added to this project to avoid errors at compile time, these header file have the prefix atl
.
Win32Explorer
It is very much similar to the above two projects, it has a fake drag-and-drop like feature, gives one the feeling that a drag-n-drop is actually in progress, but the coding for drop operation is missing. Try dragging from the Files View (right-side) to the plus-sign in the Folders view to see the effect.
This project has a splitter control between the two views, unlike MFC and ATL/WTL which have CSplitterWnd
and CSplitterWindow
controls respectively. There is no such control available for Win32 applications, the Enumdesk
sample from Microsoft uses the edge of the Tree and List controls to create a splitter, but I have used a splitter control which I got from a web-site named Catch22.
Using the code
Comments wherever applicable have been inserted in the code files of the classes but not to the above mentioned project.
This project contains 2 classes for creating Windows-like GUI at your end, you can use these classes to create either Views or Controls on Dialog. Download the source zip file and unzip to your local folder, files are as given below:
- Classes (Folder)
- ShellViewClasses (Folder)
- ShellClass.cpp
- ShellClass.h
- ShellViewClasses.cpp
- ShellViewClasses.h
- ShellCtrlClasses (Folder)
- ShellClass.cpp
- ShellClass.h
- ShellCtrlClasses.cpp
- ShellCtrlClasses.h
Adding files to your project
After creating you project you can add the above downloaded class files by selecting from the Visual Studio menu. Project->Add To Project->Files and then select the class files to add. You have to add all 4 files depending on which type of project you are creating (View CShellViewClasses
OR Dialog CShellCtrlClasses
. CShellClass
is similar in both cases).
Creating Views
To create view style Windows-Explorer like project, create a new project from the Visual Studio Wizard, select "MFC AppWizard (exe)" , lets name the project Test
. Next select "Single Document" for type of application, click "finish".
Drag-Drop /copy the files listed in the Classes\ShellViewClasses folder as shown in "Using the Code" section above. Add the class files to you project as show in the section "Adding Files to your Project" (this is not essential).
To create only a Files View (TreeView
) open the Test.cpp for editing, add the following line at the top (after TestView.h).
#include "ShellViewClasses.h"
In the InitInstance()
function change:
RUNTIME_CLASS(CTestView));
RUNTIME_CLASS(CShellTreeView));
Build and execute the project.
To create a two-pane user interface, use the same project created above, in the MainFrm.h file add the following:
public:
CSplitterWnd m_Splitter;
Open MainFrm.Cpp for editing, Add the following line at the top (after MainFrm.h).
#include "ShellViewClasses.h"
Using the class-wizard add the virtual-function OnCreateClient
, delete this line in the created function return CFrameWnd::OnCreateClient(lpcs, pContext);
and copy paste the following lines of code in this function:
m_Splitter.CreateStatic(this, 1, 2);
if(!(m_Splitter.CreateView(0,0 , RUNTIME_CLASS(CShellTreeView),
CSize(200,0), pContext)))
{
TRACE("Problem creating TreeView");
return FALSE;
}
if(!(m_Splitter.CreateView(0,1 , RUNTIME_CLASS(CShellListView),
CSize(0,0), pContext)))
{
TRACE("Problem creating ListView");
return FALSE;
}
CShellListView* pFileView = (CShellListView*)m_Splitter.GetPane(0,1);
pFileView->m_pShellTreeView = (CShellTreeView*)m_Splitter.GetPane(0,0);
CShellTreeView* pFolderView = (CShellTreeView*)m_Splitter.GetPane(0,0);
pFolderView->m_pShellListView = (CShellListView*)m_Splitter.GetPane(0,1);
return TRUE;
Build and execute the project.
Creating a dialog-based project
To create Dialog-based project, Create a new project from the Visual Studio Wizard, select "MFC AppWizard (exe)" , lets name the project TestDialog
. Next select "Dialog-based" for type of application, click "finish". From the displayed form, delete the static control IDC_STATIC
("TODO: Place dialog controls here."). Place a tree control at the left and a list control to the right (size them accordingly), add the class files for controls as given in the section "Using the Code" above, and add the files to the project as given in the section "Adding Files to your Project" above.
Open TestDialogDlg.h file for editing. At the top of the file add the following line ( after #endif
).
#include "ShellCtrlClasses.h"
Add these 2 lines (after CTestDialogDlg(CWnd* pParent = NULL);
).
CShellListCtrl m_ListCtrl;
CShellTreeCtrl m_TreeCtrl;
Open TestDialogDlg.cpp for editing, add the following lines in the OnInitDialog()
function (after TODO: Add extra initialization here
).
m_TreeCtrl.SubclassDlgItem(IDC_TREE1, this);
m_TreeCtrl.InitializeCtrl();
m_ListCtrl.SubclassDlgItem(IDC_LIST1, this);
m_ListCtrl.InitilizeCtrl();
m_TreeCtrl.m_pShellListCtrl = &m_ListCtrl;
Build and execute the project.
That's all.