Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Win32api, creating a dialog box without resource

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!

like image 842
huff Avatar asked Feb 16 '10 01:02

huff


1 Answers

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.

like image 178
John Knoeller Avatar answered Oct 20 '22 14:10

John Knoeller