Click here to Skip to main content
15,867,771 members
Articles / Desktop Programming / MFC
Article

Office 2000 style File Dialogs for Win 95/98/NT/Me

Rate me:
Please Sign up or sign in to vote.
4.52/5 (20 votes)
19 Oct 2003 461.7K   5.2K   99   165
Ever wanted to use the new Office 2000 file dialogs on Win 95/98/NT/Me, including the file previewing? Well now you can.

Sample Image - Win2kFileDlg.gif

Introduction

The included source files will allow you to use the Office 2000 and VS.NET style file dialogs in your applications, which will appear on all versions of Windows 95/98/NT/Me, as well as 2000. To use the dialog, simply add the source files to your project and use the standard CFileDialog calling functions to show / manipulate it.

  1. Quick Guide
  2. Using it in Your App U
  3. The Resource Script
  4. Handling Multiple File Types N
  5. Layout / Size / Enabling Resizing
  6. Context Help
  7. Preview Panel
  8. Using the VS.NET style
  9. Common Questions N
  10. Credits
  11. License N
  12. Update History

Quick Guide

For example, to load the dialog with an "Open" button, use the code below

BXFileDialog dlg(TRUE);

dlg.m_ofn.lpstrTitle = "Open Document";
dlg.DoModal();

To show the save button, use FALSE instead of TRUE when creating the dialog:

BXFileDialog dlg(FALSE);

dlg.m_ofn.lpstrTitle = "Save Document";
dlg.DoModal();

To show the bitmap preview panel, pass TRUE as the second parameter to the constructor:

BXFileDialog dlg(FALSE, TRUE);

dlg.m_ofn.lpstrTitle = "Save Document";
dlg.DoModal();

To allow the dialog to be resized, pass TRUE as the third parameter to the constructor:

BXFileDialog dlg(TRUE, FALSE, TRUE);

dlg.m_ofn.lpstrTitle = "Open Document";
dlg.DoModal();

To set up file type filters, add this before your call to DoModal() (this is optional):

CString szFilter = "HTML Documents (.Htm;.Html)|*.Htm;*.Html|";
szFilter += "Active Server Pages (.Asp)|*.Asp|";
szFilter += "Text Files (.Txt)|*.Txt|";
szFilter += "All Supported Files (.Htm;.Html;.Asp;.Txt;)"
    "|*.Htm;*.Html;*.Asp;*.Txt;|";
szFilter += "All Files (*.*)|*.*|";

LPTSTR pch = szFilter.GetBuffer(0); // modify the buffer in place
                                    // MFC delimits with '|' not '\0'
while ((pch = _tcschr(pch, '|')) != NULL)
        *pch++ = '\0';

dlg.m_ofn.lpstrFilter = szFilter;

Using it in Your App

Below I will attempt to explain using it instead of the default file 'open' / 'save as' dialogs. I will use a method that in my opinion is easier than using multiple versions of the same code for each of your documents' Open and Save As commands. To do this, define (public) and add the following function to your CWinApp derived class (make sure you include the dialog header in this file).

BOOL CMyApp::DoPromptFileName(CString &fileName, UINT nIDSTitle, 
        DWORD lFlags, BOOL bOpen, BOOL bPreview, BOOL bSizing)
{
    BXFileDialog dlg(bOpen, bPreview, bSizing);

    CString szFilter = ".HTML Documents (.Htm;.Html)|*.Htm;*.Html|";
    szFilter += "Active Server Pages (.Asp)|*.Asp|";
    szFilter += "Text Files (.Txt)|*.Txt|";
    szFilter += "All Supported Files (.Htm;.Html;.Asp;.Txt;)"
        "|*.Htm;*.Html;*.Asp;*.Txt;|";
    szFilter += "All Files (*.*)|*.*|";

    LPTSTR pch = szFilter.GetBuffer(0); // modify the buffer in place
                                        // MFC delimits with '|' not '\0'
    while ((pch = _tcschr(pch, '|')) != NULL)
            *pch++ = '\0';

    CString strTitle;
    strTitle.LoadString(nIDSTitle);

    dlg.m_ofn.lpstrFilter = szFilter ;
    dlg.m_ofn.lpstrTitle = strTitle;
    dlg.m_ofn.lpstrFile = fileName.GetBuffer(_MAX_PATH);
    dlg.m_ofn.hwndOwner = AfxGetMainWnd()->m_hWnd; 

    if (dlg.DoModal() == IDOK)
        return TRUE;

    return FALSE;
}

