- Dialog.c Partial sync to wine. 
  - Add WinPosActivateOtherWindow to winpos.c, activate another window when the dialog gets hidden in EndDialog.
  - Misc fixes and changes.

svn path=/trunk/; revision=23409
This commit is contained in:
James Tabor 2006-08-01 21:14:45 +00:00
parent 963218942e
commit 1d2d013384
4 changed files with 276 additions and 259 deletions

View file

@ -40,8 +40,6 @@ DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
return 0; /* all other messages are ignored */
}
VOID
STDCALL
LogFontW2A(LPLOGFONTA pA, CONST LOGFONTW *pW)

View file

@ -85,7 +85,7 @@ CreateCursor@28
CreateDesktopA@24
CreateDesktopW@24
CreateDialogIndirectParamA@20
CreateDialogIndirectParamAorW@20
CreateDialogIndirectParamAorW@24
CreateDialogIndirectParamW@20
CreateDialogParamA@20
CreateDialogParamW@20
@ -158,7 +158,7 @@ DestroyMenu@4
DestroyWindow@4
;DeviceEventWorker
DialogBoxIndirectParamA@20
DialogBoxIndirectParamAorW@20
DialogBoxIndirectParamAorW@24
DialogBoxIndirectParamW@20
DialogBoxParamA@20
DialogBoxParamW@20

View file

