Microsoft KB Archive/140725

{|
 * width="100%"|

DOCERR: Incorrect DialogBoxIndirect Code in Win32 SDK Docs

 * }

Q140725

-

The information in this article applies to:


 * Microsoft Win32 Software Development Kit (SDK), on platform(s):
 * Microsoft Windows 95
 * the operating system: Microsoft Windows NT 3.51

-

SUMMARY
The Win32 SDK documentation demonstrates how to create a template in memory for a modal dialog box by using DialogBoxIndirect in a section called "Creating a Template in Memory." The code included in this section of the documentation has problems in Windows 95 and Windows NT version 3.51, which may cause the dialog box to come up with only one control or may cause DialogBoxIndirect to return -1, indicating failure.

The same problems occur if the call to DialogBoxIndirect is replaced with CreateDialogIndirect.

NOTE: This docerr is fixed in Windows NT version 4.0 beta documents.

MORE INFORMATION
There are four problems with the DialogBoxIndirect code. The corrected code appears at the end of this article.

  The code was intended to bring up a modal dialog box that contains a static control (an OK button) and a Help button. However, because of two conflicting lines of code that were supposed to set the DLGTEMPLATE struct's cdit member to the number of controls in the dialog box, the system is made to think there is only one control in the dialog.

     lpdt->cdit = 3;  // number of controls lpdt->cdit = 1;

As is, the code works when pasted into an application, although the dialog box comes up with only the OK button and the other two controls are not shown. The second line should be removed because the dialog box actually contains three controls, not one. However, doing this while leaving the rest of the code as is causes no dialog box to come up and DialogBoxIndirect returns -1 as a result of two other problems described in this article.   The DLGTEMPLATE structure passed to the DialogBoxIndirect or CreateDialogIndirect functions is followed by one or more DLGITEMTEMPLATE structures. These DLGITEMTEMPLATE structures need to be DWORD aligned. Calling the following lpwAlign function will do just that:

     /* Helper routine. Take an input pointer, return closest pointer that is aligned on a DWORD (4 byte) boundary. */      LPWORD lpwAlign ( LPWORD lpIn) {        ULONG ul;

ul = (ULONG) lpIn; ul +=3; ul >>=2; ul <<=2; return (LPWORD) ul; }   The help button and the static control have identical (x,y) coordinates as well as width and height (cx,cy):

     lpdit->x  = 55; lpdit->y  = 10; lpdit->cx = 40; lpdit->cy = 20; This causes the static control to overlap the help button. You need to adjust these values accordingly so that they both show up in the dialog box. The following code shows how the modified code looks like so far. Note the calls to the lpwAlign function each time a DLGITEMTEMPLATE structure is added. This works fine in Windows NT version 3.51.

     #define ID_HELP   150 #define ID_TEXT  200 LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner,        LPSTR lpszMessage) {

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

hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024); 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->cdit = 1;  // COMMENTED OUT -- unnecessary code

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; lstrcpyW(lpwsz, L"My Message"); // dialog title (Unicode) lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1);

//---      // Define an OK button. //---      lpw = lpwAlign (lpw); 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; lstrcpyW(lpwsz, L"OK"); // button label (Unicode) lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1); *lpw++ = 0;             // no creation data

//---      // Define a Help button. //---      lpw = lpwAlign (lpw);

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; lstrcpyW(lpwsz, L"Help");       // button label (Unicode) lpw = (LPWORD) (lpwsz + lstrlenW(lpwsz) + 1); *lpw++ = 0;                     // no creation data

//---      // Define a static text control. //---      lpw = lpwAlign (lpw);

lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->x = 10; lpdit->y  = 10;    // Changed this from (55,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

for (lpwsz = (LPWSTR)lpw;          *lpwsz++ = (WCHAR) *lpszMessage++;           ); lpw = (LPWORD)lpwsz; *lpw++ = 0;                             // no creation data

GlobalUnlock(hgbl); ret = DialogBoxIndirect(hinst,                              (LPDLGTEMPLATE) hgbl,                               hwndOwner, (DLGPROC) DialogProc); GlobalFree(hgbl);

return ret; }  As previously stated, this modified code works fine in Windows NT 3.51. In Windows 95, however, the dialog box and the controls come up, but with no text for the help and OK buttons or for the dialog box.

Notice how the text in the code copies the text onto the memory block using lstrcpyW, which is not implemented in Windows 95, so it returns ERROR_NOT_IMPLEMENTED. To generate Unicode strings in Windows 95, the application must use MultiByteToWideChar.

Following is the modified code that works in Windows 95:

     #define ID_HELP   150 #define ID_TEXT  200 LRESULT DisplayMyMessage(HINSTANCE hinst, HWND hwndOwner,        LPSTR lpszMessage) {

HGLOBAL hgbl; LPDLGTEMPLATE lpdt; LPDLGITEMTEMPLATE lpdit; LPWORD lpw; LPWSTR lpwsz; LRESULT ret; hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024); 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 = 1+ MultiByteToWideChar (CP_ACP, 0, "My Dialog", -1,                                      lpwsz, 50); lpw  += nchar;

//---      // Define an OK button. //---      lpw = lpwAlign (lpw);

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 = 1+MultiByteToWideChar (CP_ACP, 0, "OK", -1, lpwsz, 50); lpw  += nchar; *lpw++ = 0;             // no creation data

//---      // Define a Help button. //---      lpw = lpwAlign (lpw);

lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->x = 55; lpdit->y  = 10; lpdit->cx = 40; lpdit->cy = 20; lpdit->id = 101; //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 = 1+MultiByteToWideChar (CP_ACP, 0, "Help", -1, lpwsz, 50); lpw  += nchar; *lpw++ = 0;                     // no creation data

//---      // Define a static text control. //---      lpw = lpwAlign (lpw);

lpdit = (LPDLGITEMTEMPLATE) lpw; lpdit->x = 10; lpdit->y  = 10; lpdit->cx = 40; lpdit->cy = 20; lpdit->id = 200; //ID_TEXT; // text identifier lpdit->style = WS_CHILD | WS_VISIBLE | SS_LEFT;

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

for (lpwsz = (LPWSTR)lpw;          *lpwsz++ = (WCHAR) *lpszMessage++;          );

lpw = (LPWORD)lpwsz; *lpw++ = 0;                             // no creation data

GlobalUnlock(hgbl); ret = DialogBoxIndirect(hinst,                              (LPDLGTEMPLATE) hgbl,                               hwndOwner,                               (DLGPROC) DialogProc); GlobalFree(hgbl);

return ret; } Additional query words:

Keywords : _IK kbdocfix kbdocerr kbDlg kbOSWinNT kbGrpDSUser kbOSWin

Issue type :

Technology : kbWin32SDKSearch kbAudDeveloper kbSDKSearch kbWin32sSearch