Also make sure that in your app header, theApp is defined, to make it easier to access your class. Eg:

extern CMyApp theApp;

Now open your document source file. Make sure it includes the main app header (so you can use theApp), and unless you already have an override for OnOpenDocument(...), use the class wizard to insert one for you. Then modify as follows (IDS_FILE_OPEN is a string ID for the dialog title):

BOOL CMyDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
    if (!theApp.DoPromptFileName(lpszPathName, IDS_FILE_OPEN,
        OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, FALSE, TRUE))
        return FALSE;

    return TRUE;
}

The override the documents' OnSaveDocument(...) function, as follows (again, IDS_FILE_SAVEAS is a string ID for the dialog title):

BOOL CMyDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
    if (!theApp.DoPromptFileName(lpszPathName, IDS_FILE_SAVEAS,
        OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, FALSE, FALSE, TRUE))
        return FALSE;

    return TRUE;
}

That is all you need to add. If you have more than one CDocument derived class, simply repeat as necessary.

Handling Multiple File Types

If you want to display different commands in the OK button's drop-down menu, you can override the virtual void OnFileTypeChange(DWORD dwNewFilterIndex) function. This function is called whenever the user selects a new file type from the 'File Type' combo box. The dwNewFilterIndex parameter contains the index of the new file type in the array passed to the dialog in the OPENFILENAME structure you pass to the dialog before showing it. You can switch on this DWORD to load different commands depending on the file type, e.g.:

// destroy the current menu (remove all items)
m_btn.m_menu.DestroyMenu();
 
// recreate the popup menu
m_btn.m_menu.CreatePopupMenu();
 
// add the new items, depending on the file type selected
switch(dwNewFilterIndex)
{
case 0:
    m_btn.AddMenuItem(ID_START,"&Open",0);
    m_btn.AddMenuItem(ID_START+1,"Open with &Filter",0);
    break;
case 1:
    m_btn.AddMenuItem(ID_START,"&Open",0);
case 2:
    m_btn.AddMenuItem(ID_START,"&Open",0);
    m_btn.AddMenuItem(ID_START+1,"Open As &HTML",0);
default:
    break; // do nothing
}

The Resource Script

In order to make including the dialog in your existing projects as simple as possible, you will no longer need to copy the individual resources to your own project's resource file. To use the resources, follow these steps:

  • Select the ResourceView pane in Developer Studio (the VC++ IDE).
  • Select the resource script used by your project.
  • Select View | Resource Includes... from the menu.
  • In the 'Compile-time directives' edit box, add the line #include "cmn.rc" before the final #endif statement.
  • Press OK and accept the changes.

You have just told the resource compiler to compile the separate resource script (named cmn.rc) when it compiles your project. The header defining the ID's in this script will automatically be made available to you.

Layout / Size

By default the initial size of the dialog will be that of the static control in the dialog template called IDC_SIZE_TEMPLATE. Changing this size will cause the dialog and all it's controls to be resized too. The width of the grey static control is used to calculate the width of the 'side bar'.

You can change the #define CONTROL_GAP to change the default spacing between controls used when updating the dialog's layout. Microsoft Office uses a value of 3. The default for this code is 5, as it looks better (in my opinion).

Sizing Support

On Windows 98 and NT 5 and later, the default Windows file dialogs can be resized. To enable this dialog to be resized in this way, pass TRUE (or FALSE to disable it) as the third parameter to the dialog constructor. For an example, see the Quick Guide section above.

Context Help