@ -40,9 +40,9 @@
#define DF_END 0x0001
#define DF_OWNERENABLED 0x0002
#define CW_USEDEFAULT16 ((short)0x8000)
#define DWL_INIT (12)
#define GETDLGINFO(hwnd) (DIALOGINFO*)GetWindowLongW((hwnd), DWL_INIT)
#define SETDLGINFO(hwnd, info) SetWindowLongW((hwnd), DWL_INIT, (LONG)(info))
#define DWLP_ROS_DIALOGINFO (DWLP_USER+sizeof(ULONG_PTR))
#define GETDLGINFO(hwnd) (DIALOGINFO*)GetWindowLongPtrW((hwnd),DWLP_ROS_DIALOGINFO)
#define SETDLGINFO(hwnd, info) SetWindowLongPtrW((hwnd), DWLP_ROS_DIALOGINFO, (LONG_PTR)(info))
#define GET_WORD(ptr) (*(WORD *)(ptr))
#define GET_DWORD(ptr) (*(DWORD *)(ptr))
#define MAKEINTATOMA(atom) ((LPCSTR)((ULONG_PTR)((WORD)(atom))))
@ -50,6 +50,8 @@
#define DIALOG_CLASS_ATOMA MAKEINTATOMA(32770) /* Dialog */
#define DIALOG_CLASS_ATOMW MAKEINTATOMW(32770) /* Dialog */
void STDCALL WinPosActivateOtherWindow(HWND hwnd);
/* INTERNAL STRUCTS **********************************************************/
/* Dialog info structure */
@ -123,48 +125,18 @@ typedef struct
*/
const struct builtin_class_descr DIALOG_builtin_class =
{
DIALOG_CLASS_ATOMW, /* name */
DIALOG_CLASS_ATOMW, /* name */
CS_SAVEBITS | CS_DBLCLKS, /* style */
(WNDPROC) DefDlgProcW, /* procW */
(WNDPROC) DefDlgProcA, /* procA */
DWL_INIT + sizeof(LONG), /* extra */
(LPCWSTR) IDC_ARROW, /* cursor */
0 /* brush */
(WNDPROC) DefDlgProcW, /* procW */
(WNDPROC) DefDlgProcA, /* procA */
DLGWINDOWEXTRA, /* extra */
(LPCWSTR) IDC_ARROW, /* cursor */
0 /* brush */
};
/* INTERNAL FUNCTIONS ********************************************************/
/***********************************************************************
* DIALOG_GetCharSize
*
* Despite most of MSDN insisting that the horizontal base unit is
* tmAveCharWidth it isn't. Knowledge base article Q145994
* "HOWTO: Calculate Dialog Units When Not Using the System Font",
* says that we should take the average of the 52 English upper and lower
* case characters.
*/
BOOL DIALOG_GetCharSize( HDC hDC, HFONT hFont, SIZE * pSize )
{
HFONT hFontPrev = 0;
char *alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
SIZE sz;
TEXTMETRICA tm;
if(!hDC) return FALSE;
if(hFont) hFontPrev = SelectObject(hDC, hFont);
if(!GetTextMetricsA(hDC, &tm)) return FALSE;
if(!GetTextExtentPointA(hDC, alphabet, 52, &sz)) return FALSE;
pSize->cy = tm.tmHeight;
pSize->cx = (sz.cx / 26 + 1) / 2;
if (hFontPrev) SelectObject(hDC, hFontPrev);
return TRUE;
}
/***********************************************************************
* DIALOG_EnableOwner
*
@ -372,16 +344,16 @@ static BOOL DIALOG_CreateControls32( HWND hwnd, LPCSTR template, const DLG_TEMPL
}
/* Send initialisation messages to the control */
if (dlgInfo->hUserFont) SendMessageA( hwndCtrl, WM_SETFONT,
if (dlgInfo->hUserFont) SendMessageW( hwndCtrl, WM_SETFONT,
(WPARAM)dlgInfo->hUserFont, 0 );
if (SendMessageA(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
if (SendMessageW(hwndCtrl, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
{
/* If there's already a default push-button, set it back */
/* to normal and use this one instead. */
if (hwndDefButton)
SendMessageA( hwndDefButton, BM_SETSTYLE, BS_PUSHBUTTON, FALSE );
SendMessageW( hwndDefButton, BM_SETSTYLE, BS_PUSHBUTTON, FALSE );
hwndDefButton = hwndCtrl;
dlgInfo->idResult = GetWindowLongA( hwndCtrl, GWL_ID );
dlgInfo->idResult = GetWindowLongPtrA( hwndCtrl, GWLP_ID );
}
}
return TRUE;
@ -453,14 +425,14 @@ static BOOL DIALOG_IsAccelerator( HWND hwnd, HWND hwndDlg, WPARAM wParam )
if ((dlgCode & DLGC_STATIC) || (style & 0x0f) == BS_GROUPBOX )
{
/* set focus to the control */
SendMessageA( hwndDlg, WM_NEXTDLGCTL, (WPARAM)hwndControl, 1);
SendMessageW( hwndDlg, WM_NEXTDLGCTL, (WPARAM)hwndControl, 1);
/* and bump it on to next */
SendMessageA( hwndDlg, WM_NEXTDLGCTL, 0, 0);
SendMessageW( hwndDlg, WM_NEXTDLGCTL, 0, 0);
}
else if (dlgCode & DLGC_BUTTON)
{
/* send BM_CLICK message to the control */
SendMessageA( hwndControl, BM_CLICK, 0, 0 );
SendMessageW( hwndControl, BM_CLICK, 0, 0 );
}
return TRUE;
}
@ -551,9 +523,13 @@ INT DIALOG_DoDialogBox( HWND hwnd, HWND owner )
static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
{
const WORD *p = (const WORD *)template;
WORD signature;
WORD dlgver;
result->style = GET_DWORD(p); p += 2;
if (result->style == 0xffff0001) /* DIALOGEX resource */
signature = GET_WORD(p); p++;
dlgver = GET_WORD(p); p++;
if (signature == 1 && dlgver == 0xffff) /* DIALOGEX resource */
{
result->dialogEx = TRUE;
result->helpId = GET_DWORD(p); p += 2;
@ -562,6 +538,7 @@ static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
}
else
{
result->style = GET_DWORD(p - 2);
result->dialogEx = FALSE;
result->helpId = 0;
result->exStyle = GET_DWORD(p); p += 2;
@ -615,6 +592,11 @@ static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
/* Get the font name */
result->pointSize = 0;
result->weight = FW_DONTCARE;
result->italic = FALSE;
result->faceName = NULL;
if (result->style & DS_SETFONT)
{
result->pointSize = GET_WORD(p);
@ -624,21 +606,9 @@ static LPCSTR DIALOG_ParseTemplate32( LPCSTR template, DLG_TEMPLATE * result )
result->weight = GET_WORD(p); p++;
result->italic = LOBYTE(GET_WORD(p)); p++;
}
else
{
result->weight = FW_DONTCARE;
result->italic = FALSE;
}
result->faceName = (LPCWSTR)p;
p += wcslen( result->faceName ) + 1;
}
else
{
result->pointSize = 0;
result->weight = FW_DONTCARE;
result->italic = FALSE;
result->faceName = NULL;
}
/* First control is on dword boundary */
return (LPCSTR)((((int)p) + 3) & ~3);
@ -659,72 +629,66 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
HWND hwnd;
RECT rect;
DLG_TEMPLATE template;
DIALOGINFO * dlgInfo;
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 */
/* Parse dialog template */
if (!dlgTemplate) return 0;
dlgTemplate = DIALOG_ParseTemplate32( dlgTemplate, &template );
/* Initialise dialog extra data */
/* Load menu */
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;
if (template.menuName) hMenu = LoadMenuW( hInst, template.menuName );
/* Load menu */
if (template.menuName) dlgInfo->hMenu = LoadMenuW( hInst, template.menuName );
/* Create custom font if needed */
/* 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 */
/* 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);
dlgInfo->hUserFont = CreateFontW( -pixels, 0, 0, 0, template.weight,
template.italic, FALSE, FALSE, DEFAULT_CHARSET, 0, 0,
PROOF_QUALITY, FF_DONTCARE,
template.faceName );
if (dlgInfo->hUserFont)
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, dlgInfo->hUserFont );
HFONT hOldFont = SelectObject( dc, hUserFont );
charSize.cx = GdiGetCharDimensions( dc, NULL, &charSize.cy );
if (charSize.cx)
{
dlgInfo->xBaseUnit = charSize.cx;
dlgInfo->yBaseUnit = charSize.cy;
xBaseUnit = charSize.cx;
yBaseUnit = charSize.cy;
}
SelectObject( dc, hOldFont );
}
ReleaseDC(0, dc);
TRACE("units = %d,%d\n", xBaseUnit, yBaseUnit );
}
/* Create dialog main window */
rect.left = rect.top = 0;
rect.right = MulDiv(template.cx, dlgInfo->xBaseUnit, 4);
rect.bottom = MulDiv(template.cy, dlgInfo->yBaseUnit, 8);
rect.right = MulDiv(template.cx, xBaseUnit, 4);
rect.bottom = MulDiv(template.cy, yBaseUnit, 8);
if (template.style & WS_CHILD)
template.style &= ~(WS_CAPTION|WS_SYSMENU);
if (template.style & DS_MODALFRAME)
template.exStyle |= WS_EX_DLGMODALFRAME;
if (template.style & DS_CONTROL)
template.exStyle |= WS_EX_CONTROLPARENT;
AdjustWindowRectEx( &rect, template.style, (dlgInfo->hMenu != 0), template.exStyle );
AdjustWindowRectEx( &rect, template.style, (hMenu != 0), template.exStyle );
rect.right -= rect.left;
rect.bottom -= rect.top;
@ -741,8 +705,8 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
}
else
{
rect.left += MulDiv(template.x, dlgInfo->xBaseUnit, 4);
rect.top += MulDiv(template.y, dlgInfo->yBaseUnit, 8);
rect.left += MulDiv(template.x, xBaseUnit, 4);
rect.top += MulDiv(template.y, yBaseUnit, 8);
}
if ( !(template.style & WS_CHILD) )
{
@ -754,9 +718,9 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
/* try to fit it into the desktop */
if( (dX = rect.left + rect.right + GetSystemMetrics(SM_CXDLGFRAME)
- GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX;
- GetSystemMetrics(SM_CXSCREEN)) > 0 ) rect.left -= dX;
if( (dY = rect.top + rect.bottom + GetSystemMetrics(SM_CYDLGFRAME)
- GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY;
- GetSystemMetrics(SM_CYSCREEN)) > 0 ) rect.top -= dY;
if( rect.left < 0 ) rect.left = 0;
if( rect.top < 0 ) rect.top = 0;
}
@ -765,7 +729,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
if (modal)
{
ownerEnabled = DIALOG_DisableOwner( owner );
if (ownerEnabled) dlgInfo->flags |= DF_OWNERENABLED;
if (ownerEnabled) flags |= DF_OWNERENABLED;
}
if (unicode)
@ -773,7 +737,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
hwnd = CreateWindowExW(template.exStyle, template.className, template.caption,
template.style & ~WS_VISIBLE,
rect.left, rect.top, rect.right, rect.bottom,
owner, dlgInfo->hMenu, hInst, NULL );
owner, hMenu, hInst, NULL );
}
else
{
@ -795,36 +759,44 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
hwnd = CreateWindowExA(template.exStyle, class, caption,
template.style & ~WS_VISIBLE,
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(caption)) HeapFree( GetProcessHeap(), 0, caption );
}
if (!hwnd)
{
if (dlgInfo->hUserFont) DeleteObject( dlgInfo->hUserFont );
if (dlgInfo->hMenu) DestroyMenu( dlgInfo->hMenu );
if (modal && (dlgInfo->flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner);
HeapFree( GetProcessHeap(), 0, dlgInfo );
if (hUserFont) DeleteObject( hUserFont );
if (hMenu) DestroyMenu( hMenu );
if (modal && (flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner);
return 0;
}
if (template.helpId)
SetWindowContextHelpId( hwnd, template.helpId );
/* 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 */
if (unicode)
{
SETDLGINFO(hwnd, dlgInfo); /* maybe SetPropW? */
SetWindowLongW( hwnd, DWL_DLGPROC, (LONG)dlgProc );
}
else
{
SETDLGINFO(hwnd, dlgInfo);
SetWindowLongA( hwnd, DWL_DLGPROC, (LONG)dlgProc );
}
// dlgInfo = DIALOG_get_info( hwnd, TRUE );
if (!(dlgInfo = HeapAlloc( GetProcessHeap(), 0, sizeof(*dlgInfo) ))) return 0;
SETDLGINFO(hwnd, dlgInfo);
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 (unicode) SetWindowLongPtrW( hwnd, DWLP_DLGPROC, (ULONG_PTR)dlgProc );
else SetWindowLongPtrA( hwnd, DWLP_DLGPROC, (ULONG_PTR)dlgProc );
if (dlgInfo->hUserFont)
SendMessageA( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
SendMessageW( hwnd, WM_SETFONT, (WPARAM)dlgInfo->hUserFont, 0 );
/* Create controls */
@ -847,7 +819,6 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
}
return hwnd;
}
if (modal && ownerEnabled) DIALOG_EnableOwner(owner);
if( IsWindow(hwnd) ) DestroyWindow( hwnd );
return 0;
@ -882,7 +853,7 @@ static void DEFDLG_SaveFocus( HWND hwnd )
HWND hwndFocus = GetFocus();
if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return;
if (!(infoPtr = GETDLGINFO(hwnd))) return;
if (!(infoPtr = GETDLGINFO(hwnd))) return;
infoPtr->hwndFocus = hwndFocus;
/* Remove default button */
}
@ -904,7 +875,7 @@ static void DEFDLG_RestoreFocus( HWND hwnd )
infoPtr->hwndFocus = GetNextDlgTabItem( hwnd, 0, FALSE );
if (!IsWindow( infoPtr->hwndFocus )) return;
}
DEFDLG_SetFocus( hwnd, infoPtr->hwndFocus );
SetFocus( infoPtr->hwndFocus );
/* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
sometimes losing focus when receiving WM_SETFOCUS messages. */
@ -957,15 +928,15 @@ static BOOL DEFDLG_SetDefId( HWND hwndDlg, DIALOGINFO *dlgInfo, WPARAM wParam)
/* Make sure the old default control is a valid push button ID */
hwndOld = GetDlgItem( hwndDlg, old_id );
if (!hwndOld || !(SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
if (!hwndOld || !(SendMessageW( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
hwndOld = DEFDLG_FindDefButton( hwndDlg );
if (hwndOld && hwndOld != hwndNew)
SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
SendMessageW( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
if (hwndNew)
{
if(dlgcode & DLGC_UNDEFPUSHBUTTON)
SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
SendMessageW( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
}
return TRUE;
}
@ -994,15 +965,15 @@ static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo, HWND hwndNew
}
/* Make sure the old default control is a valid push button ID */
if (!hwndOld || !(SendMessageA( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
if (!hwndOld || !(SendMessageW( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
hwndOld = DEFDLG_FindDefButton( hwndDlg );
if (hwndOld && hwndOld != hwndNew)
SendMessageA( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
SendMessageW( hwndOld, BM_SETSTYLE, BS_PUSHBUTTON, TRUE );
if (hwndNew)
{
if(dlgcode & DLGC_UNDEFPUSHBUTTON)
SendMessageA( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
SendMessageW( hwndNew, BM_SETSTYLE, BS_DEFPUSHBUTTON, TRUE );
}
return TRUE;
}
@ -1033,7 +1004,7 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
return 1;
}
case WM_NCDESTROY:
if ((dlgInfo = GETDLGINFO(hwnd)))
if ((dlgInfo = (DIALOGINFO *)SetWindowLongPtrW( hwnd, DWLP_ROS_DIALOGINFO, 0 )))
{
/* Free dialog heap (if created) */
/*if (dlgInfo->hDialogHeap)
@ -1048,7 +1019,7 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
/* Window clean-up */
return DefWindowProcA( hwnd, msg, wParam, lParam );
case WM_SHOWWINDOW:
case WM_SHOWWINDOW:
if (!wParam) DEFDLG_SaveFocus( hwnd );
return DefWindowProcA( hwnd, msg, wParam, lParam );
@ -1096,8 +1067,8 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
if (hwndFocus)
{
/* always make combo box hide its listbox control */
if (!SendMessageA( hwndFocus, CB_SHOWDROPDOWN, FALSE, 0 ))
SendMessageA( GetParent(hwndFocus), CB_SHOWDROPDOWN, FALSE, 0 );
if (!SendMessageW( hwndFocus, CB_SHOWDROPDOWN, FALSE, 0 ))
SendMessageW( GetParent(hwndFocus), CB_SHOWDROPDOWN, FALSE, 0 );
}
}
return DefWindowProcA( hwnd, msg, wParam, lParam );
@ -1109,9 +1080,6 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
PostMessageA( hwnd, WM_COMMAND, MAKEWPARAM(IDCANCEL, BN_CLICKED),
(LPARAM)GetDlgItem( hwnd, IDCANCEL ) );
return 0;
case WM_NOTIFYFORMAT:
return DefWindowProcA( hwnd, msg, wParam, lParam );
}
return 0;
}
@ -1121,14 +1089,15 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
*/
static LRESULT DEFDLG_Epilog(HWND hwnd, UINT msg, BOOL fResult)
{
// TODO: where's wine's WM_CTLCOLOR from?
// TODO: where's wine's WM_CTLCOLOR from?
if ((msg >= WM_CTLCOLORMSGBOX && msg <= WM_CTLCOLORSTATIC) ||
/*msg == WM_CTLCOLOR || */ msg == WM_COMPAREITEM ||
msg == WM_CTLCOLOR || msg == WM_COMPAREITEM ||
msg == WM_VKEYTOITEM || msg == WM_CHARTOITEM ||
msg == WM_QUERYDRAGICON || msg == WM_INITDIALOG)
return fResult;
return GetWindowLongA( hwnd, DWL_MSGRESULT );
return GetWindowLongPtrW( hwnd, DWLP_MSGRESULT );
}
/***********************************************************************
@ -1196,37 +1165,37 @@ static HWND DIALOG_GetNextTabItem( HWND hwndMain, HWND hwndDlg, HWND hwndCtrl, B
}
/**********************************************************************
* DIALOG_DlgDirList
* DIALOG_DlgDirListW
*
* Helper function for DlgDirList*
* Helper function for DlgDirList*W
*/
static INT DIALOG_DlgDirList( HWND hDlg, LPSTR spec, INT idLBox,
static INT DIALOG_DlgDirListW( HWND hDlg, LPWSTR spec, INT idLBox,
INT idStatic, UINT attrib, BOOL combo )
{
HWND hwnd;
LPSTR orig_spec = spec;
char any[] = "*.*";
LPWSTR orig_spec = spec;
WCHAR any[] = {'*','.','*',0};
#define SENDMSG(msg,wparam,lparam) \
((attrib & DDL_POSTMSGS) ? PostMessageA( hwnd, msg, wparam, lparam ) \
: SendMessageA( hwnd, msg, wparam, lparam ))
((attrib & DDL_POSTMSGS) ? PostMessageW( hwnd, msg, wparam, lparam ) \
: SendMessageW( hwnd, msg, wparam, lparam ))
DPRINT("%p '%s' %d %d %04x\n",
hDlg, spec ? spec : "NULL", idLBox, idStatic, attrib );
// DPRINT("%p '%s' %d %d %04x\n",
// hDlg, spec ? spec : "NULL", idLBox, idStatic, attrib );
/* If the path exists and is a directory, chdir to it */
if (!spec || !spec[0] || SetCurrentDirectoryA( spec )) spec = any;
if (!spec || !spec[0] || SetCurrentDirectoryW( spec )) spec = any;
else
{
char *p, *p2;
WCHAR *p, *p2;
p = spec;
if ((p2 = strrchr( p, '\\' ))) p = p2;
if ((p2 = strrchr( p, '/' ))) p = p2;
if ((p2 = strrchrW( p, '\\' ))) p = p2;
if ((p2 = strrchrW( p, '/' ))) p = p2;
if (p != spec)
{
char sep = *p;
WCHAR sep = *p;
*p = 0;
if (!SetCurrentDirectoryA( spec ))
if (!SetCurrentDirectoryW( spec ))
{
*p = sep; /* Restore the original spec */
return FALSE;
@ -1251,7 +1220,7 @@ static INT DIALOG_DlgDirList( HWND hDlg, LPSTR spec, INT idLBox,
}
if (SENDMSG( combo ? CB_DIR : LB_DIR,
(attrib & (DDL_DIRECTORY | DDL_DRIVES)) | DDL_EXCLUSIVE,
(LPARAM)"*.*" ) == LB_ERR)
(LPARAM)any ) == LB_ERR)
return FALSE;
}
else
@ -1264,17 +1233,17 @@ static INT DIALOG_DlgDirList( HWND hDlg, LPSTR spec, INT idLBox,
if (idStatic && ((hwnd = GetDlgItem( hDlg, idStatic )) != 0))
{
char temp[MAX_PATH];
GetCurrentDirectoryA( sizeof(temp), temp );
CharLowerA( temp );
WCHAR temp[MAX_PATH];
GetCurrentDirectoryW( sizeof(temp)/sizeof(WCHAR), temp );
CharLowerW( temp );
/* Can't use PostMessage() here, because the string is on the stack */
SetDlgItemTextA( hDlg, idStatic, temp );
SetDlgItemTextW( hDlg, idStatic, temp );
}
if (orig_spec && (spec != orig_spec))
{
/* Update the original file spec */
char *p = spec;
WCHAR *p = spec;
while ((*orig_spec++ = *p++));
}
@ -1283,26 +1252,24 @@ static INT DIALOG_DlgDirList( HWND hDlg, LPSTR spec, INT idLBox,
}
/**********************************************************************
* DIALOG_DlgDirListW
* DIALOG_DlgDirListA
*
* Helper function for DlgDirList*W
* Helper function for DlgDirList*A
*/
static INT DIALOG_DlgDirListW( HWND hDlg, LPWSTR spec, INT idLBox,
INT idStatic, UINT attrib, BOOL combo )
static INT DIALOG_DlgDirListA( HWND hDlg, LPSTR spec, INT idLBox,
INT idStatic, UINT attrib, BOOL combo )
{
if (spec)
{
LPSTR specA;
INT ret;
HEAP_strdupWtoA ( &specA, spec, lstrlenW(spec) );
ret = DIALOG_DlgDirList( hDlg, specA, idLBox, idStatic,
attrib, combo );
MultiByteToWideChar( CP_ACP, 0, specA, -1, spec, 0x7fffffff );
HEAP_free( specA );
INT ret, len = MultiByteToWideChar( CP_ACP, 0, spec, -1, NULL, 0 );
LPWSTR specW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
MultiByteToWideChar( CP_ACP, 0, spec, -1, specW, len );
ret = DIALOG_DlgDirListW( hDlg, specW, idLBox, idStatic, attrib, combo );
WideCharToMultiByte( CP_ACP, 0, specW, -1, spec, 0x7fffffff, NULL, NULL );
HeapFree( GetProcessHeap(), 0, specW );
return ret;
}
return DIALOG_DlgDirList( hDlg, NULL, idLBox, idStatic, attrib, combo );
return DIALOG_DlgDirListW( hDlg, NULL, idLBox, idStatic, attrib, combo );
}
/**********************************************************************
@ -1310,10 +1277,10 @@ static INT DIALOG_DlgDirListW( HWND hDlg, LPWSTR spec, INT idLBox,
*
* Helper function for DlgDirSelect*
*/
static BOOL DIALOG_DlgDirSelect( HWND hwnd, LPSTR str, INT len,
static BOOL DIALOG_DlgDirSelect( HWND hwnd, LPWSTR str, INT len,
INT id, BOOL unicode, BOOL combo )
{
char *buffer, *ptr;
WCHAR *buffer, *ptr;
INT item, size;
BOOL ret;
HWND listbox = GetDlgItem( hwnd, id );
@ -1321,14 +1288,14 @@ static BOOL DIALOG_DlgDirSelect( HWND hwnd, LPSTR str, INT len,
DPRINT("%p '%s' %d\n", hwnd, str, id );
if (!listbox) return FALSE;
item = SendMessageA(listbox, combo ? CB_GETCURSEL : LB_GETCURSEL, 0, 0 );
item = SendMessageW(listbox, combo ? CB_GETCURSEL : LB_GETCURSEL, 0, 0 );
if (item == LB_ERR) return FALSE;
size = SendMessageA(listbox, combo ? CB_GETLBTEXTLEN : LB_GETTEXTLEN, 0, 0 );
size = SendMessageW(listbox, combo ? CB_GETLBTEXTLEN : LB_GETTEXTLEN, 0, 0 );
if (size == LB_ERR) return FALSE;
if (!(buffer = HeapAlloc( GetProcessHeap(), 0, size+1 ))) return FALSE;
SendMessageA( listbox, combo ? CB_GETLBTEXT : LB_GETTEXT, item, (LPARAM)buffer );
SendMessageW( listbox, combo ? CB_GETLBTEXT : LB_GETTEXT, item, (LPARAM)buffer );
if ((ret = (buffer[0] == '['))) /* drive or directory */
{
@ -1340,7 +1307,7 @@ static BOOL DIALOG_DlgDirSelect( HWND hwnd, LPSTR str, INT len,
}
else
{
buffer[strlen(buffer)-1] = '\\';
buffer[strlenW(buffer)-1] = '\\';
ptr = buffer + 1;
}
}
@ -1348,10 +1315,10 @@ static BOOL DIALOG_DlgDirSelect( HWND hwnd, LPSTR str, INT len,
if (unicode)
{
if (len > 0 && !MultiByteToWideChar( CP_ACP, 0, ptr, -1, (LPWSTR)str, len ))
((LPWSTR)str)[len-1] = 0;
if (len > 0 && !WideCharToMultiByte( CP_ACP, 0, ptr, -1, (LPSTR)str, len, 0, 0 ))
((LPSTR)str)[len-1] = 0;
}
else lstrcpynA( str, ptr, len );
else lstrcpynW( str, ptr, len );
HeapFree( GetProcessHeap(), 0, buffer );
DPRINT("Returning %d '%s'\n", ret, str );
return ret;
@ -1376,6 +1343,28 @@ BOOL CALLBACK GetDlgItemEnumProc (HWND hwnd, LPARAM lParam )
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
HWND
STDCALL
CreateDialogIndirectParamAorW(
HINSTANCE hInstance,
LPCDLGTEMPLATE lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc,
LPARAM lParamInit,
DWORD Flags)
{
/* FIXME:
* This function might be obsolete since I don't think it is exported by NT
* Also wine has one more parameter identifying weather it should call
* the function with unicode or not
*/
return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit , !Flags, FALSE );
}
/*
* @implemented
*/
@ -1388,28 +1377,7 @@ CreateDialogIndirectParamA(
DLGPROC lpDialogFunc,
LPARAM lParamInit)
{
return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit, FALSE, FALSE );
}
/*
* @unimplemented
*/
HWND
STDCALL
CreateDialogIndirectParamAorW(
HINSTANCE hInstance,
LPCDLGTEMPLATE lpTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc,
LPARAM lParamInit)
{
/* FIXME:
This function might be obsolete since I don't think it is exported by NT
Also wine has one more parameter identifying weather it should call
the function with unicode or not */
UNIMPLEMENTED;
return (HWND)0;
return CreateDialogIndirectParamAorW( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit, 2 );
}
@ -1425,7 +1393,7 @@ CreateDialogIndirectParamW(
DLGPROC lpDialogFunc,
LPARAM lParamInit)
{
return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit, TRUE, FALSE );
return CreateDialogIndirectParamAorW( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit, 0);
}
@ -1490,9 +1458,9 @@ DefDlgProcA(
if (!(dlgInfo = GETDLGINFO(hDlg)))
return DefWindowProcA( hDlg, Msg, wParam, lParam );
SetWindowLongW( hDlg, DWL_MSGRESULT, 0 );
SetWindowLongPtrW( hDlg, DWLP_MSGRESULT, 0 );
if ((dlgproc = (WNDPROC)GetWindowLongA( hDlg, DWL_DLGPROC )))
if ((dlgproc = (WNDPROC)GetWindowLongPtrW( hDlg, DWLP_DLGPROC )))
{
/* Call dialog procedure */
result = CallWindowProcA( dlgproc, hDlg, Msg, wParam, lParam );
@ -1551,9 +1519,9 @@ DefDlgProcW(
if (!(dlgInfo = GETDLGINFO(hDlg)))
return DefWindowProcW( hDlg, Msg, wParam, lParam );
SetWindowLongW( hDlg, DWL_MSGRESULT, 0 );
SetWindowLongPtrW( hDlg, DWLP_MSGRESULT, 0 );
if ((dlgproc = (WNDPROC)GetWindowLongW( hDlg, DWL_DLGPROC )))
if ((dlgproc = (WNDPROC)GetWindowLongPtrW( hDlg, DWLP_DLGPROC )))
{
/* Call dialog procedure */
result = CallWindowProcW( dlgproc, hDlg, Msg, wParam, lParam );
@ -1593,6 +1561,30 @@ DefDlgProcW(
}
/*
* @implemented
*/
INT_PTR
STDCALL
DialogBoxIndirectParamAorW(
HINSTANCE hInstance,
LPCDLGTEMPLATE hDialogTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc,
LPARAM dwInitParam,
DWORD Flags)
{
/* FIXME:
* This function might be obsolete since I don't think it is exported by NT
* Also wine has one more parameter identifying weather it should call
* the function with unicode or not
*/
HWND hWnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, !Flags, TRUE );
if (hWnd) return DIALOG_DoDialogBox( hWnd, hWndParent );
return -1;
}
/*
* @implemented
*/
@ -1605,30 +1597,7 @@ DialogBoxIndirectParamA(
DLGPROC lpDialogFunc,
LPARAM dwInitParam)
{
HWND hwnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, FALSE, TRUE );
if (hwnd) return DIALOG_DoDialogBox( hwnd, hWndParent );
return -1;
}
/*
* @unimplemented
*/
INT_PTR
STDCALL
DialogBoxIndirectParamAorW(
HINSTANCE hInstance,
LPCDLGTEMPLATE hDialogTemplate,
HWND hWndParent,
DLGPROC lpDialogFunc,
LPARAM dwInitParam)
{
/* FIXME:
This function might be obsolete since I don't think it is exported by NT
Also wine has one more parameter identifying weather it should call
the function with unicode or not */
UNIMPLEMENTED;
return (INT_PTR)NULL;
return DialogBoxIndirectParamAorW( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, 2);
}
@ -1644,9 +1613,7 @@ DialogBoxIndirectParamW(
DLGPROC lpDialogFunc,
LPARAM dwInitParam)
{
HWND hwnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, TRUE, TRUE );
if (hwnd) return DIALOG_DoDialogBox( hwnd, hWndParent );
return -1;
return DialogBoxIndirectParamAorW( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, 0);
}
@ -1666,8 +1633,8 @@ DialogBoxParamA(
HRSRC hrsrc;
LPCDLGTEMPLATE ptr;
if (!(hrsrc = FindResourceA( hInstance, lpTemplateName, (LPCSTR)RT_DIALOG ))) return 0;
if (!(ptr = (LPCDLGTEMPLATE)LoadResource(hInstance, hrsrc))) return 0;
if (!(hrsrc = FindResourceA( hInstance, lpTemplateName, (LPCSTR)RT_DIALOG ))) return 0;
if (!(ptr = (LPCDLGTEMPLATE)LoadResource(hInstance, hrsrc))) return 0;
hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, FALSE, TRUE);
if (hwnd) return DIALOG_DoDialogBox(hwnd, hWndParent);
return -1;
@ -1690,8 +1657,8 @@ DialogBoxParamW(
HRSRC hrsrc;
LPCDLGTEMPLATE ptr;
if (!(hrsrc = FindResourceW( hInstance, lpTemplateName, (LPCWSTR)RT_DIALOG ))) return 0;
if (!(ptr = (LPCDLGTEMPLATE)LoadResource(hInstance, hrsrc))) return 0;
if (!(hrsrc = FindResourceW( hInstance, lpTemplateName, (LPCWSTR)RT_DIALOG ))) return 0;
if (!(ptr = (LPCDLGTEMPLATE)LoadResource(hInstance, hrsrc))) return 0;
hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, TRUE, TRUE);
if (hwnd) return DIALOG_DoDialogBox(hwnd, hWndParent);
return -1;
@ -1710,12 +1677,12 @@ DlgDirListA(
int nIDStaticPath,
UINT uFileType)
{
return DIALOG_DlgDirList( hDlg, lpPathSpec, nIDListBox, nIDStaticPath, uFileType, FALSE );
return DIALOG_DlgDirListA( hDlg, lpPathSpec, nIDListBox, nIDStaticPath, uFileType, FALSE );
}
/*
* @unimplemented
* @implemented
*/
int
STDCALL
@ -1726,13 +1693,12 @@ DlgDirListComboBoxA(
int nIDStaticPath,
UINT uFiletype)
{
UNIMPLEMENTED;
return 0;
return DIALOG_DlgDirListA( hDlg, lpPathSpec, nIDComboBox, nIDStaticPath, uFiletype, TRUE );
}
/*
* @unimplemented
* @implemented
*/
int
STDCALL
@ -1743,8 +1709,7 @@ DlgDirListComboBoxW(
int nIDStaticPath,
UINT uFiletype)
{
UNIMPLEMENTED;
return 0;
return DIALOG_DlgDirListW( hDlg, lpPathSpec, nIDComboBox, nIDStaticPath, uFiletype, TRUE );
}
@ -1760,12 +1725,12 @@ DlgDirListW(
int nIDStaticPath,
UINT uFileType)
{
return DIALOG_DlgDirListW( hDlg, lpPathSpec, nIDListBox, nIDStaticPath, uFileType, FALSE );
return DIALOG_DlgDirListW( hDlg, lpPathSpec, nIDListBox, nIDStaticPath, uFileType, FALSE );
}
/*
* @unimplemented
* @implemented
*/
BOOL
STDCALL
@ -1775,13 +1740,12 @@ DlgDirSelectComboBoxExA(
int nCount,
int nIDComboBox)
{
UNIMPLEMENTED;
return FALSE;
return DIALOG_DlgDirSelect( hDlg, (LPWSTR)lpString, nCount, nIDComboBox, FALSE, TRUE );
}
/*
* @unimplemented
* @implemented
*/
BOOL
STDCALL
@ -1791,8 +1755,7 @@ DlgDirSelectComboBoxExW(
int nCount,
int nIDComboBox)
{
UNIMPLEMENTED;
return FALSE;
return DIALOG_DlgDirSelect( hDlg, (LPWSTR)lpString, nCount, nIDComboBox, TRUE, TRUE );
}
@ -1807,7 +1770,7 @@ DlgDirSelectExA(
int nCount,
int nIDListBox)
{
return DIALOG_DlgDirSelect( hDlg, lpString, nCount, nIDListBox, FALSE, FALSE );
return DIALOG_DlgDirSelect( hDlg, (LPWSTR)lpString, nCount, nIDListBox, FALSE, FALSE );
}
@ -1822,7 +1785,7 @@ DlgDirSelectExW(
int nCount,
int nIDListBox)
{
return DIALOG_DlgDirSelect( hDlg, (LPSTR)lpString, nCount, nIDListBox, TRUE, FALSE );
return DIALOG_DlgDirSelect( hDlg, lpString, nCount, nIDListBox, TRUE, FALSE );
}
@ -1859,6 +1822,8 @@ EndDialog(
SetWindowPos(hDlg, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE
| SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW);
if (hDlg == GetActiveWindow()) WinPosActivateOtherWindow( hDlg );
/* unblock dialog loop */
PostMessageA(hDlg, WM_NULL, 0, 0);
return TRUE;
@ -1898,7 +1863,7 @@ STDCALL
GetDlgCtrlID(
HWND hwndCtl)
{
return GetWindowLongW( hwndCtl, GWL_ID );
return GetWindowLongPtrW( hwndCtl, GWLP_ID );
}
@ -2224,6 +2189,8 @@ IsDialogMessageW(
if ((hDlg != lpMsg->hwnd) && !IsChild( hDlg, lpMsg->hwnd )) return FALSE;
if (hDlg == GetDesktopWindow()) return FALSE;
hDlg = DIALOG_FindMsgDestination(hDlg);
switch(lpMsg->message)
@ -2278,7 +2245,6 @@ IsDialogMessageW(
return FALSE;
}
return TRUE;
}
break;
@ -2354,7 +2320,7 @@ IsDlgButtonChecked(
HWND hDlg,
int nIDButton)
{
return (UINT)SendDlgItemMessageA( hDlg, nIDButton, BM_GETCHECK, 0, 0 );
return (UINT)SendDlgItemMessageW( hDlg, nIDButton, BM_GETCHECK, 0, 0 );
}
@ -2471,13 +2437,13 @@ CheckDlgButton(
int nIDButton,
UINT uCheck)
{
SendDlgItemMessageA( hDlg, nIDButton, BM_SETCHECK, uCheck, 0 );
SendDlgItemMessageW( hDlg, nIDButton, BM_SETCHECK, uCheck, 0 );
return TRUE;
}
static BOOL CALLBACK CheckRB(HWND hwnd, LPARAM lParam)
{
LONG lChildID = GetWindowLongW(hwnd, GWL_ID);
LONG lChildID = GetWindowLongPtrW(hwnd, GWLP_ID);
RADIOGROUP *lpRadioGroup = (RADIOGROUP *)lParam;
if((lChildID >= lpRadioGroup->firstID) &&

View file

@ -17,6 +17,59 @@
/* FUNCTIONS *****************************************************************/
/*******************************************************************
* can_activate_window
*
* Check if we can activate the specified window.
*/
static BOOL can_activate_window( HWND hwnd )
{
LONG style;
if (!hwnd) return FALSE;
style = GetWindowLongW( hwnd, GWL_STYLE );
if (!(style & WS_VISIBLE)) return FALSE;
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
return !(style & WS_DISABLED);
}
/*******************************************************************
* WINPOS_ActivateOtherWindow
*
* Activates window other than pWnd.
*/
void
STDCALL
WinPosActivateOtherWindow(HWND hwnd)
{
HWND hwndTo, fg;
if ((GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) && (hwndTo = GetWindow( hwnd, GW_OWNER )))
{
hwndTo = GetAncestor( hwndTo, GA_ROOT );
if (can_activate_window( hwndTo )) goto done;
}
hwndTo = hwnd;
for (;;)
{
if (!(hwndTo = GetWindow( hwndTo, GW_HWNDNEXT ))) break;
if (can_activate_window( hwndTo )) break;
}
done:
fg = GetForegroundWindow();
TRACE("win = %p fg = %p\n", hwndTo, fg);
if (!fg || (hwnd == fg))
{
if (SetForegroundWindow( hwndTo )) return;
}
if (!SetActiveWindow( hwndTo )) SetActiveWindow(0);
}
UINT STDCALL
WinPosGetMinMaxInfo(HWND hWnd, POINT* MaxSize, POINT* MaxPos,
POINT* MinTrack, POINT* MaxTrack)