This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Dialog Template Submitted by

This class is designed to make it easy to construct DLGTEMPLATEs on the fly for displaying simple Win32 dialog boxes. For example, this class can be used to construct the dialog box for Douglas Cox's excellent assert replacement (this is actually why I made the class in the first place). By creating the dialog box on the fly, all of the information needed for the assert replacement can be neatly contained in a single file without the need for a resource file. The code snippet to construct the assert dialog is shown below. Hopefully this gives a good enough example of the class's usage to make up for my lack of commenting. But if it isn't, I assure you that it's easier to figure out how to use my class than it is to figure out how to construct the DLGTEMPLATE without it.

    DialogTemplate dialogTemplate(_T("Assert Failed!"), WS_CAPTION | DS_CENTER,
        10, 10, 257, 80, _T("Tahoma"));

    dialogTemplate.AddStatic(_T("Filename:"), WS_VISIBLE, 0,
        2 + 3, 7, 37, 8, -1);

    dialogTemplate.AddStatic(_T("Line:"), WS_VISIBLE, 0,
        188 + 3, 7, 16, 8, -1);

    dialogTemplate.AddStatic(_T("Expression:"), WS_VISIBLE, 0,
        2 + 3, 24, 37, 8, -1);

    dialogTemplate.AddStatic(_T("Message:"), WS_VISIBLE, 0,
        2 + 3, 42, 37, 8, -1);

    dialogTemplate.AddEditBox(_T("Edit"), WS_VISIBLE | ES_READONLY, WS_EX_STATICEDGE,
        45 + 3, 7, 131, 12, IDC_FILENAME);

    dialogTemplate.AddEditBox(_T("Edit"), WS_VISIBLE | ES_READONLY, WS_EX_STATICEDGE,
        209 + 3, 7, 39, 12, IDC_LINENUMBER);

    dialogTemplate.AddEditBox(_T("Edit"), WS_VISIBLE | ES_READONLY, WS_EX_STATICEDGE,
        45 + 3, 24, 131, 12, IDC_EXPRESSION);

    dialogTemplate.AddEditBox(_T("Edit"), WS_VISIBLE | ES_READONLY, WS_EX_STATICEDGE,
        45 + 3, 41, 131, 12, IDC_MESSAGE);

    dialogTemplate.AddButton(_T("Debug"), WS_VISIBLE, 0,
        2 + 3, 62, 56, 13, IDDEBUG);

    dialogTemplate.AddButton(_T("Ignore"), WS_VISIBLE, 0,
        65 + 3, 62, 56, 13, IDIGNORE);

    dialogTemplate.AddButton(_T("Ignore Always"), WS_VISIBLE, 0,
        127 + 3, 62, 56, 13, IDIGNOREALWAYS);

    dialogTemplate.AddButton(_T("Exit"), WS_VISIBLE, 0,
        192 + 3, 62, 56, 13, IDEXIT);

    res = DialogBoxIndirect(GetModuleHandle(0), dialogTemplate, NULL, (DLGPROC)AssertDlgProc);

For the most part, I'd say that this class isn't really complete. One improvement would be to have the AddListBox method take an array of strings which it uses to initialize the list box with; you could do this by putting them into the creation data that gets appended after the component description (this is why I made separate methods for each of the component types). At any rate, I'm submitting this to the public domain so feel free to make improvements to it and use it in your own projects.
Max

