Ok, so i am attempting to create a dialog box. I read that working with dialog boxes was supposed to be easier than using CreateWindowEx but i seem to be pulling my hair more trying to make a dialog box.

Well, first of all, i am trying to make a dialog box the raw way. No make resources. So i came up with a simple code:

#include <Windows.h>

LRESULT CALLBACK WindowProcedure
(
HWND WindowHandle,
UINT Message,
WPARAM WordParameter,
LPARAM LongParameter
)
{
HDC DeviceContextHandle;
PAINTSTRUCT PaintStructure;
TRACKMOUSEEVENT MouseEvent;

switch(Message)
{
case WM_INITDIALOG:
return TRUE;
case WM_MOUSEMOVE:
MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
MouseEvent.dwFlags = TME_HOVER | TME_LEAVE;
MouseEvent.hwndTrack = WindowHandle;
MouseEvent.dwHoverTime = 0;
TrackMouseEvent(&MouseEvent);
break;
case WM_MOUSEHOVER:
SetClassLongPtr(WindowHandle, GCLP_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(255,0,0)));
InvalidateRect(WindowHandle, NULL, TRUE);
break;
case WM_MOUSELEAVE:
SetClassLongPtr(WindowHandle, GCLP_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(0,0,255)));
InvalidateRect(WindowHandle, NULL, TRUE);
break;
case WM_PAINT:
DeviceContextHandle = BeginPaint(WindowHandle, &PaintStructure);
EndPaint(WindowHandle, &PaintStructure);
break;
case WM_DESTROY:
EndDialog(WindowHandle, WM_QUIT);
PostQuitMessage(WM_QUIT);
return TRUE;
}
return DefWindowProc(WindowHandle, Message, WordParameter, LongParameter);
}

int WINAPI wWinMain
(
HINSTANCE CurretnInstance,
HINSTANCE PreviousInstance,
LPWSTR CommandLine,
int CommandShow
)
{
HGLOBAL GlobalHandle = malloc(sizeof(DLGTEMPLATE)*2);
DLGTEMPLATE* DialogTemplate = (LPDLGTEMPLATE)GlobalLock(GlobalHandle);
DialogTemplate->style =  WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | WS_VISIBLE;
DialogTemplate->dwExtendedStyle = NULL;
DialogTemplate->cdit = 0;
DialogTemplate->x = CW_USEDEFAULT;
DialogTemplate->y = CW_USEDEFAULT;
DialogTemplate->cx = CW_USEDEFAULT;
DialogTemplate->cy = CW_USEDEFAULT;

LRESULT DialogHandle = DialogBoxIndirect//CreateDialogIndirectParam
(
CurretnInstance,
(LPDLGTEMPLATE)GlobalHandle,
NULL,
(DLGPROC)WindowProcedure,
NULL
);
GlobalUnlock(GlobalHandle);
delete Globalhandle;
ShowWindow(DialogHandle, CommandShow);

return 0;
}


But of course, it doesn't work. Otherwise i would not be asking for help. So then i consult Microsoft's MSDN site and found a working code: http://msdn.microsoft.com/en-us/library/windows/desktop/ms644996(v=vs.85).aspx#template_in_memory
#include <Windows.h>
#include "stdafx.h";

//LRESULT CALLBACK WindowProcedure
// (
// HWND WindowHandle,
// UINT Message,
// WPARAM WordParameter,
// LPARAM LongParameter
// )
//{
// HDC DeviceContextHandle;
// PAINTSTRUCT PaintStructure;
// TRACKMOUSEEVENT MouseEvent;
//
// switch(Message)
// {
// case WM_INITDIALOG:
// return TRUE;
// case WM_MOUSEMOVE:
// MouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
// MouseEvent.dwFlags = TME_HOVER | TME_LEAVE;
// MouseEvent.hwndTrack = WindowHandle;
// MouseEvent.dwHoverTime = 0;
// TrackMouseEvent(&MouseEvent);
// break;
// case WM_MOUSEHOVER:
// SetClassLongPtr(WindowHandle, GCLP_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(255,0,0)));
// InvalidateRect(WindowHandle, NULL, TRUE);
// break;
// case WM_MOUSELEAVE:
// SetClassLongPtr(WindowHandle, GCLP_HBRBACKGROUND, (LONG)CreateSolidBrush(RGB(0,0,255)));
// InvalidateRect(WindowHandle, NULL, TRUE);
// break;
// case WM_PAINT:
// DeviceContextHandle = BeginPaint(WindowHandle, &PaintStructure);
// EndPaint(WindowHandle, &PaintStructure);
// break;
// case WM_DESTROY:
// EndDialog(WindowHandle, WM_QUIT);
// PostQuitMessage(WM_QUIT);
// return TRUE;
// }
// return DefWindowProc(WindowHandle, Message, WordParameter, LongParameter);
//}

#define ID_HELP  150
#define ID_TEXT  200

BOOL CALLBACK DialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_INITDIALOG:
        return TRUE;

    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:
        case IDCANCEL:
            EndDialog(hwndDlg, LOWORD(wParam));
            return TRUE;
        }
    }
    return FALSE;
}