By default, Windows can't display context help for the custom controls we add to the dialog (in this case the 'side bar'), as it is not meant to be there. In order to be able to display context help for the buttons in this bar (and to override any of the default controls), simple make sure you have the HtmlHelp header and library files in your projects include path (freely available from Microsoft - search for HtmlHelp Workshop on MSDN) and compile your project with _USE_HTMLHELP defined.

The strings used to display the text in the context help windows is obtained from the string resource in cmn.rc.

Refer to the source to see how the DoPopupHelp() function is implemented. Feel free to use this function elsewhere in your projects, without credit.

Preview Panel

You can now optionally display a 'preview panel' to the right of the listbox, in the same fashion as Office 2000 does. To show this panel, pass TRUE as the second parameter in the creation statement (shown in the examples above).

This preview panel will display any images that your system will, using the IPicture interface.

Visual Studio.NET style

You can now make the sidebar buttons appear in the new VS.NET style (see screenshot at the top of this page). To do this, simply call SetAppearance(...) before calling DoModal(), and pass in APPEARANCE_VSDOTNET. E.g.:

BXFileDialog dlg();
dlg.SetAppearance(BXFileDialog::eAppearance::APPEARANCE_VSDOTNET);
 
dlg.DoModal();

Possible values to pass to SetAppearance(...) are:

APPEARANCE_DEFAULT              // Office 2000
APPEARANCE_VSDOTNET             // VS.NET

Common Questions

Why can't I compile the project?

There can be many reasons for your project not compiling, but the most common related to the use of this dialog are:

  1. You do not have the HtmlHelp SDK installed on your machine, and have not undefined _USE_HTMLHELP in the project settings.
  2. You have not set up the paths in Devloper Studio correctly, if you do have the HtmlHelp SDK installed.
  3. OLE containment support must be enabled for your project, and you have not enabled it. Call AfxEnableControlContainer() from your CWinApp::InitInstance() function.

Why isn't the new dialog showing instead of the old one?

You have to override the OnSaveDocument() function for each of your document types, and OnFileOpen() in your main CWinApp derived class, and use the new dialog in place of the old one. See the Using it in Your App section above for an example.

Credits

Based on the original code by Norm Almond. Maintained by David Wulff. Contains some code by Joel Bernard, Anatoly Danekin, Wes Rogers, Tak^Shoran and Chris Maunder.

And a special thank you to all of you who have posted bug reports and/or fixes, or have simply said "Hey, this would be cool...".

License

This code is provided on an "AS-IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. You can use the code and any segments hereof, in any product, commercial or otherwise, provided that any copyright information contained in the source files remains unaltered and intact. If you contribute to the source in any way, regardless of whether you release said changes, you must comment them and identify them as your own to prevent confusion as to the author of said changes. Use of this code in any application gives me marital rights to your first-born daughter. (Okay, maybe not that last sentence...)

I would appreciate a quick email [dwulff@battleaxesoftware.com] if you are going to use the code in a commercial application, purely out of interest. You are NOT required to do this, nor are you required to credit the original authors in your application or its documentation.

Update History

  • Previous Update History
  • 22 March 2001 - David Wulff - Updated the source to include the VS.NET style for the sidebar. Cleaned up some minor problems with the picture preview not updating if the dialog was dragged off screen (thanks to James Millson for bringing it to my attention). Added a new demo program to show off the VS.NET style dialogs. I added basic support for opening files from the Internet (by downloading them to the temp directory). This code uses Chris Maunder's CWebGrab class, and my implementation of it is still in testing and has only been used to download text files so far.
  • 24 Mar 2001 - Tak^Shoran, working sizing support for dialogs with no image preview.
  • 31 Mar 2001 - David Wulff, Major Update. A lot of the code has been updated, and the source files have been tidied up and re-commented. The sizing support now works for both preview-enabled and normal dialogs (Windows 98 and 2000 and later only). Sizing support and the new VS.NET style can now be dynamically specified rather than at compile time. Article content updated to reflect new code.
  • 5 Aug 2001 - David Wulff, now when you select a non-image file, or a folder, the preview pane is cleared. Added a handler for the CDN_TYPECHANGE message, so you can customise the OK button's drop-down menu. Article content updated to reflect new code. The debug build of the sample program will now
  • 19 October 2003 - David Wulff - Updated the source to support Windows XP (which uses a combobox instead of an edit control for the file name).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
