test: dlgbegin.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# dlgbegin.c

Go to the documentation of this file.

    00001 /***************************************************************************\
    00002 *
    00003 *  DLGBEGIN.C -
    00004 *
    00005 *      Dialog Initialization Routines
    00006 *
    00007 * ??-???-???? mikeke    Ported from Win 3.0 sources
    00008 * 12-Feb-1991 mikeke    Added Revalidation code
    00009 \***************************************************************************/
    00010
    00011 #include "precomp.h"
    00012 #pragma hdrstop
    00013
    00014 LPVOID __cdecl MakeAResizeDlg(int id,HANDLE h);
    00015
    00016 BOOL ValidateCallback(HANDLE h);
    00017
    00018 CONST WCHAR szEDITCLASS[] = TEXT("Edit");
    00019 #ifdef USE_MIRRORING
    00020 #define MIRRORED_HWND(hwnd)   (GetWindowLong(hwnd, GWL_EXSTYLE) & WS_EX_LAYOUTRTL)
    00021 #endif
    00022 /***************************************************************************\
    00023 * DefShortToInt
    00024 *
    00025 * Avoid sign extending 16 bit CW2_USEDEFAULT. We need this because the
    00026 *  dialog resource template uses SHORT fields to store the coordinates
    00027 *  but CreateWindow wants INT values.
    00028 *
    00029 * History:
    00030 * 12/04/96 GerardoB Created
    00031 \***************************************************************************/
    00032 __inline int DefShortToInt (short s)
    00033 {
    00034     if (s == (short)CW2_USEDEFAULT) {
    00035         return (int)(DWORD)(WORD)CW2_USEDEFAULT;
    00036     } else {
    00037         return (int)s;
    00038     }
    00039 }
    00040 /***************************************************************************\
    00041 * BYTE FAR *SkipSz(lpsz)
    00042 *
    00043 * History:
    00044 \***************************************************************************/
    00045
    00046 PBYTE SkipSz(
    00047     UTCHAR *lpsz)
    00048 {
    00049     if (*lpsz == 0xFF)
    00050         return (PBYTE)lpsz + 4;
    00051
    00052     while (*lpsz++ != 0) ;
    00053
    00054     return (PBYTE)lpsz;
    00055 }
    00056
    00057 PBYTE WordSkipSz(
    00058     UTCHAR *lpsz)
    00059 {
    00060     PBYTE pb = SkipSz(lpsz);
    00061     return NextWordBoundary(pb);
    00062 }
    00063
    00064 PBYTE DWordSkipSz(
    00065     UTCHAR *lpsz)
    00066 {
    00067     PBYTE pb = SkipSz(lpsz);
    00068     return NextDWordBoundary(pb);
    00069 }
    00070
    00071
    00072 /***************************************************************************\
    00073 *
    00074 * IsFontTooSmall()
    00075 *
    00076 * If this is a low res device, we need to check if the
    00077 * font we're creating is smaller than the system font.
    00078 *
    00079 \***************************************************************************/
    00080 __inline BOOLEAN IsFontTooSmall(LPWSTR szTempBuffer, LPCWSTR lpStrSubst, TEXTMETRIC* ptm)
    00081 {
    00082     //
    00083     // For FarEast version, we will allow the font smaller than system font.
    00084     //
    00085     return _wcsicmp(szTempBuffer, lpStrSubst) ||
    00086                 (!IS_ANY_DBCS_CHARSET(ptm->tmCharSet) &&
    00087                     (SYSMET(CXICON) < 32 || SYSMET(CYICON) < 32) &&
    00088                     ptm->tmHeight < gpsi->cySysFontChar);
    00089 }
    00090
    00091 // --------------------------------------------------------------------------
    00092 //  GetCharsetEnumProc()
    00093 //
    00094 //  This gets the best asian font for a dialog box.
    00095 //
    00096 //  1996-Sep-11 hideyukn     Port from Win95-FE
    00097 // --------------------------------------------------------------------------
    00098 int CALLBACK GetCharsetEnumProc(
    00099     LPLOGFONT     lpLogFont,
    00100     LPTEXTMETRIC  lptm,
    00101     DWORD         nType,
    00102     LPARAM        lpData)
    00103 {
    00104     UNREFERENCED_PARAMETER(lptm);
    00105     UNREFERENCED_PARAMETER(nType);
    00106
    00107     //
    00108     // Use other than FIXED pitch sysfont when the face name isn't specified.
    00109     //
    00110     if ((lpLogFont->lfPitchAndFamily & 3) == FIXED_PITCH)
    00111     {
    00112         if (!lstrcmpi(lpLogFont->lfFaceName,L"System") ||
    00113             !lstrcmpi(lpLogFont->lfFaceName,L"@System"))
    00114             return TRUE; // try to get another system font metric
    00115     }
    00116
    00117     ((LPLOGFONT)lpData)->lfCharSet = lpLogFont->lfCharSet;
    00118     ((LPLOGFONT)lpData)->lfPitchAndFamily = lpLogFont->lfPitchAndFamily;
    00119     return FALSE;
    00120 }
    00121
    00122 UINT GetACPCharSet()
    00123 {
    00124     CHARSETINFO csInfo;
    00125
    00126     if (!TranslateCharsetInfo((DWORD*)GetACP(), &csInfo, TCI_SRCCODEPAGE)) {
    00127         return DEFAULT_CHARSET;
    00128     }
    00129     return csInfo.ciCharset;
    00130 }
    00131
    00132
    00133 /***************************************************************************\
    00134 *
    00135 * CreateDlgFont()
    00136 *
    00137 * Create the dialog font described at the given location in a resource
    00138 *
    00139 \***************************************************************************/
    00140
    00141 HFONT CreateDlgFont(HDC hdcDlg, LPWORD FAR *lplpstr, LPDLGTEMPLATE2 lpdt, DWORD dwExpWinVer)
    00142 {
    00143     LOGFONT     LogFont;
    00144     int         fontheight, fheight;
    00145     HFONT       hOldFont, hFont;
    00146     WCHAR       szTempBuffer[20];
    00147     LPCWSTR     lpStrSubst;
    00148     TEXTMETRIC  tm;
    00149     BOOL        fDeleteFont = FALSE;
    00150     // FE
    00151     BOOL        bWillTryDefaultCharset = FALSE;
    00152
    00153     fheight = fontheight = (SHORT)(*((WORD *) *lplpstr)++);
    00154
    00155     if (fontheight == 0x7FFF) {
    00156         // a 0x7FFF height is our special code meaning use the message box font
    00157 //        return(gpsi->hMsgFont);
    00158         GetObject(gpsi->hMsgFont, sizeof(LOGFONT), &LogFont);
    00159         return(CreateFontIndirect(&LogFont));
    00160     }
    00161
    00162     //
    00163     // The dialog template contains a font description! Use it.
    00164     //
    00165     // Fill the LogFont with default values
    00166     RtlZeroMemory(&LogFont, sizeof(LOGFONT));
    00167
    00168     fontheight = -MultDiv(fontheight, gpsi->dmLogPixels, 72);
    00169     LogFont.lfHeight = fontheight;
    00170
    00171     if (lpdt->wDlgVer)
    00172     {
    00173         LogFont.lfWeight  = *((WORD FAR *) *lplpstr)++;
    00174         LogFont.lfItalic  = *((BYTE FAR *) *lplpstr)++;
    00175         LogFont.lfCharSet = *((BYTE FAR *) *lplpstr)++;
    00176         // FE_SB
    00177         if (IS_DBCS_ENABLED() && LogFont.lfCharSet == ANSI_CHARSET) {
    00178             //
    00179             // When resource compiler generates dialog resource data
    00180             // from DIALOGEX template, it can specify 'charset'. but
    00181             // optional, if it is not specified, it will be filled
    00182             // with 0 (ANSI charset). But, on localized version,
    00183             // User might guess the default will be localized-charset
    00184             //
    00185             // [Dialog Resource File]
    00186             //
    00187             // DIALOGEX ...
    00188             // ...
    00189             // FONT pointsize, typeface, [weight], [italic], [charset]
    00190             //
    00191             if (Is500Compat(dwExpWinVer)) {
    00192                 bWillTryDefaultCharset = TRUE;
    00193             } else {
    00194                 // #100182
    00195                 LogFont.lfCharSet = DEFAULT_CHARSET;
    00196                 RIPMSG0(RIP_WARNING, "No CharSet information in DIALOGEX");
    00197             }
    00198         }
    00199         // end FE_SB
    00200     }
    00201     else
    00202     {
    00203         LogFont.lfWeight  = FW_BOLD;
    00204         LogFont.lfCharSet = DEFAULT_CHARSET;
    00205     }
    00206
    00207
    00208     lpStrSubst = *lplpstr;
    00209
    00210     wcsncpycch(LogFont.lfFaceName, lpStrSubst, sizeof(LogFont.lfFaceName) / sizeof(WCHAR));
    00211
    00212     //
    00213     // "MS Shell Dlg" should have native character set ---
    00214     // Yes I hate this kind of hard code literals, but there's no way to get
    00215     // font link information.
    00216     // That's the reason why you see this hard coded **** here
    00217     //
    00218     if (IS_DBCS_ENABLED() && _wcsicmp(LogFont.lfFaceName, L"MS Shell Dlg") == 0) {
    00219         LogFont.lfCharSet = GetACPCharSet();
    00220     }
    00221
    00222     *lplpstr = (WORD *)DWordSkipSz(*lplpstr);
    00223
    00224     if (lpdt->style & DS_3DLOOK)
    00225         LogFont.lfWeight = FW_NORMAL;
    00226
    00227 TryDefaultCharset:
    00228     if (LogFont.lfCharSet == DEFAULT_CHARSET) {
    00229         if (IS_DBCS_ENABLED()) {
    00230             {
    00231                 //
    00232                 // Get character set for given facename.
    00233                 //
    00234                 EnumFonts(hdcDlg, LogFont.lfFaceName,
    00235                           (FONTENUMPROC)GetCharsetEnumProc, (LPARAM)(&LogFont));
    00236                 //
    00237                 // We already tried default charset.
    00238                 //
    00239                 bWillTryDefaultCharset = FALSE;
    00240             }
    00241
    00242             //
    00243             // [Windows 3.1 FarEast version did this...]
    00244             //
    00245             // Use FW_NORMAL as default for DIALOG template. For DIALOGEX
    00246             // template, we need to respect the value in the template.
    00247             //
    00248             if ((!(lpdt->wDlgVer)) && // not DIALOGEX template ?
    00249                 (IS_ANY_DBCS_CHARSET(LogFont.lfCharSet)) && // any FarEast font ?
    00250                 (LogFont.lfWeight != FW_NORMAL)) { // already FW_NORMAL ?
    00251
    00252                 //
    00253                 // Set weight to FW_NORMAL.
    00254                 //
    00255                 LogFont.lfWeight = FW_NORMAL;
    00256             }
    00257         } else {
    00258             LogFont.lfCharSet = GetTextCharset(hdcDlg); // Assume shell charset.
    00259         }
    00260     }
    00261
    00262     if (!(hFont = CreateFontIndirect((LPLOGFONT) &LogFont)))
    00263         return(NULL);
    00264
    00265     if (!(hOldFont = SelectFont(hdcDlg, hFont)))
    00266         goto deleteFont;
    00267
    00268     if (!GetTextMetrics(hdcDlg, &tm)) {
    00269         RIPMSG0(RIP_WARNING, "CreateDlgFont: GetTextMetrics failed");
    00270         goto deleteFont;
    00271     }
    00272
    00273
    00274     GetTextFace(hdcDlg, sizeof(szTempBuffer)/sizeof(WCHAR), szTempBuffer);
    00275
    00276     //
    00277     // If this is a low res device, we need to check if the
    00278     // font we're creating is smaller than the system font.
    00279     // If so, just use the system font.
    00280     //
    00281     if (IsFontTooSmall(szTempBuffer, lpStrSubst, &tm)) {
    00282         //
    00283         // Couldn't find a font with the height or facename
    00284         // the app wanted so use the system font instead. Note
    00285         // that we need to make sure the app knows it is
    00286         // getting the system font via the WM_SETFONT message
    00287         // so we still need to act as if a new font is being
    00288         // sent to the dialog box.
    00289         //
    00290 deleteFont:
    00291         fDeleteFont = TRUE;
    00292     }
    00293
    00294
    00295     if (hOldFont != NULL) {
    00296         SelectFont(hdcDlg, hOldFont);
    00297     }
    00298
    00299     if (fDeleteFont) {
    00300         DeleteFont(hFont);
    00301         // FE_SB
    00302         //
    00303         // Font is deleted, Prepare for reTry...
    00304         //
    00305         fDeleteFont = FALSE;
    00306         // end FE_SB
    00307         hFont = NULL;
    00308     }
    00309
    00310     // FE_SB
    00311     //
    00312     // 1. We fail to create font.
    00313     // 2. We did *NOT* try default charset, yet.
    00314     // 3. We want to try default charset.
    00315     //
    00316     // if all of answer is 'Yes', we will try...
    00317     //
    00318     if (IS_DBCS_ENABLED() && (hFont == NULL) && bWillTryDefaultCharset) {
    00319         //
    00320         // Try DEFAULT_CHARSET.
    00321         //
    00322         LogFont.lfCharSet = DEFAULT_CHARSET;
    00323         goto TryDefaultCharset;
    00324     }
    00325     // end FE_SB
    00326
    00327     return(hFont);
    00328 }
    00329
    00330 #define CD_VISIBLE          0x01
    00331 #define CD_GLOBALEDIT       0x02
    00332 #define CD_USERFONT         0x04
    00333 #define CD_SETFOREGROUND    0x08
    00334 #define CD_USEDEFAULTX      0x10
    00335 #define CD_USEDEFAULTCX     0x20
    00336
    00337
    00338 /***************************************************************************\
    00339 * GetDialogMonitor
    00340 *
    00341 * Gets the monitor a dialog should be created on.
    00342 *
    00343 * Params:
    00344 *     hwndOwner - the owner of the dialog. May be NULL.
    00345 *
    00346 * History:
    00347 * 10-Oct-1996 adams     Created.
    00348 \***************************************************************************/
    00349
    00350 PMONITOR
    00351 GetDialogMonitor(HWND hwndOwner, DWORD dwFlags)
    00352 {
    00353     PMONITOR    pMonitor;
    00354     PWND        pwnd;
    00355     HWND        hwndForeground;
    00356     DWORD       pid;
    00357
    00358     UserAssert(dwFlags == MONITOR_DEFAULTTONULL ||
    00359                dwFlags == MONITOR_DEFAULTTOPRIMARY);
    00360
    00361     pMonitor = NULL;
    00362     if (hwndOwner) {
    00363         pwnd = ValidateHwnd(hwndOwner);
    00364         if (    pwnd &&
    00365                 GETFNID(pwnd) != FNID_DESKTOP  &&
    00366                 GETFNID(REBASEPWND(pwnd, spwndParent)) == FNID_DESKTOP) {
    00367
    00368             pMonitor = _MonitorFromWindow(pwnd, MONITOR_DEFAULTTOPRIMARY);
    00369         }
    00370     } else {
    00371         /*
    00372          * HACK!  They passed in no owner and are creating a top level
    00373          * dialog window.  Does this process own the foreground window?
    00374          * If so, pin to that window's monitor.  That way 16-bit apps
    00375          * will work mostly as expected, and old multithreaded dudes just
    00376          * might too.  Especially the shell, for whom many system UI pieces
    00377          * pop up random dialogs inside of API calls.
    00378          */
    00379
    00380         hwndForeground = NtUserGetForegroundWindow();
    00381         if (hwndForeground) {
    00382             GetWindowThreadProcessId(hwndForeground, &pid);
    00383             if (pid == HandleToUlong(NtCurrentTeb()->ClientId.UniqueProcess)) {
    00384                 pwnd = ValidateHwnd(hwndForeground);
    00385                 if (pwnd) {
    00386                     pMonitor = _MonitorFromWindow(pwnd, MONITOR_DEFAULTTOPRIMARY);
    00387                 }
    00388             }
    00389         }
    00390     }
    00391
    00392     if (!pMonitor && dwFlags == MONITOR_DEFAULTTOPRIMARY) {
    00393         pMonitor = GetPrimaryMonitor();
    00394     }
    00395
    00396     return pMonitor;
    00397 }
    00398
    00399
    00400
    00401 /***************************************************************************\
    00402 * InternalCreateDialog
    00403 *
    00404 * Creates a dialog from a template. Uses passed in menu if there is one,
    00405 * destroys menu if creation failed. Server portion of
    00406 * CreateDialogIndirectParam.
    00407 *
    00408 * History:
    00409 * 04-10-91 ScottLu
    00410 * 04-17-91 Mikehar Win31 Merge
    00411 \***************************************************************************/
    00412
    00413 HWND InternalCreateDialog(
    00414     HANDLE hmod,
    00415     LPDLGTEMPLATE lpdt,
    00416     DWORD cb,
    00417     HWND hwndOwner,
    00418     DLGPROC lpfnDialog,
    00419     LPARAM lParam,
    00420     UINT fSCDLGFlags)
    00421 {
    00422     HWND                hwnd;
    00423     HWND                hwnd2;
    00424     PWND                pwnd;
    00425     HWND                hwndNewFocus;
    00426     HWND                hwndEditFirst = NULL;
    00427     RECT                rc;
    00428     WORD                w;
    00429     UTCHAR              *lpszMenu,
    00430                         *lpszClass,
    00431                         *lpszText,
    00432                         *lpCreateParams,
    00433                         *lpStr;
    00434     int                 cxChar,
    00435                         cyChar;
    00436     BOOL                f40Compat;
    00437     HFONT               hNewFont = NULL;
    00438     HFONT               hOldFont;
    00439     LPDLGITEMTEMPLATE   lpdit;
    00440     HMENU               hMenu;
    00441     BOOL                fSuccess;
    00442     BOOL                fWowWindow;
    00443     HANDLE              hmodCreate;
    00444     LPBYTE              lpCreateParamsData;
    00445     DLGTEMPLATE2        dt;
    00446     DLGITEMTEMPLATE2    dit;
    00447     DWORD               dwExpWinVer;
    00448     DWORD               dsStyleOld;
    00449     DWORD               bFlags = 0;
    00450     HDC                 hdcDlg;
    00451     LARGE_STRING        strClassName;
    00452     PLARGE_STRING       pstrClassName;
    00453     LARGE_STRING        strWindowName;
    00454     PMONITOR            pMonitor;
    00455         // FA
    00456         BOOL bResizeMe=FALSE;
    00457
    00458     UNREFERENCED_PARAMETER(cb);
    00459
    00460     ConnectIfNecessary();
    00461
    00462     UserAssert(!(fSCDLGFlags & ~(SCDLG_CLIENT|SCDLG_ANSI|SCDLG_NOREVALIDATE|SCDLG_16BIT)));    // These are the only valid flags
    00463
    00464     /*
    00465      * Is this a Win4 extended dialog?
    00466      */
    00467     if (((LPDLGTEMPLATE2)lpdt)->wSignature == 0xffff) {
    00468
    00469         UserAssert(((LPDLGTEMPLATE2)lpdt)->wDlgVer == 1);
    00470         RtlCopyMemory(&dt, lpdt, sizeof dt);
    00471     } else {
    00472         dt.wDlgVer = 0;
    00473         dt.wSignature = 0;
    00474         dt.dwHelpID = 0;
    00475         dt.dwExStyle = lpdt->dwExtendedStyle;
    00476         dt.style = lpdt->style;
    00477         dt.cDlgItems = lpdt->cdit;
    00478         dt.x = lpdt->x;
    00479         dt.y = lpdt->y;
    00480         dt.cx = lpdt->cx;
    00481         dt.cy = lpdt->cy;
    00482     }
    00483
    00484     /*
    00485      * If this is called from wow code, then the loword of hmod != 0.
    00486      * In this case, allow any DS_ style bits that were passed in win3.1
    00487      * to be legal in win32. Case in point: 16 bit quark xpress passes the
    00488      * same bit as the win32 style DS_SETFOREGROUND. Also, VC++ sample
    00489      * "scribble" does the same thing.
    00490      *
    00491      * For win32 apps test the DS_SETFOREGROUND bit; wow apps are not set
    00492      * foreground (this is the new NT semantics)
    00493      * We have to let no "valid" bits through because apps depend on them
    00494      * bug 5232.
    00495      */
    00496     dsStyleOld = LOWORD(dt.style);
    00497
    00498     /*
    00499      * If the app is Win4 or greater, require correct dialog style bits.
    00500      * Prevents conflicts with new bits introduced in Chicago
    00501      */
    00502     dwExpWinVer = GETEXPWINVER(hmod);
    00503
    00504     if ( f40Compat = Is400Compat(dwExpWinVer) ) {
    00505         dt.style &= (DS_VALID40 | 0xffff0000);
    00506
    00507         //
    00508         // For old applications:
    00509         //      If DS_COMMONDIALOG isn't set, don't touch DS_3DLOOK style
    00510         // bit.  If it's there, it stays there.  If not, not.  That way old
    00511         // apps which pass in their own templates, not commdlg's, don't get
    00512         // forced 3D.
    00513         //      If DS_COMMONDIALOG is there, remove DS_3DLOOK.
    00514         //
    00515         // For new applications:
    00516         //      Force 3D always.
    00517         //
    00518         if (GETAPPVER() < VER40) {
    00519             if (dt.style & DS_COMMONDIALOG) {
    00520                 dt.style &= ~DS_3DLOOK;
    00521                 dsStyleOld &= ~DS_3DLOOK;
    00522             }
    00523         } else {
    00524             dt.style |= DS_3DLOOK;
    00525             dsStyleOld |= DS_3DLOOK;
    00526         }
    00527     } else {
    00528 #if DBG
    00529         if (dt.style != (dt.style & (DS_VALID31 | DS_3DLOOK | 0xffff0000))) {
    00530             RIPMSG1(RIP_WARNING, "CreateDialog: stripping invalid bits %lX", dt.style);
    00531         }
    00532 #endif // DBG
    00533
    00534
    00535         /*
    00536          * Don't strip off bits for old apps, they depend on this.  Especially 16 bit MFC apps!
    00537          *
    00538          * dt.dwStyle &= (DS_VALID31 | 0xffff0000);
    00539          */
    00540     }
    00541
    00542     if (LOWORD((ULONG_PTR)hmod) == 0) {
    00543         if (dt.style & DS_SETFOREGROUND)
    00544             bFlags |= CD_SETFOREGROUND;
    00545     }
    00546
    00547     if (dsStyleOld != LOWORD(dt.style))
    00548     {
    00549
    00550         RIPMSG1(f40Compat ? RIP_ERROR : RIP_WARNING,
    00551                 "Bad dialog style bits (%x) - please remove.",
    00552                 LOWORD(dt.style));
    00553         // Fail new apps that pass in bogus bits!
    00554
    00555         if (f40Compat) {
    00556             return NULL;
    00557         }
    00558     }
    00559
    00560     if ( dt.style & DS_MODALFRAME) {
    00561         dt.dwExStyle |= WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE;
    00562     }
    00563
    00564     if (( dt.style & DS_CONTEXTHELP) && f40Compat) {
    00565         dt.dwExStyle |= WS_EX_CONTEXTHELP;
    00566     }
    00567
    00568     if (dt.style & DS_CONTROL) {
    00569         // Captions and system menus aren't allowed on "control" dialogs.
    00570         // And strip DS_SYSMODAL.
    00571         dt.style &= ~(WS_CAPTION | WS_SYSMENU | DS_SYSMODAL);
    00572     } else if (dt.style & WS_DLGFRAME) {
    00573         // Add on window edge same way that CreateWindowEx() will
    00574         dt.dwExStyle |= WS_EX_WINDOWEDGE;
    00575     }
    00576
    00577     if (dt.style & DS_SYSMODAL) {
    00578         dt.dwExStyle |= WS_EX_TOPMOST;
    00579     }
    00580
    00581     if (!(dt.style & WS_CHILD) || (dt.style & DS_CONTROL)) {
    00582         // only a control parent if it's not a child dialog or if it's
    00583         // explicitly marked as a recursive dialog
    00584         dt.dwExStyle |= WS_EX_CONTROLPARENT;
    00585     }
    00586
    00587     if (dt.x == (short)CW2_USEDEFAULT) {
    00588         bFlags |= CD_USEDEFAULTX;
    00589         dt.x = 0;
    00590     }
    00591
    00592     if (dt.cx == (short)CW2_USEDEFAULT) {
    00593         bFlags |= CD_USEDEFAULTCX;
    00594         dt.cx = 0;
    00595     } else if (dt.cx < 0) {
    00596         dt.cx = 0;
    00597     }
    00598
    00599     if (dt.cy < 0) {
    00600         dt.cy = 0;
    00601     }
    00602
    00603
    00604     // If there's a menu name string, load it.
    00605     lpszMenu = (LPWSTR)(((PBYTE)(lpdt)) + (dt.wDlgVer ? sizeof(DLGTEMPLATE2):sizeof(DLGTEMPLATE)));
    00606
    00607     /*
    00608      * If the menu id is expressed as an ordinal and not a string,
    00609      * skip all 4 bytes to get to the class string.
    00610      */
    00611     w = *(LPWORD)lpszMenu;
    00612
    00613     /*
    00614      * If there's a menu name string, load it.
    00615      */
    00616     if (w != 0) {
    00617         if ((hMenu = LoadMenu(hmod, (w == 0xFFFF) ?
    00618                 MAKEINTRESOURCE(*(WORD *)((PBYTE)lpszMenu + 2)) : lpszMenu)) == NULL) {
    00619             RIPMSG0(RIP_WARNING, "ServerCreateDialog() failed: couldn't load menu");
    00620             goto DeleteFontAndMenuAndFail;
    00621         }
    00622     } else {
    00623         hMenu = NULL;
    00624     }
    00625
    00626     if (w == 0xFFFF) {
    00627         lpszClass = (LPWSTR)((LPBYTE)lpszMenu + 4);
    00628     } else {
    00629         lpszClass = (UTCHAR *)WordSkipSz(lpszMenu);
    00630     }
    00631
    00632     lpszText = (UTCHAR *)WordSkipSz(lpszClass);
    00633
    00634     lpStr = (UTCHAR *)WordSkipSz(lpszText);
    00635
    00636     hdcDlg = CreateCompatibleDC(NULL);
    00637     if (hdcDlg == NULL)
    00638         goto DeleteFontAndMenuAndFail;
    00639
    00640     if (dt.style & DS_SETFONT) {
    00641         hNewFont = CreateDlgFont(hdcDlg, &lpStr, &dt, dwExpWinVer);
    00642         bFlags |= CD_USERFONT;
    00643         lpdit = (LPDLGITEMTEMPLATE) NextDWordBoundary(lpStr);
    00644     } else if (Is400Compat(dwExpWinVer) && (dt.style & DS_FIXEDSYS)) {
    00645
    00646         //
    00647         // B#2078 -- WISH for fixed width system font in dialog.  We need
    00648         // to tell the dialog that it's using a font different from the
    00649         // standard system font, so set CD_USERFONT bit.
    00650         //
    00651         // We need the 400 compat. check for CorelDraw, since they use
    00652         // this style bit for their own purposes.
    00653         //
    00654         hNewFont = GetStockObject(SYSTEM_FIXED_FONT);
    00655         bFlags |= CD_USERFONT;
    00656         lpdit = (LPDLGITEMTEMPLATE)NextDWordBoundary(lpStr);
    00657     } else {
    00658         lpdit = (LPDLGITEMTEMPLATE)NextDWordBoundary(lpStr);
    00659     }
    00660
    00661     /*
    00662      * If the application requested a particular font and for some
    00663      * reason we couldn't find it, we just use the system font.  BUT we
    00664      * need to make sure we tell him he gets the system font.  Dialogs
    00665      * which never request a particular font get the system font and we
    00666      * don't bother telling them this (via the WM_SETFONT message).
    00667      */
    00668
    00669     // Is it anything other than the default system font?  If we can't get
    00670     // enough memory to select in the new font specified, just use the system
    00671     // font.
    00672     if (hNewFont && (hOldFont = SelectFont(hdcDlg, hNewFont))) {
    00673         // Get the ave character width and height to be used
    00674         cxChar = GdiGetCharDimensions(hdcDlg, NULL, &cyChar);
    00675
    00676         SelectFont(hdcDlg, hOldFont);
    00677         if (cxChar == 0) {
    00678             RIPMSG0(RIP_WARNING, "InternalCreateDialog: GdiGetCharDimensions failed");
    00679             goto UseSysFontMetrics;
    00680         }
    00681     }
    00682     else
    00683     {
    00684         if (hNewFont || (bFlags & CD_USERFONT))
    00685             hNewFont = ghFontSys;
    00686
    00687 UseSysFontMetrics:
    00688         cxChar = gpsi->cxSysFontChar;
    00689         cyChar = gpsi->cySysFontChar;
    00690     }
    00691     DeleteDC(hdcDlg);
    00692
    00693     if (dt.style & WS_VISIBLE) {
    00694         bFlags |= CD_VISIBLE;
    00695         dt.style &= ~WS_VISIBLE;
    00696     }
    00697
    00698     if (!(dt.style & DS_LOCALEDIT)) {
    00699         bFlags |= CD_GLOBALEDIT;
    00700     }
    00701
    00702     /* Figure out dimensions of real window
    00703      */
    00704     rc.left = rc.top = 0;
    00705     rc.right = XPixFromXDU(dt.cx, cxChar);
    00706     rc.bottom = YPixFromYDU(dt.cy, cyChar);
    00707
    00708     _AdjustWindowRectEx(&rc, dt.style, w, dt.dwExStyle);
    00709
    00710     dt.cx = (SHORT)(rc.right - rc.left);
    00711     dt.cy = (SHORT)(rc.bottom - rc.top);
    00712
    00713     if ((dt.style & DS_CENTERMOUSE) && SYSMET(MOUSEPRESENT) && f40Compat) {
    00714         pMonitor = _MonitorFromPoint(gpsi->ptCursor, MONITOR_DEFAULTTONULL);
    00715         UserAssert(pMonitor);
    00716         *((LPPOINT)&rc.left) = gpsi->ptCursor;
    00717         rc.left -= (dt.cx / 2);
    00718         rc.top  -= (dt.cy / 2);
    00719     } else {
    00720         BOOL fNoDialogMonitor;
    00721
    00722         pMonitor = GetDialogMonitor(hwndOwner, MONITOR_DEFAULTTONULL);
    00723         fNoDialogMonitor = pMonitor ? FALSE : TRUE;
    00724         if (!pMonitor) {
    00725             pMonitor = GetPrimaryMonitor();
    00726         }
    00727
    00728         if ((dt.style & (DS_CENTER | DS_CENTERMOUSE)) && f40Compat) {
    00729             /*
    00730              * Center to the work area of the owner monitor.
    00731              */
    00732             rc.left = (pMonitor->rcWork.left + pMonitor->rcWork.right - dt.cx) / 2;
    00733             rc.top  = (pMonitor->rcWork.top + pMonitor->rcWork.bottom - dt.cy) / 2;
    00734         } else {
    00735             rc.left = XPixFromXDU(dt.x, cxChar);
    00736             rc.top = YPixFromYDU(dt.y, cyChar);
    00737
    00738             if (!(dt.style & DS_ABSALIGN) && hwndOwner) {
    00739                 /*
    00740                  * Offset relative coordinates to the owner window. If it is
    00741                  * a child window, there is nothing to do.
    00742                  */
    00743                 if ((HIWORD(dt.style) & MaskWF(WFTYPEMASK)) != MaskWF(WFCHILD)) {
    00744                     //This is will considre rc.left form the right hand side of the owner window if it a mirrored one.
    00745                     ClientToScreen(hwndOwner, (LPPOINT)&rc.left);
    00746
    00747 #ifdef USE_MIRRORING
    00748                     //It is not chiled then do Visual ClientToScreen
    00749                     //i.e. rc.left it is form the left hand side of the owner window
    00750                     if (MIRRORED_HWND(hwndOwner)) {
    00751                         rc.left -= dt.cx;
    00752                     }
    00753 #endif
    00754
    00755                 }
    00756             } else {
    00757                 /*
    00758                  * Position the dialog in screen coordinates. If the dialog's
    00759                  * owner is on a different monitor than specified in the
    00760                  * template, move the dialog to the owner window. If the owner
    00761                  * doesn't exist, then use the monitor from the dialog's
    00762                  * template.
    00763                  */
    00764
    00765                 PMONITOR    pMonitorTemplate;
    00766                 RECT        rcTemplate;
    00767
    00768                 rcTemplate.left  = rc.left;
    00769                 rcTemplate.top   = rc.top;
    00770                 rcTemplate.right  = rc.left + dt.cx;
    00771                 rcTemplate.bottom = rc.top + dt.cy;
    00772
    00773                 pMonitorTemplate = _MonitorFromRect(&rcTemplate, MONITOR_DEFAULTTOPRIMARY);
    00774                 if (fNoDialogMonitor) {
    00775                     pMonitor = pMonitorTemplate;
    00776                 } else if (pMonitorTemplate != pMonitor) {
    00777                     rc.left += pMonitor->rcMonitor.left - pMonitorTemplate->rcMonitor.left;
    00778                     rc.top  += pMonitor->rcMonitor.top  - pMonitorTemplate->rcMonitor.top;
    00779                 }
    00780             }
    00781         }
    00782     }
    00783
    00784     rc.right  = rc.left + dt.cx;
    00785     rc.bottom = rc.top  + dt.cy;
    00786
    00787     // If the right or bottom coordinate has overflowed, then pin it back to
    00788     // a valid rectangle.  Likely to happen if a minimized window is the owner of
    00789     // the dialog.
    00790     if (rc.left > rc.right || rc.top > rc.bottom) {
    00791         OffsetRect(&rc, -dt.cx, -dt.cy);
    00792     }
    00793
    00794    //
    00795     // Need to do this for ALL dialogs, not just top-level, since we used
    00796     // to in 3.1.
    00797     //
    00798
    00799     // Clip top level dialogs within working area
    00800     // Start child dialogs at least at (0, 0)
    00801     RepositionRect(pMonitor, &rc, dt.style, dt.dwExStyle);
    00802
    00803     dt.x  = (SHORT)((bFlags & CD_USEDEFAULTX) ? CW2_USEDEFAULT : rc.left);
    00804     dt.y  = (SHORT)(rc.top);
    00805     dt.cx = (SHORT)((bFlags & CD_USEDEFAULTCX) ? CW2_USEDEFAULT : rc.right - rc.left);
    00806     dt.cy = (SHORT)(rc.bottom - rc.top);
    00807
    00808     if (*lpszClass != 0) {
    00809         if (IS_PTR(lpszClass)) {
    00810             RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strClassName,
    00811                     lpszClass, (UINT)-1);
    00812             pstrClassName = &strClassName;
    00813         } else {
    00814             pstrClassName = (PLARGE_STRING)lpszClass;
    00815         }
    00816     } else {
    00817         pstrClassName = (PLARGE_STRING)DIALOGCLASS;
    00818     }
    00819
    00820     RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strWindowName,
    00821             lpszText, (UINT)-1);
    00822
    00823         //
    00824         // FA
    00825         // instantiate the resize dlg class if NOT WS_DLGFRAME and WS_THICKFRAME
    00826         // as those dialogs already support the resize code themselves.
    00827
    00828         bResizeMe=FALSE;
    00829         if(!( (dt.style & WS_DLGFRAME) && ( dt.style & WS_THICKFRAME) ))
    00830         {
    00831                 if ( (dt.style & WS_CHILD) == FALSE )
    00832                 {
    00833                         // PDLG(pwnd)->pDlgResize=MakeAResizeDlg(0,hmod);
    00834                         dt.style |= ( WS_DLGFRAME | WS_THICKFRAME );
    00835                         bResizeMe=TRUE;
    00836                 }
    00837         }
    00838
    00839     UserAssert((dt.dwExStyle & WS_EX_MDICHILD) == 0);
    00840     hwnd = NtUserCreateWindowEx(
    00841             dt.dwExStyle | ((fSCDLGFlags & SCDLG_ANSI) ? WS_EX_ANSICREATOR : 0),
    00842             pstrClassName,
    00843             &strWindowName,
    00844             dt.style,
    00845             DefShortToInt(dt.x),
    00846             dt.y,
    00847             DefShortToInt(dt.cx),
    00848             dt.cy,
    00849             hwndOwner,
    00850             hMenu,
    00851             hmod,
    00852             (LPVOID)NULL,
    00853             dwExpWinVer);
    00854
    00855     if (hwnd == NULL) {
    00856         RIPMSG0(RIP_WARNING, "CreateDialog() failed: couldn't create window");
    00857 DeleteFontAndMenuAndFail:
    00858         if (hMenu != NULL)
    00859             NtUserDestroyMenu(hMenu);
    00860         /*
    00861          * Only delete the font if we didn't grab it
    00862          * from the dialog font cache.
    00863          */
    00864         if ((hNewFont != NULL)) {
    00865             DeleteObject(hNewFont);
    00866         }
    00867         return NULL;
    00868     }
    00869
    00870     pwnd = ValidateHwnd(hwnd);
    00871
    00872     // tell WOW the hDlg of the Window just created BEFORE they get any messages
    00873     // at WOW32!w32win16wndprocex
    00874     if(fSCDLGFlags & SCDLG_16BIT) {
    00875         TellWOWThehDlg(hwnd);
    00876     }
    00877
    00878     /*
    00879      * Before anything happens with this window, we need to mark it as a
    00880      * dialog window!!!! So do that.
    00881      */
    00882     if (pwnd == NULL || !ValidateDialogPwnd(pwnd))
    00883         goto DeleteFontAndMenuAndFail;
    00884
    00885     if (dt.dwHelpID) {
    00886         NtUserSetWindowContextHelpId(hwnd, dt.dwHelpID);
    00887     }
    00888
    00889     /*
    00890      * Set up the system menu on this dialog box if it has one.
    00891      */
    00892     if (TestWF(pwnd, WFSYSMENU)) {
    00893
    00894         /*
    00895          * For a modal dialog box with a frame and caption, we want to
    00896          * delete the unselectable items from the system menu.
    00897          */
    00898         UserAssert(HIBYTE(WFSIZEBOX) == HIBYTE(WFMINBOX));
    00899         UserAssert(HIBYTE(WFMINBOX) == HIBYTE(WFMAXBOX));
    00900         if (!TestWF(pwnd, WFSIZEBOX | WFMINBOX | WFMAXBOX)) {
    00901
    00902             NtUserCallHwndLock(hwnd, SFI_XXXSETDIALOGSYSTEMMENU);
    00903         } else {
    00904
    00905             /*
    00906              * We have to give this dialog its own copy of the system menu
    00907              * in case it modifies the menu.
    00908              */
    00909             NtUserGetSystemMenu(hwnd, FALSE);
    00910         }
    00911     }
    00912
    00913     /*
    00914      * Set fDisabled to FALSE so EndDialog will Enable if dialog is ended
    00915      * before returning to DialogBox (or if modeless).
    00916      */
    00917     PDLG(pwnd)->fDisabled = FALSE;
    00918
    00919     PDLG(pwnd)->cxChar = cxChar;
    00920     PDLG(pwnd)->cyChar = cyChar;
    00921     PDLG(pwnd)->lpfnDlg = lpfnDialog;
    00922     PDLG(pwnd)->fEnd = FALSE;
    00923     PDLG(pwnd)->result = IDOK;
    00924         PDLG(pwnd)->pDlgResize = NULL;
    00925
    00926         //
    00927         // FA - instantiate the resize dlg class if WS_DLGFRAME and WS_THICKFRAME
    00928         //
    00929         if(bResizeMe)
    00930                 PDLG(pwnd)->pDlgResize=MakeAResizeDlg(0,hmod);
    00931
    00932     /*
    00933      * Need to remember Unicode status.
    00934      */
    00935     if (fSCDLGFlags & SCDLG_ANSI) {
    00936         PDLG(pwnd)->flags |= DLGF_ANSI;
    00937     }
    00938
    00939     /*
    00940      * Have to do a callback here for WOW apps.  WOW needs what's in lParam
    00941      * before the dialog gets any messages.
    00942      */
    00943
    00944     /*
    00945      * If the app is a Wow app then the Lo Word of the hInstance is the
    00946      * 16-bit hInstance.  Set the lParam, which no-one should look at
    00947      * but the app, to the 16 bit value
    00948      */
    00949     if (LOWORD((ULONG_PTR)hmod) != 0) {
    00950         fWowWindow = TRUE;
    00951     } else {
    00952         fWowWindow = FALSE;
    00953     }
    00954
    00955     /*
    00956      * If a user defined font is used, save the handle so that we can delete
    00957      * it when the dialog is destroyed.
    00958      */
    00959     if (bFlags & CD_USERFONT) {
    00960
    00961         PDLG(pwnd)->hUserFont = hNewFont;
    00962
    00963         if (lpfnDialog != NULL) {
    00964             /*
    00965              * Tell the dialog that it will be using this font...
    00966              */
    00967             SendMessageWorker(pwnd, WM_SETFONT, (WPARAM)hNewFont, 0L, FALSE);
    00968         }
    00969     }
    00970
    00971     if (!dt.wDlgVer) {
    00972         dit.dwHelpID = 0;
    00973     }
    00974
    00975     /*
    00976      * Loop through the dialog controls, doing a CreateWindowEx() for each of
    00977      * them.
    00978      */
    00979     while (dt.cDlgItems-- != 0) {
    00980         DWORD dwExpWinVer2;
    00981
    00982         if (dt.wDlgVer) {
    00983             RtlCopyMemory(&dit, lpdit, sizeof dit);
    00984         } else {
    00985             dit.dwHelpID = 0;
    00986             dit.dwExStyle = lpdit->dwExtendedStyle;
    00987             dit.style = lpdit->style;
    00988             dit.x = lpdit->x;
    00989             dit.y = lpdit->y;
    00990             dit.cx = lpdit->cx;
    00991             dit.cy = lpdit->cy;
    00992             dit.dwID = lpdit->id;
    00993         }
    00994
    00995         dit.x = XPixFromXDU(dit.x, cxChar);
    00996         dit.y = YPixFromYDU(dit.y, cyChar);
    00997         dit.cx = XPixFromXDU(dit.cx, cxChar);
    00998         dit.cy = YPixFromYDU(dit.cy, cyChar);
    00999
    01000         lpszClass = (LPWSTR)(((PBYTE)(lpdit)) + (dt.wDlgVer ? sizeof(DLGITEMTEMPLATE2):sizeof(DLGITEMTEMPLATE)));
    01001
    01002         /*
    01003          * If the first WORD is 0xFFFF the second word is the encoded class name index.
    01004          * Use it to look up the class name string.
    01005          */
    01006         if (*(LPWORD)lpszClass == 0xFFFF) {
    01007             lpszText = lpszClass + 2;
    01008             lpszClass = (LPWSTR)(gpsi->atomSysClass[*(((LPWORD)lpszClass)+1) & ~CODEBIT]);
    01009         } else {
    01010             lpszText = (UTCHAR *)SkipSz(lpszClass);
    01011         }
    01012         lpszText = (UTCHAR *)NextWordBoundary(lpszText); // UINT align lpszText
    01013
    01014         dit.dwExStyle |= WS_EX_NOPARENTNOTIFY;
    01015
    01016         //
    01017         // Replace flat borders with 3D ones for DS_3DLOOK dialogs
    01018         // We test the WINDOW style, not the template style now.  This is so
    01019         // that 4.0 apps--who get 3D stuff automatically--can turn it off on
    01020         // create if they want.
    01021         //
    01022
    01023         //
    01024         // HACK!
    01025         // Treat DS_3DLOOK combos like they have a WS_EX_CLIENTEDGE.  Why
    01026         // should we have to draw the borders of a combobox ourselves?
    01027         // We can't do the same thing for WS_BORDER though becaues of
    01028         // PC Fools--they use the presence of WS_BORDER to distinguish
    01029         // between lists and combos.
    01030         //
    01031
    01032         if (TestWF(pwnd, DF3DLOOK)) {
    01033             if (    (dit.style & WS_BORDER) ||
    01034                     (lpszClass == MAKEINTRESOURCE(gpsi->atomSysClass[ICLS_COMBOBOX]))) {
    01035
    01036                 dit.style &= ~WS_BORDER;
    01037                 dit.dwExStyle |= WS_EX_CLIENTEDGE;
    01038             }
    01039         }
    01040
    01041         /*
    01042          * Get pointer to additional data.  lpszText can point to an encoded
    01043          * ordinal number for some controls (e.g.  static icon control) so
    01044          * we check for that here.
    01045          */
    01046         if (*(LPWORD)lpszText == 0xFFFF) {
    01047             lpCreateParams = (LPWSTR)((PBYTE)lpszText + 4);
    01048             strWindowName.Buffer = lpszText;
    01049             strWindowName.Length = 4;
    01050             strWindowName.MaximumLength = 4;
    01051             strWindowName.bAnsi = FALSE;
    01052         } else {
    01053             lpCreateParams = (LPWSTR)((PBYTE)WordSkipSz(lpszText));
    01054             RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strWindowName,
    01055                     lpszText, (UINT)-1);
    01056         }
    01057
    01058         /*
    01059          * If control is edit control and caller wants global storage
    01060          * of edit text, allocate object in WOW and pass instance
    01061          * handle to CreateWindowEx().
    01062          */
    01063         if (fWowWindow && (bFlags & CD_GLOBALEDIT) &&
    01064                ((!IS_PTR(lpszClass) &&
    01065                     PTR_TO_ID(lpszClass) == (ATOM)(gpsi->atomSysClass[ICLS_EDIT])) ||
    01066                (IS_PTR(lpszClass) &&
    01067                     (wcscmp(lpszClass, szEDITCLASS) == 0)))) {
    01068
    01069             /*
    01070              * Allocate only one global object (first time we see editctl.)
    01071              */
    01072             if (!(PDLG(pwnd)->hData)) {
    01073                 PDLG(pwnd)->hData = GetEditDS();
    01074                 if (!(PDLG(pwnd)->hData))
    01075                     goto NoCreate;
    01076             }
    01077
    01078             hmodCreate = PDLG(pwnd)->hData;
    01079             dwExpWinVer2 = GETEXPWINVER(hmodCreate);
    01080         } else {
    01081             hmodCreate = hmod;
    01082             dwExpWinVer2 = dwExpWinVer;
    01083         }
    01084
    01085         UserAssert((dit.dwExStyle & WS_EX_ANSICREATOR) == 0);
    01086
    01087         /*
    01088          * Get pointer to additional data.
    01089          *
    01090          * For WOW, instead of pointing lpCreateParams at the CreateParams
    01091          * data, set lpCreateParams to whatever DWORD is stored in the 32-bit
    01092          * DLGTEMPLATE's CreateParams.  WOW has already made sure that that
    01093          * 32-bit value is indeed a 16:16 pointer to the CreateParams in the
    01094          * 16-bit DLGTEMPLATE.
    01095          */
    01096
    01097         if (*lpCreateParams) {
    01098             lpCreateParamsData = (LPBYTE)lpCreateParams;
    01099             if (fWowWindow || fSCDLGFlags & SCDLG_16BIT) {
    01100                 lpCreateParamsData =
    01101                     (LPBYTE)*(UNALIGNED DWORD *)
    01102                     (lpCreateParamsData + sizeof(WORD));
    01103             }
    01104         } else {
    01105             lpCreateParamsData = NULL;
    01106         }
    01107
    01108         /*
    01109          * If the dialog template specifies a menu ID then TestwndChild(pwnd)
    01110          * must be TRUE or CreateWindowEx will think the ID is an hMenu rather
    01111          * than an ID (in a dialog template you'll never have an hMenu).
    01112          * However for compatibility reasons we let it go if the ID = 0.
    01113          */
    01114         if (dit.dwID) {
    01115             /*
    01116              * This makes TestwndChild(pwnd) on this window return TRUE.
    01117              */
    01118             dit.style |= WS_CHILD;
    01119             dit.style &= ~WS_POPUP;
    01120         }
    01121
    01122         if (IS_PTR(lpszClass)) {
    01123             RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strClassName,
    01124                     lpszClass, (UINT)-1);
    01125             pstrClassName = &strClassName;
    01126         } else {
    01127             pstrClassName = (PLARGE_STRING)lpszClass;
    01128         }
    01129         UserAssert((dit.dwExStyle & WS_EX_MDICHILD) == 0);
    01130
    01131         hwnd2 = NtUserCreateWindowEx(
    01132                 dit.dwExStyle | ((fSCDLGFlags & SCDLG_ANSI) ? WS_EX_ANSICREATOR : 0),
    01133                 pstrClassName,
    01134                 &strWindowName,
    01135                 dit.style,
    01136                 DefShortToInt(dit.x),
    01137                 dit.y,
    01138                 DefShortToInt(dit.cx),
    01139                 dit.cy,
    01140                 hwnd,
    01141                 (HMENU)dit.dwID,
    01142                 hmodCreate,
    01143                 lpCreateParamsData,
    01144                 dwExpWinVer2);
    01145
    01146         if (hwnd2 == NULL) {
    01147 NoCreate:
    01148             /*
    01149              * Couldn't create the window -- return NULL.
    01150              */
    01151             if (!TestWF(pwnd, DFNOFAILCREATE)) {
    01152                 RIPMSG0(RIP_WARNING, "CreateDialog() failed: couldn't create control");
    01153                 NtUserDestroyWindow(hwnd);
    01154                 return NULL;
    01155             }
    01156         } else {
    01157
    01158             if (dit.dwHelpID) {
    01159                 NtUserSetWindowContextHelpId(hwnd2, dit.dwHelpID);
    01160             }
    01161
    01162         /*
    01163          * If it is a not a default system font, set the font for all the
    01164          * child windows of the dialogbox.
    01165          */
    01166             if (hNewFont != NULL) {
    01167                 SendMessage(hwnd2, WM_SETFONT, (WPARAM)hNewFont, 0L);
    01168             }
    01169
    01170         /*
    01171          * Result gets ID of last (hopefully only) defpushbutton.
    01172          */
    01173             if (SendMessage(hwnd2, WM_GETDLGCODE, 0, 0L) & DLGC_DEFPUSHBUTTON) {
    01174                 PDLG(pwnd)->result = dit.dwID;
    01175             }
    01176         }
    01177         /*
    01178          * Point at next item template
    01179          */
    01180         lpdit = (LPDLGITEMTEMPLATE)NextDWordBoundary(
    01181                 (LPBYTE)(lpCreateParams + 1) + *lpCreateParams);
    01182     }
    01183
    01184     if (!TestWF(pwnd, DFCONTROL)) {
    01185         PWND pwndT = _GetNextDlgTabItem(pwnd, NULL, FALSE);
    01186         hwndEditFirst = HW(pwndT);
    01187     }
    01188
    01189     if (lpfnDialog != NULL) {
    01190         fSuccess = SendMessageWorker(pwnd, WM_INITDIALOG,
    01191                                (WPARAM)hwndEditFirst, lParam, FALSE);
    01192
    01193         //
    01194         // Make sure the window didn't get nuked during WM_INITDIALOG
    01195         //
    01196         if (!RevalidateHwnd(hwnd)) {
    01197             goto CreateDialogReturn;
    01198         }
    01199
    01200         if (fSuccess && !PDLG(pwnd)->fEnd) {
    01201
    01202             //
    01203             // To remove the two-default-push-buttons problem, we must make
    01204             // sure CheckDefPushButton() will remove default from other push
    01205             // buttons.  This happens only if hwndEditFirst != hwndNewFocus;
    01206             // So, we make it NULL here. This breaks Designer's install
    01207             // program(which can't take a DM_GETDEFID.  So, we do a version
    01208             // check here.
    01209             //
    01210             if (!TestWF(pwnd, DFCONTROL)) {
    01211                 PWND pwndT;
    01212                 if (!IsWindow(hwndEditFirst) || TestWF(pwnd, WFWIN40COMPAT))
    01213                     hwndEditFirst = NULL;
    01214
    01215                 //
    01216                 // They could have disabled hwndEditFirst during WM_INITDIALOG.
    01217                 // So, let use obtain the First Tab again.
    01218                 //
    01219                 pwndT = _GetNextDlgTabItem(pwnd, NULL, FALSE);
    01220                 if (hwndNewFocus = HW(pwndT)) {
    01221                     DlgSetFocus(hwndNewFocus);
    01222                 }
    01223
    01224                 xxxCheckDefPushButton(pwnd, hwndEditFirst, hwndNewFocus);
    01225             }
    01226         }
    01227     }
    01228
    01229     if (!IsWindow(hwnd))
    01230     {
    01231         // Omnis7 relies on a nonzero return even though they nuked this
    01232         // dialog during processing of the WM_INITDIALOG message
    01233         // -- jeffbog -- 2/24/95 -- Win95B B#12368
    01234         if (GETAPPVER() < VER40) {
    01235             return(hwnd);
    01236         }
    01237
    01238         return(NULL);
    01239     }
    01240
    01241     /*
    01242      * Bring this dialog into the foreground
    01243      * if DS_SETFOREGROUND is set.
    01244      */
    01245     if (bFlags & CD_SETFOREGROUND) {
    01246         NtUserSetForegroundWindow(hwnd);
    01247         if (!IsWindow(hwnd)) {
    01248             hwnd = NULL;
    01249             goto CreateDialogReturn;
    01250         }
    01251     }
    01252
    01253     if ((bFlags & CD_VISIBLE) && !PDLG(pwnd)->fEnd && (!TestWF(pwnd, WFVISIBLE))) {
    01254         NtUserShowWindow(hwnd, SHOW_OPENWINDOW);
    01255         UpdateWindow(hwnd);
    01256     }
    01257
    01258 CreateDialogReturn:
    01259
    01260     /*
    01261      * 17609 Gupta's SQLWin deletes the window before CreateDialog returns
    01262      * but still expects non-zero return value from CreateDialog so we will
    01263      * do like win 3.1 and not revalidate for 16 bit apps
    01264      */
    01265     if (!(fSCDLGFlags & SCDLG_NOREVALIDATE) && !RevalidateHwnd(hwnd)) {
    01266         hwnd = NULL;
    01267     }
    01268
    01269     return hwnd;
    01270 }