- The (ATI) patch CORE-6551. Please oh please use this jira core issue for all bug reports and regressions.
- Major rewrite to input message queue. It is now attachable between threads. After all the hubbub the only thing we pass are all the SetActive/Foreground/Parent/Window wine msg and win tests. But not the message sequence tests.
- Pass all but one foreground API User32 ATI test when the message patch is installed. But w/o it, pass all but 8'ish.
- Tested XP osk (On-Screen Keyboard) with CMD, it works but is quirky. Need to look into set to top window issues.
- AHK issues work long as ATI is used and when it is not the some AHK tests fail. That was why all the hot key changes had been committed before. Still looking into this.
- Please test everything and post to the appropriate jira issue reports. I do not have a lot of time anymore to focus hard on many issues, it will take months to do so with just one.

svn path=/trunk/; revision=60718
This commit is contained in:
James Tabor 2013-10-20 05:16:52 +00:00
parent ccfd05479b
commit d700b033fc
16 changed files with 769 additions and 342 deletions

View file

@ -28,7 +28,7 @@ IntFreeDesktopHeap(IN PDESKTOP pdesk);
/* Currently active desktop */
PDESKTOP gpdeskInputDesktop = NULL;
HDC ScreenDeviceContext = NULL;
PTHREADINFO gptiDesktopThread;
PTHREADINFO gptiDesktopThread = NULL;
HCURSOR gDesktopCursor = NULL;
/* OBJECT CALLBACKS **********************************************************/
@ -834,6 +834,9 @@ VOID co_IntShellHookNotify(WPARAM Message, WPARAM wParam, LPARAM lParam)
return;
}
// Allow other devices have a shot at foreground.
if (Message == HSHELL_APPCOMMAND) ptiLastInput = NULL;
// FIXME: System Tray Support.
HwndList = UserBuildShellHookHwndList(Desktop);

View file

@ -69,9 +69,10 @@ typedef struct _DESKTOP
DESKTOP_SWITCHDESKTOP | \
DESKTOP_WRITEOBJECTS
extern PDESKTOP InputDesktop;
extern PDESKTOP gpdeskInputDesktop;
extern PCLS DesktopWindowClass;
extern HDC ScreenDeviceContext;
extern PTHREADINFO gptiForeground;
extern PTHREADINFO gptiDesktopThread;
typedef struct _SHELL_HOOK_WINDOW

View file

