Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

951 lines
28 KiB

/***************************************************************************\
*
* DLGBEGIN.C -
*
* Dialog Initialization Routines
*
* ??-???-???? mikeke Ported from Win 3.0 sources
* 12-Feb-1991 mikeke Added Revalidation code
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
BOOL ValidateCallback(HANDLE h);
LPCWSTR szEDITCLASS = TEXT("Edit");
/***************************************************************************\
* BYTE FAR *SkipSz(lpsz)
*
* History:
\***************************************************************************/
PBYTE SkipSz(
UTCHAR *lpsz)
{
if (*lpsz == 0xFF)
return (PBYTE)lpsz + 4;
while (*lpsz++ != 0) ;
return (PBYTE)lpsz;
}
PBYTE WordSkipSz(
UTCHAR *lpsz)
{
PBYTE pb = SkipSz(lpsz);
return NextWordBoundary(pb);
}
PBYTE DWordSkipSz(
UTCHAR *lpsz)
{
PBYTE pb = SkipSz(lpsz);
return NextDWordBoundary(pb);
}
/***************************************************************************\
*
* CreateDlgFont()
*
* Create the dialog font described at the given location in a resource
*
\***************************************************************************/
HFONT CreateDlgFont(HDC hdcDlg, LPWORD FAR *lplpstr, LPDLGTEMPLATE2 lpdt)
{
LOGFONT LogFont;
int fontheight, fheight;
HFONT hOldFont, hFont;
WCHAR szTempBuffer[20];
LPCWSTR lpStrSubst;
TEXTMETRIC tm;
BOOL fDeleteFont = FALSE;
fheight = fontheight = (SHORT)(*((WORD *) *lplpstr)++);
if (fontheight == 0x7FFF) {
// a 0x7FFF height is our special code meaning use the message box font
// return(gpsi->hMsgFont);
GetObject(gpsi->hMsgFont, sizeof(LOGFONT), &LogFont);
return(CreateFontIndirect(&LogFont));
}
//
// The dialog template contains a font description! Use it.
//
// Fill the LogFont with default values
RtlZeroMemory(&LogFont, sizeof(LOGFONT));
fontheight = -MultDiv(fontheight, oemInfo.cyPixelsPerInch, 72);
LogFont.lfHeight = fontheight;
if (lpdt->wDlgVer)
{
LogFont.lfWeight = *((WORD FAR *) *lplpstr)++;
LogFont.lfItalic = *((BYTE FAR *) *lplpstr)++;
LogFont.lfCharSet = *((BYTE FAR *) *lplpstr)++;
}
else
{
LogFont.lfWeight = FW_BOLD;
LogFont.lfCharSet = DEFAULT_CHARSET;
}
if (LogFont.lfCharSet == DEFAULT_CHARSET)
LogFont.lfCharSet = GetTextCharset(hdcDlg); // Assume shell charset.
if (lpdt->style & DS_3DLOOK)
LogFont.lfWeight = FW_NORMAL;
lpStrSubst = *lplpstr;
wcsncpycch(LogFont.lfFaceName, lpStrSubst, sizeof(LogFont.lfFaceName) / sizeof(WCHAR));
*lplpstr = (WORD *)DWordSkipSz(*lplpstr);
if (!(hFont = CreateFontIndirect((LPLOGFONT) &LogFont)))
return(NULL);
if (!(hOldFont = SelectFont(hdcDlg, hFont)))
goto deleteFont;
if (!GetTextMetrics(hdcDlg, &tm)) {
RIPMSG0(RIP_WARNING, "CreateDlgFont: GetTextMetrics failed");
goto deleteFont;
}
GetTextFace(hdcDlg, sizeof(szTempBuffer)/sizeof(WCHAR), szTempBuffer);
//
// If this is a low res device, we need to check if the
// font we're creating is smaller than the system font.
// If so, just use the system font.
//
if (_wcsicmp(szTempBuffer, lpStrSubst) ||
((SYSMET(CXICON) < 32 || SYSMET(CYICON) < 32) && (tm.tmHeight < gpsi->cySysFontChar)))
{
//
// Couldn't find a font with the height or facename
// the app wanted so use the system font instead. Note
// that we need to make sure the app knows it is
// getting the system font via the WM_SETFONT message
// so we still need to act as if a new font is being
// sent to the dialog box.
//
deleteFont:
fDeleteFont = TRUE;
}
if (hOldFont != NULL) {
SelectFont(hdcDlg, hOldFont);
}
if (fDeleteFont) {
DeleteFont(hFont);
hFont = NULL;
}
return(hFont);
}
#define CD_VISIBLE 0x01
#define CD_GLOBALEDIT 0x02
#define CD_USERFONT 0x04
#define CD_SETFOREGROUND 0x08
#define CD_USEDEFAULTX 0x10
#define CD_USEDEFAULTCX 0x20
/***************************************************************************\
* InternalCreateDialog
*
* Creates a dialog from a template. Uses passed in menu if there is one,
* destroys menu if creation failed. Server portion of
* CreateDialogIndirectParam.
*
* History:
* 04-10-91 ScottLu
* 04-17-91 Mikehar Win31 Merge
\***************************************************************************/
HWND InternalCreateDialog(
HANDLE hmod,
LPDLGTEMPLATE lpdt,
DWORD cb,
HWND hwndOwner,
DLGPROC lpfnDialog,
LONG lParam,
UINT fSCDLGFlags)
{
TL tlpwnd;
HWND hwnd;
HWND hwnd2;
PWND pwnd;
HWND hwndNewFocus;
HWND hwndEditFirst = NULL;
RECT rc;
WORD w;
UTCHAR *lpszMenu, *lpszClass, *lpszText, *lpCreateParams, *lpStr;
int cxChar, cyChar;
BOOL f40Compat;
HFONT hNewFont = NULL;
HFONT hOldFont;
LPDLGITEMTEMPLATE lpdit;
HMENU hMenu;
BOOL fSuccess;
BOOL fWowWindow;
HANDLE hmodCreate;
LPBYTE lpCreateParamsData;
DLGTEMPLATE2 dt;
DLGITEMTEMPLATE2 dit;
DWORD dwExpWinVer;
DWORD dsStyleOld;
DWORD bFlags = 0;
HDC hdcDlg;
LARGE_STRING strClassName;
PLARGE_STRING pstrClassName;
LARGE_STRING strWindowName;
ConnectIfNecessary();
UserAssert(!(fSCDLGFlags & ~(SCDLG_CLIENT|SCDLG_ANSI|SCDLG_NOREVALIDATE|SCDLG_16BIT))); // These are the only valid flags
/*
* Is this a Win4 extended dialog?
*/
if (((LPDLGTEMPLATE2)lpdt)->wSignature == 0xffff) {
UserAssert(((LPDLGTEMPLATE2)lpdt)->wDlgVer == 1);
RtlCopyMemory(&dt, lpdt, sizeof dt);
} else {
dt.wDlgVer = 0;
dt.wSignature = 0;
dt.dwHelpID = 0;
dt.dwExStyle = lpdt->dwExtendedStyle;
dt.style = lpdt->style;
dt.cDlgItems = lpdt->cdit;
dt.x = lpdt->x;
dt.y = lpdt->y;
dt.cx = lpdt->cx;
dt.cy = lpdt->cy;
}
/*
* If this is called from wow code, then the loword of hmod != 0.
* In this case, allow any DS_ style bits that were passed in win3.1
* to be legal in win32. Case in point: 16 bit quark xpress passes the
* same bit as the win32 style DS_SETFOREGROUND. Also, VC++ sample
* "scribble" does the same thing.
*
* For win32 apps test the DS_SETFOREGROUND bit; wow apps are not set
* foreground (this is the new NT semantics)
* We have to let no "valid" bits through because apps depend on them
* bug 5232.
*/
dsStyleOld = LOWORD(dt.style);
/*
* If the app is Win4 or greater, require correct dialog style bits.
* Prevents conflicts with new bits introduced in Chicago
*/
dwExpWinVer = GETEXPWINVER(hmod);
if ( f40Compat = Is400Compat(dwExpWinVer) ) {
dt.style &= (DS_VALID40 | 0xffff0000);
//
// For old applications:
// If DS_COMMONDIALOG isn't set, don't touch DS_3DLOOK style
// bit. If it's there, it stays there. If not, not. That way old
// apps which pass in their own templates, not commdlg's, don't get
// forced 3D.
// If DS_COMMONDIALOG is there, remove DS_3DLOOK.
//
// For new applications:
// Force 3D always.
//
if (GetAppVer(NULL) < VER40) {
if (dt.style & DS_COMMONDIALOG) {
dt.style &= ~DS_3DLOOK;
dsStyleOld &= ~DS_3DLOOK;
}
} else {
dt.style |= DS_3DLOOK;
dsStyleOld |= DS_3DLOOK;
}
} else {
#ifdef DEBUG
if (dt.style != (dt.style & (DS_VALID31 | DS_3DLOOK | 0xffff0000))) {
RIPMSG1(RIP_WARNING, "CreateDialog: stripping invalid bits %lX", dt.style);
}
#endif // DEBUG
/*
* Don't strip off bits for old apps, they depend on this. Especially 16 bit MFC apps!
*
* dt.dwStyle &= (DS_VALID31 | 0xffff0000);
*/
}
if (LOWORD(hmod) == 0) {
if (dt.style & DS_SETFOREGROUND)
bFlags |= CD_SETFOREGROUND;
}
if (dsStyleOld != LOWORD(dt.style))
{
RIPMSG1(f40Compat ? RIP_ERROR : RIP_WARNING,
"Bad dialog style bits (%x) - please remove.",
LOWORD(dt.style));
// Fail new apps that pass in bogus bits!
if (f40Compat) {
return NULL;
}
}
if ( dt.style & DS_MODALFRAME)
dt.dwExStyle |= WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE;
if (( dt.style & DS_CONTEXTHELP) && f40Compat)
dt.dwExStyle |= WS_EX_CONTEXTHELP;
if (dt.style & DS_CONTROL)
// Captions and system menus aren't allowed on "control" dialogs.
// And strip DS_SYSMODAL.
dt.style &= ~(WS_CAPTION | WS_SYSMENU | DS_SYSMODAL);
else if (dt.style & WS_DLGFRAME)
// Add on window edge same way that CreateWindowEx() will
dt.dwExStyle |= WS_EX_WINDOWEDGE;
if (dt.style & DS_SYSMODAL)
dt.dwExStyle |= WS_EX_TOPMOST;
if (!(dt.style & WS_CHILD) || (dt.style & DS_CONTROL)) {
// only a control parent if it's not a child dialog or if it's
// explicitly marked as a recursive dialog
dt.dwExStyle |= WS_EX_CONTROLPARENT;
}
if (dt.x == CW_USEDEFAULT)
{
bFlags |= CD_USEDEFAULTX;
dt.x = 0;
}
if (dt.cx == CW_USEDEFAULT)
{
bFlags |= CD_USEDEFAULTCX;
dt.cx = 0;
} else if (dt.cx < 0)
dt.cx = 0;
if (dt.cy < 0)
dt.cy = 0;
// If there's a menu name string, load it.
lpszMenu = (LPWSTR)(((PBYTE)(lpdt)) + (dt.wDlgVer ? sizeof(DLGTEMPLATE2):sizeof(DLGTEMPLATE)));
/*
* If the menu id is expressed as an ordinal and not a string,
* skip all 4 bytes to get to the class string.
*/
w = *(LPWORD)lpszMenu;
/*
* If there's a menu name string, load it.
*/
if (w != 0) {
if ((hMenu = LoadMenu(hmod, (w == 0xFFFF) ?
MAKEINTRESOURCE(*(WORD *)((PBYTE)lpszMenu + 2)) : lpszMenu)) == NULL) {
RIPMSG0(RIP_WARNING, "ServerCreateDialog() failed: couldn't load menu");
goto DeleteFontAndMenuAndFail;
}
} else {
hMenu = NULL;
}
if (w == 0xFFFF)
lpszClass = (LPWSTR)((LPBYTE)lpszMenu + 4);
else
lpszClass = (UTCHAR *)WordSkipSz(lpszMenu);
lpszText = (UTCHAR *)WordSkipSz(lpszClass);
lpStr = (UTCHAR *)WordSkipSz(lpszText);
hdcDlg = CreateCompatibleDC(NULL);
if (hdcDlg == NULL) goto DeleteFontAndMenuAndFail;
if (dt.style & DS_SETFONT) {
hNewFont = CreateDlgFont(hdcDlg, &lpStr, &dt);
bFlags |= CD_USERFONT;
lpdit = (LPDLGITEMTEMPLATE) NextDWordBoundary(lpStr);
} else if (Is400Compat(dwExpWinVer) && (dt.style & DS_FIXEDSYS)) {
//
// B#2078 -- WISH for fixed width system font in dialog. We need
// to tell the dialog that it's using a font different from the
// standard system font, so set CD_USERFONT bit.
//
// We need the 400 compat. check for CorelDraw, since they use
// this style bit for their own purposes.
//
hNewFont = GetStockObject(SYSTEM_FIXED_FONT);
bFlags |= CD_USERFONT;
lpdit = (LPDLGITEMTEMPLATE)NextDWordBoundary(lpStr);
}
else
lpdit = (LPDLGITEMTEMPLATE)NextDWordBoundary(lpStr);
/*
* If the application requested a particular font and for some
* reason we couldn't find it, we just use the system font. BUT we
* need to make sure we tell him he gets the system font. Dialogs
* which never request a particular font get the system font and we
* don't bother telling them this (via the WM_SETFONT message).
*/
// Is it anything other than the default system font? If we can't get
// enough memory to select in the new font specified, just use the system
// font.
if (hNewFont && (hOldFont = SelectFont(hdcDlg, hNewFont)))
{
// Get the ave character width and height to be used
cxChar = GdiGetCharDimensions(hdcDlg, NULL, &cyChar);
SelectFont(hdcDlg, hOldFont);
if (cxChar == 0) {
RIPMSG0(RIP_WARNING, "InternalCreateDialog: GdiGetCharDimensions failed");
goto UseSysFontMetrics;
}
}
else
{
if (hNewFont || (bFlags & CD_USERFONT))
hNewFont = ghFontSys;
UseSysFontMetrics:
cxChar = gpsi->cxSysFontChar;
cyChar = gpsi->cySysFontChar;
}
DeleteDC(hdcDlg);
if (dt.style & WS_VISIBLE)
{
bFlags |= CD_VISIBLE;
dt.style &= ~WS_VISIBLE;
}
if (!(dt.style & DS_LOCALEDIT))
bFlags |= CD_GLOBALEDIT;
/* Figure out dimensions of real window
*/
rc.left = rc.top = 0;
rc.right = XPixFromXDU(dt.cx, cxChar);
rc.bottom = YPixFromYDU(dt.cy, cyChar);
_AdjustWindowRectEx(&rc, dt.style, w, dt.dwExStyle);
dt.cx = (SHORT)(rc.right - rc.left);
dt.cy = (SHORT)(rc.bottom - rc.top);
if ((dt.style & DS_CENTERMOUSE) && f40Compat) {
if (!SYSMET(MOUSEPRESENT))
goto CenterScreen;
*((LPPOINT)&rc.left) = ptCursor;
rc.left -= (dt.cx / 2);
rc.top -= (dt.cy / 2);
} else if ((dt.style & DS_CENTER) && f40Compat) {
CenterScreen:
rc.left = (gpsi->rcWork.left + gpsi->rcWork.right - dt.cx) / 2;;
rc.top = (gpsi->rcWork.top + gpsi->rcWork.bottom - dt.cy) / 2;
} else {
rc.left = rc.top = 0;
if (!(dt.style & DS_ABSALIGN) && hwndOwner) {
if ((HIWORD(dt.style) & MaskWF(WFTYPEMASK)) != MaskWF(WFCHILD))
ClientToScreen(hwndOwner, (LPPOINT)&rc.left);
}
rc.left += MultDiv(dt.x, cxChar, 4);
rc.top += MultDiv(dt.y, cyChar, 8);
}
rc.right = rc.left + dt.cx;
rc.bottom = rc.top + dt.cy;
// If the right or bottom coordinate has overflowed, then pin it back to
// a valid rectangle. Likely to happen if a minimized window is the owner of
// the dialog.
if (rc.left > rc.right || rc.top > rc.bottom)
OffsetRect(&rc, -dt.cx, -dt.cy);
//
// Need to do this for ALL dialogs, not just top-level, since we used
// to in 3.1.
//
// Clip top level dialogs within working area
// Start child dialogs at least at (0, 0)
RepositionRect(&rc, dt.style, dt.dwExStyle);
dt.x = (SHORT)((bFlags & CD_USEDEFAULTX) ? CW_USEDEFAULT : rc.left);
dt.y = (SHORT)(rc.top);
dt.cx = (SHORT)((bFlags & CD_USEDEFAULTCX) ? CW_USEDEFAULT : rc.right - rc.left);
dt.cy = (SHORT)(rc.bottom - rc.top);
if (*lpszClass != 0) {
if (HIWORD(lpszClass)) {
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strClassName,
lpszClass, (UINT)-1);
pstrClassName = &strClassName;
} else {
pstrClassName = (PLARGE_STRING)lpszClass;
}
} else {
pstrClassName = (PLARGE_STRING)MAKEINTATOM(DIALOGCLASS);
}
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strWindowName,
lpszText, (UINT)-1);
UserAssert((dt.dwExStyle & WS_EX_MDICHILD) == 0);
hwnd = NtUserCreateWindowEx(
dt.dwExStyle | ((fSCDLGFlags & SCDLG_ANSI) ? WS_EX_ANSICREATOR : 0),
pstrClassName,
&strWindowName,
dt.style,
dt.x,
dt.y,
dt.cx,
dt.cy,
hwndOwner,
hMenu,
hmod,
(LPVOID)NULL,
dwExpWinVer,
NULL);
if (hwnd == NULL) {
RIPMSG0(RIP_WARNING, "CreateDialog() failed: couldn't create window");
DeleteFontAndMenuAndFail:
if (hMenu != NULL)
NtUserDestroyMenu(hMenu);
/*
* Only delete the font if we didn't grab it
* from the dialog font cache.
*/
if ((hNewFont != NULL)) {
DeleteObject(hNewFont);
}
return NULL;
}
pwnd = ValidateHwnd(hwnd);
/*
* Before anything happens with this window, we need to mark it as a
* dialog window!!!! So do that.
*/
if (pwnd == NULL || !ValidateDialogPwnd(pwnd))
goto DeleteFontAndMenuAndFail;
if (dt.dwHelpID)
NtUserSetWindowContextHelpId(hwnd, dt.dwHelpID);
/*
* Set up the system menu on this dialog box if it has one.
*/
if (TestWF(pwnd, WFSYSMENU)) {
/*
* For a modal dialog box with a frame and caption, we want to
* delete the unselectable items from the system menu.
*/
UserAssert(HIBYTE(WFSIZEBOX) == HIBYTE(WFMINBOX));
UserAssert(HIBYTE(WFMINBOX) == HIBYTE(WFMAXBOX));
if (!TestWF(pwnd, WFSIZEBOX | WFMINBOX | WFMAXBOX)) {
NtUserCallHwndLock(hwnd, SFI_XXXSETDIALOGSYSTEMMENU);
} else {
/*
* We have to give this dialog its own copy of the system menu
* in case it modifies the menu.
*/
NtUserGetSystemMenu(hwnd, FALSE);
}
}
/*
* Set fDisabled to FALSE so EndDialog will Enable if dialog is ended
* before returning to DialogBox (or if modeless).
*/
PDLG(pwnd)->fDisabled = FALSE;
PDLG(pwnd)->cxChar = cxChar;
PDLG(pwnd)->cyChar = cyChar;
PDLG(pwnd)->lpfnDlg = lpfnDialog;
PDLG(pwnd)->fEnd = FALSE;
PDLG(pwnd)->result = IDOK;
/*
* Need to remember Unicode status.
*/
if (fSCDLGFlags & SCDLG_ANSI)
PDLG(pwnd)->flags |= DLGF_ANSI;
/*
* Time to lock pwnd so it doesn't go away while we're calling back.
*/
ThreadLock(pwnd, &tlpwnd);
/*
* Have to do a callback here for WOW apps. WOW needs what's in lParam
* before the dialog gets any messages.
*/
/*
* If the app is a Wow app then the Lo Word of the hInstance is the
* 16-bit hInstance. Set the lParam, which no-one should look at
* but the app, to the 16 bit value
*/
if (LOWORD(hmod) != 0) {
fWowWindow = TRUE;
lParam = WOWDlgInit(hwnd, lParam);
} else {
fWowWindow = FALSE;
}
/*
* If a user defined font is used, save the handle so that we can delete
* it when the dialog is destroyed.
*/
if (bFlags & CD_USERFONT) {
PDLG(pwnd)->hUserFont = hNewFont;
if (lpfnDialog != NULL) {
/*
* Tell the dialog that it will be using this font...
*/
SendMessageWorker(pwnd, WM_SETFONT, (DWORD)hNewFont, 0L, FALSE);
}
}
if (!dt.wDlgVer)
dit.dwHelpID = 0;
/*
* Loop through the dialog controls, doing a CreateWindowEx() for each of
* them.
*/
while (dt.cDlgItems-- != 0) {
if (dt.wDlgVer) {
RtlCopyMemory(&dit, lpdit, sizeof dit);
} else
{
dit.dwHelpID = 0;
dit.dwExStyle = lpdit->dwExtendedStyle;
dit.style = lpdit->style;
dit.x = lpdit->x;
dit.y = lpdit->y;
dit.cx = lpdit->cx;
dit.cy = lpdit->cy;
dit.dwID = lpdit->id;
}
dit.x = XPixFromXDU(dit.x, cxChar);
dit.y = YPixFromYDU(dit.y, cyChar);
dit.cx = XPixFromXDU(dit.cx, cxChar);
dit.cy = YPixFromYDU(dit.cy, cyChar);
lpszClass = (LPWSTR)(((PBYTE)(lpdit)) + (dt.wDlgVer ? sizeof(DLGITEMTEMPLATE2):sizeof(DLGITEMTEMPLATE)));
/*
* If the first WORD is 0xFFFF the second word is the encoded class name index.
* Use it to look up the class name string.
*/
if (*(LPWORD)lpszClass == 0xFFFF) {
lpszText = lpszClass + 2;
lpszClass = (LPWSTR)(gpsi->atomSysClass[*(((LPWORD)lpszClass)+1) & ~CODEBIT]);
} else {
lpszText = (UTCHAR *)SkipSz(lpszClass);
}
lpszText = (UTCHAR *)NextWordBoundary(lpszText); // UINT align lpszText
dit.dwExStyle |= WS_EX_NOPARENTNOTIFY;
//
// Replace flat borders with 3D ones for DS_3DLOOK dialogs
// We test the WINDOW style, not the template style now. This is so
// that 4.0 apps--who get 3D stuff automatically--can turn it off on
// create if they want.
//
//
// HACK!
// Treat DS_3DLOOK combos like they have a WS_EX_CLIENTEDGE. Why
// should we have to draw the borders of a combobox ourselves?
// We can't do the same thing for WS_BORDER though becaues of
// PC Fools--they use the presence of WS_BORDER to distinguish
// between lists and combos.
//
if (TestWF(pwnd, DF3DLOOK))
{
if ((dit.style & WS_BORDER) ||
(lpszClass == MAKEINTRESOURCE(gpsi->atomSysClass[ICLS_COMBOBOX])))
{
dit.style &= ~WS_BORDER;
dit.dwExStyle |= WS_EX_CLIENTEDGE;
}
}
/*
* Get pointer to additional data. lpszText can point to an encoded
* ordinal number for some controls (e.g. static icon control) so
* we check for that here.
*/
if (*(LPWORD)lpszText == 0xFFFF) {
lpCreateParams = (LPWSTR)((PBYTE)lpszText + 4);
strWindowName.Buffer = lpszText;
strWindowName.Length = 4;
strWindowName.MaximumLength = 4;
strWindowName.bAnsi = FALSE;
} else {
lpCreateParams = (LPWSTR)((PBYTE)WordSkipSz(lpszText));
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strWindowName,
lpszText, (UINT)-1);
}
/*
* If control is edit control and caller wants global storage
* of edit text, allocate object in WOW and pass instance
* handle to CreateWindowEx().
*/
if (fWowWindow && (bFlags & CD_GLOBALEDIT) &&
((!HIWORD(lpszClass) &&
LOWORD(lpszClass) == (ATOM)(gpsi->atomSysClass[ICLS_EDIT])) ||
(HIWORD(lpszClass) &&
(wcscmp(lpszClass, szEDITCLASS) == 0)))) {
/*
* Allocate only one global object (first time we see editctl.)
*/
if (!(PDLG(pwnd)->hData)) {
PDLG(pwnd)->hData = GetEditDS();
if (!(PDLG(pwnd)->hData))
goto NoCreate;
}
hmodCreate = PDLG(pwnd)->hData;
dwExpWinVer = GETEXPWINVER(hmodCreate);
} else {
hmodCreate = hmod;
}
UserAssert((dit.dwExStyle & WS_EX_ANSICREATOR) == 0);
/*
* Get pointer to additional data.
*
* For WOW, instead of pointing lpCreateParams at the CreateParams
* data, set lpCreateParams to whatever DWORD is stored in the 32-bit
* DLGTEMPLATE's CreateParams. WOW has already made sure that that
* 32-bit value is indeed a 16:16 pointer to the CreateParams in the
* 16-bit DLGTEMPLATE.
*/
if (*lpCreateParams) {
lpCreateParamsData = (LPBYTE)lpCreateParams;
if (fWowWindow || fSCDLGFlags & SCDLG_16BIT) {
lpCreateParamsData =
(LPBYTE)*(UNALIGNED DWORD *)
(lpCreateParamsData + sizeof(WORD));
}
} else {
lpCreateParamsData = NULL;
}
/*
* If the dialog template specifies a menu ID then TestwndChild(pwnd)
* must be TRUE or CreateWindowEx will think the ID is an hMenu rather
* than an ID (in a dialog template you'll never have an hMenu).
* However for compatibility reasons we let it go if the ID = 0.
*/
if (dit.dwID) {
/*
* This makes TestwndChild(pwnd) on this window return TRUE.
*/
dit.style |= WS_CHILD;
dit.style &= ~WS_POPUP;
}
if (HIWORD(lpszClass)) {
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strClassName,
lpszClass, (UINT)-1);
pstrClassName = &strClassName;
} else {
pstrClassName = (PLARGE_STRING)lpszClass;
}
UserAssert((dit.dwExStyle & WS_EX_MDICHILD) == 0);
hwnd2 = NtUserCreateWindowEx(
dit.dwExStyle | ((fSCDLGFlags & SCDLG_ANSI) ? WS_EX_ANSICREATOR : 0),
pstrClassName,
&strWindowName,
dit.style,
dit.x,
dit.y,
dit.cx,
dit.cy,
hwnd,
(HMENU)dit.dwID,
hmodCreate,
lpCreateParamsData,
dwExpWinVer,
NULL);
if (hwnd2 == NULL) {
NoCreate:
/*
* Couldn't create the window -- return NULL.
*/
if (!TestWF(pwnd, DFNOFAILCREATE))
{
RIPMSG0(RIP_WARNING, "CreateDialog() failed: couldn't create control");
if (ThreadUnlock(&tlpwnd))
NtUserDestroyWindow(hwnd);
return NULL;
}
}
else
{
if (dit.dwHelpID)
NtUserSetWindowContextHelpId(hwnd2, dit.dwHelpID);
/*
* If it is a not a default system font, set the font for all the
* child windows of the dialogbox.
*/
if (hNewFont != NULL) {
SendMessage(hwnd2, WM_SETFONT, (DWORD)hNewFont, 0L);
}
/*
* Result gets ID of last (hopefully only) defpushbutton.
*/
if (SendMessage(hwnd2, WM_GETDLGCODE, 0, 0L) & DLGC_DEFPUSHBUTTON) {
PDLG(pwnd)->result = dit.dwID;
}
}
/*
* Point at next item template
*/
lpdit = (LPDLGITEMTEMPLATE)NextDWordBoundary(
(LPBYTE)(lpCreateParams + 1) + *lpCreateParams);
}
if (!TestWF(pwnd, DFCONTROL)) {
PWND pwndT = _GetNextDlgTabItem(pwnd, NULL, FALSE);
hwndEditFirst = HW(pwndT);
}
if (lpfnDialog != NULL) {
fSuccess = SendMessageWorker(pwnd, WM_INITDIALOG,
(DWORD)hwndEditFirst, lParam, FALSE);
//
// Make sure the window didn't get nuked during WM_INITDIALOG
//
if (!RevalidateHwnd(hwnd)) {
goto CreateDialogReturn;
}
if (fSuccess && !PDLG(pwnd)->fEnd) {
//
// To remove the two-default-push-buttons problem, we must make
// sure CheckDefPushButton() will remove default from other push
// buttons. This happens only if hwndEditFirst != hwndNewFocus;
// So, we make it NULL here. This breaks Designer's install
// program(which can't take a DM_GETDEFID. So, we do a version
// check here.
//
if (!TestWF(pwnd, DFCONTROL)) {
PWND pwndT;
if (!IsWindow(hwndEditFirst) || TestWF(pwnd, WFWIN40COMPAT))
hwndEditFirst = NULL;
//
// They could have disabled hwndEditFirst during WM_INITDIALOG.
// So, let use obtain the First Tab again.
//
pwndT = _GetNextDlgTabItem(pwnd, NULL, FALSE);
if (hwndNewFocus = HW(pwndT))
DlgSetFocus(hwndNewFocus);
xxxCheckDefPushButton(pwnd, hwndEditFirst, hwndNewFocus);
}
}
}
if (!IsWindow(hwnd))
{
// Omnis7 relies on a nonzero return even though they nuked this
// dialog during processing of the WM_INITDIALOG message
// -- jeffbog -- 2/24/95 -- Win95B B#12368
ThreadUnlock(&tlpwnd);
if (GetAppVer(NULL) < VER40)
return(hwnd);
else
return(NULL);
}
/*
* Bring this dialog into the foreground
* if DS_SETFOREGROUND is set.
*/
if (bFlags & CD_SETFOREGROUND) {
NtUserSetForegroundWindow(hwnd);
if (!IsWindow(hwnd))
{
hwnd = NULL;
goto CreateDialogReturn;
}
}
if ((bFlags & CD_VISIBLE) && !PDLG(pwnd)->fEnd && (!TestWF(pwnd, WFVISIBLE))) {
NtUserShowWindow(hwnd, SHOW_OPENWINDOW);
UpdateWindow(hwnd);
}
CreateDialogReturn:
ThreadUnlock(&tlpwnd);
/*
* 17609 Gupta's SQLWin deletes the window before CreateDialog returns
* but still expects non-zero return value from CreateDialog so we will
* do like win 3.1 and not revalidate for 16 bit apps
*/
if (!(fSCDLGFlags & SCDLG_NOREVALIDATE) && !RevalidateHwnd(hwnd)) {
hwnd = NULL;
}
return hwnd;
}