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:
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
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.
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.
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.
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.