@ -80,7 +80,7 @@ BOOL FASTCALL
co_IntMakeWindowActive(PWND Window)
{
PWND spwndOwner;
if (Window)
if (VerifyWnd(Window))
{ // Set last active for window and it's owner.
spwndOwner = Window;
while (spwndOwner->spwndOwner)
@ -132,6 +132,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
{
UINT flags = SWP_NOSIZE | SWP_NOMOVE;
if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
//ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground);
co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags);
}
}
@ -156,8 +157,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
if ( OldTID )
{
ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags;
// Note: Do not set pci flags, this does crash!
for (phWnd = List; *phWnd; ++phWnd)
{
cWindow = ValidateHwndNoErr(*phWnd);
@ -168,13 +168,11 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
}
}
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)
{
@ -186,7 +184,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
}
}
}
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
ExFreePool(List);//ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
}
if (WindowPrev)
@ -205,12 +203,11 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
co_IntMakeWindowActive(Window);
UserDerefObjectCo(Window);
/* FIXME: IntIsWindow */
co_IntSendMessageNoWait( UserHMGetHandle(Window),
WM_NCACTIVATE,
(WPARAM)(gpqForeground ? (Window == gpqForeground->spwndActive) : FALSE),
(WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)),
0); //(LPARAM)hWndPrev);
co_IntSendMessageNoWait( UserHMGetHandle(Window),
@ -226,6 +223,7 @@ co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOO
Window->state &= ~WNDS_NONCPAINT;
UserDerefObjectCo(Window);
}
return InAAPM;
}
@ -294,7 +292,7 @@ IntFindChildWindowToOwner(PWND Root, PWND Owner)
}
VOID FASTCALL
FindRemoveAsyncMsg(PWND Wnd)
FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam)
{
PTHREADINFO pti;
PUSER_SENT_MESSAGE Message;
@ -311,20 +309,60 @@ FindRemoveAsyncMsg(PWND Wnd)
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
do
{
if (IsListEmpty(Entry)) return;
if (!Message) return;
Entry = Message->ListEntry.Flink;
if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
Message->Msg.wParam == 0 )
Message->Msg.wParam == wParam )
{
TRACE("ASYNC SAW: Found one in the Sent Msg Queue! %p\n", Message->Msg.hwnd);
RemoveEntryList(Entry); // Purge the entry.
ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd,!!wParam);
RemoveEntryList(&Message->ListEntry); // Purge the entry.
ExFreePoolWithTag(Message, TAG_USRMSG);
}
Entry = Message->ListEntry.Flink;
Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
}
while (Entry != &pti->SentMessagesListHead);
}
}
BOOL FASTCALL
ToggleFGActivate(PTHREADINFO pti)
{
BOOL Ret;
PPROCESSINFO ppi = pti->ppi;
Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE);
if (Ret)
{
pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
}
else
Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE);
if (Ret)
ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
//ERR("ToggleFGActivate is %d\n",Ret);
return Ret;
}
BOOL FASTCALL
IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
{
// Not allowed if one or more,,
if (!ToggleFGActivate(pti) || // bits not set,
pti->rpdesk != gpdeskInputDesktop || // not current Desktop,
pti->MessageQueue == gpqForeground || // if already the queue foreground,
IsFGLocked() || // foreground is locked,
Wnd->ExStyle & WS_EX_NOACTIVATE ) // or,,, does not become the foreground window when the user clicks it.
{
return FALSE;
}
//ERR("IsAllowedFGActive is TRUE\n");
return TRUE;
}
/*
Can the system force foreground from one or more conditions.
*/
@ -339,6 +377,7 @@ CanForceFG(PPROCESSINFO ppi)
gppiInputProvider == ppi ||
!gpqForeground
) return TRUE;
//ERR("CanForceFG is FALSE\n");
return FALSE;
}
@ -356,37 +395,35 @@ CanForceFG(PPROCESSINFO ppi)
* The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
* No menus are active.
*/
static BOOL FASTCALL
static
BOOL FASTCALL
co_IntSetForegroundAndFocusWindow(
_In_ PWND Wnd,
_In_ BOOL MouseActivate)
{
HWND hWnd;
HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
HWND hWndPrev = NULL;
PWND pWndPrev = NULL;
PUSER_MESSAGE_QUEUE PrevForegroundQueue;
PTHREADINFO pti;
BOOL fgRet = FALSE, Ret = FALSE;
ASSERT_REFS_CO(Wnd);
NT_ASSERT(Wnd != NULL);
if (Wnd) ASSERT_REFS_CO(Wnd);
hWnd = UserHMGetHandle(Wnd);
TRACE("SetForegroundAndFocusWindow(%p, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
//ERR("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)
{
//ERR("Same Window Q as foreground just do active.\n");
if (pti->MessageQueue == PrevForegroundQueue)
{ // Same WQ and TQ go active.
//ERR("Same WQ and TQ go active.\n");
Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE);
Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
}
else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
{ // Same WQ and it is active.
@ -396,13 +433,14 @@ co_IntSetForegroundAndFocusWindow(
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 );
co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
Ret = TRUE;
}
return Ret;
}
hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0;
pWndPrev = PrevForegroundQueue->spwndActive;
}
if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
@ -410,16 +448,29 @@ co_IntSetForegroundAndFocusWindow(
pti->ppi == ppiScrnSaver
)
{
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);
//ToggleFGActivate(pti); // win.c line 2662 fail
if (Wnd)
{
IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
gptiForeground = Wnd->head.pti;
//ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h);
}
else
{
IntSetFocusMessageQueue(NULL);
gptiForeground = NULL;
//ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n");
}
/*
Henri Verbeet,
What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the
other thread after we already changed the foreground window back to our own
window.
*/
FindRemoveAsyncMsg(Wnd); // Do this to fix test_SFW todos!
//ERR("SFAFW: 1\n");
FindRemoveAsyncMsg(Wnd, 0); // Do this to fix test_SFW todos!
fgRet = TRUE;
}
@ -428,34 +479,41 @@ co_IntSetForegroundAndFocusWindow(
{
if (PrevForegroundQueue &&
fgRet &&
Wnd->head.pti->MessageQueue != PrevForegroundQueue &&
PrevForegroundQueue->spwndActive)
{
//ERR("SFGW: Send NULL to 0x%x\n",hWndPrev);
if (pti->MessageQueue == PrevForegroundQueue)
{
//ERR("SFGW: TI same as Prev TI\n");
co_IntSetActiveWindow(NULL, NULL, FALSE, TRUE, FALSE);
co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE);
}
else if (pWndPrev)
{
//ERR("SFGW Deactivate: TI not same as Prev TI\n");
// No real reason to wait here.
co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
}
else
co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
}
}
if (!Wnd) return FALSE; // Always return false.
if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
{
Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE);
//ERR("Same PQ and WQ go active.\n");
Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
}
else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
{
//ERR("Same Active and Wnd.\n");
Ret = TRUE;
}
else
{
//ERR("Activate Not same PQ and WQ and Wnd.\n");
co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
Ret = TRUE;
}
return Ret && fgRet;
}
@ -500,7 +558,7 @@ co_IntMouseActivateWindow(PWND Wnd)
}
BOOL FASTCALL
co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, BOOL Async)
co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async)
{
PTHREADINFO pti;
PUSER_MESSAGE_QUEUE ThreadQueue;
@ -509,38 +567,83 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus,
HWND hWnd = 0;
BOOL InAAPM;
CBTACTIVATESTRUCT cbt;
//ERR("co_IntSetActiveWindow 1\n");
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;
//ERR("co_IntSetActiveWindow 1a hWnd 0x%p\n",hWnd);
}
//ERR("co_IntSetActiveWindow 2\n");
pti = PsGetCurrentThreadWin32Thread();
ThreadQueue = pti->MessageQueue;
ASSERT(ThreadQueue != 0);
hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;
if (Prev) *Prev = hWndPrev;
if (hWndPrev == hWnd) return TRUE;
pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
if (Wnd)
while (Wnd)
{
if (ThreadQueue != Wnd->head.pti->MessageQueue)
{
PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
// Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
if (!ForegroundQueue || ForegroundQueue == ThreadQueue)
{
return co_IntSetForegroundAndFocusWindow(Wnd, bMouse);
}
}
BOOL Ret, DoFG, AllowFG;
if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE;
if (ThreadQueue == Wnd->head.pti->MessageQueue)
{
if (IsAllowedFGActive(pti, Wnd))
{
DoFG = TRUE;
}
else
{
//ERR("co_IntSetActiveWindow 3 Go Out!\n");
break;
}
AllowFG = !pti->cVisWindows; // Nothing is visable.
//ERR("co_IntSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
}
else //if (ThreadQueue != Wnd->head.pti->MessageQueue)
{
//PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
// Rule 1 & 4, We are foreground so set this FG window or NULL foreground....
//if (!ForegroundQueue || ForegroundQueue == ThreadQueue)
if (!gpqForeground || gpqForeground == ThreadQueue)
{
DoFG = TRUE;
}
else
DoFG = FALSE;
if (DoFG)
{
if (pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE || pti->cVisWindows)
AllowFG = TRUE;
else
AllowFG = FALSE;
}
else
AllowFG = FALSE;
//ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
}
Ret = FALSE;
if (DoFG)
{
pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
//ERR("co_IntSetActiveWindow 3c FG set\n");
Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse);
if (AllowFG)
{
pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
}
else
{
pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
}
}
return Ret;
}
/* Call CBT hook chain */
@ -562,14 +665,16 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus,
if (WndPrev)
{
if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
if (!co_IntSendDeactivateMessages(hWndPrev, hWnd)) return FALSE;
if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd)) return FALSE;
}
WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active.
// 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 ||
pWndChg != WndPrev ||
(Wnd && !VerifyWnd(Wnd)) ||
ThreadQueue != pti->MessageQueue )
{
@ -582,6 +687,8 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus,
if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED;
IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
//// Breaks Atl-Esc/Tab via User32.
////FindRemoveAsyncMsg(Wnd,(WPARAM)Wnd); // Clear out activate ASYNC messages.
/* check if the specified window can be set in the input data of a given queue */
if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue)
@ -590,6 +697,8 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus,
ThreadQueue->spwndActive = Wnd;
}
WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
/* now change focus if necessary */
@ -610,16 +719,40 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus,
if (InAAPM)
{
pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
pti->pClientInfo->dwTIFlags = pti->TIF_flags;
}
// FIXME: Used in the menu loop!!!
//ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
//ERR("co_IntSetActiveWindow Exit\n");
if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED;
return (ThreadQueue->spwndActive == Wnd);
}
BOOL FASTCALL
UserSetActiveWindow(PWND Wnd)
{
if (Wnd) // Must have a window!
{
if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
}
/*
Yes your eye are not deceiving you~!
First part of wines Win.c test_SetActiveWindow:
flush_events( TRUE );
ShowWindow(hwnd, SW_HIDE);
SetFocus(0);
SetActiveWindow(0);
check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
*/
return FALSE;
}
HWND FASTCALL
co_UserSetFocus(PWND Window)
{
@ -653,17 +786,10 @@ co_UserSetFocus(PWND Window)
}
/* Check if we can set the focus to this window */
pwndTop = Window;
for (;;)
for (pwndTop = Window; pwndTop != NULL; pwndTop = pwndTop->spwndParent)
{
if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
if (!pwndTop->spwndParent || pwndTop->spwndParent == UserGetDesktopWindow())
{
if ((pwndTop->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return 0;
break;
}
if (pwndTop->spwndParent == UserGetMessageWindow()) return 0;
pwndTop = pwndTop->spwndParent;
if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
}
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
@ -676,8 +802,13 @@ co_UserSetFocus(PWND Window)
if (pwndTop != ThreadQueue->spwndActive)
{
PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
if (ThreadQueue != ForegroundQueue) // HACK see rule 2 & 3.
if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3.
{
//ERR("SetFocus: Set Foreground!\n");
if (!(pwndTop->style & WS_VISIBLE))
{
pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
}
if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE))
{
ERR("SetFocus: Set Foreground and Focus Failed!\n");
@ -688,7 +819,8 @@ co_UserSetFocus(PWND Window)
/* Set Active when it is needed. */
if (pwndTop != ThreadQueue->spwndActive)
{
if (!co_IntSetActiveWindow(pwndTop, NULL, FALSE, FALSE, FALSE))
//ERR("SetFocus: Set Active!\n");
if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
{
ERR("SetFocus: Set Active Failed!\n");
return 0;
@ -714,8 +846,6 @@ co_UserSetFocus(PWND Window)
}
else /* NULL hwnd passed in */
{
// if (!hWndPrev) return 0; /* nothing to do */
if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
{
ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
@ -857,7 +987,7 @@ IntReleaseCapture(VOID)
BOOL FASTCALL
co_IntSetForegroundWindow(PWND Window)
{
ASSERT_REFS_CO(Window);
if (Window) ASSERT_REFS_CO(Window);
return co_IntSetForegroundAndFocusWindow(Window, FALSE);
}
@ -937,12 +1067,13 @@ IntAllowSetForegroundWindow(DWORD dwProcessId)
}
if (dwProcessId == ASFW_ANY)
{ // All processes will be enabled to set the foreground window.
//ERR("ptiLastInput is CLEARED!!\n");
ptiLastInput = NULL;
}
else
{ // Rule #3, last input event in force.
ERR("Fixme: ptiLastInput is SET!!\n");
//ptiLastInput = ppi->ptiList;
ERR("ptiLastInput is SET!!\n");
//ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030.
ObDereferenceObject(Process);
}
return TRUE;
@ -962,7 +1093,7 @@ NtUserGetForegroundWindow(VOID)
RETURN( UserGetForegroundWindow());
CLEANUP:
TRACE("Leave NtUserGetForegroundWindow, ret=%p\n", _ret_);
TRACE("Leave NtUserGetForegroundWindow, ret=%p\n",_ret_);
UserLeave();
END_CLEANUP;
}
@ -993,7 +1124,7 @@ NtUserSetActiveWindow(HWND hWnd)
{
hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL;
if (Window) UserRefObjectCo(Window, &Ref);
co_IntSetActiveWindow(Window, NULL, FALSE, TRUE, FALSE);
UserSetActiveWindow(Window);
if (Window) UserDerefObjectCo(Window);
RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
}

View file

@ -2,6 +2,7 @@
extern PUSER_MESSAGE_QUEUE gpqForeground;
extern PUSER_MESSAGE_QUEUE gpqForegroundPrev;
extern PTHREADINFO ptiLastInput;
/*
* These functions take the window handles from current message queue.
@ -18,7 +19,8 @@ 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,HWND *,BOOL,BOOL,BOOL);
BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window);
BOOL FASTCALL co_IntSetActiveWindow(PWND,BOOL,BOOL,BOOL);
BOOL FASTCALL UserSetActiveWindow(PWND Wnd);
BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode);
BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId);

View file

@ -402,24 +402,47 @@ NtUserBlockInput(
return ret;
}
PTHREADINFO FASTCALL
IsThreadAttach(PTHREADINFO ptiTo)
BOOL
FASTCALL
IsRemoveAttachThread(PTHREADINFO pti)
{
NTSTATUS Status;
PATTACHINFO pai;
BOOL Ret = TRUE;
PTHREADINFO ptiFrom = NULL, ptiTo = NULL;
if (!gpai) return NULL;
pai = gpai;
do
{
if (pai->pti2 == ptiTo) break;
pai = pai->paiNext;
} while (pai);
if (!gpai) return TRUE;
pai = gpai; // Bottom of the list.
if (!pai) return NULL;
do
{
if (pai->pti2 == pti)
{
ptiFrom = pai->pti1;
ptiTo = pti;
break;
}
if (pai->pti1 == pti)
{
ptiFrom = pti;
ptiTo = pai->pti2;
break;
}
pai = pai->paiNext;
} while (pai);
// Return ptiFrom.
return pai->pti1;
if (!pai && !ptiFrom && !ptiTo) break;
Status = UserAttachThreadInput(ptiFrom, ptiTo, FALSE);
if (!NT_SUCCESS(Status)) Ret = FALSE;
} while (Ret);
return Ret;
}
NTSTATUS FASTCALL
@ -454,44 +477,52 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
paiCount++;
ERR("Attach Allocated! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
if (ptiTo->MessageQueue == ptiFrom->MessageQueue)
if (ptiTo->MessageQueue != ptiFrom->MessageQueue)
{
ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
// FIXME: conditions?
if (ptiTo->MessageQueue == gpqForeground)
{
ERR("ptiTo is Foreground\n");
}
else
{
ERR("ptiTo NOT Foreground\n");
}
if (ptiFrom->MessageQueue == gpqForeground)
{
ERR("ptiFrom is Foreground\n");
ptiTo->MessageQueue->spwndActive = ptiFrom->MessageQueue->spwndActive;
ptiTo->MessageQueue->spwndFocus = ptiFrom->MessageQueue->spwndFocus;
ptiTo->MessageQueue->CursorObject = ptiFrom->MessageQueue->CursorObject;
ptiTo->MessageQueue->spwndCapture = ptiFrom->MessageQueue->spwndCapture;
ptiTo->MessageQueue->QF_flags ^= ((ptiTo->MessageQueue->QF_flags ^ ptiFrom->MessageQueue->QF_flags) & QF_CAPTURELOCKED);
ptiTo->MessageQueue->CaretInfo = ptiFrom->MessageQueue->CaretInfo;
IntSetFocusMessageQueue(NULL);
IntSetFocusMessageQueue(ptiTo->MessageQueue);
gptiForeground = ptiTo;
}
else
{
ERR("ptiFrom NOT Foreground\n");
}
MsqDestroyMessageQueue(ptiFrom);
ptiFrom->MessageQueue = ptiTo->MessageQueue;
ptiFrom->MessageQueue->cThreads++;
ERR("ptiTo S Share count %d\n", ptiFrom->MessageQueue->cThreads);
IntReferenceMessageQueue(ptiTo->MessageQueue);
}
else
{
ERR("Attach Threads are already associated!\n");
}
ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
/* Keep the original queue in pqAttach (ie do not trash it in a second attachment) */
if (ptiFrom->pqAttach == NULL)
ptiFrom->pqAttach = ptiFrom->MessageQueue;
ptiFrom->MessageQueue = ptiTo->MessageQueue;
ptiFrom->MessageQueue->cThreads++;
ERR("ptiTo S Share count %lu\n", ptiFrom->MessageQueue->cThreads);
// FIXME: conditions?
if (ptiFrom->pqAttach == gpqForeground)
{
ERR("ptiFrom is Foreground\n");
ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive;
ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus;
ptiFrom->MessageQueue->CursorObject = ptiFrom->pqAttach->CursorObject;
ptiFrom->MessageQueue->spwndCapture = ptiFrom->pqAttach->spwndCapture;
ptiFrom->MessageQueue->QF_flags ^= ((ptiFrom->MessageQueue->QF_flags ^ ptiFrom->pqAttach->QF_flags) & QF_CAPTURELOCKED);
ptiFrom->MessageQueue->CaretInfo = ptiFrom->pqAttach->CaretInfo;
}
else
{
ERR("ptiFrom NOT Foreground\n");
}
if (ptiTo->MessageQueue == gpqForeground)
{
ERR("ptiTo is Foreground\n");
}
else
{
ERR("ptiTo NOT Foreground\n");
}
}
else /* If clear, unlink and free it. */
{
@ -518,41 +549,31 @@ UserAttachThreadInput(PTHREADINFO ptiFrom, PTHREADINFO ptiTo, BOOL fAttach)
}
if (!Hit) return STATUS_INVALID_PARAMETER;
ASSERT(ptiFrom->pqAttach);
ERR("Attach Free! ptiFrom 0x%p ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
/* Search list and check if the thread is attached one more time */
pai = gpai;
while(pai)
if (ptiTo->MessageQueue == ptiFrom->MessageQueue)
{
/* If the thread is attached again , we are done */
if (pai->pti1 == ptiFrom)
{
ptiFrom->MessageQueue->cThreads--;
ERR("ptiTo L Share count %lu\n", ptiFrom->MessageQueue->cThreads);
/* Use the message queue of the last attachment */
ptiFrom->MessageQueue = pai->pti2->MessageQueue;
ptiFrom->MessageQueue->CursorObject = NULL;
ptiFrom->MessageQueue->spwndActive = NULL;
ptiFrom->MessageQueue->spwndFocus = NULL;
ptiFrom->MessageQueue->spwndCapture = NULL;
return STATUS_SUCCESS;
}
pai = pai->paiNext;
}
if (gptiForeground == ptiFrom)
{
ERR("ptiTo is now pti FG.\n");
// MessageQueue foreground is set so switch threads.
gptiForeground = ptiTo;
}
ptiTo->MessageQueue->cThreads--;
ERR("ptiTo E Share count %d\n", ptiTo->MessageQueue->cThreads);
ASSERT(ptiTo->MessageQueue->cThreads >= 1);
ptiFrom->MessageQueue->cThreads--;
ERR("ptiTo E Share count %lu\n", ptiFrom->MessageQueue->cThreads);
ptiFrom->MessageQueue = ptiFrom->pqAttach;
// FIXME: conditions?
ptiFrom->MessageQueue->CursorObject = NULL;
ptiFrom->MessageQueue->spwndActive = NULL;
ptiFrom->MessageQueue->spwndFocus = NULL;
ptiFrom->MessageQueue->spwndCapture = NULL;
ptiFrom->pqAttach = NULL;
ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
IntDereferenceMessageQueue(ptiTo->MessageQueue);
ptiFrom->MessageQueue = MsqCreateMessageQueue(ptiFrom);
ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
}
else
{
ERR("Detaching Threads are not associated!\n");
}
}
/* Note that key state, which can be ascertained by calls to the GetKeyState
or GetKeyboardState function, is reset after a call to AttachThreadInput.

View file

@ -63,7 +63,7 @@ INIT_FUNCTION NTSTATUS NTAPI InitInputImpl(VOID);
BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt);
DWORD NTAPI CreateSystemThreads(UINT Type);
NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
PTHREADINFO FASTCALL IsThreadAttach(PTHREADINFO);
BOOL FASTCALL IsRemoveAttachThread(PTHREADINFO);
VOID FASTCALL DoTheScreenSaver(VOID);
#define ThreadHasInputAccess(W32Thread) (TRUE)

View file

@ -825,6 +825,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
TRACE("HotKey Processed\n");
bPostMsg = FALSE;
}
wFixedVk = IntFixVk(wSimpleVk, bExt); /* LSHIFT + EXT = RSHIFT */
if (wSimpleVk == VK_SHIFT) /* shift can't be extended */
bExt = FALSE;
@ -892,23 +893,31 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
}
else if (pFocusQueue && bPostMsg)
{
PWND Wnd = pFocusQueue->spwndFocus;
if (!Wnd)
PWND Wnd = pFocusQueue->spwndFocus; // SysInit.....
pti = pFocusQueue->ptiKeyboard;
if (!Wnd && pFocusQueue->spwndActive) // SysInit.....
{
// Focus can be null so going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
// Going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
Wnd = pFocusQueue->spwndActive;
}
if (Wnd) pti = Wnd->head.pti;
if ( !Wnd || Wnd->state2 & WNDS2_INDESTROY || Wnd->state & WNDS_DESTROYED )
if ( Msg.message == WM_KEYDOWN || Msg.message == WM_SYSKEYDOWN )
{
ERR("ProcessKeyEvent Active Focus window is dead!\n");
return FALSE;
if ( (Msg.wParam == VK_SHIFT ||
Msg.wParam == VK_CONTROL ||
Msg.wParam == VK_MENU ) &&
!IS_KEY_DOWN(gafAsyncKeyState, Msg.wParam))
{
ERR("Set last input\n");
//ptiLastInput = pti;
}
}
pti = Wnd->head.pti;
/* Init message */
Msg.hwnd = UserHMGetHandle(Wnd);
Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */
Msg.lParam = MAKELPARAM(1, wScanCode);
Msg.time = dwTime;
@ -934,6 +943,7 @@ ProcessKeyEvent(WORD wVk, WORD wScanCode, DWORD dwFlags, BOOL bInjected, DWORD d
/* Post a keyboard message */
TRACE("Posting keyboard msg %u wParam 0x%x lParam 0x%x\n", Msg.message, Msg.wParam, Msg.lParam);
if (!Wnd) {ERR("Window is NULL\n");}
MsqPostMessage(pti, &Msg, TRUE, QS_KEY, 0);
}
@ -956,9 +966,9 @@ UserSendKeyboardInput(KEYBDINPUT *pKbdInput, BOOL bInjected)
/* Find the target thread whose locale is in effect */
pFocusQueue = IntGetFocusMessageQueue();
if (pFocusQueue && pFocusQueue->ptiOwner)
if (pFocusQueue && pFocusQueue->ptiKeyboard)
{
pKl = pFocusQueue->ptiOwner->KeyboardLayout;
pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
}
if (!pKl)
@ -1039,9 +1049,9 @@ UserProcessKeyboardInput(
/* Find the target thread whose locale is in effect */
pFocusQueue = IntGetFocusMessageQueue();
if (pFocusQueue && pFocusQueue->ptiOwner)
if (pFocusQueue && pFocusQueue->ptiKeyboard)
{
pKl = pFocusQueue->ptiOwner->KeyboardLayout;
pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
}
if (!pKl)

View file

@ -154,6 +154,9 @@ Win32kProcessCallback(struct _EPROCESS *Process,
ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER;
}
// Fixme check if this process is allowed.
ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off.
/* Create pools for GDI object attributes */
ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
@ -275,14 +278,17 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));
/* Initialize the THREADINFO */
PsSetThreadWin32Thread(Thread, ptiCurrent);
IntReferenceThreadInfo(ptiCurrent);
ptiCurrent->pEThread = Thread;
ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
pTeb->Win32ThreadInfo = ptiCurrent;
ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
/* Initialize the THREADINFO */
IntReferenceThreadInfo(ptiCurrent);
InitializeListHead(&ptiCurrent->WindowListHead);
InitializeListHead(&ptiCurrent->W32CallbackListHead);
InitializeListHead(&ptiCurrent->PostedMessagesListHead);
@ -294,8 +300,6 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
{
InitializeListHead(&ptiCurrent->aphkStart[i]);
}
ptiCurrent->pEThread = Thread;
ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
ptiCurrent->ppi->ptiList = ptiCurrent;
ptiCurrent->ppi->cThreads++;
@ -307,7 +311,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
{
goto error;
}
Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
ExEventObjectType, KernelMode,
(PVOID*)&ptiCurrent->pEventQueueServer, NULL);
if (!NT_SUCCESS(Status))
@ -319,7 +323,7 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
KeQueryTickCount(&LargeTickCount);
ptiCurrent->timeLast = LargeTickCount.u.LowPart;
ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent);
if(ptiCurrent->MessageQueue == NULL)
{
@ -419,8 +423,14 @@ UserCreateThreadInfo(struct _ETHREAD *Thread)
/* mark the thread as fully initialized */
ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED;
ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) &&
(gptiForeground && gptiForeground->ppi == ptiCurrent->ppi ))
{
ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
}
ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
ERR_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent);
return STATUS_SUCCESS;
error:
@ -483,27 +493,10 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread)
ppiCurrent = ptiCurrent->ppi;
ASSERT(ppiCurrent);
// ptiTo
if (IsThreadAttach(ptiCurrent))
{
PTHREADINFO ptiFrom = IsThreadAttach(ptiCurrent);
TRACE_CH(UserThread,"Attached Thread ptiTo is getting switched!\n");
UserAttachThreadInput(ptiFrom, ptiCurrent, FALSE);
}
IsRemoveAttachThread(ptiCurrent);
// ptiFrom
if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue)
{
PTHREADINFO ptiTo;
ptiTo = ptiCurrent->MessageQueue->ptiOwner;
TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n");
if (ptiTo) UserAttachThreadInput( ptiCurrent, ptiTo, FALSE);
else
{
// eThread maybe okay but Win32Thread already made NULL!
ERR_CH(UserThread,"Attached Thread ptiFrom did not switch due to ptiTo is NULL!\n");
}
}
ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE;
ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
/* Decrement thread count and check if its 0 */
ppiCurrent->cThreads--;
@ -553,9 +546,10 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread)
*/
co_DestroyThreadWindows(Thread);
if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling)
if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling &&
ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED)
{
//ERR_CH(UserThread,"DestroyProcessClasses\n");
ERR_CH(UserThread,"DestroyProcessClasses\n");
/* no process windows should exist at this point, or the function will assert! */
DestroyProcessClasses(ppiCurrent);
ppiCurrent->W32PF_flags &= ~W32PF_CLASSESREGISTERED;
@ -592,8 +586,24 @@ UserDestroyThreadInfo(struct _ETHREAD *Thread)
if (ptiCurrent->KeyboardLayout)
UserDereferenceObject(ptiCurrent->KeyboardLayout);
IntSetThreadDesktop(NULL, TRUE);
if (gptiForeground == ptiCurrent)
{
// IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
// IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, NULL, OBJID_WINDOW, CHILDID_SELF, 0);
gptiForeground = NULL;
}
// Fixes CORE-6384 & CORE-7030.
/* if (ptiLastInput == ptiCurrent)
{
if (!ppiCurrent->ptiList)
ptiLastInput = gptiForeground;
else
ptiLastInput = ppiCurrent->ptiList;
ERR_CH(UserThread,"DTI: ptiLastInput is Cleared!!\n");
}
*/
TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);
/* Free the THREADINFO */

