I'm new to win32api programming. I would like to know how to create a dialog box within a non-gui program (without any resource created).
I've seen some examples with that CreateIndirect
function. Is it the best method? Any other way?
Thanks!
You would use DialogBoxIndirectParam or CreateDialogIndirectParam
With these functions, its a bit more work, but it's possible to imbed a simple dialog template as an initialized static struct in your code. The format of a dialog template has some inplace variable sized arrays, so you have to have a struct declaration that is specific to a particular dialog, but this works OK for debug code.
Something like this
#define DLGTITLE L"Debug"
#define DLGFONT L"MS Sans Serif"
#define DLGAPPLY L"&Apply"
#define DLGCANCEL L"&Cancel"
#define NUMCHARS(aa) (sizeof(aa)/sizeof((aa)[0]))
#define IDC_BITMAP 99
#pragma pack(push, 4)
static struct { // dltt
DWORD style;
DWORD dwExtendedStyle;
WORD ccontrols;
short x;
short y;
short cx;
short cy;
WORD menu; // name or ordinal of a menu resource
WORD windowClass; // name or ordinal of a window class
WCHAR wszTitle[NUMCHARS(DLGTITLE)]; // title string of the dialog box
short pointsize; // only if DS_SETFONT flag is set
WCHAR wszFont[NUMCHARS(DLGFONT)]; // typeface name, if DS_SETFONT is set
// control info
//
struct {
DWORD style;
DWORD exStyle;
short x;
short y;
short cx;
short cy;
WORD id;
WORD sysClass; // 0xFFFF identifies a system window class
WORD idClass; // ordinal of a system window class
WCHAR wszTitle[NUMCHARS(DLGAPPLY)];
WORD cbCreationData; // bytes of following creation data
// WORD wAlign; // align next control to DWORD boundry.
} apply;
struct {
DWORD style;
DWORD exStyle;
short x;
short y;
short cx;
short cy;
WORD id;
WORD sysClass; // 0xFFFF identifies a system window class
WORD idClass; // ordinal of a system window class
WCHAR wszTitle[NUMCHARS(DLGCANCEL)];
WORD cbCreationData; // bytes of following creation data
} cancel;
struct {
DWORD style;
DWORD exStyle;
short x;
short y;
short cx;
short cy;
WORD id;
WORD sysClass; // 0xFFFF identifies a system window class
WORD idClass; // ordinal of a system window class
WCHAR wszTitle[1]; // title string or ordinal of a resource
WORD cbCreationData; // bytes of following creation data
} bitmap;
} g_DebugDlgTemplate = {
WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU // style 0x94c800c4
| DS_MODALFRAME | DS_3DLOOK
| DS_SETFONT,
0x0, // exStyle;
3, // ccontrols
0, 0, 300, 180,
0, // menu: none
0, // window class: none
DLGTITLE, // Window caption
8, // font pointsize
DLGFONT,
{
WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_GROUP | BS_DEFPUSHBUTTON, // 0x50030001
WS_EX_NOPARENTNOTIFY, // 0x4
190,160,50,14,
IDOK,
0xFFFF, 0x0080, // button
DLGAPPLY, 0,
},
{
WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON, // 0x50010000
WS_EX_NOPARENTNOTIFY, // 0x4
244,160,50,14,
IDCANCEL,
0xFFFF, 0x0080, // button
DLGCANCEL, 0,
},
{
WS_CHILD | WS_VISIBLE | WS_GROUP | SS_LEFT, // 0x50020000
WS_EX_NOPARENTNOTIFY, // 0x4
6,6,288,8,
IDC_BITMAP,
0xFFFF, 0x0082, // static
L"", 0,
},
};
#pragma pack(pop)
INT_PTR CALLBACK Debug_DlgProc (
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
}
break;
case WM_COMMAND:
{
UINT wId = LOWORD(wParam);
if (wId == IDOK || wId == IDCANCEL)
{
EndDialog (hwnd, wId);
}
}
break;
case WM_CLOSE:
EndDialog(hwnd, IDCANCEL);
break;
}
return FALSE;
}
LRESULT DoDebugDialog(HWND hwndApp, LPVOID pvData)
{
HINSTANCE hinst = hwndApp ? (HINSTANCE)(LONG_PTR)GetWindowLongPtr(hwndApp, GWLP_HINSTANCE)
: (HINSTANCE)GetModuleHandle(NULL);
return DialogBoxIndirectParamW (hinst, (LPCDLGTEMPLATEW)&g_DebugDlgTemplate, hwndApp,
Debug_DlgProc, (LPARAM)pvData);
}
A more sophisticated solution would be to build up a dialog template structure in memory, but this works well for debug code where the dialog itself doesn't change much.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With