DDXFile v1.34
For developers who use MFC this is a freeware control which subclasses an edit
control to allow you to easily specify a file. When the edit control is correctly
setup it will look like:

The button beside the edit control sports a tooltip when the button is over it
and when the button is hit a modified version of the common file open dialog is
displayed to allow the user to select a filename as:

Both the caption and file extension filter can be customized. In addition the
control integrates with the AutoCompletion functionality of Windows, so that a drop
down list appears underneath the edit control which allows the user to quickly select
a specific file. Other methods allow the developer to customize whether overwrites
are notified to the user and only existing files allowed. The code is most useful
when you want to specify a filename from somewhere in the user interface but don't
necessarily want to "Open" or "Save" a file.
Note that the default button has the text "OK" as opposed to "Save"
or "Open" which is what you normally would get with the standard common
file dialogs.
Features
- Simple DDX and DDV function which you can use in your MFC code.
- All the code is fully UNICODE compliant.
- Includes autocompletion functionality.
- A simple test app is included.
Copyright
- You are allowed to include the source code in any product (commercial, shareware,
freeware or otherwise) when your product is released in binary form.
- You are allowed to modify the source code in any way you want except you
cannot modify the copyright details at the top of each module.
- If you want to distribute source code with your application, then you are
only allowed to distribute versions released by the author. This is to maintain
a single distribution point for the source code.
Usage
- To use DDXFile in your project simply include DDXFile.cpp and the IDS_DDXFILE_*
and IDP_DDXFILE_* string resources from the test application in your application.
Then #include DDXFile.h in which ever of your modules requires it and make the
appropriate calls. Included is a simple dialog based application which shows
how to use it. Basically at a minimum, all you need to do is add to your DoDataExchange
function as follows:
- void CTestgetfileDlg::DoDataExchange(CDataExchange* pDX)
- {
//Let the base class do its thing
- __super::DoDataExchange(pDX);
DDX_FilenameControl(pDX, IDC_FILENAME, m_ctrlGetFilename);
- }
- As of v1.21, the code now uses ATL's CComPtr class to provide some of
the AutoCompletion functionality. This does mean that for MFC only client projects,
you will need to add ATL support to your project.
- As of v1.29 the classes are now designed for VC 2017 or later. They will
not compile on earlier releases of VC.
History
v1.34 (1 April 2022)
- Updated copyright details.
- Updated the code to use C++ uniform initialization for all variable
declarations.
v1.33 (3 May 2020)
- Fixed more Clang-Tidy static code analysis warnings in the code.
v1.32 (14 March 2020)
- Updated copyright details.
- Fixed more Clang-Tidy static code analysis warnings in the code.
v1.31 (21 December 2019)
- Fixed various Clang-Tidy static code analysis warnings in the code.
v1.30 (18 May 2019)
- Updated copyright details.
- Updated the code to clean compile on VC 2019
v1.29 (9 July 2018)
- Updated copyright details.
- Fixed a number of C++ core guidelines compiler warnings. These changes
mean that the code will now only compile on VC 2017 or later.
v1.28 (24 September 2017)
- Updated copyright details.
- Replaced NULL throughout the codebase with nullptr. This means that the
minimum requirement for the framework is now VC 2010.
- Reworked the code in CGetFilenameControl::InitializeAutoComplete to use
ATL::CComPtr::CoCreateInstance.
- All the code has had SAL annotations added.
v1.27 (11 November 2015)
- Verified the code compiles cleanly on VC 2015.
- Updated the sample apps main icon.
- Updated copyright details.
v1.26 (23 December 2014)
- If the main edit control is now hidden, the buddy buttton is now also hidden.
The corrolary of if the main edit control is now shown, then the buddy button
is now also shown. Thanks to Rene Laviolette for requesting this update.
v1.25 (1 March 2014)
- Updated copyright details.
- Updated MFC message maps in sample app and in DDXFile module to use C++
standard for pointers to member methods.
- Reworked DDX_FilenameControl to use DDX_Control for most of its functionality
- Reworked how the code exposes the bVistaStyle support in the MFC CFileDialog
class. The code now uses the MSC C++ __if_exists / __if_not_exists statements
- Updated the code to clean compile on VC 2013 & 2012.
- Updated the code to clean compile using /analyze
v1.24 (10 September 2011)
- Updated copyright details.
- Verified code compiles cleanly on VC 2010
- Fixed an access violation bug in CDDXFileModifyButton::PreTranslateMessage
if the IDS_DDXFILE_EDIT_TEXT string resource is not loaded
v1.23 (21 December 2008)
- Updated copyright details
- Removed VC 6 style AppWizard comments from the code
- InitializeAutoComplete now returns a HRESULT instead of a BOOL
- Updated DDX_FileControl code to be consistent with DDX_Control in VC 2008
- The code has now been updated to support VC 2005 or later only
- Code now compiles cleanly using Code Analysis (/analyze)
- The code now can use the Vista style of file dialog provided by VC 2008
- Fixed a bug in the sample app where the various checkbox UI states were
not initially in sync with the control.
v1.22 (19 November 2007)
- Minor update to display HRESULT's correctly.
- Minor tidy up to remove old style AppWizard comments
v1.21 (20 August 2006)
- Control now takes advantage of the AutoCompletion functionality (IAutoComplete
et al) built into Windows to improve the UI experience. If enabled then a drop
down list will appear underneath the edit control which allows the user to quickly
select a specific file. The code uses the COM interfaces (IAutoComplete) to
AutoCompletion instead of the more simplified functionality provided by SHAutoComplete.
This allows the code to customize the auto completion UI so that only file system
folders are selectable.
v1.20 (11 August 2006)
- Reworked all the use of string resources. Now all the string resources used
by the control are all loaded in one single virtual function. In addition if
you do not want to use inheritance, all the strings can be customized via Get/Set
methods.
- Broke the DDV functionality into seperate discreet DDV functions
- The dialog control id of the edit button can now be specified via the SubclassEdit
and DDX_FilenameControl functions
v1.19 (29 July 2006)
- Initial enabled state of the edit control is now reflected into the edit
button when AddEditButton is called.
v1.18 (19 July 2006)
- Updated copyright details
- Optimized CDDXFileModifyButton constructor code
- Updated documentation to use the same style as the web site.
- Optimized CDDXFileFileNameDialog constructor code
- Addition of a CDDXFILE_EXT_CLASS preprocessor macro to allow the classes
to be easily added to an extension dll.
- Removed now defunct Win32s support code
- Removed support for showing the old style Win3.1 file open dialog
- Changed the names of the constants used for DDX_GetFilenameControl
- Replaced all calls to CFile::GetStatus with GetFileAttributes
- Verified code clean compiles in VC2005
10 January 2003
- Minor update to the documentation, no code changes.
v1.17 (9 January 2003)
- Updated copyright details.
- Changed a class name from "CModifyButton" to the better named "CDDXFileModifyButton".
- Enabled state of control is now reflected to buddy button edit control.
Thanks to "matro" for pointing out this problem.
- Made the "CGetFilenameControl::Edit" virtual for easier customisation
- Made all strings used by the classes easier to modify by making them virtual
methods of the class
- Changed a class name from "CGetFileNameDialog" to the better named "CDDXFileFileNameDialog"
- Made the "CGetFilenameControl::AddEditButton" method virtual for
easier customisation.
v1.16 (27 December 2001)
- Fixed an issue where the browse button would do nothing when you type in
for example "c:\". Thanks to Stephen Agate for spotting this.
v1.15 (24 May 2001)
- Fixed a problem with the Z-Order of the control being set incorrectly.
- Updated copyright message.
v1.14 (18 July 2000)
- Width of the edit button is now determined from the text which it displays.
v1.13 (17 May 2000)
- The width of the underlying edit control is now shrunk when the "..."
button is created. This makes layout of the control using the resource designer
a lot simpler.
v1.12 (14 May 2000)
- The "..." button now supports being tabbed into i.e. the WS_TABSTOP
style
v1.11 (11 December 1999)
- Cosmetic item where now a 1 pixel space is included between the edit control
and the "..." button
v1.1 (17 September 1998)
- Updated all the documentation to be HTML based as with my other shareware
/ freeware.
- Unicode enabled all the code and provision of Unicode build configurations.
- VC 5 mak files provided now as standard
- Provision of a DDV function.
- General tidy up of the sample app including removing all the AppWizard generated
comments.
- All code now compiles cleanly at warning level 4.
- Replaced all TRACE0 calls with TRACE.
- Changed name of main function from DDX_GetFileControl to DDX_FilenameControl.
- Module name has been changed from ddxgetfile to ddxfile.
- Sample app now allows read only state of widget to be toggled.
- Addition of a DDX_FileValue function.
- Change the ID's of the strings in the resource table which the code
uses.
API Reference
The following functions are provided:
DDX_FilenameControl
DDX_FilenameValue
DDV_FilenameControlNotFolder
DDV_FilenameControlMustFile
DDV_FilenameControlOverwritePrompt
DDV_FilenameControlNotEmpty
DDX_FilenameControl
bool DDX_FilenameControl(CDataExchange* pDX,
int nIDC, CGetFilenameControl&
rControl, UINT nModifyButtonID
= 0xFFFFFFFF);
Parameters
pDX is the usual CDataExchange object which will be passed into your
DoDataExchange function.
nIDC is the dialog ID of the edit control to subclass.
rControl will contain upon return the window control which manages the
compound edit and button controls.
nModifyButtonID is a control id of the modify button.
Remarks
Associates an existing edit control with dialog ID "nIDC" to a compound
filename picker control. Normally you would calls to this function in your dialog
class's DoDataExchange member function. The function returns TRUE if the setup
of the edit control succeeded otherwise FALSE is returned.
DDX_FilenameValue
void DDX_FilenameControl(CDataExchange* pDX,
CGetFilenameControl& rControl, CString&
sFile);
Parameters
pDX is the usual CDataExchange object which will be passed into your
DoDataExchange function.
rControl is the folder control to get or set the filename for.
sFile is the actual file to get or set into the control depending on
the direction of data exchange occurring.
Remarks
Gets the actual string value which the control contains.
DDV_FilenameControlNotFolder
void DDV_FilenameControlNotFolder(CDataExchange* pDX,
const CGetFilenameControl&
rControl,
UINT nFailureResourceID,
UINT nHelpID = 0xFFFFFFFF);
Parameters
pDX is the usual CDataExchange object which will be passed into your
DoDataExchange function.
rControl is the filename control to validate for.
nFailureResourceID is the resource id of the string which will be displayed as
a failure message.
nHelpID is the help context ID for the message.
Remarks
This DDV function ensures that the value selected does not specify a folder.
DDV_FilenameControlMustExist
void DDV_FilenameControlMustExist(CDataExchange* pDX,
const CGetFilenameControl&
rControl,
UINT nFailureResourceID,
UINT nHelpID = 0xFFFFFFFF);
Parameters
pDX is the usual CDataExchange object which will be passed into your
DoDataExchange function.
rControl is the filename control to validate for.
nFailureResourceID is the resource id of the string which will be displayed as
a failure message.
nHelpID is the help context ID for the message.
Remarks
This DDV function ensures that the value selected specifies an existing file.
DDV_FilenameControlOverwritePrompt
void DDV_FilenameControlOverwritePrompt(CDataExchange* pDX,
CGetFilenameControl& rControl,
UINT nHelpID = 0xFFFFFFFF);
Parameters
pDX is the usual CDataExchange object which will be passed into your
DoDataExchange function.
rControl is the filename control to validate for.
nHelpID is the help context ID for the message.
Remarks
This DDV function prompts the user if an overwrite is allowable if the file already
exists. Validation fails if the end user selects No to the message.
DDV_FilenameControlNotEmpty
void DDV_FilenameControlNotEmpty(CDataExchange* pDX,
const CGetFilenameControl&
rControl,
UINT nFailureResourceID,
UINT nHelpID = 0xFFFFFFFF);
Parameters
pDX is the usual CDataExchange object which will be passed into your
DoDataExchange function.
rControl is the filename control to validate for.
nFailureResourceID is the resource id of the string which will be displayed as
a failure message.
nHelpID is the help context ID for the message.
Remarks
This DDV function ensures that the value selected is not an empty string.
Contacting the Author
PJ Naughter
Email: pjna@naughter.com
Web: http://www.naughter.com
1 April
2022