View file

@ -502,13 +502,7 @@ VOID FASTCALL
IdlePing(VOID)
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
PUSER_MESSAGE_QUEUE ForegroundQueue;
PTHREADINFO pti, ptiForeground = NULL;
ForegroundQueue = IntGetFocusMessageQueue();
if (ForegroundQueue)
ptiForeground = ForegroundQueue->ptiOwner;
PTHREADINFO pti;
pti = PsGetCurrentThreadWin32Thread();
@ -516,7 +510,7 @@ IdlePing(VOID)
{
pti->pClientInfo->cSpins = 0; // Reset spins.
if ( pti->pDeskInfo && pti == ptiForeground )
if ( pti->pDeskInfo && pti == gptiForeground )
{
if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ||
pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) )
@ -602,13 +596,14 @@ static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPAR
{
LRESULT lRes;
USER_REFERENCE_ENTRY Ref;
// PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
if (!pWnd ||
pWnd == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
pWnd == UserGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
return 0;
TRACE("Internal Event Msg %u hWnd %p\n", msg, pWnd->head.h);
TRACE("Internal Event Msg %p hWnd 0x%x\n",msg,pWnd->head.h);
switch(msg)
{
@ -632,7 +627,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,TRUE);
lRes = (LRESULT)co_IntSetActiveWindow(Window,(BOOL)lparam,TRUE,TRUE);
if (wparam) UserDerefObjectCo(Window);
return lRes;
}
@ -751,6 +746,14 @@ IntDispatchMessage(PMSG pMsg)
/*
* Internal version of PeekMessage() doing all the work
*
* MSDN:
* Sent messages
* Posted messages
* Input (hardware) messages and system internal events
* Sent messages (again)
* WM_PAINT messages
* WM_TIMER messages
*/
BOOL FASTCALL
co_IntPeekMessage( PMSG Msg,
@ -770,7 +773,7 @@ co_IntPeekMessage( PMSG Msg,
RemoveMessages = RemoveMsg & PM_REMOVE;
ProcessMask = HIWORD(RemoveMsg);
/* Hint, "If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns
all available messages (that is, no range filtering is performed)". */
if (!ProcessMask) ProcessMask = (QS_ALLPOSTMESSAGE|QS_ALLINPUT);
@ -1083,6 +1086,19 @@ UserPostThreadMessage( PTHREADINFO pti,
return TRUE;
}
PTHREADINFO FASTCALL
IntSendTo(PWND Window, PTHREADINFO ptiCur, UINT Msg)
{
if ( ptiCur )
{
if ( Window->head.pti->MessageQueue == ptiCur->MessageQueue )
{
return NULL;
}
}
return Window->head.pti;
}
BOOL FASTCALL
UserPostMessage( HWND Wnd,
UINT Msg,
@ -1192,11 +1208,11 @@ UserPostMessage( HWND Wnd,
if (WM_QUIT == Msg)
{
MsqPostQuitMessage(Window->head.pti, wParam);
MsqPostQuitMessage(pti, wParam);
}
else
{
MsqPostMessage(Window->head.pti, &Message, FALSE, QS_POSTMESSAGE, 0);
MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0);
}
}
return TRUE;
@ -1230,7 +1246,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
LPARAM lParamPacked;
PTHREADINFO Win32Thread;
PTHREADINFO Win32Thread, ptiSendTo = NULL;
ULONG_PTR Hi, Lo, Result = 0;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
@ -1246,8 +1262,9 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
Win32Thread = PsGetCurrentThreadWin32Thread();
if ( Win32Thread &&
Window->head.pti == Win32Thread)
ptiSendTo = IntSendTo(Window, Win32Thread, Msg);
if ( !ptiSendTo )
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
@ -1333,7 +1350,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
RETURN( TRUE);
}
if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti))
if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(ptiSendTo/*Window->head.pti*/))
{
// FIXME: Set window hung and add to a list.
/* FIXME: Set a LastError? */
@ -1349,7 +1366,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
do
{
Status = co_MsqSendMessage( Window->head.pti,
Status = co_MsqSendMessage( ptiSendTo, //Window->head.pti,
hWnd,
Msg,
wParam,
@ -1361,7 +1378,7 @@ co_IntSendMessageTimeoutSingle( HWND hWnd,
}
while ((STATUS_TIMEOUT == Status) &&
(uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
!MsqIsHung(Window->head.pti)); // FIXME: Set window hung and add to a list.
!MsqIsHung(ptiSendTo/*Window->head.pti*/)); // FIXME: Set window hung and add to a list.
if (STATUS_TIMEOUT == Status)
{
@ -1491,7 +1508,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
PMSGMEMORY MsgMemoryEntry;
INT lParamBufferSize;
LPARAM lParamPacked;
PTHREADINFO Win32Thread;
PTHREADINFO Win32Thread, ptiSendTo = NULL;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
PUSER_SENT_MESSAGE Message;
@ -1519,9 +1536,11 @@ co_IntSendMessageWithCallBack( HWND hWnd,
{
RETURN(FALSE);
}
ptiSendTo = IntSendTo(Window, Win32Thread, Msg);
if (Msg & 0x80000000 &&
Window->head.pti == Win32Thread)
!ptiSendTo)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP) RETURN( FALSE);
@ -1542,14 +1561,14 @@ co_IntSendMessageWithCallBack( HWND hWnd,
lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
}
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti != Win32Thread)))
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, !!ptiSendTo)))
{
ERR("Failed to pack message parameters\n");
RETURN( FALSE);
}
/* If it can be sent now, then send it. */
if (Window->head.pti == Win32Thread)
if ( !ptiSendTo )
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
{
@ -1599,7 +1618,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
}
}
if (Window->head.pti == Win32Thread)
if ( !ptiSendTo)
{
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
@ -1622,7 +1641,7 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->Result = 0;
Message->lResult = 0;
Message->QS_Flags = 0;
Message->ptiReceiver = Window->head.pti;
Message->ptiReceiver = ptiSendTo; //Window->head.pti;
Message->ptiSender = NULL; // mjmartin, you are right! This is null.
Message->ptiCallBackSender = Win32Thread;
Message->DispatchingListEntry.Flink = NULL;
@ -1633,10 +1652,10 @@ co_IntSendMessageWithCallBack( HWND hWnd,
Message->QS_Flags = QS_SENDMESSAGE;
if (Msg & 0x80000000) // Higher priority event message!
InsertHeadList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry);
InsertHeadList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry);
else
InsertTailList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry);
MsqWakeQueue(Window->head.pti, QS_SENDMESSAGE, TRUE);
InsertTailList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry);
MsqWakeQueue(ptiSendTo/*Window->head.pti*/, QS_SENDMESSAGE, TRUE);
RETURN(TRUE);
@ -1674,7 +1693,7 @@ co_IntPostOrSendMessage( HWND hWnd,
pti = PsGetCurrentThreadWin32Thread();
if ( Window->head.pti->MessageQueue != pti->MessageQueue &&
if ( IntSendTo(Window, pti, Msg) &&
FindMsgMemory(Msg) == 0 )
{
Result = UserPostMessage(hWnd, Msg, wParam, lParam);

View file

@ -662,8 +662,11 @@ void UserDbgAssertThreadInfo(BOOL showCaller)
ASSERT(pti->pDeskInfo == pti->rpdesk->pDeskInfo);
/*too bad we still get this assertion*/
// Why? Not all flags are passed to the user and doing so could crash the system........
/* ASSERT(pci->dwTIFlags == pti->TIF_flags); */
if(pci->dwTIFlags != pti->TIF_flags)
/* if(pci->dwTIFlags != pti->TIF_flags)
{
ERR("pci->dwTIFlags(0x%x) doesn't match pti->TIF_flags(0x%x)\n", pci->dwTIFlags, pti->TIF_flags);
if(showCaller)
@ -673,6 +676,7 @@ void UserDbgAssertThreadInfo(BOOL showCaller)
}
pci->dwTIFlags = pti->TIF_flags;
}
*/
}
void

View file

@ -404,7 +404,6 @@ MsqWakeQueue(PTHREADINFO pti, DWORD MessageBits, BOOL KeyEvent)
{
ERR("This Message Queue is in Destroy!\n");
}
pti->pcti->fsWakeBits |= MessageBits;
pti->pcti->fsChangeBits |= MessageBits;
@ -475,6 +474,10 @@ ClearMsgBitsMask(PTHREADINFO pti, UINT MessageBits)
{
if (--pti->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY;
}
if (MessageBits & QS_EVENT)
{
if (--pti->nCntsQBits[QSRosEvent] == 0) ClrMask |= QS_EVENT;
}
pti->pcti->fsWakeBits &= ~ClrMask;
pti->pcti->fsChangeBits &= ~ClrMask;
@ -506,6 +509,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
{
LARGE_INTEGER LargeTickCount;
MSLLHOOKSTRUCT MouseHookData;
// PDESKTOP pDesk;
PWND pwnd, pwndDesktop;
HDC hdcScreen;
PTHREADINFO pti;
@ -549,6 +553,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
/* Get the desktop window */
pwndDesktop = UserGetDesktopWindow();
if (!pwndDesktop) return;
// pDesk = pwndDesktop->head.rpdesk;
/* Check if the mouse is captured */
Msg->hwnd = IntGetCaptureWindow();
@ -626,6 +631,7 @@ co_MsqInsertMouseMessage(MSG* Msg, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook
}
else
{
//if (!IntGetCaptureWindow()) ptiLastInput = pti;
TRACE("Posting mouse message to hwnd=%p!\n", UserHMGetHandle(pwnd));
MsqPostMessage(pti, Msg, TRUE, QS_MOUSEBUTTON, 0);
}
@ -661,7 +667,7 @@ MsqDestroyMessage(PUSER_MESSAGE Message)
}
BOOLEAN FASTCALL
co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti)
co_MsqDispatchOneSentMessage(PTHREADINFO pti)
{
PUSER_SENT_MESSAGE SaveMsg, Message;
PLIST_ENTRY Entry;
@ -911,12 +917,6 @@ co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
ptiSender = PsGetCurrentThreadWin32Thread();
IntReferenceMessageQueue(ptiReceiver->MessageQueue);
/* Take reference on this MessageQueue if its a callback. It will be released
when message is processed or removed from target hwnd MessageQueue */
if (CompletionCallback)
IntReferenceMessageQueue(ptiSender->MessageQueue);
Message->Msg.hwnd = hwnd;
Message->Msg.message = Msg;
Message->Msg.wParam = wParam;
@ -1180,6 +1180,12 @@ MsqPostMessage(PTHREADINFO pti,
PUSER_MESSAGE Message;
PUSER_MESSAGE_QUEUE MessageQueue;
if ( pti->TIF_flags & TIF_INCLEANUP || pti->MessageQueue->QF_flags & QF_INDESTROY )
{
ERR("Post Msg; Thread or Q is Dead!\n");
return;
}
if(!(Message = MsqCreateMessage(Msg)))
{
return;
@ -1189,6 +1195,7 @@ MsqPostMessage(PTHREADINFO pti,
if (dwQEvent)
{
ERR("Post Msg; System Qeued Event Message!\n");
InsertHeadList(&pti->PostedMessagesListHead,
&Message->ListEntry);
}
@ -1206,7 +1213,7 @@ MsqPostMessage(PTHREADINFO pti,
if (Msg->message == WM_HOTKEY) MessageBits |= QS_HOTKEY; // Justin Case, just set it.
Message->dwQEvent = dwQEvent;
Message->QS_Flags = MessageBits;
//Message->pti = pti; Fixed in ATI changes. See CORE-6551
Message->pti = pti;
MsqWakeQueue(pti, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE));
}
@ -1254,7 +1261,7 @@ FASTCALL
IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
{
// PWND pwndTrack = IntChildrenWindowFromPoint(pwndMsg, msg->pt.x, msg->pt.y);
hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this???
// hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this???
if ( pDesk->spwndTrack != pwndTrack || // Change with tracking window or
msg->message != WM_MOUSEMOVE || // Mouse click changes or
@ -1491,7 +1498,7 @@ BOOL co_IntProcessMouseMessage(MSG* msg, BOOL* RemoveMessages, UINT first, UINT
hook.dwExtraInfo = 0 /* extra_info */ ;
co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook );
ERR("WH_MOUSE dorpped mouse message!\n");
ERR("WH_MOUSE dropped mouse message!\n");
/* Remove and skip message */
*RemoveMessages = TRUE;
@ -1805,7 +1812,7 @@ MsqPeekMessage(IN PTHREADINFO pti,
ListHead = &pti->PostedMessagesListHead;
if (IsListEmpty(CurrentEntry)) return FALSE;
CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
ListEntry);
do
@ -1880,9 +1887,8 @@ HungAppSysTimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
BOOLEAN FASTCALL
MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue)
{
MessageQueue->ptiOwner = pti;
MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1);
InitializeListHead(&MessageQueue->HardwareMessagesListHead);
InitializeListHead(&MessageQueue->HardwareMessagesListHead); // Keep here!
MessageQueue->spwndFocus = NULL;
MessageQueue->iCursorLevel = 0;
MessageQueue->CursorObject = NULL;
@ -1900,7 +1906,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
PLIST_ENTRY CurrentEntry;
PUSER_MESSAGE CurrentMessage;
PUSER_SENT_MESSAGE CurrentSentMessage;
/* cleanup posted messages */
while (!IsListEmpty(&pti->PostedMessagesListHead))
{
@ -1936,7 +1942,7 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
if (CurrentSentMessage->Msg.lParam)
ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
}
/* free the message */
ExFreePool(CurrentSentMessage);
}
@ -1999,16 +2005,16 @@ MsqCleanupThreadMsgs(PTHREADINFO pti)
pti->nCntsQBits[QSRosPostMessage] = 0;
pti->nCntsQBits[QSRosSendMessage] = 0;
pti->nCntsQBits[QSRosHotKey] = 0;
pti->nCntsQBits[QSRosEvent] = 0;
}
VOID FASTCALL
MsqCleanupMessageQueue(PTHREADINFO pti)
{
PUSER_MESSAGE_QUEUE MessageQueue;
MessageQueue = pti->MessageQueue;
MessageQueue->cThreads--;
MessageQueue->cThreads--;
if (MessageQueue->cThreads)
{
@ -2033,6 +2039,7 @@ MsqCleanupMessageQueue(PTHREADINFO pti)
IntGetSysCursorInfo()->CurrentCursorObject = NULL;
}
ERR("DereferenceObject pCursor\n");
UserDereferenceObject(pCursor);
}

View file

@ -42,7 +42,6 @@ typedef struct _USER_MESSAGE_QUEUE
/* Reference counter, only access this variable with interlocked functions! */
LONG References;
PTHREADINFO ptiOwner; // temp..
/* Desktop that the message queue is attached to */
struct _DESKTOP *Desktop;

View file

@ -548,6 +548,13 @@ UserSetObjectOwner(PVOID obj, HANDLE_TYPE type, PVOID owner)
#endif
}
HANDLE FASTCALL ValidateHandleNoErr(HANDLE handle, HANDLE_TYPE type)
{
if (handle) return (PWND)UserGetObjectNoErr(gHandleTable, handle, type);
return NULL;
}
/*
* NtUserValidateHandleSecure
*

View file

@ -18,6 +18,7 @@ BOOL FASTCALL UserCreateHandleTable(VOID);
BOOL FASTCALL UserObjectInDestroy(HANDLE);
void DbgUserDumpHandleTable();
VOID FASTCALL UserSetObjectOwner(PVOID obj, HANDLE_TYPE type, PVOID owner);
HANDLE FASTCALL ValidateHandleNoErr(HANDLE handle, HANDLE_TYPE type);
static __inline VOID
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)

View file

@ -123,7 +123,12 @@ IntSetStyle( PWND pwnd, ULONG set_bits, ULONG clear_bits )
styleNew = (pwnd->style | set_bits) & ~clear_bits;
if (styleNew == styleOld) return styleNew;
pwnd->style = styleNew;
if ((styleOld ^ styleNew) & WS_VISIBLE) DceResetActiveDCEs( pwnd );
if ((styleOld ^ styleNew) & WS_VISIBLE) // State Change.
{
if (styleOld & WS_VISIBLE) pwnd->head.pti->cVisWindows--;
if (styleNew & WS_VISIBLE) pwnd->head.pti->cVisWindows++;
DceResetActiveDCEs( pwnd );
}
return styleOld;
}
@ -159,21 +164,16 @@ IntIsWindow(HWND hWnd)
BOOL FASTCALL
IntIsWindowVisible(PWND Wnd)
{
BOOL Ret = TRUE;
do
PWND Temp = Wnd;
for (;;)
{
if (!(Wnd->style & WS_VISIBLE))
{
Ret = FALSE;
break;
}
if (Wnd->spwndParent != NULL)
Wnd = Wnd->spwndParent;
else
break;
if (!Temp) return TRUE;
if (!(Temp->style & WS_VISIBLE)) break;
if (Temp->style & WS_MINIMIZE && Temp != Wnd) break;
if (Temp->fnid == FNID_DESKTOP) return TRUE;
Temp = Temp->spwndParent;
}
while (Wnd != NULL);
return Ret;
return FALSE;
}
PWND FASTCALL
@ -436,6 +436,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
}
Window->state2 |= WNDS2_INDESTROY;
Window->style &= ~WS_VISIBLE;
Window->head.pti->cVisWindows--;
IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
@ -497,9 +498,6 @@ static LRESULT co_UserFreeWindow(PWND Window,
/* flush the message queue */
MsqRemoveWindowMessagesFromQueue(Window);
NT_ASSERT(Window->head.pti);
IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
/* from now on no messages can be sent to this window anymore */
Window->state |= WNDS_DESTROYED;
Window->fnid |= FNID_FREED;
@ -578,6 +576,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
GreDeleteObject(Window->hrgnClip);
Window->hrgnClip = NULL;
}
Window->head.pti->cWindows--;
// ASSERT(Window != NULL);
UserFreeWindowInfo(Window->head.pti, Window);
@ -1098,8 +1097,8 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner)
Wnd->head.pti == WndNewOwner->head.pti ||
WndOldOwner->head.pti != WndNewOwner->head.pti )
{
ERR("ProcessOwnerSwap Old out.\n");
//UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE);
//ERR("ProcessOwnerSwap Old out.\n");
UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE);
}
}
}
@ -1110,8 +1109,8 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner)
if (!WndOldOwner ||
WndOldOwner->head.pti != WndNewOwner->head.pti )
{
ERR("ProcessOwnerSwap New in.\n");
//UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE);
//ERR("ProcessOwnerSwap New in.\n");
UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE);
}
}
}
@ -1140,6 +1139,8 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner)
goto Error;
}
/* if parent belongs to a different thread and the window isn't */
/* top-level, attach the two threads */
IntProcessOwnerSwap(Wnd, WndNewOwner, WndOldOwner);
if (IntValidateOwnerDepth(Wnd, WndNewOwner))
@ -1186,6 +1187,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
/* Some applications try to set a child as a parent */
if (IntIsChildWindow(Wnd, WndNewParent))
{
TRACE("IntSetParent try to set a child as a parent.\n");
EngSetLastError( ERROR_INVALID_PARAMETER );
return NULL;
}
@ -1196,6 +1198,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
{
if (Wnd == pWndExam)
{
TRACE("IntSetParent Failed Test for set parent to parent!\n");
EngSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
@ -1210,7 +1213,10 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
/* Window must belong to current process */
if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process())
{
ERR("IntSetParent Window must belong to current process!\n");
return NULL;
}
WndOldParent = Wnd->spwndParent;
@ -1249,22 +1255,31 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
}
if ( WndNewParent == co_GetDesktopWindow(Wnd) &&
!(Wnd->style & WS_CLIPSIBLINGS) )
{
Wnd->style |= WS_CLIPSIBLINGS;
DceResetActiveDCEs(Wnd);
}
/* if parent belongs to a different thread and the window isn't */
/* top-level, attach the two threads */
if ((Wnd->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
{
if ( Wnd->spwndParent != co_GetDesktopWindow(Wnd))
{
if (Wnd->head.pti != WndOldParent->head.pti)
{
ERR("SetParent Old out.\n");
//UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE);
//ERR("SetParent Old out.\n");
UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE);
}
}
if ( WndNewParent != co_GetDesktopWindow(Wnd))
{
if (Wnd->head.pti != WndNewParent->head.pti)
{
ERR("SetParent New in.\n");
//UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE);
//ERR("SetParent New in.\n");
UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE);
}
}
}
@ -1278,10 +1293,11 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
* in the z-order and send the expected WM_WINDOWPOSCHANGING and
* WM_WINDOWPOSCHANGED notification messages.
*/
//ERR("IntSetParent SetWindowPos 1\n");
co_WinPosSetWindowPos( Wnd,
(0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
pt.x, pt.y, 0, 0, swFlags);
//ERR("IntSetParent SetWindowPos 2\n");
if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL);
return WndOldParent;
@ -1302,6 +1318,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
if (hWndChild == IntGetDesktopWindow())
{
ERR("UserSetParent Access Denied!\n");
EngSetLastError(ERROR_ACCESS_DENIED);
return( NULL);
}
@ -1310,6 +1327,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
{
if (!(WndParent = UserGetWindowObject(hWndNewParent)))
{
ERR("UserSetParent Bad New Parent!\n");
return( NULL);
}
}
@ -1323,6 +1341,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
if (!(Wnd = UserGetWindowObject(hWndChild)))
{
ERR("UserSetParent Bad Child!\n");
return( NULL);
}
@ -1762,13 +1781,14 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
pWnd->InternalPos.MaxPos.x = pWnd->InternalPos.MaxPos.y = -1;
pWnd->InternalPos.IconPos.x = pWnd->InternalPos.IconPos.y = -1;
IntReferenceMessageQueue(pWnd->head.pti->MessageQueue);
if (pWnd->spwndParent != NULL && Cs->hwndParent != 0)
{
pWnd->HideFocus = pWnd->spwndParent->HideFocus;
pWnd->HideAccel = pWnd->spwndParent->HideAccel;
}
pWnd->head.pti->cWindows++;
if (Class->hIcon && !Class->hIconSm)
{
Class->hIconSmIntern = co_IntCopyImage( Class->hIcon, IMAGE_ICON,
@ -1962,8 +1982,8 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
Class->atomClassName != gpsi->atomSysClass[ICLS_IME] &&
pti != pWnd->spwndOwner->head.pti)
{
ERR("CreateWindow Owner in.\n");
//UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE);
//ERR("CreateWindow Owner in.\n");
UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE);
}
}
@ -2203,6 +2223,15 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
Cs->lpszName = (LPCWSTR) WindowName;
Cs->lpszClass = (LPCWSTR) ClassName;
if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
{
if (ParentWindow != co_GetDesktopWindow(Window))
{
Cs->x += ParentWindow->rcClient.left;
Cs->y += ParentWindow->rcClient.top;
}
}
/* Send the WM_GETMINMAXINFO message */
Size.cx = Cs->cx;
Size.cy = Cs->cy;
@ -2220,6 +2249,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
Window->rcWindow.top = Cs->y;
Window->rcWindow.right = Cs->x + Size.cx;
Window->rcWindow.bottom = Cs->y + Size.cy;
/*
if (0 != (Window->style & WS_CHILD) && ParentWindow)
{
// ERR("co_UserCreateWindowEx(): Offset rcWindow\n");
@ -2227,6 +2257,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
ParentWindow->rcClient.left,
ParentWindow->rcClient.top);
}
*/
Window->rcClient = Window->rcWindow;
/* Link the window */
@ -2239,8 +2270,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
IntLinkHwnd(Window, hwndInsertAfter);
}
// Remove flags that are retro.
if (!(Window->state2 & WNDS2_WIN31COMPAT)) // FIXME: support version flags.
if (!(Window->state2 & WNDS2_WIN31COMPAT))
{
if (Class->style & CS_PARENTDC && !(ParentWindow->style & WS_CLIPCHILDREN))
Window->style &= ~(WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
@ -2252,8 +2282,8 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
{
if (pti != Window->spwndParent->head.pti)
{
ERR("CreateWindow Parent in.\n");
//UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE);
//ERR("CreateWindow Parent in.\n");
UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE);
}
}
}
@ -2267,14 +2297,19 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
}
/* Send the WM_NCCALCSIZE message */
{
// RECT rc;
MaxPos.x = Window->rcWindow.left;
MaxPos.y = Window->rcWindow.top;
Result = co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient);
//rc = Window->rcWindow;
//Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM)&rc);
//Window->rcClient = rc;
RECTL_vOffsetRect(&Window->rcWindow, MaxPos.x - Window->rcWindow.left,
MaxPos.y - Window->rcWindow.top);
}
/* Send the WM_CREATE message. */
Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs);
@ -2593,8 +2628,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
{
if (Window->spwndOwner)
{
ERR("DestroyWindow Owner out.\n");
//UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE);
//ERR("DestroyWindow Owner out.\n");
UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE);
}
}
}
@ -2632,8 +2667,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
{
if (!IntIsTopLevelWindow(Window))
{
ERR("DestroyWindow Parent out.\n");
//UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE);
//ERR("DestroyWindow Parent out.\n");
UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE);
}
}
}
@ -3377,9 +3412,12 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
if (ti->pDeskInfo)
{
ti->pDeskInfo->hShellWindow = hwndShell;
ti->pDeskInfo->spwndShell = WndShell;
ti->pDeskInfo->ppiShellProcess = ti->ppi;
}
UserRegisterHotKey(WndShell, SC_TASKLIST, MOD_CONTROL, VK_ESCAPE);
UserDerefObjectCo(WndShell);
ObDereferenceObject(WinStaObject);
@ -3579,6 +3617,12 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
else
Window->ExStyle &= ~WS_EX_WINDOWEDGE;
if ((Style.styleOld ^ Style.styleNew) & WS_VISIBLE)
{
if (Style.styleOld & WS_VISIBLE) Window->head.pti->cVisWindows--;
if (Style.styleNew & WS_VISIBLE) Window->head.pti->cVisWindows++;
DceResetActiveDCEs( Window );
}
Window->style = (DWORD)Style.styleNew;
co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
break;

