原理可以看
/***********************************************************************
* DIALOG_CreateIndirect
* Creates a dialog box window
*
* modal = TRUE if we are called from a modal dialog box.
* (it's more compatible to do it here, as under Windows the owner
* is never disabled if the dialog fails because of an invalid template)
*/
static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
HWND owner, DLGPROC dlgProc, LPARAM param,
BOOL unicode, BOOL modal )
{
HWND hwnd;
RECT rect;
DLG_TEMPLATE template;
DIALOGINFO * dlgInfo = NULL;
DWORD units = GetDialogBaseUnits();
BOOL ownerEnabled = TRUE;
HMENU hMenu = 0;
HFONT hUserFont = 0;
UINT flags = 0;
UINT xBaseUnit = LOWORD(units);
UINT yBaseUnit = HIWORD(units);
/* Parse dialog template */
if (!dlgTemplate) return 0;
dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template );
/* Load menu */
if (template.menuName) hMenu = LoadMenuW( hInst, template.menuName );
/* Create custom font if needed */
if (template.style & DS_SETFONT)
{
/* We convert the size to pixels and then make it -ve. This works
* for both +ve and -ve template.pointSize */
HDC dc;
int pixels;
dc = GetDC(0);
pixels = MulDiv(template.pointSize, GetDeviceCaps(dc , LOGPIXELSY), 72);
hUserFont = CreateFontW( -pixels, 0, 0, 0, template.weight,
template.italic, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
PROOF_QUALITY, FF_DONTCARE,
template.faceName );
if (hUserFont)
{
SIZE charSize;
HFONT hOldFont = SelectObject( dc, hUserFont );
charSize.cx = GdiGetCharDimensions( dc, NULL, &charSize.cy );
if (charSize.cx)
{
xBaseUnit = charSize.cx;
yBaseUnit = charSize.cy;
}
SelectObject( dc, hOldFont );
}
ReleaseDC(0, dc);
TRACE("units = %d,%d\n", xBaseUnit, yBaseUnit );
}
if (HIWORD(class))
{
DWORD len = WideCharToMultiByte( CP_ACP, 0, template.className, -1, NULL, 0, NULL, NULL );
class = HeapAlloc( GetProcessHeap(), 0, len );
WideCharToMultiByte( CP_ACP, 0, template.className, -1, class, len, NULL, NULL );
}
if (HIWORD(caption))
{
DWORD len = WideCharToMultiByte( CP_ACP, 0, template.caption, -1, NULL, 0, NULL, NULL );
caption = HeapAlloc( GetProcessHeap(), 0, len );
WideCharToMultiByte( CP_ACP, 0, template.caption, -1, caption, len, NULL, NULL );
}
hwnd = User32CreateWindowEx(template.exStyle, class, caption,
template.style & ~WS_VISIBLE,
rect.left, rect.top, rect.right, rect.bottom,
owner, hMenu, hInst, NULL,
FALSE);
if (HIWORD(class)) HeapFree( GetProcessHeap(), 0, class );
if (HIWORD(caption)) HeapFree( GetProcessHeap(), 0, caption );
}
if (!hwnd)
{
if (hUserFont) DeleteObject( hUserFont );
if (hMenu) DestroyMenu( hMenu );
if (modal && (flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner);
return 0;
}
/* moved this from the top of the method to here as DIALOGINFO structure
will be valid only after WM_CREATE message has been handled in DefDlgProc
All the members of the structure get filled here using temp variables */
/***********************************************************************
* DIALOG_EnableOwner
*
* Helper function for modal dialogs to enable again the
* owner of the dialog box.
*/
void DIALOG_EnableOwner( HWND hOwner )
{
/* Owner must be a top-level window */
if (hOwner)
hOwner = GetAncestor( hOwner, GA_ROOT );
if (!hOwner) return;
EnableWindow( hOwner, TRUE );}