In one project I was involved in, we had to display font selection dialog.
My Product Manager had some issues with MFC's
He is very focused on reducing support costs by simplifying
user interface, to eliminate anything that might be confusing
or misleading. OK, it is hard to argue against this goal.
In case of
he didn't like all the controls that were unnecessary
for our application. Here is what the standard
My Product Manager didn't like Effects
, Font Style
, or Script
controls, since our
app used only Font
and Font Size
values. I was starting to feel a little
apprehensive (since I had never once won an argument with him),
so I pointed out that we could easily eliminate some of the unnecessary controls.
I asked him to come back tomorrow for a demonstration. For the rest of day,
I tried to figure out how to remove controls he didn't like. I was
only partially successful, because
provides very little
in its API to facilitate customizing user interface.
When the Product Manager came by next day, this is what
I showed him:
He thought it looked really lame, and I had to agree. The Font Style
combo was still there, and getting rid of Effects
only left a big hole in the dialog - the Sample
not even been resized to take advantage of free space on left.
Finally, the best I could do was to disable Script
But I had found out two things in my research into
CFontDialog: first, you could use your own dialog template,
based on the template provided in Font.Dlg;
and second, there was a hook proc you could supply in your own
After a few days playing with
I knew it would be possible to customize the font dialog to look
the way we wanted. Mostly this involved editing the template
used for the standard font dialog, and moving the unwanted controls
outside the dialog:
I also had to create new controls for sample text, because
CFontDialog insists on reverting to text "AaBbYyZz" when
you select new font in fonts combo.
To jump ahead a bit, here is final dialog:
This is more compact than the standard font dialog,
but looks enough like it
that our users won't have to learn a completely different UI.
At the same time, it removes the elements that might be frustrating
to try to select (with no apparent effect, since they're not
used in our apps). Plus,
it gave us an opportunity to add some features that
permitted better integration with our apps.
Here are the features in the new CXFontDialog
Removal of all controls except font list and size list
Font filters to select only specific groups of fonts to display
Visual indication of monospaced fonts
New APIs for monospaced and symbol fonts
API to set caption of font dialog
API to set sample text of font dialog
The main source for technical information that I relied on
to customize CFontDialog is the MSDN documentation on the
This struct includes the
member that allows you to
set your hook proc, and
members, which must be set in order to load the customized template.
What MSDN doesn't tell you is where to find the default template.
For VS 6.0, I found it in
C:\Program Files\Microsoft Visual Studio\VC98\Include\Font.Dlg
For Visual Studio 8 and 9, it's located in the Platform SDK's
After I found it, next step was to set up a separate XFontDialog.rc
and cut and paste the template from Font.Dlg
. To set up XFontDialog.rc
I used the techniques I describe in my article
XDialogImport - How to share dialogs between projects
Note that by not defining
the Class Wizard will treat
IDD_XFONTDIALOG as a string.
The advantage of this is that there is no possibility of conflicts
with any other dialog resource ids in your project.
Now I can use Visual Studio Resource Editor to configure controls
like I wanted - moving unwanted controls to the side and marking them not visible.
I also make sample control bigger,
and add static control to top of font list - so for
monospaced fonts, you will see MONOSPACED displayed:
I then use Class Wizard to generate new CXFontDialog class by double-clicking
on template in Resource Editor:
I select CFontDialog
as base class, and enter CXFontDialog for new class name:
And finally I am able to use Class Wizard for the new class:
You will notice that all symbolic names in Font.Dlg have been
converted to numeric IDs. This doesn't matter, since these IDs must
not change anyway or CFontDialog would not work.
(I assign names to these IDs inside XFontDialog.cpp
to make it easier to work with.)
I have added
two handler functions to CXFontDialog:
OnShowMonoSpaced(), which is called from within the hook proc
when user selects a monospaced font (this is where the MONOSPACED
gets displayed). I also add
which is where dialog template and hook function are specified.
The key function is the hook proc, where
is caught. This is where font filters (if any) are applied.
How To Use
CXFontDialog into your app, you first need
to add following files to your project:
Note that XFontDialogRes.h
- even though basically empty - is needed
if you want to edit the dialog template in the resource editor.
You also need to add XFontDialog.rc to project rc file - go to
View | Resource Includes... and in the bottom listbox,
scroll down to the end. Insert
#include "XFontDialog.rc" right before the
Next, include header file XFontDialog.h in
appropriate project files.
Now you are ready to start using
demo shows how to use
Version 1.1 - 2008 October 7
Version 1.0 - 2003 June 21
This software is released into the public domain. You are free to use it in
any way you like, except that you may not sell this source code. If you modify
it or extend it, please to consider posting new code here for everyone to share.
This software is provided "as is" with no expressed or implied warranty.
I accept no liability for any damage or loss of business that this software