File Explorer (aka Windows Explorer) is a well known and commonly used file manager application, shipped since early Windows 95 operating system. There are also other replacements that can be found over the Internet, however, let’s see how can we make our own file manager, having multiple (tabbed) views.

A brief tour of possible ways

Ones can say that’s a piece of cake: just use raw-WinAPI to populate a tree with folders then a list with folder contents. Another ones can choose to use IShellFolder and browse the shell namespace for the same purpose. Booth methods require a lot of work to do and may be a real overkill. Even more advanced methods like using IShellView and IFolderView are not so easy.

Fortunately, for Windows Vista, Windows Server 2008 and newer Windows versions, we can use IExplorerBrowser interface to get a “full featured” File Explorer.

We have it so let’s use it!

Create the multiple tabbed views application

If have Visual Studio 2008 SP1 or newer, creating such type of project is no sweat.

Create a new MFC Application project (Ctrl+Shift+N).

In MFC Application Wizard check theese options: Application type: Multiple documents & Tabbed documents Project style: MFC Standard User interface Features: Split window Change generated view class name to CFileExplorerView.

Click the “Finish” button.

Of course, you can choose other options, but for our purpose the most important are multiple tabbed documents and split window.

Use IExplorerBrowser interface

We can directly use IExplorerBrowser interface in the view class but to make things easier, I wrote an MFC-extension class named CFileExplorer that takes care of instantiating, releasing and using IExplorerBrowser methods. Here is its definition:

// FileExplorer.h #pragma once class CFileExplorer : public CObject { // Attributtes private: CComPtr<IExplorerBrowser> m_pIExplorerBrowser; // Operations public: void Create(); void SetOptions(EXPLORER_BROWSER_OPTIONS dwOptions = EBO_SHOWFRAMES|EBO_ALWAYSNAVIGATE); void Initialize(HWND hWndParent, const CRect& rc, UINT nViewMode = FVM_DETAILS, UINT nFlags = FWF_NONE); void SetRect(const CRect& rc) throw(); void BrowseToFolder(LPCTSTR pszPath); }; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // FileExplorer.h #pragma once class CFileExplorer : public CObject { // Attributtes private : CComPtr < IExplorerBrowser > m_pIExplorerBrowser ; // Operations public : void Create ( ) ; void SetOptions ( EXPLORER_BROWSER_OPTIONS dwOptions = EBO_SHOWFRAMES | EBO_ALWAYSNAVIGATE ) ; void Initialize ( HWND hWndParent , const CRect & rc , UINT nViewMode = FVM_DETAILS , UINT nFlags = FWF_NONE ) ; void SetRect ( const CRect & rc ) throw ( ) ; void BrowseToFolder ( LPCTSTR pszPath ) ; } ;

The implementation of CFileExplorer class can be found in the demo project attached to this article. Now, let’s use CFileExplorer in our application view class.

Add a CFileExplorer member to CFileExplorerView class

// FileExplorerView.h #pragma once #include "FileExplorer.h" class CFileExplorerView : public CView { // Attributes private: CFileExplorer m_fileExplorer; 1 2 3 4 5 6 7 8 9 // FileExplorerView.h #pragma once #include "FileExplorer.h" class CFileExplorerView : public CView { // Attributes private : CFileExplorer m_fileExplorer ; Handle WM_CREATE message. In the OnCreate handler function, perform browser intialization like creating IExplorerBrowser instance, set initial options, set the parent window and folder options.