LPWORD lpwAlign(LPWORD lpIn, ULONG dw2Power = 4)
{
    ULONG ul;

    ul = (ULONG)lpIn;
    ul += dw2Power-1;
    ul &= ~(dw2Power-1);
    return (LPWORD)ul;
}


int WINAPI wWinMain
(
HINSTANCE CurretnInstance,
HINSTANCE PreviousInstance,
LPWSTR CommandLine,
int CommandShow
)
{
//HGLOBAL GlobalHandle = malloc(sizeof(DLGTEMPLATE)*2);
//DLGTEMPLATE* DialogTemplate = (LPDLGTEMPLATE)GlobalLock(GlobalHandle);
//DialogTemplate->style =  WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | WS_VISIBLE;
//DialogTemplate->dwExtendedStyle = NULL;
//DialogTemplate->cdit = 0;
//DialogTemplate->x = CW_USEDEFAULT;
//DialogTemplate->y = CW_USEDEFAULT;
//DialogTemplate->cx = CW_USEDEFAULT;
//DialogTemplate->cy = CW_USEDEFAULT;

//LRESULT DialogHandle = DialogBoxIndirect//CreateDialogIndirectParam
// (
// CurretnInstance,
// (LPDLGTEMPLATE)GlobalHandle,
// NULL,
// (DLGPROC)WindowProcedure,
// NULL
// );
//GlobalUnlock(GlobalHandle);
//delete GlobalHandle;
//ShowWindow(DialogHandle, CommandShow);

HGLOBAL hgbl;
    LPDLGTEMPLATE lpdt;
    LPDLGITEMTEMPLATE lpdit;
    LPWORD lpw;
    LPWSTR lpwsz;
    LRESULT ret;
    int nchar;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 512);
    if (!hgbl)
        return -1;

    lpdt = (LPDLGTEMPLATE)GlobalLock(hgbl);

    // Define a dialog box.

    lpdt->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION;
    lpdt->cdit = 3;        // Number of controls
    lpdt->x  = 10;  lpdt->y  = 10;
    lpdt->cx = 100; lpdt->cy = 100;

    lpw = (LPWORD)(lpdt + 1);
    *lpw++ = 0;            // No menu
    *lpw++ = 0;            // Predefined dialog box class (by default)

    lpwsz = (LPWSTR)lpw;
    nchar = MultiByteToWideChar(CP_ACP, 0, "My Dialog", -1, lpwsz, 50);
    lpw += nchar;

    //-----------------------
    // Define an OK button.
    //-----------------------
    lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->x  = 10; lpdit->y  = 70;
    lpdit->cx = 80; lpdit->cy = 20;
    lpdit->id = IDOK;      // OK button identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;

    lpw = (LPWORD)(lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;        // Button class

    lpwsz = (LPWSTR)lpw;
    nchar = MultiByteToWideChar(CP_ACP, 0, "OK", -1, lpwsz, 50);
    lpw += nchar;
    *lpw++ = 0;            // No creation data

    //-----------------------
    // Define a Help button.
    //-----------------------
    lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->x  = 55; lpdit->y  = 10;
    lpdit->cx = 40; lpdit->cy = 20;
    lpdit->id = ID_HELP;    // Help button identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;

    lpw = (LPWORD)(lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0080;        // Button class atom

    lpwsz = (LPWSTR)lpw;
    nchar = MultiByteToWideChar(CP_ACP, 0, "Help", -1, lpwsz, 50);
    lpw += nchar;
    *lpw++ = 0;            // No creation data

    //-----------------------
    // Define a static text control.
    //-----------------------
    lpw = lpwAlign(lpw);    // Align DLGITEMTEMPLATE on DWORD boundary
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->x  = 10; lpdit->y  = 10;
    lpdit->cx = 40; lpdit->cy = 20;
    lpdit->id = ID_TEXT;    // Text identifier
    lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;

    lpw = (LPWORD)(lpdit + 1);
    *lpw++ = 0xFFFF;
    *lpw++ = 0x0082;        // Static class

    lpwsz = (LPWSTR)lpw;
    nchar = MultiByteToWideChar(CP_ACP, 0, "Message", -1, lpwsz, 150);
    lpw += nchar;
    *lpw++ = 0;            // No creation data

    GlobalUnlock(hgbl);
    ret = DialogBoxIndirect(
CurretnInstance,
        (LPDLGTEMPLATE)hgbl,
        NULL,
        (DLGPROC)DialogProc);
    GlobalFree(hgbl);


return 0;
}


Then what is the problem? Well, i want to start from making a button-less dialog box so when i try to remove any, and i mean ANY even just one dialog item; the entire dialog box doesn't show. Just like my dialog box.
Posted on 2012-04-11 11:44:46 by banzemanga
After lot of documentation reading and experimenting, i found what the problem was.

The "cdit" variable of the "DLGTEMPLATE" structure must be 0 for blank dialog windows. And for every control there is, that is the value in it. For example, if the dialog window has 3 controls then the value is 3.

Also, it is important that the numbers of controls and the cdit value match. If there are 2 controls and the value is 3, the dialog box would not show. And if there are 4 controls but the value is 3, it will only parse the first three controls.
Posted on 2012-04-11 19:47:53 by banzemanga