From 92cc25a074cd2efb9a437e8bdcd3310cf4cec6bd Mon Sep 17 00:00:00 2001 From: Casper Hornstrup Date: Thu, 10 Jul 2003 00:24:04 +0000 Subject: [PATCH] Joakim Asplund lib/user32/controls/combo.c: - Combo height fix lib/user32/windows/window.c - Fix to FindWindowExW, incorrect allocation of UNICODE_STRING:s (uninitialized pointers...) subsys/win32k/ntuser/painting.c: - Put in locking of window lists where it was missing - Fixed an incorrect CONTAINING_RECORD subsys/win32k/ntuser/windc.c - Put in locking of window lists where it was missing subsys/win32k/ntuser/window.c - Put in locking of window lists, both children and thread, where it was missing - W32kCreateDesktopWindow had forgotten initializing its ChildrenListLock! - Remade NtUserFindWindowEx which I hope should work more as expected now subsys/win32k/ntuser/winpos.c: - Put in locking of window lists where it was missing svn path=/trunk/; revision=5031 --- reactos/lib/user32/controls/combo.c | 8 +- reactos/lib/user32/windows/window.c | 42 +++++---- reactos/subsys/win32k/ntuser/painting.c | 9 +- reactos/subsys/win32k/ntuser/windc.c | 6 +- reactos/subsys/win32k/ntuser/window.c | 109 ++++++++++++++++++++---- reactos/subsys/win32k/ntuser/winpos.c | 11 ++- 6 files changed, 146 insertions(+), 39 deletions(-) diff --git a/reactos/lib/user32/controls/combo.c b/reactos/lib/user32/controls/combo.c index ca44f6ba442..e6d28022657 100644 --- a/reactos/lib/user32/controls/combo.c +++ b/reactos/lib/user32/controls/combo.c @@ -223,7 +223,8 @@ static INT CBGetTextAreaHeight( ReleaseDC(hwnd, hDC); - iTextItemHeight = ((13 * baseUnitY) / 8); +#if 0 + iTextItemHeight = ((13 * baseUnitY) / 8); /* * This "formula" calculates the height of the complete control. @@ -231,6 +232,11 @@ static INT CBGetTextAreaHeight( * borders. */ iTextItemHeight -= 2*COMBO_YBORDERSIZE(); +#endif + + /* Joakim: This seems to work better, the old formula caused the combo box + to be waaay to big with big font sizes */ + iTextItemHeight = baseUnitY+2*COMBO_YBORDERSIZE(); } /* diff --git a/reactos/lib/user32/windows/window.c b/reactos/lib/user32/windows/window.c index b080d9fa015..3be236394b9 100644 --- a/reactos/lib/user32/windows/window.c +++ b/reactos/lib/user32/windows/window.c @@ -1,4 +1,4 @@ -/* $Id: window.c,v 1.41 2003/07/07 06:39:34 jimtabor Exp $ +/* $Id: window.c,v 1.42 2003/07/10 00:24:04 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS user32.dll @@ -719,8 +719,17 @@ FindWindowExA(HWND hwndParent, HWND STDCALL FindWindowW(LPCWSTR lpClassName, LPCWSTR lpWindowName) { - //FIXME: FindWindow does not search children, but FindWindowEx does. - // what should we do about this? + /* + + There was a FIXME here earlier, but I think it is just a documentation unclarity. + + FindWindow only searches top level windows. What they mean is that child + windows of other windows than the desktop can be searched. + FindWindowExW never does a recursive search. + + / Joakim + */ + return FindWindowExW (NULL, NULL, lpClassName, lpWindowName); } @@ -730,29 +739,26 @@ FindWindowExW(HWND hwndParent, LPCWSTR lpszClass, LPCWSTR lpszWindow) { - PUNICODE_STRING ucClassName; - PUNICODE_STRING ucWindowName; + UNICODE_STRING ucClassName; + UNICODE_STRING ucWindowName; if (IS_ATOM(lpszClass)) { - RtlInitUnicodeString(ucClassName, NULL); - ucClassName->Buffer = (LPWSTR)lpszClass; + RtlInitUnicodeString(&ucClassName, NULL); + ucClassName.Buffer = (LPWSTR)lpszClass; } else { - RtlInitUnicodeString(ucClassName, lpszClass); - } - if (IS_ATOM(lpszWindow)) - { - RtlInitUnicodeString(ucWindowName, NULL); - ucClassName->Buffer = (LPWSTR)lpszWindow; - } - else - { - RtlInitUnicodeString(ucWindowName, lpszWindow); + RtlInitUnicodeString(&ucClassName, lpszClass); } - return NtUserFindWindowEx(hwndParent, hwndChildAfter, ucClassName, ucWindowName); + // Window names can't be atoms, and if lpszWindow = NULL, + // RtlInitUnicodeString will clear it + + RtlInitUnicodeString(&ucWindowName, lpszWindow); + + + return NtUserFindWindowEx(hwndParent, hwndChildAfter, &ucClassName, &ucWindowName); } WINBOOL STDCALL diff --git a/reactos/subsys/win32k/ntuser/painting.c b/reactos/subsys/win32k/ntuser/painting.c index d8259e89f5a..9686bcb236c 100644 --- a/reactos/subsys/win32k/ntuser/painting.c +++ b/reactos/subsys/win32k/ntuser/painting.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: painting.c,v 1.18 2003/06/15 20:08:02 gvg Exp $ +/* $Id: painting.c,v 1.19 2003/07/10 00:24:04 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -386,6 +386,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, Client.x = Window->ClientRect.left - Window->WindowRect.left; Client.y = Window->ClientRect.top - Window->WindowRect.top; + ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); ChildListEntry = Window->ChildrenListHead.Flink; while (ChildListEntry != &Window->ChildrenListHead) { @@ -416,6 +417,8 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, } ChildListEntry = ChildListEntry->Flink; } + ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); + W32kOffsetRgn(hRgn, Total.x, Total.y); HasChildren = FALSE; } @@ -426,6 +429,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, PWINDOW_OBJECT Child; PLIST_ENTRY ChildListEntry; + ExAcquireFastMutexUnsafe(&Window->ChildrenListLock); ChildListEntry = Window->ChildrenListHead.Flink; while (ChildListEntry != &Window->ChildrenListHead) { @@ -437,6 +441,7 @@ PaintUpdateRgns(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags, } ChildListEntry = ChildListEntry->Flink; } + ExReleaseFastMutexUnsafe(&Window->ChildrenListLock); } PaintUpdateInternalPaint(Window, Flags); @@ -678,7 +683,7 @@ PaintingFindWinToRepaint(HWND hWnd, PW32THREAD Thread) while (current_entry != &BaseWindow->ChildrenListHead) { Window = CONTAINING_RECORD(current_entry, WINDOW_OBJECT, - ChildrenListHead); + SiblingListEntry); if (Window->Style & WS_VISIBLE) { hFoundWnd = PaintingFindWinToRepaint(Window->Self, Thread); diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index ec574d8e587..a6bcb6950c4 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: windc.c,v 1.12 2003/06/15 20:08:02 gvg Exp $ +/* $Id: windc.c,v 1.13 2003/07/10 00:24:04 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -123,6 +123,8 @@ DceAddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End, PWINDOW_OBJECT Child; RECT Rect1; + + ExAcquireFastMutexUnsafe(&Parent->ChildrenListLock); ChildListEntry = Parent->ChildrenListHead.Flink; while (ChildListEntry != &Parent->ChildrenListHead) { @@ -130,6 +132,7 @@ DceAddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End, SiblingListEntry); if (Child == End) { + ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); return(TRUE); } if (Child->Style & WS_VISIBLE) @@ -146,6 +149,7 @@ DceAddClipRects(PWINDOW_OBJECT Parent, PWINDOW_OBJECT End, } ChildListEntry = ChildListEntry->Flink; } + ExReleaseFastMutexUnsafe(&Parent->ChildrenListLock); return(FALSE); } diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index 647315eca23..722b0468354 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: window.c,v 1.61 2003/07/07 06:09:45 jimtabor Exp $ +/* $Id: window.c,v 1.62 2003/07/10 00:24:04 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -490,7 +490,9 @@ W32kCreateDesktopWindow(PWINSTATION_OBJECT WindowStation, WindowObject->ClientRect = WindowObject->WindowRect; WindowObject->UserData = 0; WindowObject->WndProc = DesktopClass->Class.lpfnWndProc; + InitializeListHead(&WindowObject->ChildrenListHead); + ExInitializeFastMutex(&WindowObject->ChildrenListLock); WindowName = ExAllocatePool(NonPagedPool, sizeof(L"DESKTOP")); wcscpy(WindowName, L"DESKTOP"); @@ -608,8 +610,12 @@ NtUserCreateWindowEx(DWORD dwExStyle, WindowObject->Parent = ParentWindow; WindowObject->UserData = 0; WindowObject->WndProc = ClassObject->Class.lpfnWndProc; + + ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock); InsertHeadList(&ParentWindow->ChildrenListHead, &WindowObject->SiblingListEntry); + ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock); + InitializeListHead(&WindowObject->ChildrenListHead); InitializeListHead(&WindowObject->PropListHead); ExInitializeFastMutex(&WindowObject->ChildrenListLock); @@ -1032,9 +1038,17 @@ static LRESULT W32kDestroyWindow(PWINDOW_OBJECT Window, WINPROC_FreeProc(Window->winproc, WIN_PROC_WINDOW); CLASS_RemoveWindow(Window->Class); #endif + + ExAcquireFastMutexUnsafe(&Window->Parent->ChildrenListLock); RemoveEntryList(&Window->SiblingListEntry); + ExReleaseFastMutexUnsafe(&Window->Parent->ChildrenListLock); + RemoveEntryList(&Window->DesktopListEntry); + + ExAcquireFastMutexUnsafe (&ThreadData->WindowListLock); RemoveEntryList(&Window->ThreadListEntry); + ExReleaseFastMutexUnsafe (&ThreadData->WindowListLock); + Window->Class = NULL; ObmCloseHandle(ProcessData->WindowStation->HandleTable, Window->Self); @@ -1231,6 +1245,31 @@ NtUserFillWindow(DWORD Unknown0, return 0; } +/* + * FUNCTION: + * Searches a window's children for a window with the specified + * class and name + * ARGUMENTS: + * hwndParent = The window whose childs are to be searched. + * NULL = desktop + * + * hwndChildAfter = Search starts after this child window. + * NULL = start from beginning + * + * ucClassName = Class name to search for + * Reguired parameter. + * + * ucWindowName = Window name + * ->Buffer == NULL = don't care + * + * RETURNS: + * The HWND of the window if it was found, otherwise NULL + * + * FIXME: + * Should use MmCopyFromCaller, we don't want an access violation in here + * + */ + HWND STDCALL NtUserFindWindowEx(HWND hwndParent, HWND hwndChildAfter, @@ -1240,41 +1279,79 @@ NtUserFindWindowEx(HWND hwndParent, NTSTATUS status; HWND windowHandle; PWINDOW_OBJECT windowObject; + PWINDOW_OBJECT ParentWindow; PLIST_ENTRY currentEntry; PWNDCLASS_OBJECT classObject; + // Get a pointer to the class status = ClassReferenceClassByNameOrAtom(&classObject, ucClassName->Buffer); if (!NT_SUCCESS(status)) { - return (HWND)0; + return NULL; + } + + // If hwndParent==NULL use the desktop window instead + if(!hwndParent) + hwndParent = PsGetWin32Thread()->Desktop->DesktopWindow; + + // Get the object + ParentWindow = W32kGetWindowObject(hwndParent); + + if(!ParentWindow) + { + ObmDereferenceObject(classObject); + return NULL; } - //ExAcquireFastMutexUnsafe (&PsGetWin32Process()->WindowListLock); - currentEntry = W32kGetActiveDesktop()->WindowListHead.Flink; - while (currentEntry != &W32kGetActiveDesktop()->WindowListHead) + ExAcquireFastMutexUnsafe (&ParentWindow->ChildrenListLock); + currentEntry = ParentWindow->ChildrenListHead.Flink; + + if(hwndChildAfter) + { + while (currentEntry != &ParentWindow->ChildrenListHead) + { + windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT, + SiblingListEntry); + + if(windowObject->Self == hwndChildAfter) + { + /* "The search begins with the _next_ child window in the Z order." */ + currentEntry = currentEntry->Flink; + break; + } + + currentEntry = currentEntry->Flink; + } + + /* If the child hwndChildAfter was not found: + currentEntry=&ParentWindow->ChildrenListHead now so the next + block of code will just fall through and the function returns NULL */ + } + + while (currentEntry != &ParentWindow->ChildrenListHead) { windowObject = CONTAINING_RECORD (currentEntry, WINDOW_OBJECT, - ListEntry); + SiblingListEntry); - if (classObject == windowObject->Class && - RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName, - TRUE) == 0) + if (classObject == windowObject->Class && (ucWindowName->Buffer==NULL || + RtlCompareUnicodeString (ucWindowName, &windowObject->WindowName, TRUE) == 0)) { - ObmCreateHandle(W32kGetActiveDesktop()->WindowStation->HandleTable, - windowObject, - &windowHandle); - //ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock); + windowHandle = windowObject->Self; + + ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock); + W32kReleaseWindowObject(ParentWindow); ObmDereferenceObject (classObject); return windowHandle; } currentEntry = currentEntry->Flink; } - //ExReleaseFastMutexUnsafe (&PsGetWin32Process()->WindowListLock); - + + ExReleaseFastMutexUnsafe (&ParentWindow->ChildrenListLock); + W32kReleaseWindowObject(ParentWindow); ObmDereferenceObject (classObject); - return (HWND)0; + return NULL; } DWORD STDCALL diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index 36673a35fd5..18177c36e85 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: winpos.c,v 1.12 2003/07/05 16:04:01 chorns Exp $ +/* $Id: winpos.c,v 1.13 2003/07/10 00:24:04 chorns Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -802,6 +802,8 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point, PLIST_ENTRY CurrentEntry; PWINDOW_OBJECT Current; + + ExAcquireFastMutexUnsafe(&ScopeWin->ChildrenListLock); CurrentEntry = ScopeWin->ChildrenListHead.Flink; while (CurrentEntry != &ScopeWin->ChildrenListHead) { @@ -816,10 +818,12 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point, *Window = Current; if (Current->Style & WS_DISABLED) { + ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); return(HTERROR); } if (Current->Style & WS_MINIMIZE) { + ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); return(HTCAPTION); } if (Point.x >= Current->ClientRect.left && @@ -830,12 +834,17 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point, Point.x -= Current->ClientRect.left; Point.y -= Current->ClientRect.top; + ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); return(WinPosSearchChildren(Current, Point, Window)); } + + ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); return(0); } CurrentEntry = CurrentEntry->Flink; } + + ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock); return(0); }