CEO Bttlxe Ltd & Incentica Ltd
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralHistory Special Folder Problem Pin
hacheema16-Jul-08 1:24
hacheema16-Jul-08 1:24 
GeneralVista problem Pin
Box202024-Nov-06 4:59
Box202024-Nov-06 4:59 
GeneralRe: Vista problem Pin
Box202026-Nov-06 23:49
Box202026-Nov-06 23:49 
QuestionRe: Vista problem Pin
hacheema16-Jul-08 1:21
hacheema16-Jul-08 1:21 
Generalgood file,you are a likesome fallow Pin
xfxtianyi10-Oct-06 15:24
xfxtianyi10-Oct-06 15:24 
GeneralMemory leak!Warnning Pin
shengcheng_jin6-Mar-06 20:45
shengcheng_jin6-Mar-06 20:45 
Generalvery nice! but a bug when set OFN_ALLOWMULTISELECT Pin
xiaoyu731110-Oct-05 21:39
xiaoyu731110-Oct-05 21:39 
GeneralWINDOWS XP without common extension displayed Pin
Pancini Paolo3-Jun-05 3:49
Pancini Paolo3-Jun-05 3:49 
QuestionDLL? Pin
Gerhard294-Jun-04 4:19
Gerhard294-Jun-04 4:19 
GeneralGreat Class! Some workarounds for win2k suggested Pin
Valerio Aimale21-Nov-03 13:18
Valerio Aimale21-Nov-03 13:18 
GeneralToo hard to implement ... much easier way at MSDN ! Pin
Robert Ibsen Voith3-Nov-03 20:19
Robert Ibsen Voith3-Nov-03 20:19 
GeneralRe: Too hard to implement ... much easier way at MSDN ! Pin
David Wulff3-Nov-03 22:00
David Wulff3-Nov-03 22:00 
QuestionAny chance of XP look? Pin
Obliterator20-Oct-03 4:47
Obliterator20-Oct-03 4:47 
GeneralProblem: Open-Button position & resizing Pin
Alexander Bischofberger20-Oct-03 1:02
Alexander Bischofberger20-Oct-03 1:02 
GeneralRe: Problem: Open-Button position & resizing Pin
David Wulff20-Oct-03 2:57
David Wulff20-Oct-03 2:57 
GeneralRe: Problem: Open-Button position & resizing Pin
Obliterator20-Oct-03 4:39
Obliterator20-Oct-03 4:39 
GeneralHelp... Pin
crystalyd31-Aug-03 22:28
crystalyd31-Aug-03 22:28 
GeneralRe: Help... Pin
David Wulff1-Sep-03 5:25
David Wulff1-Sep-03 5:25 
GeneralFilters Pin
Anonymous2-Jul-03 3:24
Anonymous2-Jul-03 3:24 
GeneralDoModal() //error help Pin
kitasoo2-May-03 3:12
kitasoo2-May-03 3:12 
GeneralRe: DoModal() //error help Pin
DanPetitt8-Sep-03 10:34
DanPetitt8-Sep-03 10:34 
GeneralRe: DoModal() //error help Pin
DanPetitt9-Sep-03 6:53
DanPetitt9-Sep-03 6:53 
GeneralMove the toolbar Pin
Spyro11-Feb-03 22:15
Spyro11-Feb-03 22:15 
GeneralRe: Move the toolbar Pin
Min, Byeong-Don.24-Jun-03 15:32
Min, Byeong-Don.24-Jun-03 15:32 
GeneralPlacing the other controls Pin
Vinayrev1-Dec-02 22:43
Vinayrev1-Dec-02 22:43 

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.