![]() |
Desktop Development »
Dialogs and Windows »
Windows 2000 Styles
Intermediate
Office 2000 style File Dialogs for Win 95/98/NT/MeBy David WulffEver wanted to use the new Office 2000 file dialogs on Win 95/98/NT/Me, including the file previewing? Well now you can. |
VC6Win2K, MFC, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||

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.
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;
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.
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 }
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:
#include "cmn.rc" before the final #endif statement.
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.
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.
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.
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.
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
There can be many reasons for your project not compiling, but the most common related to the use of this dialog are:
_USE_HTMLHELP in the project settings.
AfxEnableControlContainer() from your CWinApp::InitInstance() function. 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.
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...".
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.
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
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 19 Oct 2003 Editor: Nishant Sivakumar |
Copyright 2000 by David Wulff Everything else Copyright © CodeProject, 1999-2009 Web20 | Advertise on the Code Project |