Developing Applications with a User-Customizable GUI Layout

Environment: Visual C++ 6.0, MSXML 2.0

Many applications that use dialogs and form views would be more effective if they allowed a user to customize their screen GUI layout. This article describes a solution that would give developers a possibility to make their applications customizable by users.

The proposed library, XMLGUI, is a tool for developing user-customizable applications. A user can change the size and position of any control on dialogs, form views, or property pages; change captions of the controls using any language; change styles of the controls; add or remove controls to/from dialogs, forms, and pages.

All templates for dialogs and forms creation are stored in XML files using specially designed XML template syntax for GUI layout. The path to these XML files may be stored in the Registry for every user, allowing users to have different GUI layouts of the application, even sharing the same machine for work. Resource files are retained as a reserve, and when XML files cannot be found or contain erroneous data, the application's dialogs are built using templates from the resource file. This will ensure the system reliability: Even if loading XML template files fails, a dialog window may be shown as defined in resource file without the user's customization.

The customizing possibility is available through a right mouse click anywhere within the dialog window. The Notepad application is invoked and the XML file with the dialog template is opened. The user edits the file and saves the changes; then, it is necessary to open the dialog once again—for modal dialog it is enough to close the dialog and open it again for the changes to take effect; form views require an application restart. But no recompilation is required in any case.

An MFC-based application can be easily given GUI layout customization possibilities through use of the XMLGUI library. An XMLGUI library contains classes that read XML with the GUI template and build a Win32 DLGTEMPLATE structure in runtime. This structure is then passed to the window-creation functions. Creating customizable dialogs using XMLGUI incudes the next steps:

  • First, create XML files describing the default GUI layout of the dialog. In the future, a utility for converting existing resource files to XML-style templates may be developed for this purpose.
  • Then, if your dialog, form, or page class derives directly from the corresponding MFC class—CDialog, CFormView, or CPropertyPage—change the base class to one of the instantiations of XMLGUI customizable classes: CXMLGUIDialog, CXMLGUIFormView, or CXMLGUIPropertyPage. Or, you may use new instantiations of the XMLGUI template classes; for example, CXMLCustomizableDialog<CMyDialog>. This may be useful if your dialog class derives from the MFC class through a set of ancestor classes.
  • In the constructor of your dialog class, call the constructor of the base XMLGUI class, passing the full name of the XML file that will be used as a template for the dialog's creation.

Here is an example of using CXMLGUIDialog class for creating a customizable dialog:

/////////////////////////////////////////////////////////////////
// MyDialog.h
// declaration of CMyDialog class

#include <XMLCustomizableDialogs.h>

class CMyDialog : public CXMLGUIDialog
{
public:
        CMyDialog(CWnd* pParent = NULL);  // standard constructor
        enum { IDD = IDD_DIALOG1 };       // resource ID of the
                                          // dialog template
}


/////////////////////////////////////////////////////////////////
// MyDialog.cpp
// implementation of CMyDialog class

CMyDialog::CMyDialog(CWnd* pParent /*=NULL*/)
         : CXMLGUIDialog("C:\\MyGUILayouts\\MyDialogLayout.xml",
                         CMyDialog::IDD, pParent)
{
}

All the other code for the CMyDialog dialog is left untouched; it may reference dialog controls as usual if the correct IDs for controls are specified in the XML template file. The dialog constructed in such a way will create its GUI layout from the specified XML file; the option for editing this file is available through a right-click anywhere within the dialog window.

Here is an example of a valid XML file with a GUI template definition:

<?xml version="1.0"?>
<dialog caption="Dialog Example" top="0" left="0"
                                 width="320" height="200"
        style="popup,clipsiblings,caption,sysmenu,modalframe,
               3dlook,setfont"
        fontname="Comic Sans MS" fontsize="10">
<control class="Static" top="29" left="32" width="70"
         height="11">Static Text Example</control>
<control class="Edit" top="76" left="32" width="78" height="14"
         style="not border" id="1000"></control>
<control class="Picture" top="96" left="32" width="32"
                         height="32" style="icon"
         resource-id="128"/>
<control class="Button" top="179" left="86" width="50"
                        height="14" id="1">&amp;OK</control>
<control class="Button" top="179" left="183" width="50"
                        height="14" id="2">&amp;Cancel</control>
<control class="ActiveX" top="26" left="130" width="128"
                         height="118"
         id="1009" clsid="{6262D3A0-531B-11CF-91F6-C2863C385E30}"/>
</dialog>

This article gives a brief overview of the syntax and an example; the full description of the used syntax is available in the Documentation Set under the link below the article text.

There are library source code and a demo project available for download. All the changes for the customization support are marked with "// XMLGUI change" in the demo source code. Instructions to build the demo are as follows:

  • Extract XMLGUI_src.zip and XMLGUI_demo.zip to the same folder.
  • Open workspace XMLGUITest\XMLGUITest.dsw. This workspace contains two projects: XMLGUI and XMLGUITest.
  • Set XMLGUITest project as an active project, choose the necessary build configuration, and build the solution. The workspace contains the dependency of XMLGUITest on XMLGUI, so the library will be built first, and then the demo executable will be built.
  • After that, the demo project is ready to run. XML files with examples of GUI layout definitions are placed in the folder XMLGUITest\gui; this path is specified in the demo source code for XML files to be searched.

Besides the customization support, the XMLGUI library contains several classes that may be useful for the other purposes. For example, CDlgTemplate and CDlgItemTemplate are C++ wrappers for the Win32 structures DLGTEMPLATE and DLGITEMTEMPLATE. These classes simplify work with the mentioned structures, hiding their rather complex syntax from the developer. Class CXMLTag and classes derived from it may be used to simplify XML attributes' retrieval, and the CXMLIteratable template class may provide efficient iterating through XML elements of various kinds. See the Documentation Set for a detailed description of each class.

Downloads

Download demo project - 24 Kb
Download source - 40 Kb
Download documentation set - 77 Kb