[Win32SS]

- Active, Focus and Foreground. Fixes many of the the wine tests and including the todos. Fix bug 7089.
- Get ATI support points in place, include code support for ptiSysLock which will be rewritten soon.
- Move Desktop Proc to Win32k. This will allow the access checks to work. Note: DesktopBG.c creates a Win32 thread every time a Desktop is created. Please keep the file and code intact for historical purposes.
- Get code close to wine.

References:
Focus test ROS passes: http://www.winehq.org/pipermail/wine-patches/2012-August/116887.html
Install acts and looks better: http://www.resmap.com/instructions/plug-ins/ERViewer7_0_RC.exe


svn path=/trunk/; revision=57111
This commit is contained in:
James Tabor
2012-08-20 00:26:08 +00:00
parent 0be33b81df
commit 12dc854709
20 changed files with 977 additions and 342 deletions
+13 -1
View File
@@ -30,6 +30,7 @@ IntCreatePrimarySurface()
{
SIZEL SurfSize;
SURFOBJ *pso;
PDESKTOP rpDesk;
/* Attach monitor */
UserAttachMonitor((HDEV)gppdevPrimary);
@@ -45,7 +46,18 @@ IntCreatePrimarySurface()
gpsi->ptCursor.x = pso->sizlBitmap.cx / 2;
gpsi->ptCursor.y = pso->sizlBitmap.cy / 2;
co_IntShowDesktop(IntGetActiveDesktop(), SurfSize.cx, SurfSize.cy);
rpDesk = IntGetActiveDesktop();
if (!rpDesk)
{ /* First time going in from winlogon and starting up application desktop and
haven't switch to winlogon desktop. Also still in WM_CREATE. */
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
rpDesk = pti->rpdesk;
if (!rpDesk)
{
DPRINT1("No DESKTOP Window!!!!!\n");
}
}
co_IntShowDesktop(rpDesk, SurfSize.cx, SurfSize.cy);
// Init Primary Displays Device Capabilities.
PDEVOBJ_vGetDeviceCaps(gppdevPrimary, &GdiHandleTable->DevCaps);
+3 -3
View File
@@ -202,11 +202,11 @@ BOOL FASTCALL co_UserShowCaret(PWND Window OPTIONAL)
return FALSE;
}
if(!ThreadQueue->CaretInfo->Visible && ThreadQueue->CaretInfo->hWnd)
if (!ThreadQueue->CaretInfo->Visible)
{
ThreadQueue->CaretInfo->Visible = 1;
pWnd = UserGetWindowObject(ThreadQueue->CaretInfo->hWnd);
if (!ThreadQueue->CaretInfo->Showing)
pWnd = ValidateHwndNoErr(ThreadQueue->CaretInfo->hWnd);
if (!ThreadQueue->CaretInfo->Showing && pWnd)
{
co_IntSendMessage(ThreadQueue->CaretInfo->hWnd, WM_SYSTIMER, IDCARETTIMER, 0);
IntNotifyWinEvent(EVENT_OBJECT_SHOW, pWnd, OBJID_CARET, OBJID_CARET, 0);
+29 -60
View File
@@ -550,6 +550,8 @@ HWND FASTCALL IntGetCurrentThreadDesktopWindow(VOID)
LRESULT FASTCALL
DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
ULONG Value;
//ERR("DesktopWindowProc\n");
switch (Msg)
{
case WM_NCCREATE:
@@ -558,6 +560,20 @@ DesktopWindowProc(PWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
Wnd->fnid = FNID_DESKTOP;
}
return (LRESULT)TRUE;
case WM_CREATE:
Value = HandleToULong(PsGetCurrentProcessId());
// Save Process ID
co_UserSetWindowLong(UserHMGetHandle(Wnd), DT_GWL_PROCESSID, Value, FALSE);
Value = HandleToULong(PsGetCurrentThreadId());
// Save Thread ID
co_UserSetWindowLong(UserHMGetHandle(Wnd), DT_GWL_THREADID, Value, FALSE);
case WM_CLOSE:
return 0;
case WM_DISPLAYCHANGE:
co_WinPosSetWindowPos(Wnd, 0, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER | SWP_NOACTIVATE);
break;
}
return 0;
}
@@ -605,17 +621,6 @@ UserRedrawDesktop()
NTSTATUS FASTCALL
co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height)
{
//#if 0
CSR_API_MESSAGE Request;
Request.Type = MAKE_CSR_API(SHOW_DESKTOP, CSR_GUI);
Request.Data.ShowDesktopRequest.DesktopWindow = Desktop->DesktopWindow;
Request.Data.ShowDesktopRequest.Width = Width;
Request.Data.ShowDesktopRequest.Height = Height;
return co_CsrNotify(&Request);
//#endif
#if 0 // DESKTOPWNDPROC
PWND Window;
Window = IntGetWindowObject(Desktop->DesktopWindow);
@@ -629,7 +634,6 @@ co_IntShowDesktop(PDESKTOP Desktop, ULONG Width, ULONG Height)
co_UserRedrawWindow( Window, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN);
return STATUS_SUCCESS;
#endif
}
NTSTATUS FASTCALL
@@ -680,7 +684,7 @@ UserBuildShellHookHwndList(PDESKTOP Desktop)
* notifications. The lParam contents depend on the Message. See
* MSDN for more details (RegisterShellHookWindow)
*/
VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
{
PDESKTOP Desktop = IntGetActiveDesktop();
HWND* HwndList;
@@ -700,6 +704,8 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
return;
}
// FIXME: System Tray Support.
HwndList = UserBuildShellHookHwndList(Desktop);
if (HwndList)
{
@@ -711,12 +717,16 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam)
co_IntPostOrSendMessage(*cursor,
gpsi->uiShellMsg,
Message,
lParam);
(Message == HSHELL_LANGUAGE ? lParam : (LPARAM)wParam) );
}
ExFreePool(HwndList);
}
if (ISITHOOKED(WH_SHELL))
{
co_HOOK_CallHooks(WH_SHELL, Message, wParam, lParam);
}
}
/*
@@ -996,7 +1006,6 @@ IntPaintDesktop(HDC hDC)
return TRUE;
}
/* SYSCALLS *******************************************************************/
/*
@@ -1069,6 +1078,8 @@ NtUserCreateDesktop(
ptiCurrent->TIF_flags |= TIF_DISABLEHOOKS;
ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
}
/*else
{ERR("NtUserCreateDesktop: No ptiCurrent\n");}*/
DesktopName.Buffer = NULL;
/*
@@ -1169,9 +1180,9 @@ NtUserCreateDesktop(
{
InitializeListHead(&DesktopObject->pDeskInfo->aphkStart[i]);
}
//#if 0
/*
* Create a handle for CSRSS and notify CSRSS for Creating Desktop Background Window.
* Create a handle for CSRSS and notify CSRSS for Creating Desktop Background Windows and Threads.
*/
Request.Type = MAKE_CSR_API(CREATE_DESKTOP, CSR_GUI);
Status = CsrInsertObject(Desktop,
@@ -1194,51 +1205,9 @@ NtUserCreateDesktop(
SetLastNtError(Status);
RETURN( NULL);
}
//#endif
if (ptiCurrent && !ptiCurrent->rpdesk) IntSetThreadDesktop(Desktop,FALSE);
/*
Based on wine/server/window.c in get_desktop_window.
*/
#if 0 // DESKTOPWNDPROC from Revision 6908 Dedicated to GvG!
// Turn on when server side proc is ready.
//
// Create desktop window.
//
/*
Currently this works but it hangs in
co_IntShowDesktop->co_UserRedrawWindow->co_IntPaintWindows->co_IntSendMessage
Commenting out co_UserRedrawWindow will allow it to run with gui issues.
*/
ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_DESKTOP])));
ClassName.Length = 0;
RtlZeroMemory(&WindowName, sizeof(WindowName));
RtlZeroMemory(&Cs, sizeof(Cs));
Cs.x = UserGetSystemMetrics(SM_XVIRTUALSCREEN);
Cs.y = UserGetSystemMetrics(SM_YVIRTUALSCREEN);
Cs.cx = UserGetSystemMetrics(SM_CXVIRTUALSCREEN);
Cs.cy = UserGetSystemMetrics(SM_CYVIRTUALSCREEN);
Cs.style = WS_POPUP|WS_CLIPCHILDREN;
Cs.hInstance = hModClient; // Experimental mode... hModuleWin; // Server side winproc!
Cs.lpszName = (LPCWSTR) &WindowName;
Cs.lpszClass = (LPCWSTR) &ClassName;
pWnd = co_UserCreateWindowEx(&Cs, &ClassName, &WindowName, NULL);
if (!pWnd)
{
ERR("Failed to create Desktop window handle\n");
}
else
{ // Should be set in window.c, Justin Case,
if (!DesktopObject->DesktopWindow)
{
DesktopObject->pDeskInfo->spwnd = pWnd;
DesktopObject->DesktopWindow = UserHMGetHandle(pWnd);
}
}
#endif
ClassName.Buffer = ((PWSTR)((ULONG_PTR)(WORD)(gpsi->atomSysClass[ICLS_HWNDMESSAGE])));
ClassName.Length = 0;
RtlZeroMemory(&WindowName, sizeof(WindowName));
+6 -2
View File
@@ -39,6 +39,10 @@ typedef struct _DESKTOP
#define DF_DESKWNDDESTROYED 0x00010000
#define DF_DYING 0x00020000
// Index offset for Desktop data. Should these be global?
#define DT_GWL_PROCESSID 0
#define DT_GWL_THREADID 4
#define DESKTOP_READ STANDARD_RIGHTS_READ | \
DESKTOP_ENUMERATE | \
DESKTOP_READOBJECTS
@@ -146,7 +150,7 @@ IntParseDesktopPath(PEPROCESS Process,
VOID APIENTRY UserRedrawDesktop(VOID);
BOOL IntRegisterShellHookWindow(HWND hWnd);
BOOL IntDeRegisterShellHookWindow(HWND hWnd);
VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam);
VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam);
HDC FASTCALL UserGetDesktopDC(ULONG,BOOL,BOOL);
#define IntIsActiveDesktop(Desktop) \
@@ -277,6 +281,6 @@ DesktopHeapAddressToUser(PVOID lpMem)
PWND FASTCALL IntGetThreadDesktopWindow(PTHREADINFO);
PWND FASTCALL co_GetDesktopWindow(PWND);
BOOL FASTCALL IntPaintDesktop(HDC);
LRESULT FASTCALL DesktopWindowProc(PWND, UINT, WPARAM, LPARAM);
/* EOF */
+220 -122
View File
@@ -45,18 +45,35 @@ IntGetThreadFocusWindow(VOID)
return ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
}
VOID FASTCALL
BOOL FASTCALL
co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd)
{
PWND WndPrev ;
USER_REFERENCE_ENTRY RefPrev;
PWND WndPrev;
BOOL Ret = TRUE;
if (hWndPrev && (WndPrev = UserGetWindowObject(hWndPrev)))
if (hWndPrev && (WndPrev = ValidateHwndNoErr(hWndPrev)))
{
co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0);
co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE,
MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE),
(LPARAM)hWnd);
UserRefObjectCo(WndPrev, &RefPrev);
if (co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0)) //(LPARAM)hWnd))
{
co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE,
MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE),
(LPARAM)hWnd);
if (WndPrev)
WndPrev->state &= ~WNDS_ACTIVEFRAME;
}
else
{
ERR("Application is keeping itself Active to prevent the change!\n");
Ret = FALSE;
}
UserDerefObjectCo(WndPrev);
}
return Ret;
}
BOOL FASTCALL
@@ -65,99 +82,103 @@ co_IntMakeWindowActive(PWND Window)
PWND spwndOwner;
if (Window)
{ // Set last active for window and it's owner.
Window->spwndLastActive = Window;
spwndOwner = Window->spwndOwner;
while (spwndOwner)
spwndOwner = Window;
while (spwndOwner->spwndOwner)
{
spwndOwner->spwndLastActive = Window;
spwndOwner = spwndOwner->spwndOwner;
}
spwndOwner->spwndLastActive = Window;
return TRUE;
}
ERR("MakeWindowActive Failed!\n");
return FALSE;
}
VOID FASTCALL
co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
BOOL FASTCALL
co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
{
USER_REFERENCE_ENTRY Ref, RefPrev;
PWND Window, WindowPrev = NULL;
HANDLE OldTID, NewTID;
PTHREADINFO ptiOld, ptiNew;
PTHREADINFO pti, ptiOld, ptiNew;
BOOL InAAPM = FALSE;
if (Window)
{
pti = PsGetCurrentThreadWin32Thread();
if ((Window = UserGetWindowObject(hWnd)))
{
UserRefObjectCo(Window, &Ref);
WindowPrev = UserGetWindowObject(hWndPrev);
if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev);
/* Send palette messages */
if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
co_IntPostOrSendMessage(hWnd, WM_QUERYNEWPALETTE, 0, 0))
co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
{
UserSendNotifyMessage( HWND_BROADCAST,
WM_PALETTEISCHANGING,
(WPARAM)hWnd,
(WPARAM)UserHMGetHandle(Window),
0);
}
if (Window->spwndPrev != NULL)
co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0,
SWP_NOSIZE | SWP_NOMOVE);
if (!Window->spwndOwner && !IntGetParent(Window))
//// Fixes bug 7089.
if (!(Window->style & WS_CHILD))
{
co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd);
}
PWND pwndTemp = co_GetDesktopWindow(Window)->spwndChild;
if (Window)
{
Window->state |= WNDS_ACTIVEFRAME;
while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext;
if (Window->style & WS_MINIMIZE)
if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev)))
{
TRACE("Widow was minimized\n");
if (!Async || pti->MessageQueue == gpqForeground)
{
UINT flags = SWP_NOSIZE | SWP_NOMOVE;
if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags);
}
}
}
if (WindowPrev)
WindowPrev->state &= ~WNDS_ACTIVEFRAME;
////
OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
NewTID = Window ? IntGetWndThreadId(Window) : NULL;
NewTID = IntGetWndThreadId(Window);
ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
ptiNew = Window ? Window->head.pti : NULL;
ptiNew = Window->head.pti;
TRACE("SendActiveMessage Old -> %x, New -> %x\n", OldTID, NewTID);
//ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID);
if (OldTID != NewTID)
if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
(!WindowPrev || OldTID != NewTID) )
{
PWND cWindow;
HWND *List, *phWnd;
List = IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow()));
List = IntWinListChildren(UserGetDesktopWindow());
if ( List )
{
if ( OldTID )
if ( OldTID )
{
ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags;
for (phWnd = List; *phWnd; ++phWnd)
{
cWindow = UserGetWindowObject(*phWnd);
cWindow = ValidateHwndNoErr(*phWnd);
if (cWindow && cWindow->head.pti == ptiOld)
{ // FALSE if the window is being deactivated,
// ThreadId that owns the window being activated.
co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
}
}
ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags;
}
if ( NewTID )
{
{ //// Prevents a resource crash due to reentrance!
InAAPM = TRUE;
pti->TIF_flags |= TIF_INACTIVATEAPPMSG;
pti->pClientInfo->dwTIFlags = pti->TIF_flags;
////
for (phWnd = List; *phWnd; ++phWnd)
{
cWindow = UserGetWindowObject(*phWnd);
cWindow = ValidateHwndNoErr(*phWnd);
if (cWindow && cWindow->head.pti == ptiNew)
{ // TRUE if the window is being activated,
// ThreadId that owns the window being deactivated.
@@ -171,38 +192,81 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
if (WindowPrev)
UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.
if (Window->state & WNDS_ACTIVEFRAME)
{ // If already active frame do not allow NCPaint.
//ERR("SendActivateMessage Is Active Frame!\n");
Window->state |= WNDS_NONCPAINT;
}
if (Window->style & WS_MINIMIZE)
{
TRACE("Widow was minimized\n");
}
co_IntMakeWindowActive(Window);
UserDerefObjectCo(Window);
/* FIXME: IntIsWindow */
co_IntSendMessageNoWait(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == UserGetForegroundWindow()), 0);
/* FIXME: WA_CLICKACTIVE */
co_IntSendMessageNoWait(hWnd, WM_ACTIVATE,
MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE,
Window->style & WS_MINIMIZE),
(LPARAM)hWndPrev);
co_IntSendMessageNoWait( UserHMGetHandle(Window),
WM_NCACTIVATE,
(WPARAM)(Window == gpqForeground->spwndActive),
0); //(LPARAM)hWndPrev);
co_IntSendMessageNoWait( UserHMGetHandle(Window),
WM_ACTIVATE,
MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, Window->style & WS_MINIMIZE),
(LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
if (!Window->spwndOwner && !IntGetParent(Window))
{
// FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise.
co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE);
}
Window->state &= ~WNDS_NONCPAINT;
}
return InAAPM;
}
VOID FASTCALL
co_IntSendKillFocusMessages(HWND hWndPrev, HWND hWnd)
IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
{
if (hWndPrev)
{
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(hWndPrev, WM_KILLFOCUS, (WPARAM)hWnd, 0);
}
}
PWND pWndPrev;
PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
VOID FASTCALL
co_IntSendSetFocusMessages(HWND hWndPrev, HWND hWnd)
{
if (hWnd)
ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
if (!pWnd && ThreadQueue->spwndActive)
{
PWND pWnd = UserGetWindowObject(hWnd);
if (pWnd)
ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
}
pWndPrev = ThreadQueue->spwndFocus;
/* check if the specified window can be set in the input data of a given queue */
if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
/* set the current thread focus window */
ThreadQueue->spwndFocus = pWnd;
if (pWnd)
{
if (pWndPrev)
{
co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0);
}
if (ThreadQueue->spwndFocus == pWnd)
{
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(hWnd, WM_SETFOCUS, (WPARAM)hWndPrev, 0);
co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0);
}
}
else
{
if (pWndPrev)
{
IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0);
}
}
}
@@ -304,25 +368,29 @@ co_IntSetForegroundAndFocusWindow(PWND Wnd, BOOL MouseActivate)
ASSERT_REFS_CO(Wnd);
TRACE("SetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd, MouseActivate ? "TRUE" : "FALSE");
TRACE("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
pti = PsGetCurrentThreadWin32Thread();
if (PrevForegroundQueue)
{ // Same Window Q as foreground just do active.
//ERR("Same Window Q as foreground just do active.\n");
if (Wnd && Wnd->head.pti->MessageQueue == PrevForegroundQueue)
{
if (pti->MessageQueue == PrevForegroundQueue)
{ // Same WQ and TQ go active.
Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE);
//ERR("Same WQ and TQ go active.\n");
Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE);
}
else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
{ // Same WQ and it is active.
//ERR("Same WQ and it is active.\n");
Ret = TRUE;
}
else
{ // Same WQ as FG but not the same TQ send active.
//ERR("Same WQ as FG but not the same TQ send active.\n");
co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
Ret = TRUE;
}
@@ -339,6 +407,7 @@ co_IntSetForegroundAndFocusWindow(PWND Wnd, BOOL MouseActivate)
{
IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
gptiForeground = Wnd->head.pti;
TRACE("Set Foreground pti 0x%p Q 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue);
/*
Henri Verbeet,
What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
@@ -361,7 +430,7 @@ co_IntSetForegroundAndFocusWindow(PWND Wnd, BOOL MouseActivate)
if (pti->MessageQueue == PrevForegroundQueue)
{
//ERR("SFGW: TI same as Prev TI\n");
co_IntSetActiveWindow(NULL, NULL, FALSE, TRUE);
co_IntSetActiveWindow(NULL, NULL, FALSE, TRUE, FALSE);
}
else
co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
@@ -370,7 +439,7 @@ co_IntSetForegroundAndFocusWindow(PWND Wnd, BOOL MouseActivate)
if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
{
Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE);
Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE);
}
else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
{
@@ -398,11 +467,11 @@ co_IntMouseActivateWindow(PWND Wnd)
{
BOOL Ret;
PWND TopWnd;
PWND DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
PWND DesktopWindow = UserGetDesktopWindow();
if (DesktopWindow)
{
Top = IntFindChildWindowToOwner(DesktopWindow, Wnd);
if ((TopWnd = UserGetWindowObject(Top)))
if ((TopWnd = ValidateHwndNoErr(Top)))
{
UserRefObjectCo(TopWnd, &Ref);
Ret = co_IntMouseActivateWindow(TopWnd);
@@ -415,31 +484,33 @@ co_IntMouseActivateWindow(PWND Wnd)
}
TopWindow = UserGetAncestor(Wnd, GA_ROOT);
//if (TopWindow) {ERR("MAW 2 pWnd %p hWnd %p\n",TopWindow,TopWindow->head.h);}
if (!TopWindow) return FALSE;
/* TMN: Check return valud from this function? */
/* TMN: Check return value from this function? */
UserRefObjectCo(TopWindow, &Ref);
co_IntSetForegroundAndFocusWindow(TopWindow, TRUE);
UserDerefObjectCo(TopWindow);
return TRUE;
}
BOOL FASTCALL
co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus)
co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, BOOL Async)
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue;
PWND pWndChg, WndPrev; // State changes.
HWND hWndPrev;
HWND hWnd = 0;
BOOL InAAPM;
CBTACTIVATESTRUCT cbt;
if (Wnd)
{
ASSERT_REFS_CO(Wnd);
hWnd = UserHMGetHandle(Wnd);
if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
if (Wnd == UserGetDesktopWindow()) return FALSE;
}
pti = PsGetCurrentThreadWin32Thread();
@@ -450,6 +521,8 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus)
if (Prev) *Prev = hWndPrev;
if (hWndPrev == hWnd) return TRUE;
pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
if (Wnd)
{
if (ThreadQueue != Wnd->head.pti->MessageQueue)
@@ -470,11 +543,36 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus)
cbt.hWndActive = hWndPrev;
if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt))
{
ERR("SetActiveWindow WH_CBT Call Hook return!\n");
ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
return FALSE;
}
co_IntSendDeactivateMessages(hWndPrev, hWnd);
if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED )
ThreadQueue->spwndActive = NULL;
else
ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
WndPrev = ThreadQueue->spwndActive; // Keep to save changing active.
if (WndPrev)
{
if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
if (!co_IntSendDeactivateMessages(hWndPrev, hWnd)) return FALSE;
}
// While in calling message proc or hook:
// Fail if a preemptive switch was made, current active not made previous,
// focus window is dead or no longer the same thread queue.
if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive ||
pWndChg != ThreadQueue->spwndActive ||
(Wnd && !VerifyWnd(Wnd)) ||
ThreadQueue != pti->MessageQueue )
{
ERR("SetActiveWindow: Summery ERROR, active state changed!\n");
return FALSE;
}
if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED;
@@ -484,32 +582,36 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus)
if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue)
{
/* set the current thread active window */
if (!Wnd || co_IntMakeWindowActive(Wnd))
{
ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
ThreadQueue->spwndActive = Wnd;
}
ThreadQueue->spwndActive = Wnd;
}
co_IntSendActivateMessages(hWndPrev, hWnd, bMouse);
InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
/* now change focus if necessary */
if (bFocus)
if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
{
/* Do not change focus if the window is no longer active */
if (ThreadQueue->spwndActive == Wnd)
if ( !Wnd || IntGetNonChildAncestor(ThreadQueue->spwndFocus) != ThreadQueue->spwndActive)
{
if (!ThreadQueue->spwndFocus ||
!Wnd ||
UserGetAncestor(ThreadQueue->spwndFocus, GA_ROOT) != Wnd)
{
co_UserSetFocus(Wnd);
}
PWND pWndTemp = Wnd;
if (ThreadQueue->spwndActive && ThreadQueue->spwndActive->style & WS_MINIMIZE)
pWndTemp = NULL;
TRACE("SAW is setting Focus! 0x%p Temp 0x%p\n",Wnd, pWndTemp);
IntSendFocusMessages(pti, pWndTemp);
}
}
if (InAAPM)
{
pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
pti->pClientInfo->dwTIFlags = pti->TIF_flags;
}
// FIXME: Used in the menu loop!!!
//ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED;
return TRUE;
return (ThreadQueue->spwndActive == Wnd);
}
HWND FASTCALL
@@ -527,13 +629,15 @@ co_UserSetFocus(PWND Window)
ThreadQueue = pti->MessageQueue;
ASSERT(ThreadQueue != 0);
TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );
hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
if (Window != 0)
{
if (hWndPrev == UserHMGetHandle(Window))
{
return hWndPrev; /* Nothing to do */
return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
}
if (Window->head.pti->MessageQueue != ThreadQueue)
@@ -570,7 +674,7 @@ co_UserSetFocus(PWND Window)
{
if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE))
{
ERR("SetFocus Set Foreground and Focus Failed!\n");
ERR("SetFocus: Set Foreground and Focus Failed!\n");
return 0;
}
}
@@ -578,9 +682,9 @@ co_UserSetFocus(PWND Window)
/* Set Active when it is needed. */
if (pwndTop != ThreadQueue->spwndActive)
{
if (!co_IntSetActiveWindow(pwndTop, NULL, FALSE, FALSE))
if (!co_IntSetActiveWindow(pwndTop, NULL, FALSE, FALSE, FALSE))
{
ERR("SetFocus Set Active Failed!\n");
ERR("SetFocus: Set Active Failed!\n");
return 0;
}
}
@@ -590,7 +694,7 @@ co_UserSetFocus(PWND Window)
/* Do not change focus if the window is no longer active */
if (pwndTop != ThreadQueue->spwndActive)
{
ERR("SetFocus Top window did not go active!\n");
ERR("SetFocus: Top window did not go active!\n");
return 0;
}
}
@@ -598,29 +702,22 @@ co_UserSetFocus(PWND Window)
// Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
/* check if the specified window can be set in the input data of a given queue */
if (ThreadQueue == Window->head.pti->MessageQueue)
/* set the current thread focus window */
ThreadQueue->spwndFocus = Window;
IntSendFocusMessages( pti, Window);
TRACE("Focus: %d -> %d\n", hWndPrev, Window->head.h);
co_IntSendKillFocusMessages(hWndPrev, Window->head.h);
co_IntSendSetFocusMessages(hWndPrev, Window->head.h);
}
else /* NULL hwnd passed in */
{
if (!hWndPrev) return 0; /* nothing to do */
// if (!hWndPrev) return 0; /* nothing to do */
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
{
ERR("SetFocusWindow 2 WH_CBT Call Hook return!\n");
ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
return 0;
}
/* set the current thread focus window null */
ThreadQueue->spwndFocus = 0;
co_IntSendKillFocusMessages(hWndPrev, 0);
IntSendFocusMessages( pti, NULL);
}
return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0;
}
@@ -667,7 +764,7 @@ co_UserSetCapture(HWND hWnd)
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue;
PWND Window, pWnd;
PWND pWnd, Window = NULL;
HWND hWndPrev;
pti = PsGetCurrentThreadWin32Thread();
@@ -676,7 +773,7 @@ co_UserSetCapture(HWND hWnd)
if (ThreadQueue->QF_flags & QF_CAPTURELOCKED)
return NULL;
if ((Window = UserGetWindowObject(hWnd)))
if (hWnd && (Window = UserGetWindowObject(hWnd)))
{
if (Window->head.pti->MessageQueue != ThreadQueue)
{
@@ -868,24 +965,24 @@ NtUserSetActiveWindow(HWND hWnd)
{
if (!(Window = UserGetWindowObject(hWnd)))
{
RETURN( 0);
ERR("NtUserSetActiveWindow: Invalid handle 0x%p!\n",hWnd);
RETURN( NULL);
}
}
if (!Window ||
Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
{
hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL;
if (Window) UserRefObjectCo(Window, &Ref);
if (!co_IntSetActiveWindow(Window, &hWndPrev, FALSE, TRUE)) hWndPrev = NULL;
co_IntSetActiveWindow(Window, NULL, FALSE, TRUE, FALSE);
if (Window) UserDerefObjectCo(Window);
RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
}
else
hWndPrev = NULL;
RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
RETURN( NULL);
CLEANUP:
TRACE("Leave NtUserSetActiveWindow, ret=%i\n",_ret_);
TRACE("Leave NtUserSetActiveWindow, ret=%p\n",_ret_);
UserLeave();
END_CLEANUP;
}
@@ -927,6 +1024,7 @@ NtUserSetFocus(HWND hWnd)
{
if (!(Window = UserGetWindowObject(hWnd)))
{
ERR("NtUserSetFocus: Invalid handle 0x%p!\n",hWnd);
RETURN(NULL);
}
@@ -942,7 +1040,7 @@ NtUserSetFocus(HWND hWnd)
}
CLEANUP:
TRACE("Leave NtUserSetFocus, ret=%i\n",_ret_);
TRACE("Leave NtUserSetFocus, ret=%p\n",_ret_);
UserLeave();
END_CLEANUP;
}
+1 -1
View File
@@ -18,6 +18,6 @@ HWND APIENTRY IntGetCapture(VOID);
HWND FASTCALL UserGetActiveWindow(VOID);
BOOL FASTCALL co_IntMouseActivateWindow(PWND Window);
BOOL FASTCALL co_IntSetForegroundWindow(PWND Window);
BOOL FASTCALL co_IntSetActiveWindow(PWND Window,HWND * Prev,BOOL bMouse,BOOL bFocus);
BOOL FASTCALL co_IntSetActiveWindow(PWND,HWND *,BOOL,BOOL,BOOL);
BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode);
BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId);
+2 -2
View File
@@ -644,7 +644,7 @@ NtUserLoadKeyboardLayoutEx(
/* Send shell message */
if (!(Flags & KLF_NOTELLSHELL))
co_IntShellHookNotify(HSHELL_LANGUAGE, (LPARAM)hkl);
co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);
/* Return hkl on success */
hklRet = (HKL)hkl;
@@ -713,7 +713,7 @@ NtUserActivateKeyboardLayout(
/* Send shell message */
if (!(Flags & KLF_NOTELLSHELL))
co_IntShellHookNotify(HSHELL_LANGUAGE, (LPARAM)hkl);
co_IntShellHookNotify(HSHELL_LANGUAGE, 0, (LPARAM)hkl);
}
cleanup:
+9 -4
View File
@@ -632,7 +632,7 @@ static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPAR
{
PWND Window = (PWND)wparam;
if (wparam) UserRefObjectCo(Window, &Ref);
lRes = (LRESULT)co_IntSetActiveWindow(Window,NULL,(BOOL)lparam,TRUE);
lRes = (LRESULT)co_IntSetActiveWindow(Window,NULL,(BOOL)lparam,TRUE,TRUE);
if (wparam) UserDerefObjectCo(Window);
return lRes;
}
@@ -1807,11 +1807,9 @@ DWORD APIENTRY
IntGetQueueStatus(DWORD Changes)
{
PTHREADINFO pti;
//PUSER_MESSAGE_QUEUE Queue;
DWORD Result;
pti = PsGetCurrentThreadWin32Thread();
//Queue = pti->MessageQueue;
// wine:
Changes &= (QS_ALLINPUT|QS_ALLPOSTMESSAGE|QS_SMRESULT);
@@ -2159,7 +2157,7 @@ NtUserTranslateMessage(LPMSG lpMsg, UINT flags)
}
else
{
ERR("No Window for Translate. hwnd 0x%p Msg %d\n",SafeMsg.hwnd,SafeMsg.message);
TRACE("No Window for Translate. hwnd 0x%p Msg %d\n",SafeMsg.hwnd,SafeMsg.message);
Ret = FALSE;
}
UserLeave();
@@ -2192,6 +2190,12 @@ NtUserMessageCall( HWND hWnd,
lResult = ScrollBarWndProc(hWnd, Msg, wParam, lParam);
break;
}
case FNID_DESKTOP:
{
Window = UserGetWindowObject(hWnd);
if (Window) lResult = DesktopWindowProc(Window, Msg, wParam, lParam);
break;
}
case FNID_DEFWINDOWPROC:
/* Validate input */
if (hWnd)
@@ -2676,6 +2680,7 @@ NtUserMessageCall( HWND hWnd,
case FNID_CALLWNDPROC:
case FNID_CALLWNDPROCRET:
case FNID_SCROLLBAR:
case FNID_DESKTOP:
if (ResultInfo)
{
_SEH2_TRY
+75 -13
View File
@@ -997,6 +997,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_MESSAGE_QUEUE ThreadQueue;
LARGE_INTEGER Timeout;
PLIST_ENTRY Entry;
PWND pWnd;
LRESULT Result = 0; //// Result could be trashed. ////
pti = PsGetCurrentThreadWin32Thread();
@@ -1015,14 +1016,27 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
if ( HookMessage == MSQ_NORMAL )
{
pWnd = ValidateHwndNoErr(Wnd);
// These can not cross International Border lines!
if ( pti->ppi != ptirec->ppi )
if ( pti->ppi != ptirec->ppi && pWnd )
{
switch(Msg)
{
// Handle the special case when working with password transfers across bordering processes.
case EM_GETLINE:
case EM_SETPASSWORDCHAR:
case WM_GETTEXT:
// Look for edit controls setup for passwords.
if ( gpsi->atomSysClass[ICLS_EDIT] == pWnd->pcls->atomClassName && // Use atomNVClassName.
pWnd->style & ES_PASSWORD )
{
if (uResult) *uResult = -1;
ERR("Running across the border without a passport!\n");
EngSetLastError(ERROR_ACCESS_DENIED);
return STATUS_UNSUCCESSFUL;
}
break;
case WM_NOTIFY:
if (uResult) *uResult = -1;
ERR("Running across the border without a passport!\n");
@@ -1551,13 +1565,12 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
/* Activate the window if needed */
if (pwndMsg != pti->MessageQueue->spwndActive) //msg->hwnd != UserGetForegroundWindow())
if (pwndMsg != MessageQueue->spwndActive)
{
PWND pwndTop = pwndMsg;
while (pwndTop)
while (pwndTop && ((pwndTop->style & (WS_POPUP|WS_CHILD)) == WS_CHILD))
{
if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
pwndTop = IntGetParent( pwndTop );
pwndTop = pwndTop->spwndParent;
}
if (pwndTop && pwndTop != pwndDesktop)
@@ -1673,10 +1686,23 @@ co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
{
BOOL AcceptMessage;
MSG msg;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
if(!(MessageQueue->MouseMoved))
return FALSE;
if (!MessageQueue->ptiSysLock)
{
MessageQueue->ptiSysLock = pti;
pti->pcti->CTI_flags |= CTI_THREADSYSLOCK;
}
if (MessageQueue->ptiSysLock != pti)
{
ERR("MsqPeekMouseMove: Thread Q is locked to another pti!\n");
return FALSE;
}
msg = MessageQueue->MouseMoveMsg;
AcceptMessage = co_IntProcessMouseMessage(&msg, &Remove, MsgFilterLow, MsgFilterHigh);
@@ -1690,7 +1716,9 @@ co_MsqPeekMouseMove(IN PUSER_MESSAGE_QUEUE MessageQueue,
MessageQueue->MouseMoved = FALSE;
}
return AcceptMessage;
MessageQueue->ptiSysLock = NULL;
pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK;
return AcceptMessage;
}
/* check whether a message filter contains at least one potential hardware message */
@@ -1724,6 +1752,8 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
PUSER_MESSAGE CurrentMessage;
PLIST_ENTRY ListHead, CurrentEntry = NULL;
MSG msg;
BOOL Ret = FALSE;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
if (!filter_contains_hw_range( MsgFilterLow, MsgFilterHigh )) return FALSE;
@@ -1732,6 +1762,18 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
if (IsListEmpty(CurrentEntry)) return FALSE;
if (!MessageQueue->ptiSysLock)
{
MessageQueue->ptiSysLock = pti;
pti->pcti->CTI_flags |= CTI_THREADSYSLOCK;
}
if (MessageQueue->ptiSysLock != pti)
{
ERR("MsqPeekHardwareMessage: Thread Q is locked to another pti!\n");
return FALSE;
}
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
do
@@ -1766,7 +1808,8 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
if (AcceptMessage)
{
*pMsg = msg;
return TRUE;
Ret = TRUE;
break;
}
}
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
@@ -1774,7 +1817,9 @@ co_MsqPeekHardwareMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
}
while(CurrentEntry != ListHead);
return FALSE;
MessageQueue->ptiSysLock = NULL;
pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK;
return Ret;
}
BOOLEAN APIENTRY
@@ -1789,12 +1834,26 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
PLIST_ENTRY CurrentEntry;
PUSER_MESSAGE CurrentMessage;
PLIST_ENTRY ListHead;
BOOL Ret = FALSE;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
CurrentEntry = MessageQueue->PostedMessagesListHead.Flink;
ListHead = &MessageQueue->PostedMessagesListHead;
if (IsListEmpty(CurrentEntry)) return FALSE;
if (!MessageQueue->ptiSysLock)
{
MessageQueue->ptiSysLock = pti;
pti->pcti->CTI_flags |= CTI_THREADSYSLOCK;
}
if (MessageQueue->ptiSysLock != pti)
{
ERR("MsqPeekMessage: Thread Q is locked to another pti!\n");
return FALSE;
}
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
do
@@ -1822,14 +1881,17 @@ MsqPeekMessage(IN PUSER_MESSAGE_QUEUE MessageQueue,
ClearMsgBitsMask(MessageQueue, CurrentMessage->QS_Flags);
MsqDestroyMessage(CurrentMessage);
}
return(TRUE);
Ret = TRUE;
break;
}
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
}
while (CurrentEntry != ListHead);
return(FALSE);
MessageQueue->ptiSysLock = NULL;
pti->pcti->CTI_flags &= ~CTI_THREADSYSLOCK;
return Ret;
}
NTSTATUS FASTCALL
@@ -2190,15 +2252,15 @@ MsqSetStateWindow(PUSER_MESSAGE_QUEUE MessageQueue, ULONG Type, HWND hWnd)
{
case MSQ_STATE_CAPTURE:
Prev = MessageQueue->spwndCapture ? UserHMGetHandle(MessageQueue->spwndCapture) : 0;
MessageQueue->spwndCapture = UserGetWindowObject(hWnd);
MessageQueue->spwndCapture = ValidateHwndNoErr(hWnd);
return Prev;
case MSQ_STATE_ACTIVE:
Prev = MessageQueue->spwndActive ? UserHMGetHandle(MessageQueue->spwndActive) : 0;
MessageQueue->spwndActive = UserGetWindowObject(hWnd);
MessageQueue->spwndActive = ValidateHwndNoErr(hWnd);
return Prev;
case MSQ_STATE_FOCUS:
Prev = MessageQueue->spwndFocus ? UserHMGetHandle(MessageQueue->spwndFocus) : 0;
MessageQueue->spwndFocus = UserGetWindowObject(hWnd);
MessageQueue->spwndFocus = ValidateHwndNoErr(hWnd);
return Prev;
case MSQ_STATE_MENUOWNER:
Prev = MessageQueue->MenuOwner;
+2 -4
View File
@@ -810,7 +810,7 @@ co_IntFixCaret(PWND Window, RECTL *lprc, UINT flags)
CaretInfo = ActiveMessageQueue->CaretInfo;
hWndCaret = CaretInfo->hWnd;
WndCaret = UserGetWindowObject(hWndCaret);
WndCaret = ValidateHwndNoErr(hWndCaret);
// FIXME: Check for WndCaret can be NULL
if (WndCaret == Window ||
@@ -1720,7 +1720,7 @@ NtUserScrollWindowEx(
((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0));
}
if ((CaretWnd = UserGetWindowObject(hwndCaret)))
if (hwndCaret && (CaretWnd = UserGetWindowObject(hwndCaret)))
{
UserRefObjectCo(CaretWnd, &CaretRef);
@@ -1975,8 +1975,6 @@ cleanup:
return Ret;
}
BOOL FASTCALL IntPaintDesktop(HDC hDC);
INT
FASTCALL
UserRealizePalette(HDC hdc)
+2 -2
View File
@@ -123,7 +123,7 @@ NtUserCallNoParam(DWORD Routine)
case NOPARAM_ROUTINE_ZAPACTIVEANDFOUS:
{
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
ERR("Zapping the Active and Focus window out of the Queue!\n");
TRACE("Zapping the Active and Focus window out of the Queue!\n");
pti->MessageQueue->spwndFocus = NULL;
pti->MessageQueue->spwndActive = NULL;
RETURN(0);
@@ -572,7 +572,7 @@ NtUserCallHwndLock(
SWP_FRAMECHANGED );
if (!Window->spwndOwner && !IntGetParent(Window))
{
co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
co_IntShellHookNotify(HSHELL_REDRAW, (WPARAM) hWnd, FALSE); // FIXME Flashing?
}
Ret = TRUE;
break;
+29 -3
View File
@@ -32,7 +32,19 @@
#define W32PF_MANUALGUICHECK (0x02000000)
#define W32PF_CREATEDWINORDC (0x04000000)
#define W32PF_APIHOOKLOADED (0x08000000)
/*
#define QSIDCOUNTS 6
typedef enum _QS_ROS_TYPES
{
QSRosKey = 0,
QSRosMouseMove,
QSRosMouseButton,
QSRosPostMessage,
QSRosSendMessage,
QSRosHotKey,
}QS_ROS_TYPES,*PQS_ROS_TYPES;
*/
extern BOOL ClientPfnInit;
extern HINSTANCE hModClient;
extern HANDLE hModuleWin; // This Win32k Instance.
@@ -77,10 +89,13 @@ typedef struct _THREADINFO
PCLIENTINFO pClientInfo;
FLONG TIF_flags;
PUNICODE_STRING pstrAppName;
LIST_ENTRY psmsSent; // DispatchingMessagesHead
struct _USER_SENT_MESSAGE *pusmCurrent;
LIST_ENTRY psmsReceiveList; // SentMessagesListHead
LONG timeLast;
ULONG_PTR idLast;
INT exitCode;
BOOLEAN QuitPosted;
INT exitCode; // QuitExitCode
HDESK hdesk;
UINT cPaintsReady; /* Count of paints pending. */
UINT cTimersReady; /* Count of timers pending. */
@@ -94,16 +109,27 @@ typedef struct _THREADINFO
LPARAM lParamHkCurrent;
WPARAM wParamHkCurrent;
struct tagSBTRACK* pSBTrack;
HANDLE hEventQueueClient;
PKEVENT pEventQueueServer;
HANDLE hEventQueueClient; // NewMessagesHandle
PKEVENT pEventQueueServer; // NewMessages
LIST_ENTRY PtiLink;
INT iCursorLevel;
POINT ptLast;
LIST_ENTRY mlPost; // PostedMessagesListHead
LIST_ENTRY aphkStart[NB_HOOKS];
CLIENTTHREADINFO cti; // Used only when no Desktop or pcti NULL.
/* ReactOS */
/* Queue state tracking */
// Send list QS_SENDMESSAGE
// Post list QS_POSTMESSAGE|QS_HOTKEY|QS_PAINT|QS_TIMER|QS_KEY
// Hard list QS_MOUSE|QS_KEY only
// Accounting of queue bit sets, the rest are flags. QS_TIMER QS_PAINT counts are handled in thread information.
//DWORD nCntsQBits[QSIDCOUNTS]; // QS_KEY QS_MOUSEMOVE QS_MOUSEBUTTON QS_POSTMESSAGE QS_SENDMESSAGE QS_HOTKEY
LIST_ENTRY LocalDispatchingMessagesHead;
LIST_ENTRY WindowListHead;
LIST_ENTRY W32CallbackListHead;
SINGLE_LIST_ENTRY ReferencesList;
+208 -21
View File
@@ -9,6 +9,8 @@
#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserWnd);
INT gNestedWindowLimit = 50;
/* HELPER FUNCTIONS ***********************************************************/
BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam)
@@ -147,7 +149,9 @@ IntIsWindow(HWND hWnd)
PWND Window;
if (!(Window = UserGetWindowObject(hWnd)))
{
return FALSE;
}
return TRUE;
}
@@ -217,6 +221,7 @@ IntEnableWindow( HWND hWnd, BOOL bEnable )
/* Remove keyboard focus from that window if it had focus */
if (hWnd == IntGetThreadFocusWindow())
{
TRACE("IntEnableWindow SF NULL\n");
co_UserSetFocus(NULL);
}
IntSetStyle( pWnd, WS_DISABLED, 0 );
@@ -269,6 +274,39 @@ IntWinListChildren(PWND Window)
return List;
}
PWND FASTCALL
IntGetNonChildAncestor(PWND pWnd)
{
if (pWnd)
{
while(pWnd && ((pWnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD))
pWnd = pWnd->spwndParent;
}
return pWnd;
}
BOOL FASTCALL
IntIsTopLevelWindow(PWND pWnd)
{
if ( pWnd->spwndParent &&
pWnd->spwndParent == co_GetDesktopWindow(pWnd) ) return TRUE;
return FALSE;
}
BOOL FASTCALL
IntValidateOwnerDepth(PWND Wnd, PWND Owner)
{
INT Depth = 1;
for (;;)
{
if ( !Owner ) return gNestedWindowLimit >= Depth;
if (Owner == Wnd) break;
Owner = Owner->spwndOwner;
Depth++;
}
return FALSE;
}
/***********************************************************************
* IntSendDestroyMsg
*/
@@ -297,7 +335,7 @@ static void IntSendDestroyMsg(HWND hWnd)
if (!Window->spwndOwner && !IntGetParent(Window))
{
co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) hWnd);
co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM) hWnd, 0);
}
// UserDerefObjectCo(Window);
@@ -696,6 +734,7 @@ IntSetMenu(
if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
{
ERR("SetMenu: Invalid handle 0x%p!\n",UserHMGetHandle(Wnd));
EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
return FALSE;
}
@@ -1037,6 +1076,36 @@ VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
}
}
}
Wnd->ExStyle2 |= WS_EX2_LINKED;
}
VOID FASTCALL
IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner)
{
if (WndOldOwner)
{
if (Wnd->head.pti != WndOldOwner->head.pti)
{
if (!WndNewOwner ||
Wnd->head.pti == WndNewOwner->head.pti ||
WndOldOwner->head.pti != WndNewOwner->head.pti )
{
UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE);
}
}
}
if (WndNewOwner)
{
if (Wnd->head.pti != WndNewOwner->head.pti)
{
if (!WndOldOwner ||
WndOldOwner->head.pti != WndNewOwner->head.pti )
{
UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE);
}
}
}
// FIXME: System Tray checks.
}
HWND FASTCALL
@@ -1051,17 +1120,36 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner)
WndOldOwner = Wnd->spwndOwner;
ret = WndOldOwner ? WndOldOwner->head.h : 0;
ret = WndOldOwner ? UserHMGetHandle(WndOldOwner) : 0;
WndNewOwner = UserGetWindowObject(hWndNewOwner);
if((WndNewOwner = UserGetWindowObject(hWndNewOwner)))
if (!WndNewOwner && hWndNewOwner)
{
Wnd->spwndOwner= WndNewOwner;
EngSetLastError(ERROR_INVALID_PARAMETER);
ret = NULL;
goto Error;
}
IntProcessOwnerSwap(Wnd, WndNewOwner, WndOldOwner);
if (IntValidateOwnerDepth(Wnd, WndNewOwner))
{
if (WndNewOwner)
{
Wnd->spwndOwner= WndNewOwner;
}
else
{
Wnd->spwndOwner = NULL;
}
}
else
{
Wnd->spwndOwner = NULL;
IntProcessOwnerSwap(Wnd, WndOldOwner, WndNewOwner);
EngSetLastError(ERROR_INVALID_PARAMETER);
ret = NULL;
}
Error:
UserDereferenceObject(Wnd);
return ret;
}
@@ -1129,6 +1217,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
{
/* Unlink the window from the siblings list */
IntUnlinkWindow(Wnd);
Wnd->ExStyle2 &= ~WS_EX2_LINKED;
/* Set the new parent */
Wnd->spwndParent = WndNewParent;
@@ -1148,6 +1237,24 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
}
if ((Wnd->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
{
if ( Wnd->spwndParent != co_GetDesktopWindow(Wnd))
{
if (Wnd->head.pti != WndOldParent->head.pti)
{
UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE);
}
}
if ( WndNewParent != co_GetDesktopWindow(Wnd))
{
if (Wnd->head.pti != WndNewParent->head.pti)
{
UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE);
}
}
}
if (WndOldParent == UserGetMessageWindow() || WndNewParent == UserGetMessageWindow())
swFlags |= SWP_NOACTIVATE;
@@ -1617,6 +1724,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
if (NULL == pti->rpdesk->DesktopWindow)
{ /* HACK: Helper for win32csr/desktopbg.c */
/* If there is no desktop window yet, we must be creating it */
TRACE("CreateWindow setting desktop.\n");
pti->rpdesk->DesktopWindow = hWnd;
pti->rpdesk->pDeskInfo->spwnd = pWnd;
}
@@ -1809,6 +1917,31 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
else // Not a child
pWnd->IDMenu = (UINT) Cs->hMenu;
if ( ParentWindow &&
ParentWindow != ParentWindow->head.rpdesk->spwndMessage &&
ParentWindow != ParentWindow->head.rpdesk->pDeskInfo->spwnd )
{
PWND Owner = IntGetNonChildAncestor(ParentWindow);
if (!IntValidateOwnerDepth(pWnd, Owner))
{
EngSetLastError(ERROR_INVALID_PARAMETER);
goto Error;
}
if ( pWnd->spwndOwner &&
pWnd->spwndOwner->ExStyle & WS_EX_TOPMOST )
{
pWnd->ExStyle |= WS_EX_TOPMOST;
}
if ( pWnd->spwndOwner &&
Class->atomClassName != gpsi->atomSysClass[ICLS_IME] &&
pti != pWnd->spwndOwner->head.pti)
{
UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE);
}
}
/* Insert the window into the thread's window list. */
InsertTailList (&pti->WindowListHead, &pWnd->ThreadListEntry);
@@ -1826,10 +1959,10 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
AllocError:
ERR("IntCreateWindow Allocation Error.\n");
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
Error:
if(pWnd)
UserDereferenceObject(pWnd);
SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
return NULL;
}
@@ -2082,6 +2215,17 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
IntLinkHwnd(Window, hwndInsertAfter);
}
if ((Window->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
{
if ( !IntIsTopLevelWindow(Window) )
{
if (pti != Window->spwndParent->head.pti)
{
UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE);
}
}
}
/* Send the NCCREATE message */
Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
if (!Result)
@@ -2143,7 +2287,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
/* Notify the shell that a new window was created */
if ((!hWndParent) && (!hWndOwner))
{
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)hWnd);
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)hWnd, 0);
}
/* Initialize and show the window's scrollbars */
@@ -2379,6 +2523,7 @@ cleanup:
BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
{
HWND hWnd;
PWND pwndTemp;
PTHREADINFO ti;
MSG msg;
@@ -2407,6 +2552,17 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
}
}
if (Window->pcls->atomClassName != gpsi->atomSysClass[ICLS_IME])
{
if ((Window->style & (WS_POPUP|WS_CHILD)) != WS_CHILD)
{
if (Window->spwndOwner)
{
UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE);
}
}
}
/* Inform the parent */
if (Window->style & WS_CHILD)
{
@@ -2419,11 +2575,32 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
if (!co_WinPosShowWindow(Window, SW_HIDE))
{ // Rule #1.
if (ti->MessageQueue->spwndActive == Window && ti->MessageQueue == IntGetFocusMessageQueue())
{ //ERR("DestroyWindow AOW\n");
{
co_WinPosActivateOtherWindow(Window);
}
}
// Adjust last active.
if ((pwndTemp = Window->spwndOwner))
{
while (pwndTemp->spwndOwner)
pwndTemp = pwndTemp->spwndOwner;
if (pwndTemp->spwndLastActive == Window)
pwndTemp->spwndLastActive = Window->spwndOwner;
}
if (Window->spwndParent && IntIsWindow(Window->head.h))
{
if ((Window->style & (WS_POPUP | WS_CHILD)) == WS_CHILD)
{
if (!IntIsTopLevelWindow(Window))
{
UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE);
}
}
}
if (Window->head.pti->MessageQueue->spwndActive == Window)
Window->head.pti->MessageQueue->spwndActive = NULL;
if (Window->head.pti->MessageQueue->spwndFocus == Window)
@@ -3298,12 +3475,6 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
LONG OldValue;
STYLESTRUCT Style;
if (hWnd == IntGetDesktopWindow())
{
EngSetLastError(STATUS_ACCESS_DENIED);
return( 0);
}
if (!(Window = UserGetWindowObject(hWnd)))
{
return( 0);
@@ -3444,6 +3615,12 @@ NtUserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
TRACE("Enter NtUserSetWindowLong\n");
UserEnterExclusive();
if (hWnd == IntGetDesktopWindow())
{
EngSetLastError(STATUS_ACCESS_DENIED);
RETURN( 0);
}
RETURN( co_UserSetWindowLong(hWnd, Index, NewValue, Ansi));
CLEANUP:
@@ -3471,6 +3648,12 @@ NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
TRACE("Enter NtUserSetWindowWord\n");
UserEnterExclusive();
if (hWnd == IntGetDesktopWindow())
{
EngSetLastError(STATUS_ACCESS_DENIED);
RETURN( 0);
}
if (!(Window = UserGetWindowObject(hWnd)))
{
RETURN( 0);
@@ -3481,7 +3664,7 @@ NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
case GWL_ID:
case GWL_HINSTANCE:
case GWL_HWNDPARENT:
RETURN( (WORD)co_UserSetWindowLong(Window->head.h, Index, (UINT)NewValue, TRUE));
RETURN( (WORD)co_UserSetWindowLong(UserHMGetHandle(Window), Index, (UINT)NewValue, TRUE));
default:
if (Index < 0)
{
@@ -3836,7 +4019,7 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
/* Send shell notifications */
if (!Wnd->spwndOwner && !IntGetParent(Wnd))
{
co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
co_IntShellHookNotify(HSHELL_REDRAW, (WPARAM) hWnd, FALSE); // FIXME Flashing?
}
Ret = TRUE;
@@ -3913,7 +4096,9 @@ CLEANUP:
END_CLEANUP;
}
/*
API Call
*/
BOOL
FASTCALL
IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
@@ -3924,7 +4109,8 @@ IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
// ASSERT(OwnerWnd);
win_array = IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow()));
TRACE("Enter ShowOwnedPopups Show: %s\n", (fShow ? "TRUE" : "FALSE"));
win_array = IntWinListChildren(OwnerWnd);
if (!win_array)
return TRUE;
@@ -3933,7 +4119,7 @@ IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
count++;
while (--count >= 0)
{
if (!(pWnd = UserGetWindowObject( win_array[count] )))
if (!(pWnd = ValidateHwndNoErr( win_array[count] )))
continue;
if (pWnd->spwndOwner != OwnerWnd)
continue;
@@ -3965,6 +4151,7 @@ IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
}
ExFreePool( win_array );
TRACE("Leave ShowOwnedPopups\n");
return TRUE;
}
+3
View File
@@ -49,8 +49,11 @@ LRESULT FASTCALL IntDefWindowProc( PWND Window, UINT Msg, WPARAM wParam, LPARAM
VOID FASTCALL IntNotifyWinEvent(DWORD, PWND, LONG, LONG, DWORD);
PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRING, PVOID);
BOOL FASTCALL IntEnableWindow(HWND,BOOL);
BOOL FASTCALL IntIsWindowVisible(PWND);
DWORD FASTCALL GetNCHitEx(PWND,POINT);
ULONG FASTCALL IntSetStyle(PWND,ULONG,ULONG);
PWND FASTCALL VerifyWnd(PWND);
PWND FASTCALL IntGetNonChildAncestor(PWND);
LONG FASTCALL co_UserSetWindowLong(HWND,DWORD,LONG,BOOL);
/* EOF */
+249 -86
View File
@@ -139,6 +139,121 @@ IntMapWindowPoints(PWND FromWnd, PWND ToWnd, LPPOINT lpPoints, UINT cPoints)
return MAKELONG(LOWORD(Delta.x), LOWORD(Delta.y));
}
BOOL FASTCALL IsChildVisible(PWND pWnd)
{
do
{
if ( (pWnd->style & (WS_POPUP|WS_CHILD)) != WS_CHILD ||
!(pWnd = pWnd->spwndParent) )
return TRUE;
}
while (pWnd->style & WS_VISIBLE);
return FALSE;
}
PWND FASTCALL IntGetLastTopMostWindow(VOID)
{
PWND pWnd;
PDESKTOP rpdesk = gptiCurrent->rpdesk;
if ( rpdesk &&
(pWnd = rpdesk->pDeskInfo->spwnd->spwndChild) &&
pWnd->ExStyle & WS_EX_TOPMOST)
{
for (;;)
{
if (!pWnd->spwndNext) break;
if (!(pWnd->spwndNext->ExStyle & WS_EX_TOPMOST)) break;
pWnd = pWnd->spwndNext;
}
return pWnd;
}
return NULL;
}
//
// This helps with bug 6751 forcing modal dialog active when another app is minimized or closed.
//
BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd)
{
BOOL ActivePrev, FindTopWnd;
PWND pWndTopMost, pWndChild, pWndSetActive, pWndTemp, pWndDesk;
USER_REFERENCE_ENTRY Ref;
PTHREADINFO pti = gptiCurrent;
//ERR("AOWM 1\n");
ActivePrev = (pti->MessageQueue->spwndActivePrev != NULL);
FindTopWnd = TRUE;
if ((pWndTopMost = IntGetLastTopMostWindow()))
pWndChild = pWndTopMost->spwndNext;
else
pWndChild = Wnd->spwndParent->spwndChild;
for (;;)
{
if ( ActivePrev )
pWndSetActive = pti->MessageQueue->spwndActivePrev;
else
pWndSetActive = pWndChild;
pWndTemp = NULL;
while(pWndSetActive)
{
if ( VerifyWnd(pWndSetActive) &&
!(pWndSetActive->ExStyle & WS_EX_NOACTIVATE) &&
(pWndSetActive->style & (WS_VISIBLE|WS_DISABLED)) == WS_VISIBLE &&
(!(pWndSetActive->style & WS_ICONIC) /* FIXME MinMax pos? */ ) )
{
if (!(pWndSetActive->ExStyle & WS_EX_TOOLWINDOW) )
{
UserRefObjectCo(pWndSetActive, &Ref);
co_IntSetForegroundWindow(pWndSetActive);
UserDerefObjectCo(pWndSetActive);
//ERR("AOWM 2 Exit Good\n");
return TRUE;
}
if (!pWndTemp ) pWndTemp = pWndSetActive;
}
if ( ActivePrev )
{
ActivePrev = FALSE;
pWndSetActive = pWndChild;
}
else
pWndSetActive = pWndSetActive->spwndNext;
}
if ( !FindTopWnd ) break;
FindTopWnd = FALSE;
if ( pWndChild )
{
pWndChild = pWndChild->spwndParent->spwndChild;
continue;
}
if (!(pWndDesk = IntGetThreadDesktopWindow(pti)))
{
pWndChild = NULL;
continue;
}
pWndChild = pWndDesk->spwndChild;
}
if ((pWndSetActive = pWndTemp))
{
UserRefObjectCo(pWndSetActive, &Ref);
co_IntSetForegroundWindow(pWndSetActive);
UserDerefObjectCo(pWndSetActive);
//ERR("AOWM 3 Exit Good\n");
return TRUE;
}
//ERR("AOWM 4 Bad\n");
return FALSE;
}
/*******************************************************************
* can_activate_window
*
@@ -203,7 +318,7 @@ done:
if (WndTo) UserRefObjectCo(WndTo, &Ref);
Fg = UserGetForegroundWindow();
if ((!Fg || Wnd->head.h == Fg) && WndTo) // FIXME: Ok if WndTo is NULL??
if ((!Fg || Wnd->head.h == Fg) && WndTo) // FIXME: Ok if WndTo is NULL?? No, rule #4.
{
/* FIXME: Wine can pass WndTo = NULL to co_IntSetForegroundWindow. Hmm... */
if (co_IntSetForegroundWindow(WndTo))
@@ -213,13 +328,15 @@ done:
}
}
if (!co_IntSetActiveWindow(WndTo,&previous,FALSE,TRUE) || /* Ok for WndTo to be NULL here */
if (!co_IntSetActiveWindow(WndTo,&previous,FALSE,TRUE,FALSE) || /* Ok for WndTo to be NULL here */
!previous)
co_IntSetActiveWindow(0,NULL,FALSE,TRUE);
{
co_IntSetActiveWindow(0,NULL,FALSE,TRUE,FALSE);
}
if (WndTo) UserDerefObjectCo(WndTo);
}
UINT
FASTCALL
co_WinPosArrangeIconicWindows(PWND parent)
@@ -250,7 +367,7 @@ co_WinPosArrangeIconicWindows(PWND parent)
{
PWND Child;
if (!(Child = UserGetWindowObject(List[i])))
if (!(Child = ValidateHwndNoErr(List[i])))
continue;
if((Child->style & WS_MINIMIZE) != 0 )
@@ -295,6 +412,7 @@ WinPosFindIconPos(PWND Window, POINT *Pos)
pwndParent = Window->spwndParent;
if (pwndParent == UserGetDesktopWindow())
{
//ERR("Parent is Desktop, Min off screen!\n");
/* ReactOS doesn't support iconic minimize to desktop */
Pos->x = Pos->y = -32000;
Window->InternalPos.flags |= WPF_MININIT;
@@ -413,8 +531,7 @@ WinPosInitInternalPos(PWND Wnd, RECTL *RestoreRect)
Wnd->InternalPos.MaxPos.x,
Rect.left, WorkArea.left,
Wnd->InternalPos.MaxPos.y,
Rect.top, WorkArea.top);
*/
Rect.top, WorkArea.top);*/
}
}
else
@@ -603,6 +720,7 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
{
POINT Size;
WINDOWPLACEMENT wpl;
LONG old_style;
UINT SwpFlags = 0;
ASSERT_REFS_CO(Wnd);
@@ -617,8 +735,14 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
}
if (Wnd->style & WS_MINIMIZE)
{
if (ShowFlag == SW_MINIMIZE) return SWP_NOSIZE | SWP_NOMOVE;
switch (ShowFlag)
{
case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
return SWP_NOSIZE | SWP_NOMOVE;
}
if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0))
{
return(SWP_NOSIZE | SWP_NOMOVE);
@@ -627,24 +751,33 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
}
switch (ShowFlag)
{
case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
{
//ERR("MinMaximize Minimize\n");
if (Wnd->style & WS_MAXIMIZE)
{
Wnd->InternalPos.flags |= WPF_RESTORETOMAXIMIZED;
Wnd->style &= ~WS_MAXIMIZE;
SwpFlags |= SWP_STATECHANGED;
}
else
{
Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
}
old_style = IntSetStyle( Wnd, WS_MINIMIZE, WS_MAXIMIZE );
co_UserRedrawWindow(Wnd, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
RDW_NOINTERNALPAINT);
Wnd->style |= WS_MINIMIZE;
if (!(Wnd->InternalPos.flags & WPF_SETMINPOSITION))
Wnd->InternalPos.flags &= ~WPF_MININIT;
WinPosFindIconPos(Wnd, &wpl.ptMinPosition);
if (!(old_style & WS_MINIMIZE)) SwpFlags |= SWP_STATECHANGED;
/*ERR("Minimize: %d,%d %dx%d\n",
wpl.ptMinPosition.x, wpl.ptMinPosition.y, UserGetSystemMetrics(SM_CXMINIMIZED),
UserGetSystemMetrics(SM_CYMINIMIZED));
@@ -660,33 +793,42 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
case SW_MAXIMIZE:
{
//ERR("MinMaximize Maximize\n");
if ((Wnd->style & WS_MAXIMIZE) && (Wnd->style & WS_VISIBLE))
{
SwpFlags = SWP_NOSIZE | SWP_NOMOVE;
break;
}
co_WinPosGetMinMaxInfo(Wnd, &Size, &wpl.ptMaxPosition, NULL, NULL);
/*ERR("Maximize: %d,%d %dx%d\n",
wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
*/
if (Wnd->style & WS_MINIMIZE)
{
SwpFlags |= SWP_STATECHANGED;
Wnd->style &= ~WS_MINIMIZE;
}
Wnd->style |= WS_MAXIMIZE;
old_style = IntSetStyle( Wnd, WS_MAXIMIZE, WS_MINIMIZE );
if (!(old_style & WS_MAXIMIZE)) SwpFlags |= SWP_STATECHANGED;
RECTL_vSetRect(NewPos, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y,
// wpl.ptMaxPosition.x + Size.x, wpl.ptMaxPosition.y + Size.y);
Size.x, Size.y);
break;
}
case SW_SHOWNOACTIVATE:
Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
/* fall through */
case SW_SHOWNORMAL:
case SW_RESTORE:
case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
{
if (Wnd->style & WS_MINIMIZE)
//ERR("MinMaximize Restore\n");
old_style = IntSetStyle( Wnd, 0, WS_MINIMIZE | WS_MAXIMIZE );
if (old_style & WS_MINIMIZE)
{
Wnd->style &= ~WS_MINIMIZE;
if (Wnd->InternalPos.flags & WPF_RESTORETOMAXIMIZED)
{
co_WinPosGetMinMaxInfo(Wnd, &Size, &wpl.ptMaxPosition, NULL, NULL);
IntSetStyle( Wnd, WS_MAXIMIZE, 0 );
SwpFlags |= SWP_STATECHANGED;
Wnd->style |= WS_MAXIMIZE;
/*ERR("Restore to Max: %d,%d %dx%d\n",
wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
*/
@@ -708,11 +850,10 @@ co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
}
else
{
if (!(Wnd->style & WS_MAXIMIZE))
if (!(old_style & WS_MAXIMIZE))
{
return 0;
break;
}
Wnd->style &= ~WS_MAXIMIZE;
SwpFlags |= SWP_STATECHANGED;
Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
*NewPos = wpl.rcNormalPosition;
@@ -1020,17 +1161,17 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
if ((ClientRect->right - ClientRect->left !=
Window->rcClient.right - Window->rcClient.left) ||
(ClientRect->bottom - ClientRect->top !=
Window->rcClient.bottom - Window->rcClient.top))
(ClientRect->bottom - ClientRect->top !=
Window->rcClient.bottom - Window->rcClient.top))
{
WinPos->flags &= ~SWP_NOCLIENTSIZE;
}
}
else
{
if (! (WinPos->flags & SWP_NOMOVE)
&& (ClientRect->left != Window->rcClient.left ||
ClientRect->top != Window->rcClient.top))
if (!(WinPos->flags & SWP_NOMOVE) &&
(ClientRect->left != Window->rcClient.left ||
ClientRect->top != Window->rcClient.top))
{
WinPos->flags &= ~SWP_NOCLIENTMOVE;
}
@@ -1118,7 +1259,7 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
if (hWndInsertAfter != HWND_TOPMOST)
{
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
if (List != NULL)
@@ -1163,10 +1304,10 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
{
PWND Wnd;
if (List[i] == Window->head.h)
if (List[i] == UserHMGetHandle(Window))
break;
if (!(Wnd = ValidateHwndNoErr(List[i])))
if (!(Wnd = ValidateHwndNoErr(List[i])))
continue;
if (Wnd->style & WS_POPUP && Wnd->spwndOwner == Window)
@@ -1288,7 +1429,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
if (WinPos->hwndInsertAfter == HWND_NOTOPMOST)
{
if (!(Wnd->ExStyle & WS_EX_TOPMOST))
WinPos->flags |= SWP_NOZORDER;
WinPos->flags |= SWP_NOZORDER;
WinPos->hwndInsertAfter = HWND_TOP;
}
@@ -1307,7 +1448,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
{
PWND InsAfterWnd;
InsAfterWnd = ValidateHwndNoErr(WinPos->hwndInsertAfter);
InsAfterWnd = ValidateHwndNoErr(WinPos->hwndInsertAfter);
if(!InsAfterWnd)
{
return TRUE;
@@ -1375,16 +1516,6 @@ co_WinPosSetWindowPos(
ASSERT_REFS_CO(Window);
/* FIXME: Get current active window from active queue. */
/*
* Only allow CSRSS to mess with the desktop window
*/
if ( Window->head.h == IntGetDesktopWindow() &&
Window->head.pti->ppi != PsGetCurrentProcessWin32Process())
{
ERR("Desktop Window...\n");
return FALSE;
}
bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
@@ -1559,7 +1690,7 @@ co_WinPosSetWindowPos(
RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN);
if (Window->spwndParent == UserGetDesktopWindow())
co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM)Window->head.h);
co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM)Window->head.h, 0);
Window->style &= ~WS_VISIBLE; //IntSetStyle( Window, 0, WS_VISIBLE );
IntNotifyWinEvent(EVENT_OBJECT_HIDE, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
@@ -1567,7 +1698,7 @@ co_WinPosSetWindowPos(
else if (WinPos.flags & SWP_SHOWWINDOW)
{
if (Window->spwndParent == UserGetDesktopWindow())
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Window->head.h);
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0);
Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 );
IntNotifyWinEvent(EVENT_OBJECT_SHOW, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
@@ -1795,7 +1926,7 @@ co_WinPosSetWindowPos(
}
else
{
TRACE("SetWindowPos Set FG Window!\n");
//ERR("SetWindowPos Set FG Window!\n");
co_IntSetForegroundWindow(Window);
}
}
@@ -1891,15 +2022,18 @@ BOOLEAN FASTCALL
co_WinPosShowWindow(PWND Wnd, INT Cmd)
{
BOOLEAN WasVisible;
UINT Swp = 0;
UINT Swp = 0, EventMsg = 0;
RECTL NewPos;
BOOLEAN ShowFlag;
LONG style;
PWND Parent;
PTHREADINFO pti;
BOOL ShowOwned = FALSE;
// HRGN VisibleRgn;
ASSERT_REFS_CO(Wnd);
pti = PsGetCurrentThreadWin32Thread();
WasVisible = (Wnd->style & WS_VISIBLE) != 0;
style = Wnd->style;
@@ -1912,11 +2046,12 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
return(FALSE);
}
Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (Wnd->head.h != UserGetActiveWindow())
if (Wnd != pti->MessageQueue->spwndActive)
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
}
case SW_FORCEMINIMIZE: /* FIXME: Does not work if thread is hung. */
case SW_SHOWMINNOACTIVE:
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
@@ -1928,6 +2063,8 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Swp |= SWP_NOACTIVATE;
if (!(style & WS_MINIMIZE))
{
//IntShowOwnedPopups(Wnd, FALSE );
// Fix wine Win test_SetFocus todo #1 & #2,
if (Cmd == SW_SHOWMINIMIZED)
{
@@ -1937,16 +2074,20 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
co_UserSetFocus(0);
}
Swp |= co_WinPosMinMaximize(Wnd, SW_MINIMIZE, &NewPos) |
Swp |= co_WinPosMinMaximize(Wnd, Cmd, &NewPos) |
SWP_FRAMECHANGED;
EventMsg = EVENT_SYSTEM_MINIMIZESTART;
}
else
{
Swp |= SWP_NOSIZE | SWP_NOMOVE;
if (! WasVisible)
if (!WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
else ////
return TRUE;
Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
break;
}
@@ -1956,68 +2097,87 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Swp |= SWP_SHOWWINDOW;
if (!(style & WS_MAXIMIZE))
{
ShowOwned = TRUE;
Swp |= co_WinPosMinMaximize(Wnd, SW_MAXIMIZE, &NewPos) |
SWP_FRAMECHANGED;
EventMsg = EVENT_SYSTEM_MINIMIZEEND;
}
else
{
Swp |= SWP_NOSIZE | SWP_NOMOVE;
if (! WasVisible)
if (!WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
else ////
return TRUE;
Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
break;
}
case SW_SHOWNA:
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
Swp |= SWP_NOACTIVATE | SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (style & WS_CHILD && !(Wnd->ExStyle & WS_EX_MDICHILD)) Swp |= SWP_NOZORDER;
break;
case SW_SHOW:
if (WasVisible) return(TRUE); // Nothing to do!
if (WasVisible) return(TRUE); // Nothing to do!
Swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
/* Don't activate the topmost window. */
if (style & WS_CHILD) Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
if (style & WS_CHILD && !(Wnd->ExStyle & WS_EX_MDICHILD)) Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
case SW_SHOWNOACTIVATE:
Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
//Swp |= SWP_NOZORDER;
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
case SW_SHOWNORMAL:
case SW_SHOWDEFAULT:
case SW_RESTORE:
Swp |= SWP_SHOWWINDOW;
if (!WasVisible) Swp |= SWP_SHOWWINDOW;
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
Swp |= co_WinPosMinMaximize(Wnd, SW_RESTORE, &NewPos) |
Swp |= co_WinPosMinMaximize(Wnd, Cmd, &NewPos) |
SWP_FRAMECHANGED;
if (style & WS_MINIMIZE) EventMsg = EVENT_SYSTEM_MINIMIZEEND;
}
else
{
Swp |= SWP_NOSIZE | SWP_NOMOVE;
if (! WasVisible)
if (!WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
else ////
return TRUE;
Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
if ( style & WS_CHILD &&
!(Wnd->ExStyle & WS_EX_MDICHILD) &&
!(Swp & SWP_STATECHANGED))
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
default:
return WasVisible;
}
ShowFlag = (Cmd != SW_HIDE);
if (ShowFlag != WasVisible)
if ((ShowFlag != WasVisible || Cmd == SW_SHOWNA) && Cmd != SW_SHOWMAXIMIZED && !(Swp & SWP_STATECHANGED))
{
co_IntSendMessageNoWait(Wnd->head.h, WM_SHOWWINDOW, ShowFlag, 0);
if (!(Wnd->state2 & WNDS2_WIN31COMPAT))
co_IntSendMessageNoWait(Wnd->head.h, WM_SETVISIBLE, ShowFlag, 0);
if (!VerifyWnd(Wnd)) return WasVisible;
}
/* We can't activate a child window */
if ((Wnd->style & WS_CHILD) &&
!(Wnd->ExStyle & WS_EX_MDICHILD))
!(Wnd->ExStyle & WS_EX_MDICHILD) &&
Cmd != SW_SHOWNA)
{
//ERR("SWP Child No active and ZOrder\n");
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
}
@@ -2026,11 +2186,16 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Wnd->pcls->style & CS_SAVEBITS &&
((Cmd == SW_SHOW) || (Cmd == SW_NORMAL)))
{
co_IntSetActiveWindow(Wnd,NULL,FALSE,TRUE);
co_IntSetActiveWindow(Wnd,NULL,FALSE,TRUE,FALSE);
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
}
#endif
if (IsChildVisible(Wnd) || Swp & SWP_STATECHANGED)
{
TRACE("Child is Vis %s or State changed %s. ShowFlag %s\n",
(IsChildVisible(Wnd) ? "TRUE" : "FALSE"), (Swp & SWP_STATECHANGED ? "TRUE" : "FALSE"),
(ShowFlag ? "TRUE" : "FALSE"));
co_WinPosSetWindowPos( Wnd,
0 != (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOPMOST : HWND_TOP,
NewPos.left,
@@ -2038,13 +2203,24 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
NewPos.right, //NewPos.right - NewPos.left,
NewPos.bottom, //NewPos.bottom - NewPos.top,
LOWORD(Swp));
}
else
{
TRACE("Parent Vis?\n");
/* if parent is not visible simply toggle WS_VISIBLE and return */
if (ShowFlag) IntSetStyle( Wnd, WS_VISIBLE, 0 );
else IntSetStyle( Wnd, 0, WS_VISIBLE );
}
if ( EventMsg ) IntNotifyWinEvent(EventMsg, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
//if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE );
if ((Cmd == SW_HIDE) || (Cmd == SW_MINIMIZE))
{
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
// and Rule #1.
if (Wnd == pti->MessageQueue->spwndActive && pti->MessageQueue == IntGetFocusMessageQueue())
if ( ( Wnd->spwndParent == UserGetDesktopWindow() && !ActivateOtherWindowMin(Wnd) ) ||
// and Rule #1.
( Wnd == pti->MessageQueue->spwndActive && pti->MessageQueue == IntGetFocusMessageQueue() ) )
{
co_WinPosActivateOtherWindow(Wnd);
}
@@ -2649,8 +2825,6 @@ NtUserMinMaximize(
UINT cmd, // Wine SW_ commands
BOOL Hide)
{
RECTL NewPos;
UINT SwFlags;
PWND pWnd;
TRACE("Enter NtUserMinMaximize\n");
@@ -2670,17 +2844,7 @@ NtUserMinMaximize(
goto Exit;
}
SwFlags = co_WinPosMinMaximize(pWnd, cmd, &NewPos);
SwFlags |= Hide ? SWP_NOACTIVATE : 0;
co_WinPosSetWindowPos( pWnd,
NULL,
NewPos.left,
NewPos.top,
NewPos.right, //NewPos.right - NewPos.left,
NewPos.bottom, //NewPos.bottom - NewPos.top,
SwFlags);
cmd |= Hide ? SW_HIDE : 0;
co_WinPosShowWindow(pWnd, cmd);
@@ -2749,8 +2913,7 @@ NtUserSetWindowPos(
UserEnterExclusive();
if (!(Window = UserGetWindowObject(hWnd)) || // FIXME:
// Due to desktopbg.c
// Window == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
Window == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
Window == UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
{
ERR("NtUserSetWindowPos bad window handle!\n");
@@ -146,8 +146,8 @@ BOOL WINAPI RegisterClientPFN(VOID)
pfnClientW.pfnTitleWndProc = IconTitleWndProc;
pfnClientA.pfnMenuWndProc = PopupMenuWndProcA;
pfnClientW.pfnMenuWndProc = PopupMenuWndProcW;
pfnClientA.pfnDesktopWndProc = DesktopWndProc;
pfnClientW.pfnDesktopWndProc = DesktopWndProc;
pfnClientA.pfnDesktopWndProc = DesktopWndProcA;
pfnClientW.pfnDesktopWndProc = DesktopWndProcW;
pfnClientA.pfnDefWindowProc = DefWindowProcA;
pfnClientW.pfnDefWindowProc = DefWindowProcW;
pfnClientA.pfnMessageWindowProc = MsgWindowProc;
@@ -90,7 +90,8 @@ extern BOOL COMBO_FlipListbox( LPHEADCOMBO, BOOL, BOOL );
HRGN set_control_clipping( HDC hdc, const RECT *rect );
LRESULT WINAPI DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
LRESULT WINAPI DesktopWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
LRESULT WINAPI DesktopWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );
LRESULT WINAPI User32DefWindowProc(HWND,UINT,WPARAM,LPARAM,BOOL);
BOOL WINAPI RegisterClientPFN(VOID);
LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
+52 -4
View File
@@ -29,13 +29,61 @@ const struct builtin_class_descr DESKTOP_builtin_class =
(HBRUSH)(COLOR_BACKGROUND+1) /* brush */
};
#endif
LRESULT
WINAPI
DesktopWndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
DesktopWndProcW(HWND Wnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
TRACE("Desktop Class Atom! hWnd 0x%x, Msg %d\n", hwnd, message);
if (message == WM_NCCREATE) return TRUE;
return 0; /* all other messages are ignored */
PAINTSTRUCT PS;
TRACE("Desktop W Class Atom! hWnd 0x%x, Msg %d\n", Wnd, Msg);
switch(Msg)
{
case WM_NCCREATE:
case WM_CREATE:
case WM_CLOSE:
case WM_DISPLAYCHANGE:
{
LRESULT lResult;
NtUserMessageCall( Wnd, Msg, wParam, lParam, (ULONG_PTR)&lResult, FNID_DESKTOP, FALSE);
return lResult;
}
case WM_ERASEBKGND:
PaintDesktop((HDC)wParam);
return 1;
case WM_PAINT:
if (BeginPaint(Wnd, &PS))
{
EndPaint(Wnd, &PS);
}
return 0;
case WM_SYSCOLORCHANGE:
RedrawWindow(Wnd, NULL, NULL, RDW_INVALIDATE|RDW_ERASE|RDW_ALLCHILDREN);
break;
case WM_PALETTECHANGED:
if (Wnd == (HWND)wParam) break;
case WM_QUERYNEWPALETTE:
{
HDC hdc = GetWindowDC( Wnd );
PaintDesktop(hdc);
ReleaseDC( Wnd, hdc );
break;
}
case WM_SETCURSOR:
return (LRESULT)SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW));
default:
return DefWindowProcW(Wnd, Msg, wParam, lParam);
}
return 0;
}
VOID
@@ -1158,7 +1158,33 @@ map_wparam_AtoW( UINT message, WPARAM wparam )
return wparam;
}
+LRESULT
+WINAPI
DesktopWndProcA( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
LRESULT Result;
MSG AnsiMsg, UcMsg;
TRACE("Desktop A Class Atom! hWnd 0x%x, Msg %d\n", hwnd, message);
AnsiMsg.hwnd = hwnd;
AnsiMsg.message = message;
AnsiMsg.wParam = wParam;
AnsiMsg.lParam = lParam;
// Desktop is always Unicode so convert Ansi here.
if (!MsgiAnsiToUnicodeMessage(hwnd, &UcMsg, &AnsiMsg))
{
return FALSE;
}
Result = DesktopWndProcW(hwnd, message, UcMsg.wParam, UcMsg.lParam);
MsgiAnsiToUnicodeCleanup(&UcMsg, &AnsiMsg);
return Result;
}
/*
* @implemented
*/
+44 -11
View File
@@ -1,10 +1,27 @@
/* $Id$
*
* reactos/subsys/csrss/win32csr/desktopbg.c
/*
* win32ss/user/win32csr/desktopbg.c
*
* Desktop background window functions
*
* ReactOS Operating System
*
* Looks as a hax fix to a problem of not having a proper class window proc support
* which ReactOS has now.
*
* Notes on reason why this is here:
* http://www.reactos.org/archives/public/ros-kernel/2003-November/000538.html
* http://www.reactos.org/archives/public/ros-kernel/2003-November/000545.html
* http://www.reactos.org/archives/public/ros-kernel/2003-November/000586.html
* http://www.reactos.org/archives/public/ros-kernel/2003-November/000674.html
* Revision 6908 Move desktop window proc from WIN32K to CSRSS
* Bugs 42, 48 and 57.
*
* http://www.reactos.org/archives/public/ros-kernel/2003-December/001186.html
*
Now this is used to start Desktops Threads with TEB support.
These first three are Application, Winlogon and ScreenSaver desktops.
*/
#define NDEBUG
@@ -36,7 +53,7 @@ typedef struct tagPRIVATE_NOTIFY_DESKTOP
static BOOL BgInitialized = FALSE;
static HWND VisibleDesktopWindow = NULL;
#if 0
static
LRESULT
CALLBACK
@@ -160,7 +177,7 @@ DtbgInit(VOID)
return TRUE;
}
#endif
static
DWORD
WINAPI
@@ -170,6 +187,8 @@ DtbgDesktopThread(PVOID Data)
MSG msg;
PDTBG_THREAD_DATA ThreadData = (PDTBG_THREAD_DATA)Data;
DPRINT("DtbgDesktopThread\n");
if (!SetThreadDesktop(ThreadData->Desktop))
{
DPRINT1("Failed to set thread desktop\n");
@@ -181,9 +200,12 @@ DtbgDesktopThread(PVOID Data)
BackgroundWnd = CreateWindowW((LPCWSTR)DESKTOP_WINDOW_ATOM,
L"",
WS_POPUP | WS_CLIPCHILDREN,
0, 0, 0, 0,
GetSystemMetrics(SM_XVIRTUALSCREEN),
GetSystemMetrics(SM_YVIRTUALSCREEN),
GetSystemMetrics(SM_CXVIRTUALSCREEN),
GetSystemMetrics(SM_CYVIRTUALSCREEN),
NULL, NULL,
(HINSTANCE)GetModuleHandleW(NULL),
(HINSTANCE)GetModuleHandleW(L"user32.dll"), // Run in win32k/user32.
NULL);
if (NULL == BackgroundWnd)
@@ -194,15 +216,22 @@ DtbgDesktopThread(PVOID Data)
return 1;
}
DPRINT("BackgroundWnd 0x%p\n",BackgroundWnd);
ThreadData->Status = STATUS_SUCCESS;
SetEvent(ThreadData->Event);
while (GetMessageW(&msg, NULL, 0, 0))
{
if (msg.message == WM_QUIT)
{
DPRINT1("DtbgDesktopThread WM_QUIT\n");
}
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
DPRINT1("DtbgDesktopThread Exit\n");
return 1;
}
@@ -217,8 +246,8 @@ CSR_API(CsrCreateDesktop)
{
BgInitialized = TRUE;
if (!DtbgInit())
return STATUS_UNSUCCESSFUL;
// if (!DtbgInit())
// return STATUS_UNSUCCESSFUL;
}
/*
@@ -259,6 +288,7 @@ CSR_API(CsrCreateDesktop)
CSR_API(CsrShowDesktop)
{
#if 0
PRIVATE_NOTIFY_DESKTOP nmh;
DPRINT("CsrShowDesktop\n");
@@ -276,12 +306,13 @@ CSR_API(CsrShowDesktop)
{
return STATUS_UNSUCCESSFUL;
}
#endif
return STATUS_SUCCESS;
}
CSR_API(CsrHideDesktop)
{
#if 0
PRIVATE_NOTIFY_DESKTOP nmh;
DPRINT("CsrHideDesktop\n");
@@ -296,7 +327,7 @@ CSR_API(CsrHideDesktop)
{
return STATUS_UNSUCCESSFUL;
}
#endif
return STATUS_SUCCESS;
}
@@ -304,6 +335,8 @@ BOOL
FASTCALL
DtbgIsDesktopVisible(VOID)
{
VisibleDesktopWindow = GetDesktopWindow(); // DESKTOPWNDPROC
if (VisibleDesktopWindow != NULL &&
!IsWindowVisible(VisibleDesktopWindow))
{