View file

@ -237,6 +237,7 @@ BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd)
if (!(pWndSetActive->ExStyle & WS_EX_TOOLWINDOW) )
{
UserRefObjectCo(pWndSetActive, &Ref);
//ERR("ActivateOtherWindowMin Set FG 1\n");
co_IntSetForegroundWindow(pWndSetActive);
UserDerefObjectCo(pWndSetActive);
//ERR("AOWM 2 Exit Good\n");
@ -273,6 +274,7 @@ BOOL FASTCALL ActivateOtherWindowMin(PWND Wnd)
if ((pWndSetActive = pWndTemp))
{
UserRefObjectCo(pWndSetActive, &Ref);
//ERR("ActivateOtherWindowMin Set FG 2\n");
co_IntSetForegroundWindow(pWndSetActive);
UserDerefObjectCo(pWndSetActive);
//ERR("AOWM 3 Exit Good\n");
@ -299,7 +301,7 @@ BOOL FASTCALL can_activate_window( PWND Wnd OPTIONAL)
if (style & WS_MINIMIZE) return FALSE;
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
return TRUE;
/* FIXME: This window could be disable because the child that closed
/* FIXME: This window could be disable because the child that closed
was a popup. */
//return !(style & WS_DISABLED);
}
@ -314,7 +316,6 @@ VOID FASTCALL
co_WinPosActivateOtherWindow(PWND Wnd)
{
PWND WndTo = NULL;
HWND Fg, previous;
USER_REFERENCE_ENTRY Ref;
ASSERT_REFS_CO(Wnd);
@ -345,26 +346,24 @@ done:
if (WndTo) UserRefObjectCo(WndTo, &Ref);
Fg = UserGetForegroundWindow();
if ((!Fg || Wnd->head.h == Fg) && WndTo) // FIXME: Ok if WndTo is NULL?? No, rule #4.
if (!gpqForeground || Wnd == gpqForeground->spwndActive)
{
/* FIXME: Wine can pass WndTo = NULL to co_IntSetForegroundWindow. Hmm... */
/* ReactOS can pass WndTo = NULL to co_IntSetForegroundWindow and returns FALSE. */
//ERR("WinPosActivateOtherWindow Set FG 0x%p\n",WndTo);
if (co_IntSetForegroundWindow(WndTo))
{
UserDerefObjectCo(WndTo);
if (WndTo) UserDerefObjectCo(WndTo);
return;
}
}
if (!co_IntSetActiveWindow(WndTo,&previous,FALSE,TRUE,FALSE) || /* Ok for WndTo to be NULL here */
!previous)
//ERR("WinPosActivateOtherWindow Set Active 0x%p\n",WndTo);
if (!co_IntSetActiveWindow(WndTo,FALSE,TRUE,FALSE)) /* Ok for WndTo to be NULL here */
{
co_IntSetActiveWindow(0,NULL,FALSE,TRUE,FALSE);
co_IntSetActiveWindow(0,FALSE,TRUE,FALSE);
}
if (WndTo) UserDerefObjectCo(WndTo);
}
UINT
FASTCALL
co_WinPosArrangeIconicWindows(PWND parent)
@ -1131,11 +1130,71 @@ FixClientRect(PRECTL ClientRect, PRECTL WindowRect)
ClientRect->bottom = WindowRect->bottom;
}
}
/***********************************************************************
* get_valid_rects
*
* Compute the valid rects from the old and new client rect and WVR_* flags.
* Helper for WM_NCCALCSIZE handling.
*/
static
VOID FASTCALL
get_valid_rects( RECTL *old_client, RECTL *new_client, UINT flags, RECTL *valid )
{
int cx, cy;
if (flags & WVR_REDRAW)
{
RECTL_vSetEmptyRect( &valid[0] );
RECTL_vSetEmptyRect( &valid[1] );
return;
}
if (flags & WVR_VALIDRECTS)
{
if (!RECTL_bIntersectRect( &valid[0], &valid[0], new_client ) ||
!RECTL_bIntersectRect( &valid[1], &valid[1], old_client ))
{
RECTL_vSetEmptyRect( &valid[0] );
RECTL_vSetEmptyRect( &valid[1] );
return;
}
flags = WVR_ALIGNLEFT | WVR_ALIGNTOP;
}
else
{
valid[0] = *new_client;
valid[1] = *old_client;
}
/* make sure the rectangles have the same size */
cx = min( valid[0].right - valid[0].left, valid[1].right - valid[1].left );
cy = min( valid[0].bottom - valid[0].top, valid[1].bottom - valid[1].top );
if (flags & WVR_ALIGNBOTTOM)
{
valid[0].top = valid[0].bottom - cy;
valid[1].top = valid[1].bottom - cy;
}
else
{
valid[0].bottom = valid[0].top + cy;
valid[1].bottom = valid[1].top + cy;
}
if (flags & WVR_ALIGNRIGHT)
{
valid[0].left = valid[0].right - cx;
valid[1].left = valid[1].right - cx;
}
else
{
valid[0].right = valid[0].left + cx;
valid[1].right = valid[1].left + cx;
}
}
static
LONG FASTCALL
co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
RECT* WindowRect, RECT* ClientRect)
co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL* WindowRect, RECTL* ClientRect, RECTL* validRects)
{
PWND Parent;
UINT wvrFlags = 0;
@ -1148,9 +1207,10 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
NCCALCSIZE_PARAMS params;
WINDOWPOS winposCopy;
params.rgrc[0] = *WindowRect;
params.rgrc[1] = Window->rcWindow;
params.rgrc[2] = Window->rcClient;
params.rgrc[0] = *WindowRect; // new coordinates of a window that has been moved or resized
params.rgrc[1] = Window->rcWindow; // window before it was moved or resized
params.rgrc[2] = Window->rcClient; // client area before the window was moved or resized
Parent = Window->spwndParent;
if (0 != (Window->style & WS_CHILD) && Parent)
{
@ -1161,6 +1221,7 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
RECTL_vOffsetRect(&(params.rgrc[2]), - Parent->rcClient.left,
- Parent->rcClient.top);
}
params.lppos = &winposCopy;
winposCopy = *WinPos;
@ -1170,7 +1231,7 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
if (params.rgrc[0].left <= params.rgrc[0].right &&
params.rgrc[0].top <= params.rgrc[0].bottom)
{
*ClientRect = params.rgrc[0];
*ClientRect = params.rgrc[0]; // First rectangle contains the coordinates of the new client rectangle resulting from the move or resize
if ((Window->style & WS_CHILD) && Parent)
{
RECTL_vOffsetRect(ClientRect, Parent->rcClient.left,
@ -1179,21 +1240,30 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
FixClientRect(ClientRect, WindowRect);
}
/* FIXME: WVR_ALIGNxxx */
if (ClientRect->left != Window->rcClient.left ||
ClientRect->top != Window->rcClient.top)
{
WinPos->flags &= ~SWP_NOCLIENTMOVE;
}
if ((ClientRect->right - ClientRect->left !=
Window->rcClient.right - Window->rcClient.left) ||
(ClientRect->bottom - ClientRect->top !=
Window->rcClient.bottom - Window->rcClient.top))
if (ClientRect->right - ClientRect->left !=
Window->rcClient.right - Window->rcClient.left)
{
WinPos->flags &= ~SWP_NOCLIENTSIZE;
}
else
wvrFlags &= ~WVR_HREDRAW;
if (ClientRect->bottom - ClientRect->top !=
Window->rcClient.bottom - Window->rcClient.top)
{
WinPos->flags &= ~SWP_NOCLIENTSIZE;
}
else
wvrFlags &= ~WVR_VREDRAW;
validRects[0] = params.rgrc[1]; // second rectangle contains the valid destination rectangle
validRects[1] = params.rgrc[2]; // third rectangle contains the valid source rectangle
}
else
{
@ -1205,6 +1275,13 @@ co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
}
}
if (WinPos->flags & (SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_SHOWWINDOW | SWP_HIDEWINDOW))
{
RECTL_vSetEmptyRect( &validRects[0] );
RECTL_vSetEmptyRect( &validRects[1] );
}
else get_valid_rects( &Window->rcClient, ClientRect, wvrFlags, validRects );
return wvrFlags;
}
@ -1215,15 +1292,46 @@ co_WinPosDoWinPosChanging(PWND Window,
PRECTL WindowRect,
PRECTL ClientRect)
{
INT X, Y;
ASSERT_REFS_CO(Window);
/* Send WM_WINDOWPOSCHANGING message */
if (!(WinPos->flags & SWP_NOSENDCHANGING))
{
co_IntSendMessageNoWait(Window->head.h, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
}
/* Calculate new position and size */
*WindowRect = Window->rcWindow;
*ClientRect = (Window->style & WS_MINIMIZE) ? Window->rcWindow : Window->rcClient;
if (!(WinPos->flags & SWP_NOSIZE))
{
if (Window->style & WS_MINIMIZE)
{
WindowRect->right = WindowRect->left + UserGetSystemMetrics(SM_CXICON);
WindowRect->bottom = WindowRect->top + UserGetSystemMetrics(SM_CYICON);
}
else
{
WindowRect->right = WindowRect->left + WinPos->cx;
WindowRect->bottom = WindowRect->top + WinPos->cy;
}
}
#if 0
if (!(WinPos->flags & SWP_NOMOVE))
{
WindowRect->left = WinPos->x;
WindowRect->top = WinPos->y;
WindowRect->right += WinPos->x - Window->rcWindow.left;
WindowRect->bottom += WinPos->y - Window->rcWindow.top;
RECTL_vOffsetRect(ClientRect,
WinPos->x - Window->rcWindow.left,
WinPos->y - Window->rcWindow.top);
}
*WindowRect = Window->rcWindow;
*ClientRect = Window->rcClient;
@ -1232,22 +1340,26 @@ co_WinPosDoWinPosChanging(PWND Window,
WindowRect->right = WindowRect->left + WinPos->cx;
WindowRect->bottom = WindowRect->top + WinPos->cy;
}
#endif
if (!(WinPos->flags & SWP_NOMOVE))
{
INT X, Y;
PWND Parent;
X = WinPos->x;
Y = WinPos->y;
//ERR("Not SWP_NOMOVE\n");
Parent = Window->spwndParent;
if ((0 != (Window->style & WS_CHILD)) && Parent)
if ((0 != (Window->style & WS_CHILD)) && Parent &&
Parent != Window->head.rpdesk->pDeskInfo->spwnd)
{
//ERR("Not SWP_NOMOVE Parent client offset\n");
X += Parent->rcClient.left;
Y += Parent->rcClient.top;
}
WindowRect->left = X;
WindowRect->top = Y;
WindowRect->right += X - Window->rcWindow.left;
WindowRect->left = X;
WindowRect->top = Y;
WindowRect->right += X - Window->rcWindow.left;
WindowRect->bottom += Y - Window->rcWindow.top;
RECTL_vOffsetRect(ClientRect,
X - Window->rcWindow.left,
@ -1256,6 +1368,10 @@ co_WinPosDoWinPosChanging(PWND Window,
WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y,
WinPos->cx, WinPos->cy, WinPos->flags );
return TRUE;
}
@ -1396,6 +1512,21 @@ static
BOOL FASTCALL
WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
{
PWND Parent;
POINT pt;
/* Finally make sure that all coordinates are valid */
if (WinPos->x < -32768) WinPos->x = -32768;
else if (WinPos->x > 32767) WinPos->x = 32767;
if (WinPos->y < -32768) WinPos->y = -32768;
else if (WinPos->y > 32767) WinPos->y = 32767;
WinPos->cx = max(WinPos->cx, 0);
WinPos->cy = max(WinPos->cy, 0);
Parent = UserGetAncestor( Wnd, GA_PARENT );
if (!IntIsWindowVisible( Parent )) WinPos->flags |= SWP_NOREDRAW;
if (Wnd->style & WS_VISIBLE)
{
WinPos->flags &= ~SWP_SHOWWINDOW;
@ -1407,9 +1538,6 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
WinPos->flags |= SWP_NOREDRAW;
}
WinPos->cx = max(WinPos->cx, 0);
WinPos->cy = max(WinPos->cy, 0);
/* Check for right size */
if (Wnd->rcWindow.right - Wnd->rcWindow.left == WinPos->cx &&
Wnd->rcWindow.bottom - Wnd->rcWindow.top == WinPos->cy)
@ -1417,10 +1545,15 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
WinPos->flags |= SWP_NOSIZE;
}
pt.x = WinPos->x;
pt.y = WinPos->y;
IntClientToScreen( Parent, &pt );
// ERR("WPFU C2S wpx %d wpy %d ptx %d pty %d\n",WinPos->x,WinPos->y,pt.x,pt.y);
/* Check for right position */
if (Wnd->rcWindow.left == WinPos->x &&
Wnd->rcWindow.top == WinPos->y)
if (Wnd->rcWindow.left == pt.x &&
Wnd->rcWindow.top == pt.y)
{
// ERR("In right pos\n");
WinPos->flags |= SWP_NOMOVE;
}
@ -1526,6 +1659,7 @@ co_WinPosSetWindowPos(
WINDOWPOS WinPos;
RECTL NewWindowRect;
RECTL NewClientRect;
RECTL valid_rects[2];
PROSRGNDATA VisRgn;
HRGN VisBefore = NULL;
HRGN VisAfter = NULL;
@ -1543,7 +1677,7 @@ co_WinPosSetWindowPos(
ASSERT_REFS_CO(Window);
/* FIXME: Get current active window from active queue. */
/* FIXME: Get current active window from active queue. Why? since r2915. */
bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
@ -1555,6 +1689,27 @@ co_WinPosSetWindowPos(
WinPos.cy = cy;
WinPos.flags = flags;
if ( flags & SWP_ASYNCWINDOWPOS )
{
LRESULT lRes;
PWINDOWPOS ppos = ExAllocatePoolWithTag(PagedPool, sizeof(WINDOWPOS), USERTAG_SWP);
if ( ppos )
{
WinPos.flags &= ~SWP_ASYNCWINDOWPOS; // Clear flag.
*ppos = WinPos;
/* Yes it's a pointer inside Win32k! */
lRes = co_IntSendMessageNoWait( WinPos.hwnd, WM_ASYNC_SETWINDOWPOS, 0, (LPARAM)ppos);
/* We handle this the same way as Event Hooks and Hooks. */
if ( !lRes )
{
ExFreePoolWithTag(ppos, USERTAG_SWP);
return FALSE;
}
return TRUE;
}
return FALSE;
}
co_WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
// HWND_NOTOPMOST is redirected in WinPosFixupFlags.
@ -1610,9 +1765,11 @@ co_WinPosSetWindowPos(
}
}
WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect);
WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect, valid_rects);
TRACE("co_WinPosDoNCCALCSize returned %lu\n", WvrFlags);
// ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags,
// valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom,
// valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom);
/* Validate link windows. (also take into account shell window in hwndShellWindow) */
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow())
@ -1624,6 +1781,7 @@ co_WinPosSetWindowPos(
if ((ParentWindow = Window->spwndParent)) // Must have a Parent window!
{
//ERR("SetWindowPos has parent window.\n");
if (WinPos.hwndInsertAfter == HWND_TOPMOST)
{
InsertAfterWindow = NULL;
@ -1682,20 +1840,8 @@ co_WinPosSetWindowPos(
OldWindowRect = Window->rcWindow;
OldClientRect = Window->rcClient;
if (OldClientRect.bottom - OldClientRect.top ==
NewClientRect.bottom - NewClientRect.top)
{
WvrFlags &= ~WVR_VREDRAW;
}
if (OldClientRect.right - OldClientRect.left ==
NewClientRect.right - NewClientRect.left)
{
WvrFlags &= ~WVR_HREDRAW;
}
/* FIXME: Actually do something with WVR_VALIDRECTS */
//ERR("SetWindowPos OldWindowRect: %d %d %d %d\n", OldWindowRect.left,OldWindowRect.top,OldWindowRect.right,OldWindowRect.bottom);
//ERR("SetWindowPos OldClientRect: %d %d %d %d\n", OldClientRect.left,OldClientRect.top,OldClientRect.right,OldClientRect.bottom);
if (NewClientRect.left != OldClientRect.left ||
NewClientRect.top != OldClientRect.top)
@ -1708,6 +1854,9 @@ co_WinPosSetWindowPos(
Window->rcWindow = NewWindowRect;
Window->rcClient = NewClientRect;
//ERR("SetWindowPos NewWindowRect: %d %d %d %d\n", NewWindowRect.left,NewWindowRect.top,NewWindowRect.right,NewWindowRect.bottom);
//ERR("SetWindowPos NewClientRect: %d %d %d %d\n", NewClientRect.left,NewClientRect.top,NewClientRect.right,NewClientRect.bottom);
/* erase parent when hiding or resizing child */
if (WinPos.flags & SWP_HIDEWINDOW)
{
@ -1721,6 +1870,7 @@ co_WinPosSetWindowPos(
co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM)Window->head.h, 0);
Window->style &= ~WS_VISIBLE; //IntSetStyle( Window, 0, WS_VISIBLE );
Window->head.pti->cVisWindows--;
IntNotifyWinEvent(EVENT_OBJECT_HIDE, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
}
else if (WinPos.flags & SWP_SHOWWINDOW)
@ -1729,6 +1879,7 @@ co_WinPosSetWindowPos(
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0);
Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 );
Window->head.pti->cVisWindows++;
IntNotifyWinEvent(EVENT_OBJECT_SHOW, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
}
@ -1955,7 +2106,10 @@ co_WinPosSetWindowPos(
else
{
//ERR("SetWindowPos Set FG Window!\n");
co_IntSetForegroundWindow(Window);
if (Window->state & WNDS_BEINGACTIVATED) // Inside SAW?
co_IntSetActiveWindow(Window, FALSE, TRUE, FALSE); // Fixes Api AttachThreadInput tests.
else
co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow.
}
}
@ -2036,7 +2190,7 @@ co_WinPosSendSizeMove(PWND Wnd)
co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam, lParam);
if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid != FNID_DESKTOP )
if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid == FNID_DESKTOP )
lParam = MAKELONG(Wnd->rcClient.left, Wnd->rcClient.top);
else
lParam = MAKELONG(Wnd->rcClient.left-Wnd->spwndParent->rcClient.left, Wnd->rcClient.top-Wnd->spwndParent->rcClient.top);
@ -2056,9 +2210,9 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
LONG style;
PWND Parent;
PTHREADINFO pti;
// BOOL ShowOwned = FALSE;
// HRGN VisibleRgn;
//ERR("co_WinPosShowWindow START\n");
BOOL ShowOwned = FALSE;
ASSERT_REFS_CO(Wnd);
pti = PsGetCurrentThreadWin32Thread();
@ -2071,6 +2225,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
{
if (!WasVisible)
{
//ERR("co_WinPosShowWindow Exit Bad\n");
return(FALSE);
}
Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
@ -2091,11 +2246,12 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Swp |= SWP_NOACTIVATE;
if (!(style & WS_MINIMIZE))
{
//IntShowOwnedPopups(Wnd, FALSE );
IntShowOwnedPopups(Wnd, FALSE );
// Fix wine Win test_SetFocus todo #1 & #2,
if (Cmd == SW_SHOWMINIMIZED)
{
//ERR("co_WinPosShowWindow Set focus 1\n");
if ((style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
co_UserSetFocus(Wnd->spwndParent);
else
@ -2114,7 +2270,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Swp |= SWP_FRAMECHANGED;
}
else ////
{
//ERR("co_WinPosShowWindow Exit Good\n");
return TRUE;
}
Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
break;
@ -2125,7 +2284,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Swp |= SWP_SHOWWINDOW;
if (!(style & WS_MAXIMIZE))
{
//ShowOwned = TRUE;
ShowOwned = TRUE;
Swp |= co_WinPosMinMaximize(Wnd, SW_MAXIMIZE, &NewPos) |
SWP_FRAMECHANGED;
@ -2139,7 +2298,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Swp |= SWP_FRAMECHANGED;
}
else ////
{
//ERR("co_WinPosShowWindow Exit Good 1\n");
return TRUE;
}
Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
break;
@ -2177,7 +2339,10 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Swp |= SWP_FRAMECHANGED;
}
else ////
{
//ERR("co_WinPosShowWindow Exit Good 3\n");
return TRUE;
}
Swp |= SWP_NOSIZE | SWP_NOMOVE;
}
if ( style & WS_CHILD &&
@ -2187,6 +2352,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
break;
default:
//ERR("co_WinPosShowWindow Exit Good 4\n");
return WasVisible;
}
@ -2214,7 +2380,8 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
Wnd->pcls->style & CS_SAVEBITS &&
((Cmd == SW_SHOW) || (Cmd == SW_NORMAL)))
{
co_IntSetActiveWindow(Wnd,NULL,FALSE,TRUE,FALSE);
ERR("WinPosShowWindow Set active\n");
UserSetActiveWindow(Wnd);
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
}
#endif
@ -2242,7 +2409,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
if ( EventMsg ) IntNotifyWinEvent(EventMsg, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
//if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE );
if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE );
if ((Cmd == SW_HIDE) || (Cmd == SW_MINIMIZE))
{
@ -2281,6 +2448,7 @@ co_WinPosShowWindow(PWND Wnd, INT Cmd)
// Fix wine Win test_SetFocus todo #3,
if (!(style & WS_CHILD)) co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_ACTIVATE, WA_ACTIVE, 0);
}
//ERR("co_WinPosShowWindow EXIT\n");
return(WasVisible);
}