Download Associated File: DialogTemplate.cpp (6,284 bytes)

    #include <windows.h>

    class DialogTemplate
    {

    public:

        DialogTemplate(LPCSTR caption, DWORD style, int x, int y, int w, int h
            LPCSTR font = NULL, WORD fontSize = 8)
        {

            usedBufferLength = sizeof(DLGTEMPLATE );
            totalBufferLength = usedBufferLength;

            dialogTemplate = (DLGTEMPLATE*)malloc(totalBufferLength);

            dialogTemplate->style = style;

            if (font != NULL)
            {
                dialogTemplate->style |= DS_SETFONT;
            }

            dialogTemplate->x     = x;
            dialogTemplate->y     = y;
            dialogTemplate->cx    = w;
            dialogTemplate->cy    = h;
            dialogTemplate->cdit  = 0;

            dialogTemplate->dwExtendedStyle = 0;

            // The dialog box doesn't have a menu or a special class

            AppendData(_T("\0"), 2);
            AppendData(_T("\0"), 2);

            // Add the dialog's caption to the template

            AppendString(caption);

            if (font != NULL)
            {
                AppendData(&fontSize, sizeof(WORD));
                AppendString(font);
            }

        }

        void AddComponent(LPCSTR type, LPCSTR caption, DWORD style, DWORD exStyle,
            int x, int y, int w, int h, WORD id)
        {

            DLGITEMTEMPLATE item;

            item.style = style;
            item.x     = x;
            item.y     = y;
            item.cx    = w;
            item.cy    = h;
            item.id    = id;

            item.dwExtendedStyle = exStyle;

            AppendData(&item, sizeof(DLGITEMTEMPLATE));

            AppendString(type);
            AppendString(caption);

            WORD creationDataLength = 0;
            AppendData(&creationDataLength, sizeof(WORD));

            // Increment the component count

            dialogTemplate->cdit++;

        }

        void AddButton(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
            int w, int h, WORD id)
        {

            AddStandardComponent(0x0080, caption, style, exStyle, x, y, w, h, id);

            WORD creationDataLength = 0;
            AppendData(&creationDataLength, sizeof(WORD));

        }

        void AddEditBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
            int w, int h, WORD id)
        {

            AddStandardComponent(0x0081, caption, style, exStyle, x, y, w, h, id);

            WORD creationDataLength = 0;
            AppendData(&creationDataLength, sizeof(WORD));

        }

        void AddStatic(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
            int w, int h, WORD id)
        {

            AddStandardComponent(0x0082, caption, style, exStyle, x, y, w, h, id);

            WORD creationDataLength = 0;
            AppendData(&creationDataLength, sizeof(WORD));

        }

        void AddListBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
            int w, int h, WORD id)
        {

            AddStandardComponent(0x0083, caption, style, exStyle, x, y, w, h, id);

            WORD creationDataLength = 0;
            AppendData(&creationDataLength, sizeof(WORD));

        }

        void AddScrollBar(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
            int w, int h, WORD id)
        {

            AddStandardComponent(0x0084, caption, style, exStyle, x, y, w, h, id);

            WORD creationDataLength = 0;
            AppendData(&creationDataLength, sizeof(WORD));

        }

        void AddComboBox(LPCSTR caption, DWORD style, DWORD exStyle, int x, int y,
            int w, int h, WORD id)
        {

            AddStandardComponent(0x0085, caption, style, exStyle, x, y, w, h, id);

            WORD creationDataLength = 0;
            AppendData(&creationDataLength, sizeof(WORD));

        }

        /**
         * Returns a pointer to the Win32 dialog template which the object
         * represents. This pointer may become invalid if additional
         * components are added to the template.
         */

        operator const DLGTEMPLATE*() const
        {
            return dialogTemplate;
        }

        virtual ~DialogTemplate()
        {
            free(dialogTemplate);
        }

    protected:

        void AddStandardComponent(WORD type, LPCSTR caption, DWORD style,
            DWORD exStyle, int x, int y, int w, int h, WORD id)
        {

            DLGITEMTEMPLATE item;

            // DWORD algin the beginning of the component data

            AlignData(sizeof(DWORD));

            item.style = style;
            item.x     = x;
            item.y     = y;
            item.cx    = w;
            item.cy    = h;
            item.id    = id;

            item.dwExtendedStyle = exStyle;

            AppendData(&item, sizeof(DLGITEMTEMPLATE));

            WORD preType = 0xFFFF;

            AppendData(&preType, sizeof(WORD));
            AppendData(&type, sizeof(WORD));

            AppendString(caption);

            // Increment the component count

            dialogTemplate->cdit++;

        }

        void AlignData(int size)
        {

            int paddingSize = usedBufferLength % size;

            if (paddingSize != 0)
            {
                EnsureSpace(paddingSize);
                usedBufferLength += paddingSize;
            }

        }

        void AppendString(LPCSTR string)
        {

            int length = MultiByteToWideChar(CP_ACP, 0, string, -1, NULL, 0);

            WCHAR* wideString = (WCHAR*)malloc(sizeof(WCHAR) * length);
            MultiByteToWideChar(CP_ACP, 0, string, -1, wideString, length);

            AppendData(wideString, length * sizeof(WCHAR));
            free(wideString);

        }

        void AppendData(void* data, int dataLength)
        {

            EnsureSpace(dataLength);

            memcpy((char*)dialogTemplate + usedBufferLength, data, dataLength);
            usedBufferLength += dataLength;

        }

        void EnsureSpace(int length)
        {

            if (length + usedBufferLength > totalBufferLength)
            {

                totalBufferLength += length * 2;

                void* newBuffer = malloc(totalBufferLength);
                memcpy(newBuffer, dialogTemplate, usedBufferLength);

                free(dialogTemplate);
                dialogTemplate = (DLGTEMPLATE*)newBuffer;

            }

        }

    private:

        DLGTEMPLATE* dialogTemplate;

        int totalBufferLength;
        int usedBufferLength;

    };

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.