Resizing dialogue boxes

Dialogue boxes are typically defined using a "template", created using the Microsoft Visual Studio resource editor, and stored within the resources of the executable. The dialogue template uses dialog units, which determine the size of the dialogue box relative to the font selected for the dialogue box. To scale the size of a dialogue box, the selected font must be changed. The following code example shows how this can be done at run-time, for example to scale a dialogue box to take account of the screen resolution, or whether "small fonts" or "large fonts" have been selected.

class CDlgExample : public CDialog
{
public:
    CDlgExample(WORD wdFontSizeInPoints);
};

CDlgExample::CDlgExample(WORD wdFontSizeInPoints) : CDialog()
{
    // Get the handle for the dialogue resource containing the template for the dialogue box.
    HRSRC hResource = ::FindResource(NULL, MAKEINTRESOURCE(IDD_SOMETHING), RT_DIALOG);
    ASSERT(hResource != NULL);

    // Load the specified resource into memory.
    HGLOBAL hDlgTemplate = ::LoadResource(NULL, hResource);
    ASSERT(hDlgTemplate != NULL);

    // Get a pointer to the dialogue template. The template always starts with a DLGTEMPLATE
    // structure.
    DLGTEMPLATE* const kpDlgTemplate = reinterpret_cast<DLGTEMPLATE*>(::LockResource(hDlgTemplate));
    ASSERT(kpDlgTemplate != NULL);

    // Check it doesn't start with a DLGTEMPLATEEX structure.
    ASSERT(kpDlgTemplate->style != 0xFFFF0001);

    // And check it contains a custom font.
    ASSERT(kpDlgTemplate->style & DS_SETFONT);

    // Skip over the DLGTEMPLATE structure to the menu array.
    WORD* const kpwdMenuArray = reinterpret_cast<WORD*>(kpDlgTemplate + 1);

    // Skip over the menu array to the class array.
    WORD* pwdClassArray = NULL;
    if (*kpwdMenuArray == 0xFFFF)
    {
        pwdClassArray = kpwdMenuArray + 2;
    }
    else
    {
        pwdClassArray = kpwdMenuArray + wcslen(kpwdMenuArray) + 1;
    }

    // Skip over the class array to the title array.
    WORD* pwdTitleArray = NULL;
    if (*pwdClassArray == 0xFFFF)
    {
        pwdTitleArray = pwdClassArray + 2;
    }
    else
    {
        pwdTitleArray = pwdClassArray + wcslen(pwdClassArray) + 1;
    }

    // Skip over the class array to the font size in points.
    WORD* pwdFontSize = pwdTitleArray + wcslen(pwdTitleArray) + 1;

    // Set the font size.
    *pwdFontSize = wdFontSizeInPoints;

    // Pass the modified dialogue template to the MFC base class.
    BOOL bResult = InitModalIndirect(hDlgTemplate);
    ASSERT(bResult);
}