From 1d2d01338458314eaa3a566d0f93e1cf8e41c7cf Mon Sep 17 00:00:00 2001 From: James Tabor Date: Tue, 1 Aug 2006 21:14:45 +0000 Subject: [PATCH] - User32 - 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 --- reactos/dll/win32/user32/misc/desktop.c | 2 - reactos/dll/win32/user32/user32.def | 4 +- reactos/dll/win32/user32/windows/dialog.c | 476 ++++++++++------------ reactos/dll/win32/user32/windows/winpos.c | 53 +++ 4 files changed, 276 insertions(+), 259 deletions(-) diff --git a/reactos/dll/win32/user32/misc/desktop.c b/reactos/dll/win32/user32/misc/desktop.c index e8942ea8763..db7412ada78 100644 --- a/reactos/dll/win32/user32/misc/desktop.c +++ b/reactos/dll/win32/user32/misc/desktop.c @@ -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) diff --git a/reactos/dll/win32/user32/user32.def b/reactos/dll/win32/user32/user32.def index dd92c3563d8..13af78be68d 100644 --- a/reactos/dll/win32/user32/user32.def +++ b/reactos/dll/win32/user32/user32.def @@ -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 diff --git a/reactos/dll/win32/user32/windows/dialog.c b/reactos/dll/win32/user32/windows/dialog.c index db331eda2cb..e1be9825296 100644 --- a/reactos/dll/win32/user32/windows/dialog.c +++ b/reactos/dll/win32/user32/windows/dialog.c @@ -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) && diff --git a/reactos/dll/win32/user32/windows/winpos.c b/reactos/dll/win32/user32/windows/winpos.c index 145d98b8362..a5ee9de9153 100644 --- a/reactos/dll/win32/user32/windows/winpos.c +++ b/reactos/dll/win32/user32/windows/winpos.c @@ -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)