int CFileExplorerView::OnCreate(LPCREATESTRUCT lpCreateStruct) { if(CView::OnCreate(lpCreateStruct) == -1) return -1; try { // create IExplorerBrowser instance m_fileExplorer.Create(); // set default browser options EBO_SHOWFRAMES | EBO_ALWAYSNAVIGATE m_fileExplorer.SetOptions(); // prepares the browser to be navigated // parent window is this window, default view mode is FVM_DETAILS, // default folder flag is FWF_NONE m_fileExplorer.Initialize(m_hWnd, CRect(0, 0, 0, 0)); // NOTE: a further implementation can change the default values } catch(COleException* e) { e->ReportError(); // show what's going wrong e->Delete(); return -1; } return 0; } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 int CFileExplorerView :: OnCreate ( LPCREATESTRUCT lpCreateStruct ) { if ( CView :: OnCreate ( lpCreateStruct ) == - 1 ) return - 1 ; try { // create IExplorerBrowser instance m_fileExplorer . Create ( ) ; // set default browser options EBO_SHOWFRAMES | EBO_ALWAYSNAVIGATE m_fileExplorer . SetOptions ( ) ; // prepares the browser to be navigated // parent window is this window, default view mode is FVM_DETAILS, // default folder flag is FWF_NONE m_fileExplorer . Initialize ( m_hWnd , CRect ( 0 , 0 , 0 , 0 ) ) ; // NOTE: a further implementation can change the default values } catch ( COleException * e ) { e -> ReportError ( ) ; // show what's going wrong e -> Delete ( ) ; return - 1 ; } return 0 ; } Handle WM_SIZE and resize the browser to fit the parent client area.

void CFileExplorerView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); // resize the browser to fit this window's clent area m_fileExplorer.SetRect(CRect(0, 0, cx, cy)); } 1 2 3 4 5 6 void CFileExplorerView :: OnSize ( UINT nType , int cx , int cy ) { CView :: OnSize ( nType , cx , cy ) ; // resize the browser to fit this window's clent area m_fileExplorer . SetRect ( CRect ( 0 , 0 , cx , cy ) ) ; } Handle WM_ERASEBKGND to avoid flickering when the parent view is resized.

BOOL CFileExplorerView::OnEraseBkgnd(CDC* pDC) { return FALSE; // just avoid flickering } 1 2 3 4 BOOL CFileExplorerView :: OnEraseBkgnd ( CDC * pDC ) { return FALSE ; // just avoid flickering } Finally, let’s override CView::OnUpdate and browse for a folder.

void CFileExplorerView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) { TCHAR pszDesktopFolder[MAX_PATH] = {0}; ::SHGetFolderPath(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, pszDesktopFolder); m_fileExplorer.BrowseToFolder(pszDesktopFolder); // NOTE: just for demo purpose, this browses using the desktop as root folder. // In a complete implementation you may change this, // by using any other root path. } 1 2 3 4 5 6 7 8 9 10 void CFileExplorerView :: OnUpdate ( CView * pSender , LPARAM lHint , CObject * pHint ) { TCHAR pszDesktopFolder [ MAX_PATH ] = { 0 } ; :: SHGetFolderPath ( NULL , CSIDL_DESKTOP , NULL , SHGFP_TYPE_CURRENT , pszDesktopFolder ) ; m_fileExplorer . BrowseToFolder ( pszDesktopFolder ) ; // NOTE: just for demo purpose, this browses using the desktop as root folder. // In a complete implementation you may change this, // by using any other root path. }

Demo Project

The demo project uses CFileExplorer to make a simple file manager with multiple views.

Download demo project: Multiple-View File Explorer.zip (2269)

to open new views choose File/New menu item, press Ctrl+N or push the “New” button;









to split a view choose Window/Split menu;









to arrange views side by side drag from view tab caption;









to change a view layout push “Organize” then check “Layout” subitems;









to change the view style (details, small icons, tiles, etc) push “More options” button.

Notes

This article as well as the demo project presents just proof of concepts. It can be improved by adding many other features: navigate back and forward; add more functions to menu / toolbar or use a ribbon; filter the columns to be shown in details view; search; automatically show views side by side; make the layout and other settings persistent between application instances; and so on, and so on.



Resources

Share this: Twitter

LinkedIn

StumbleUpon

Facebook

Reddit

More

Google

Email



Print

