Thread: custom dialogs / DialogBoxIndirect() / dialog template in memory problems

  1. #1
    Registered User
    Join Date
    May 2005
    Posts
    2

    Question custom dialogs / DialogBoxIndirect() / dialog template in memory problems

    hi there,

    i have a problem with creating a custom dialog with a dialog template in memory. i have been working on this
    for days, but now i am close to giving up. i just cannot see the mistake i seem to make. i hope you can help me.

    i wrote a function called LRESULT ConflictDialog() that should create a dialog-window with two buttons. (actually it
    should do much more, but i minimized the code to focus on the problem) i used the sample code from MSDN for
    "Creating a Template in Memory" (Platform SDK->User Interface Services->Windowing->Dialog Boxes->Using Dialog Boxes)
    but it just doesn't work. i always get the -1 error code which according to documentation means that the function
    failed.

    i really changed only a few details and watched out for allignment and stuff, but it only worked arbitrarily and now
    i found a state where it never works. i also tried inserting the real values instead of the NULLs into the
    Code:
    ret = DialogBoxIndirect(NULL,(LPDLGTEMPLATE) hgbl,NULL,(DLGPROC) ConflictDialogProc);
    line but it didn't
    change a thing.

    i work with dev-cpp if that matters. you can download a 7kb-zip including the whole source-code from
    www.torchous.de/thomas/conflictDialogTest.zip ...

    the code of the ConflictDialog() function is as follows..:

    Code:
    LRESULT ConflictDialog()
    {
           HGLOBAL hgbl;
           LPDLGTEMPLATE uebergabeTemplate;
           LPDLGITEMTEMPLATE lpdit;
           LPWORD lpword;
           LPWSTR lpwsz;
           LRESULT ret;
    	   int nchar;
    
           // check for memory allocation errors
           hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
           if (!hgbl) 
           {
                mb("error@ConflictDialog :: GlobalAlloc failed!");
                return -1;
           }
            
    
           uebergabeTemplate = (LPDLGTEMPLATE)GlobalLock(hgbl);
    
           // Define a dialog box.
    
           uebergabeTemplate->style = DS_CENTER| WS_POPUP | WS_BORDER | WS_SYSMENU | 
                                      DS_MODALFRAME | WS_CAPTION;
           uebergabeTemplate->cdit = 2;  // number of controls
           uebergabeTemplate->x  = 100;  uebergabeTemplate->y  = 20;
           uebergabeTemplate->cx = 300;  uebergabeTemplate->cy = 170;
    
           lpword = (LPWORD) (uebergabeTemplate + 1);
           *lpword++ = 0;   // no menu
           *lpword++ = 0;   // predefined dialog box class (by default)
    
           lpwsz = (LPWSTR) lpword;
           nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "File Conflict\0", -1,
                                           lpwsz, 50);
           lpword   += nchar;
    
    
           //-----------------------
           // Define a Ignore button.
           //-----------------------
           lpword = lpwAlign (lpword);
           lpdit = (LPDLGITEMTEMPLATE) lpword;
           lpdit->x  = 130; lpdit->y  = 150;
           lpdit->cx = 30; lpdit->cy = 15;
           lpdit->id = ID_IGNORE;   
           lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
    
           lpword = (LPWORD) (lpdit + 1);
           *lpword++ = 0xFFFF;
           *lpword++ = 0x0080;                 // button class atom
    
           lpwsz = (LPWSTR) lpword;
           nchar = 1+MultiByteToWideChar (CP_ACP, 0, "Ignore\0", -1, lpwsz, 50);
           lpword   += nchar;
           lpword = lpwAlign (lpword); // align creation data on DWORD boundary
           *lpword++ = 0;                      // no creation data
    
           //-----------------------
           // Define a Ignore button.
           //-----------------------
           lpword = lpwAlign (lpword);
           lpdit = (LPDLGITEMTEMPLATE) lpword;
           lpdit->x  = 260; lpdit->y  = 50;
           lpdit->cx = 30; lpdit->cy = 12;
           lpdit->id = ID_SHOW1;  // OK button identifier
           lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
    
           lpword = (LPWORD) (lpdit + 1);
           *lpword++ = 0xFFFF;
           *lpword++ = 0x0080;                 // button class atom
    
           lpwsz = (LPWSTR) lpword;
           nchar = 1+MultiByteToWideChar (CP_ACP, 0, "show\0", -1, lpwsz, 50);
           lpword   += nchar;
           lpword = lpwAlign (lpword); // align creation data on DWORD boundary
           *lpword++ = 0;                      // no creation data
    
    
    
    
        GlobalUnlock(hgbl);
        ret = DialogBoxIndirect(NULL,(LPDLGTEMPLATE) hgbl,NULL,(DLGPROC) ConflictDialogProc);
        
        // check for errors
        if( ret != ID_IGNORE && ret != ID_SHOW1 && ret != 0 && ret!=-1)
            mb("error in DialogBoxIndirect! unknow return code!");
        if( ret == 0 )
            mb("error in DialogBoxIndirect! returned 0!");
        if( ret == -1 )
            mb("error in DialogBoxIndirect! returned -1! so the dialog failed!");
            
        GlobalFree(hgbl);
        return ret;
    }
    the code of the ConflictDialogProc is as follows..:

    Code:
    BOOL CALLBACK  ConflictDialogProc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam)
    {
         switch (iMsg)
    	 {
              case WM_INITDIALOG :
              {
                   HFONT hfont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
                   SendDlgItemMessage(hDlg, ID_SHOW1, WM_SETFONT, (WPARAM)hfont, TRUE);            
                   SendDlgItemMessage(hDlg, ID_IGNORE, WM_SETFONT, (WPARAM)hfont, TRUE);            
                   return TRUE ;
              }
            	   
              case WM_COMMAND :
                   switch (LOWORD (wParam))
                   {
    					case ID_IGNORE :
                             EndDialog (hDlg, ID_IGNORE) ;
    			             return TRUE ;
    		            case ID_SHOW1 :
                             EndDialog (hDlg, ID_SHOW1) ;
    			             return TRUE ;
    			   }
                  break ;
         }
         return FALSE ;
    }
    and this is the lpwAlign function..:

    Code:
    LPWORD lpwAlign ( LPWORD lpIn)
    {
             ULONG ul;
    
             ul = (ULONG) lpIn;
             ul +=3;
             ul >>=2;
             ul <<=2;
             return (LPWORD) ul;
    }
    every help would be incredibly appreciated!

  2. #2
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    The msdn memory template dialog code is broken, as mentioned in this old thread here; your code produces the same result with GetLastError (you should try to use this function when winapi functions fail to get an idea of why that failure happened).

    Anyway, it seems that the problem lies in the repeated calls to the dword alignment helper function, the following should create your memory template dialog:
    Code:
    LRESULT ConflictDialog()
    {
           HGLOBAL hgbl;
           LPDLGTEMPLATE uebergabeTemplate;
           LPDLGITEMTEMPLATE lpdit;
           LPWORD lpword;
           LPWSTR lpwsz;
           LRESULT ret;
    	   int nchar;
    
           // check for memory allocation errors
           hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
           if (!hgbl) 
           {
                mb("error@ConflictDialog :: GlobalAlloc failed!");
                return -1;
           }
            
    
           uebergabeTemplate = (LPDLGTEMPLATE)GlobalLock(hgbl);
    
           // Define a dialog box.
    
           uebergabeTemplate->style = DS_CENTER| WS_POPUP | WS_BORDER | WS_SYSMENU | 
                                      DS_MODALFRAME | WS_CAPTION;
           uebergabeTemplate->cdit = 2;  // number of controls
           uebergabeTemplate->x  = 100;  uebergabeTemplate->y  = 20;
           uebergabeTemplate->cx = 300;  uebergabeTemplate->cy = 170;
    
           lpword = (LPWORD) (uebergabeTemplate + 1);
           *lpword++ = 0;   // no menu
           *lpword++ = 0;   // predefined dialog box class (by default)
    
           lpwsz = (LPWSTR) lpword;
           nchar = 1+ MultiByteToWideChar (CP_ACP, 0, "File Conflict\0", -1,
                                           lpwsz, 50);
           lpword   += nchar;
    
    
           //-----------------------
           // Define a Ignore button.
           //-----------------------
           lpword = lpwAlign (lpword);
           lpdit = (LPDLGITEMTEMPLATE) lpword;
           lpdit->x  = 130; lpdit->y  = 150;
           lpdit->cx = 30; lpdit->cy = 15;
           lpdit->id = ID_IGNORE;   
           lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
    
           lpword = (LPWORD) (lpdit + 1);
           *lpword++ = 0xFFFF;
           *lpword++ = 0x0080;                 // button class atom
    
           lpwsz = (LPWSTR) lpword;
           nchar = 1+MultiByteToWideChar (CP_ACP, 0, "Ignore\0", -1, lpwsz, 50);
           lpword   += nchar;
           //lpword = lpwAlign (lpword); // align creation data on DWORD boundary
           *lpword++ = 0;                      // no creation data
    
           //-----------------------
           // Define a Ignore button.
           //-----------------------
           lpword = lpwAlign (lpword);
           lpdit = (LPDLGITEMTEMPLATE) lpword;
           lpdit->x  = 260; lpdit->y  = 50;
           lpdit->cx = 30; lpdit->cy = 12;
           lpdit->id = ID_SHOW1;  // OK button identifier
           lpdit->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON;
    
           lpword = (LPWORD) (lpdit + 1);
           *lpword++ = 0xFFFF;
           *lpword++ = 0x0080;                 // button class atom
    
           lpwsz = (LPWSTR) lpword;
           nchar = 1+MultiByteToWideChar (CP_ACP, 0, "show\0", -1, lpwsz, 50);
           lpword   += nchar;
           //lpword = lpwAlign (lpword); // align creation data on DWORD boundary
           *lpword++ = 0;                      // no creation data
    
    
    
    
        GlobalUnlock(hgbl);
        ret = DialogBoxIndirect(NULL,(LPDLGTEMPLATE) hgbl,NULL,(DLGPROC) ConflictDialogProc);
        
        // check for errors
        if( ret != ID_IGNORE && ret != ID_SHOW1 && ret != 0 && ret!=-1)
            mb("error in DialogBoxIndirect! unknow return code!");
        if( ret == 0 )
            mb("error in DialogBoxIndirect! returned 0!");
        if( ret == -1 )
            mb("error in DialogBoxIndirect! returned -1! so the dialog failed!");
            
        GlobalFree(hgbl);
        return ret;
    }
    If there's no overwhelming reason to use memory templates you would be strongly advised to switch to using normal resource scripts to avoid all this fiddling about.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  3. #3
    Registered User
    Join Date
    May 2005
    Posts
    2
    first of all: thank you very much! your correction of my code worked and now i can sleep again

    i have read this old thread you mentioned but i didn't get the message at that time. now i understand.

    the thing with getLastError() was, that it returned 0, which means that no error occured which didn't help me much...

    in the meantime i found a much easier way to get the function to do what i want. the point is, that the dialog should show 2 filenames that produce a certain conflict. because those names are only known at runtime i wanted this template solution because it was mentioned in the msdn database (which i from now on hate because it spreads malfunctioning code). now i do it like this: i get an instance of a normal resource script and just change the two dummy LTEXT-labels via SendDlgItemMessage() to the given filenames. that is much easier i guess... an it works steadily.

    but thank you all the same! i have learned much on the way and maybe this thread will help some other poor people that get tricked by this bloody msdn code

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function template has already been defined
    By Elysia in forum C++ Programming
    Replies: 19
    Last Post: 04-14-2009, 10:17 AM
  2. Dialogs in memory? How ridiculous...
    By SMurf in forum Windows Programming
    Replies: 2
    Last Post: 08-13-2002, 02:12 PM
  3. Is it necessary to write a specific memory manager ?
    By Morglum in forum Game Programming
    Replies: 18
    Last Post: 07-01-2002, 01:41 PM
  4. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM
  5. Linked list with two class types within template.
    By SilasP in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2002, 06:13 AM