Allocate DIALOGINFO structure in DefDlgProc instead of in

DIALOG_CreateIndirect, so that it gets created correctly for non
template-based dialogs.
This commit is contained in:
Santosh Siddheshwar 2004-04-20 04:02:35 +00:00 committed by Alexandre Julliard
parent 01064d524d
commit 87109682ed
2 changed files with 97 additions and 48 deletions

View File

@ -131,10 +131,12 @@ static HWND DEFDLG_FindDefButton( HWND hwndDlg )
* *
* Set the new default button to be hwndNew. * Set the new default button to be hwndNew.
*/ */
static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo, static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo, WPARAM wParam )
HWND hwndNew )
{ {
DWORD dlgcode=0; /* initialize just to avoid a warning */ DWORD dlgcode=0; /* initialize just to avoid a warning */
HWND hwndNew = GetDlgItem(hwndDlg, wParam);
dlgInfo->idResult = wParam;
if (hwndNew && if (hwndNew &&
!((dlgcode=SendMessageW(hwndNew, WM_GETDLGCODE, 0, 0 )) !((dlgcode=SendMessageW(hwndNew, WM_GETDLGCODE, 0, 0 ))
& (DLGC_UNDEFPUSHBUTTON | DLGC_BUTTON))) & (DLGC_UNDEFPUSHBUTTON | DLGC_BUTTON)))
@ -143,16 +145,14 @@ static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
if (dlgInfo->idResult) /* There's already a default pushbutton */ if (dlgInfo->idResult) /* There's already a default pushbutton */
{ {
HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult ); HWND hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
if (SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON) if (hwndOld && (SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE ); SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
} }
if (hwndNew) if (hwndNew)
{ {
if(dlgcode==DLGC_UNDEFPUSHBUTTON) if(dlgcode==DLGC_UNDEFPUSHBUTTON)
SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE ); SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
dlgInfo->idResult = GetDlgCtrlID( hwndNew );
} }
else dlgInfo->idResult = 0;
return TRUE; return TRUE;
} }
@ -214,7 +214,7 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
case DM_SETDEFID: case DM_SETDEFID:
if (dlgInfo && !(dlgInfo->flags & DF_END)) if (dlgInfo && !(dlgInfo->flags & DF_END))
DEFDLG_SetDefButton( hwnd, dlgInfo, wParam ? GetDlgItem( hwnd, wParam ) : 0 ); DEFDLG_SetDefButton( hwnd, dlgInfo, wParam );
return 1; return 1;
case DM_GETDEFID: case DM_GETDEFID:
@ -235,7 +235,7 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
if (!lParam) if (!lParam)
hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam); hwndDest = GetNextDlgTabItem(hwnd, GetFocus(), wParam);
if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest ); if (hwndDest) DEFDLG_SetFocus( hwnd, hwndDest );
DEFDLG_SetDefButton( hwnd, dlgInfo, hwndDest ); DEFDLG_SetDefButton( hwnd, dlgInfo, GetDlgCtrlID(hwndDest) );
} }
return 0; return 0;
@ -283,16 +283,57 @@ static LRESULT DEFDLG_Epilog(HWND hwnd, UINT msg, BOOL fResult)
return GetWindowLongA( hwnd, DWL_MSGRESULT ); return GetWindowLongA( hwnd, DWL_MSGRESULT );
} }
/***********************************************************************
* DEFDLG_InitDlgInfo
*
* Allocate memory for DIALOGINFO structure and store in DWL_DIALOGINFO
* structure. Also flag the window as a dialog type.
*/
static DIALOGINFO* DEFDLG_InitDlgInfo(HWND hwnd)
{
WND* wndPtr;
DIALOGINFO* dlgInfo = DIALOG_get_info( hwnd );
if(!dlgInfo)
{
if (!(dlgInfo = HeapAlloc( GetProcessHeap(), 0, sizeof(*dlgInfo) ))) return NULL;
dlgInfo->hwndFocus = 0;
dlgInfo->hUserFont = 0;
dlgInfo->hMenu = 0;
dlgInfo->xBaseUnit = 0;
dlgInfo->yBaseUnit = 0;
dlgInfo->idResult = 0;
dlgInfo->flags = 0;
dlgInfo->hDialogHeap = 0;
wndPtr = WIN_GetPtr( hwnd );
if (wndPtr && wndPtr != WND_OTHER_PROCESS)
{
wndPtr->flags |= WIN_ISDIALOG;
WIN_ReleasePtr( wndPtr );
SetWindowLongW( hwnd, DWL_WINE_DIALOGINFO, (LONG)dlgInfo );
}
else
{
HeapFree( GetProcessHeap(), 0, dlgInfo );
return NULL;
}
}
return dlgInfo;
}
/*********************************************************************** /***********************************************************************
* DefDlgProc (USER.308) * DefDlgProc (USER.308)
*/ */
LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam, LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
LPARAM lParam ) LPARAM lParam )
{ {
DIALOGINFO *dlgInfo;
WNDPROC16 dlgproc; WNDPROC16 dlgproc;
HWND hwnd32 = WIN_Handle32( hwnd ); HWND hwnd32 = WIN_Handle32( hwnd );
BOOL result = FALSE; BOOL result = FALSE;
/* Perform DIALOGINFO intialization if not done */
if(!(dlgInfo = DEFDLG_InitDlgInfo(hwnd32))) return -1;
SetWindowLongW( hwnd32, DWL_MSGRESULT, 0 ); SetWindowLongW( hwnd32, DWL_MSGRESULT, 0 );
if ((dlgproc = (WNDPROC16)DEFDLG_GetDlgProc( hwnd32 ))) if ((dlgproc = (WNDPROC16)DEFDLG_GetDlgProc( hwnd32 )))
@ -323,7 +364,7 @@ LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
case WM_ENTERMENULOOP: case WM_ENTERMENULOOP:
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
case WM_NCLBUTTONDOWN: case WM_NCLBUTTONDOWN:
return DEFDLG_Proc( hwnd32, msg, (WPARAM)wParam, lParam, DIALOG_get_info(hwnd32) ); return DEFDLG_Proc( hwnd32, msg, (WPARAM)wParam, lParam, dlgInfo );
case WM_INITDIALOG: case WM_INITDIALOG:
case WM_VKEYTOITEM: case WM_VKEYTOITEM:
case WM_COMPAREITEM: case WM_COMPAREITEM:
@ -343,9 +384,13 @@ LRESULT WINAPI DefDlgProc16( HWND16 hwnd, UINT16 msg, WPARAM16 wParam,
*/ */
LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{ {
DIALOGINFO *dlgInfo;
WNDPROC dlgproc; WNDPROC dlgproc;
BOOL result = FALSE; BOOL result = FALSE;
/* Perform DIALOGINFO initialization if not done */
if(!(dlgInfo = DEFDLG_InitDlgInfo(hwnd))) return -1;
SetWindowLongW( hwnd, DWL_MSGRESULT, 0 ); SetWindowLongW( hwnd, DWL_MSGRESULT, 0 );
if ((dlgproc = DEFDLG_GetDlgProc( hwnd ))) if ((dlgproc = DEFDLG_GetDlgProc( hwnd )))
@ -376,7 +421,7 @@ LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
case WM_ENTERMENULOOP: case WM_ENTERMENULOOP:
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
case WM_NCLBUTTONDOWN: case WM_NCLBUTTONDOWN:
return DEFDLG_Proc( hwnd, msg, wParam, lParam, DIALOG_get_info(hwnd) ); return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
case WM_INITDIALOG: case WM_INITDIALOG:
case WM_VKEYTOITEM: case WM_VKEYTOITEM:
case WM_COMPAREITEM: case WM_COMPAREITEM:
@ -396,9 +441,13 @@ LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
*/ */
LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
{ {
DIALOGINFO *dlgInfo;
BOOL result = FALSE; BOOL result = FALSE;
WNDPROC dlgproc; WNDPROC dlgproc;
/* Perform DIALOGINFO intialization if not done */
if(!(dlgInfo = DEFDLG_InitDlgInfo(hwnd))) return -1;
SetWindowLongW( hwnd, DWL_MSGRESULT, 0 ); SetWindowLongW( hwnd, DWL_MSGRESULT, 0 );
if ((dlgproc = DEFDLG_GetDlgProc( hwnd ))) if ((dlgproc = DEFDLG_GetDlgProc( hwnd )))
@ -429,7 +478,7 @@ LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
case WM_ENTERMENULOOP: case WM_ENTERMENULOOP:
case WM_LBUTTONDOWN: case WM_LBUTTONDOWN:
case WM_NCLBUTTONDOWN: case WM_NCLBUTTONDOWN:
return DEFDLG_Proc( hwnd, msg, wParam, lParam, DIALOG_get_info(hwnd) ); return DEFDLG_Proc( hwnd, msg, wParam, lParam, dlgInfo );
case WM_INITDIALOG: case WM_INITDIALOG:
case WM_VKEYTOITEM: case WM_VKEYTOITEM:
case WM_COMPAREITEM: case WM_COMPAREITEM:

View File

@ -490,32 +490,24 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
{ {
HWND hwnd; HWND hwnd;
RECT rect; RECT rect;
WND * wndPtr;
DLG_TEMPLATE template; DLG_TEMPLATE template;
DIALOGINFO * dlgInfo; DIALOGINFO * dlgInfo = NULL;
DWORD units = GetDialogBaseUnits(); DWORD units = GetDialogBaseUnits();
BOOL ownerEnabled = TRUE; BOOL ownerEnabled = TRUE;
HMENU hMenu = 0;
HFONT hUserFont = 0;
UINT flags = 0;
UINT xBaseUnit = LOWORD(units);
UINT yBaseUnit = HIWORD(units);
/* Parse dialog template */ /* Parse dialog template */
if (!dlgTemplate) return 0; if (!dlgTemplate) return 0;
dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template ); dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template );
/* Initialise dialog extra data */
if (!(dlgInfo = HeapAlloc( GetProcessHeap(), 0, sizeof(*dlgInfo) ))) return 0;
dlgInfo->hwndFocus = 0;
dlgInfo->hUserFont = 0;
dlgInfo->hMenu = 0;
dlgInfo->xBaseUnit = LOWORD(units);
dlgInfo->yBaseUnit = HIWORD(units);
dlgInfo->idResult = 0;
dlgInfo->flags = 0;
dlgInfo->hDialogHeap = 0;
/* Load menu */ /* Load menu */
if (template.menuName) dlgInfo->hMenu = LoadMenuW( hInst, template.menuName ); if (template.menuName) hMenu = LoadMenuW( hInst, template.menuName );
/* Create custom font if needed */ /* Create custom font if needed */
@ -527,33 +519,33 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
int pixels; int pixels;
dc = GetDC(0); dc = GetDC(0);
pixels = MulDiv(template.pointSize, GetDeviceCaps(dc , LOGPIXELSY), 72); pixels = MulDiv(template.pointSize, GetDeviceCaps(dc , LOGPIXELSY), 72);
dlgInfo->hUserFont = CreateFontW( -pixels, 0, 0, 0, template.weight, hUserFont = CreateFontW( -pixels, 0, 0, 0, template.weight,
template.italic, FALSE, FALSE, DEFAULT_CHARSET, 0, 0, template.italic, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
PROOF_QUALITY, FF_DONTCARE, PROOF_QUALITY, FF_DONTCARE,
template.faceName ); template.faceName );
if (dlgInfo->hUserFont) if (hUserFont)
{ {
SIZE charSize; SIZE charSize;
if (DIALOG_GetCharSize( dc, dlgInfo->hUserFont, &charSize )) if (DIALOG_GetCharSize( dc, hUserFont, &charSize ))
{ {
dlgInfo->xBaseUnit = charSize.cx; xBaseUnit = charSize.cx;
dlgInfo->yBaseUnit = charSize.cy; yBaseUnit = charSize.cy;
} }
} }
ReleaseDC(0, dc); ReleaseDC(0, dc);
TRACE("units = %d,%d\n", dlgInfo->xBaseUnit, dlgInfo->yBaseUnit ); TRACE("units = %d,%d\n", xBaseUnit, yBaseUnit );
} }
/* Create dialog main window */ /* Create dialog main window */
rect.left = rect.top = 0; rect.left = rect.top = 0;
rect.right = MulDiv(template.cx, dlgInfo->xBaseUnit, 4); rect.right = MulDiv(template.cx, xBaseUnit, 4);
rect.bottom = MulDiv(template.cy, dlgInfo->yBaseUnit, 8); rect.bottom = MulDiv(template.cy, yBaseUnit, 8);
if (template.style & WS_CHILD) if (template.style & WS_CHILD)
template.style &= ~(WS_CAPTION|WS_SYSMENU); template.style &= ~(WS_CAPTION|WS_SYSMENU);
if (template.style & DS_MODALFRAME) if (template.style & DS_MODALFRAME)
template.exStyle |= WS_EX_DLGMODALFRAME; template.exStyle |= WS_EX_DLGMODALFRAME;
AdjustWindowRectEx( &rect, template.style, (dlgInfo->hMenu != 0), template.exStyle ); AdjustWindowRectEx( &rect, template.style, (hMenu != 0), template.exStyle );
rect.right -= rect.left; rect.right -= rect.left;
rect.bottom -= rect.top; rect.bottom -= rect.top;
@ -570,8 +562,8 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
} }
else else
{ {
rect.left += MulDiv(template.x, dlgInfo->xBaseUnit, 4); rect.left += MulDiv(template.x, xBaseUnit, 4);
rect.top += MulDiv(template.y, dlgInfo->yBaseUnit, 8); rect.top += MulDiv(template.y, yBaseUnit, 8);
} }
if ( !(template.style & WS_CHILD) ) if ( !(template.style & WS_CHILD) )
{ {
@ -594,7 +586,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
if (modal) if (modal)
{ {
ownerEnabled = DIALOG_DisableOwner( owner ); ownerEnabled = DIALOG_DisableOwner( owner );
if (ownerEnabled) dlgInfo->flags |= DF_OWNERENABLED; if (ownerEnabled) flags |= DF_OWNERENABLED;
} }
if (unicode) if (unicode)
@ -602,7 +594,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
hwnd = CreateWindowExW(template.exStyle, template.className, template.caption, hwnd = CreateWindowExW(template.exStyle, template.className, template.caption,
template.style & ~WS_VISIBLE, template.style & ~WS_VISIBLE,
rect.left, rect.top, rect.right, rect.bottom, rect.left, rect.top, rect.right, rect.bottom,
owner, dlgInfo->hMenu, hInst, NULL ); owner, hMenu, hInst, NULL );
} }
else else
{ {
@ -624,25 +616,33 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
hwnd = CreateWindowExA(template.exStyle, class, caption, hwnd = CreateWindowExA(template.exStyle, class, caption,
template.style & ~WS_VISIBLE, template.style & ~WS_VISIBLE,
rect.left, rect.top, rect.right, rect.bottom, rect.left, rect.top, rect.right, rect.bottom,
owner, dlgInfo->hMenu, hInst, NULL ); owner, hMenu, hInst, NULL );
if (HIWORD(class)) HeapFree( GetProcessHeap(), 0, class ); if (HIWORD(class)) HeapFree( GetProcessHeap(), 0, class );
if (HIWORD(caption)) HeapFree( GetProcessHeap(), 0, caption ); if (HIWORD(caption)) HeapFree( GetProcessHeap(), 0, caption );
} }
if (!hwnd) if (!hwnd)
{ {
if (dlgInfo->hUserFont) DeleteObject( dlgInfo->hUserFont ); if (hUserFont) DeleteObject( hUserFont );
if (dlgInfo->hMenu) DestroyMenu( dlgInfo->hMenu ); if (hMenu) DestroyMenu( hMenu );
if (modal && (dlgInfo->flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner); if (modal && (flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner);
HeapFree( GetProcessHeap(), 0, dlgInfo );
return 0; return 0;
} }
wndPtr = WIN_GetPtr( hwnd );
wndPtr->flags |= WIN_ISDIALOG; /* moved this from the top of the method to here as DIALOGINFO structure
WIN_ReleasePtr( wndPtr ); 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 */
dlgInfo = DIALOG_get_info(hwnd);
dlgInfo->hwndFocus = 0;
dlgInfo->hUserFont = hUserFont;
dlgInfo->hMenu = hMenu;
dlgInfo->xBaseUnit = xBaseUnit;
dlgInfo->yBaseUnit = yBaseUnit;
dlgInfo->idResult = 0;
dlgInfo->flags = flags;
dlgInfo->hDialogHeap = 0;
if (template.helpId) SetWindowContextHelpId( hwnd, template.helpId ); if (template.helpId) SetWindowContextHelpId( hwnd, template.helpId );
SetWindowLongW( hwnd, DWL_WINE_DIALOGINFO, (LONG)dlgInfo );
if (unicode) SetWindowLongW( hwnd, DWL_DLGPROC, (LONG)dlgProc ); if (unicode) SetWindowLongW( hwnd, DWL_DLGPROC, (LONG)dlgProc );
else SetWindowLongA( hwnd, DWL_DLGPROC, (LONG)dlgProc ); else SetWindowLongA( hwnd, DWL_DLGPROC, (LONG)dlgProc );