#include <win32k.h>
DBG_DEFAULT_CHANNEL(UserWnd);
+INT gNestedWindowLimit = 50;
+
/* HELPER FUNCTIONS ***********************************************************/
BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam)
PWND FASTCALL ValidateHwndNoErr(HWND hWnd)
{
- if (hWnd) return (PWND)UserGetObjectNoErr(gHandleTable, hWnd, otWindow);
+ if (hWnd) return (PWND)UserGetObjectNoErr(gHandleTable, hWnd, TYPE_WINDOW);
return NULL;
}
return NULL;
}
- Window = (PWND)UserGetObject(gHandleTable, hWnd, otWindow);
+ Window = (PWND)UserGetObject(gHandleTable, hWnd, TYPE_WINDOW);
if (!Window || 0 != (Window->state & WNDS_DESTROYED))
{
EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
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;
}
PWND Window;
if (!(Window = UserGetWindowObject(hWnd)))
+ {
return FALSE;
+ }
return TRUE;
}
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
/* 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 );
return List;
}
+PWND FASTCALL
+IntGetNonChildAncestor(PWND 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;
+}
+
+HWND FASTCALL
+IntGetWindow(HWND hWnd,
+ UINT uCmd)
+{
+ PWND Wnd, FoundWnd;
+ HWND Ret = NULL;
+
+ Wnd = ValidateHwndNoErr(hWnd);
+ if (!Wnd)
+ return NULL;
+
+ FoundWnd = NULL;
+ switch (uCmd)
+ {
+ case GW_OWNER:
+ if (Wnd->spwndOwner != NULL)
+ FoundWnd = Wnd->spwndOwner;
+ break;
+
+ case GW_HWNDFIRST:
+ if(Wnd->spwndParent != NULL)
+ {
+ FoundWnd = Wnd->spwndParent;
+ if (FoundWnd->spwndChild != NULL)
+ FoundWnd = FoundWnd->spwndChild;
+ }
+ break;
+ case GW_HWNDNEXT:
+ if (Wnd->spwndNext != NULL)
+ FoundWnd = Wnd->spwndNext;
+ break;
+
+ case GW_HWNDPREV:
+ if (Wnd->spwndPrev != NULL)
+ FoundWnd = Wnd->spwndPrev;
+ break;
+
+ case GW_CHILD:
+ if (Wnd->spwndChild != NULL)
+ FoundWnd = Wnd->spwndChild;
+ break;
+
+ case GW_HWNDLAST:
+ FoundWnd = Wnd;
+ while ( FoundWnd->spwndNext != NULL)
+ FoundWnd = FoundWnd->spwndNext;
+ break;
+
+ default:
+ Wnd = NULL;
+ break;
+ }
+
+ if (FoundWnd != NULL)
+ Ret = UserHMGetHandle(FoundWnd);
+ return Ret;
+}
+
/***********************************************************************
* IntSendDestroyMsg
*/
if (!Window->spwndOwner && !IntGetParent(Window))
{
- co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM) hWnd);
+ co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM) hWnd, 0);
}
// UserDerefObjectCo(Window);
}
// DesktopHeapFree(Wnd->head.rpdesk, Wnd);
-// WindowObject->Wnd = NULL;
+// WindowObject->hWnd = NULL;
}
/***********************************************************************
HWND *Children;
HWND *ChildHandle;
PWND Child;
- PMENU_OBJECT Menu;
+ PMENU Menu;
BOOLEAN BelongsToThreadData;
ASSERT(Window);
}
Window->state2 |= WNDS2_INDESTROY;
Window->style &= ~WS_VISIBLE;
+ Window->head.pti->cVisWindows--;
IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
UserDereferenceObject(Child);
}
}
- ExFreePool(Children);
+ ExFreePoolWithTag(Children, USERTAG_WINDOWLIST);
}
if(SendMessages)
/* flush the message queue */
MsqRemoveWindowMessagesFromQueue(Window);
- 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;
IntUnlinkWindow(Window);
+ if (Window->PropListItems)
+ {
+ IntRemoveWindowProp(Window);
+ TRACE("Window->PropListItems %d\n",Window->PropListItems);
+ ASSERT(Window->PropListItems==0);
+ }
+
UserReferenceObject(Window);
- UserDeleteObject(Window->head.h, otWindow);
+ UserDeleteObject(Window->head.h, TYPE_WINDOW);
IntDestroyScrollBars(Window);
GreDeleteObject(Window->hrgnClip);
Window->hrgnClip = NULL;
}
+ Window->head.pti->cWindows--;
// ASSERT(Window != NULL);
UserFreeWindowInfo(Window->head.pti, Window);
if (IsCallProcHandle(NewWndProc))
{
- CallProc = UserGetObject(gHandleTable, NewWndProc, otCallProc);
+ CallProc = UserGetObject(gHandleTable, NewWndProc, TYPE_CALLPROC);
if (CallProc)
{ // Reset new WndProc.
NewWndProc = CallProc->pfnClientPrevious;
HMENU Menu,
BOOL *Changed)
{
- PMENU_OBJECT OldMenu, NewMenu = NULL;
+ PMENU OldMenu, NewMenu = NULL;
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;
}
if (Wnd->IDMenu)
{
OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu);
- ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Wnd->head.h);
+ ASSERT(NULL == OldMenu || OldMenu->hWnd == Wnd->head.h);
}
else
{
EngSetLastError(ERROR_INVALID_MENU_HANDLE);
return FALSE;
}
- if (NULL != NewMenu->MenuInfo.Wnd)
+ if (NULL != NewMenu->hWnd)
{
/* Can't use the same menu for two windows */
if (NULL != OldMenu)
Wnd->IDMenu = (UINT) Menu;
if (NULL != NewMenu)
{
- NewMenu->MenuInfo.Wnd = Wnd->head.h;
+ NewMenu->hWnd = Wnd->head.h;
IntReleaseMenuObject(NewMenu);
}
if (NULL != OldMenu)
{
- OldMenu->MenuInfo.Wnd = NULL;
+ OldMenu->hWnd = NULL;
IntReleaseMenuObject(OldMenu);
}
Current = WThread->WindowListHead.Flink;
Wnd = CONTAINING_RECORD(Current, WND, ThreadListEntry);
- TRACE("thread cleanup: while destroy wnds, wnd=0x%x\n",Wnd);
+ TRACE("thread cleanup: while destroy wnds, wnd=%p\n", Wnd);
/* Window removes itself from the list */
UserRefObjectCo(Wnd, &Ref); // FIXME: Temp HACK??
if (!co_UserDestroyWindow(Wnd))
{
- ERR("Unable to destroy window 0x%x at thread cleanup... This is _VERY_ bad!\n", Wnd);
+ ERR("Unable to destroy window %p at thread cleanup... This is _VERY_ bad!\n", Wnd);
}
UserDerefObjectCo(Wnd); // FIXME: Temp HACK??
}
}
-PMENU_OBJECT FASTCALL
+PMENU FASTCALL
IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
{
- PMENU_OBJECT Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
+ PMENU Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
PTHREADINFO W32Thread;
HMENU hNewMenu, hSysMenu;
- ROSMENUITEMINFO ItemInfo;
+ ROSMENUITEMINFO ItemInfoSet = {0};
+ ROSMENUITEMINFO ItemInfo = {0};
+ UNICODE_STRING MenuName;
if(bRevert)
{
NewMenu = IntCloneMenu(Menu);
if(NewMenu)
- {
- Window->SystemMenu = NewMenu->MenuInfo.Self;
- NewMenu->MenuInfo.Flags |= MF_SYSMENU;
- NewMenu->MenuInfo.Wnd = Window->head.h;
+ { // Use spmenuSys
+ Window->SystemMenu = NewMenu->head.h;
+ NewMenu->fFlags |= MNF_SYSDESKMN;
+ NewMenu->hWnd = Window->head.h;
ret = NewMenu;
//IntReleaseMenuObject(NewMenu);
}
UserDestroyMenu(hSysMenu);
return NULL;
}
- SysMenu->MenuInfo.Flags |= MF_SYSMENU;
- SysMenu->MenuInfo.Wnd = Window->head.h;
- hNewMenu = co_IntLoadSysMenuTemplate();
+ SysMenu->fFlags |= MNF_SYSDESKMN;
+ SysMenu->hWnd = Window->head.h;
+ //hNewMenu = co_IntLoadSysMenuTemplate();
+ //if ( Window->ExStyle & WS_EX_MDICHILD )
+ //{
+ // RtlInitUnicodeString( &MenuName, L"SYSMENUMDI");
+ // hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
+ //}
+ //else
+ {
+ RtlInitUnicodeString( &MenuName, L"SYSMENU");
+ hNewMenu = co_IntCallLoadMenu( hModClient, &MenuName);
+ //ERR("%wZ\n",&MenuName);
+ }
if(!hNewMenu)
{
+ ERR("No Menu!!\n");
IntReleaseMenuObject(SysMenu);
UserDestroyMenu(hSysMenu);
return NULL;
return NULL;
}
+ // Do the rest in here.
+
+ Menu->fFlags |= MNS_CHECKORBMP | MNF_SYSDESKMN | MNF_POPUP;
+
+ ItemInfoSet.cbSize = sizeof( MENUITEMINFOW);
+ ItemInfoSet.fMask = MIIM_BITMAP;
+ ItemInfoSet.hbmpItem = HBMMENU_POPUP_CLOSE;
+ IntMenuItemInfo(Menu, SC_CLOSE, FALSE, &ItemInfoSet, TRUE, NULL);
+ ItemInfoSet.hbmpItem = HBMMENU_POPUP_RESTORE;
+ IntMenuItemInfo(Menu, SC_RESTORE, FALSE, &ItemInfoSet, TRUE, NULL);
+ ItemInfoSet.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
+ IntMenuItemInfo(Menu, SC_MAXIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
+ ItemInfoSet.hbmpItem = HBMMENU_POPUP_MINIMIZE;
+ IntMenuItemInfo(Menu, SC_MINIMIZE, FALSE, &ItemInfoSet, TRUE, NULL);
+
NewMenu = IntCloneMenu(Menu);
if(NewMenu)
{
- NewMenu->MenuInfo.Flags |= MF_SYSMENU | MF_POPUP;
+ NewMenu->fFlags |= MNF_SYSDESKMN | MNF_POPUP;
+ // Do not set MNS_CHECKORBMP it breaks menus, also original code destroyed the style anyway.
IntReleaseMenuObject(NewMenu);
UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
+ if (Window->pcls->style & CS_NOCLOSE)
+ IntRemoveMenuItem(NewMenu, SC_CLOSE, MF_BYCOMMAND, TRUE);
+
ItemInfo.cbSize = sizeof(MENUITEMINFOW);
ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU;
- ItemInfo.fType = MF_POPUP;
+ ItemInfo.fType = 0;
ItemInfo.fState = MFS_ENABLED;
ItemInfo.dwTypeData = NULL;
ItemInfo.cch = 0;
- ItemInfo.hSubMenu = NewMenu->MenuInfo.Self;
- IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo);
+ ItemInfo.hSubMenu = NewMenu->head.h;
+ IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo, NULL);
- Window->SystemMenu = SysMenu->MenuInfo.Self;
+ Window->SystemMenu = SysMenu->head.h;
ret = SysMenu;
}
}
}
}
+ 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 )
+ {
+ //ERR("ProcessOwnerSwap Old out.\n");
+ 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 )
+ {
+ //ERR("ProcessOwnerSwap New in.\n");
+ UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE);
+ }
+ }
+ }
+ // FIXME: System Tray checks.
}
HWND FASTCALL
WndOldOwner = Wnd->spwndOwner;
- ret = WndOldOwner ? WndOldOwner->head.h : 0;
+ ret = WndOldOwner ? UserHMGetHandle(WndOldOwner) : 0;
+ WndNewOwner = UserGetWindowObject(hWndNewOwner);
+
+ if (!WndNewOwner && hWndNewOwner)
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ ret = NULL;
+ 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((WndNewOwner = UserGetWindowObject(hWndNewOwner)))
+ if (IntValidateOwnerDepth(Wnd, WndNewOwner))
{
- Wnd->spwndOwner= 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;
}
/* 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;
}
{
if (Wnd == pWndExam)
{
+ TRACE("IntSetParent Failed Test for set parent to parent!\n");
EngSetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
/* 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;
- if ( WndOldParent &&
+ if ( WndOldParent &&
WndOldParent->ExStyle & WS_EX_LAYOUTRTL)
pt.x = Wnd->rcWindow.right;
else
pt.x = Wnd->rcWindow.left;
pt.y = Wnd->rcWindow.top;
+ IntScreenToClient(WndOldParent, &pt);
+
if (WndOldParent) UserReferenceObject(WndOldParent); /* Caller must deref */
if (WndNewParent != WndOldParent)
{
/* Unlink the window from the siblings list */
IntUnlinkWindow(Wnd);
+ Wnd->ExStyle2 &= ~WS_EX2_LINKED;
/* Set the new parent */
Wnd->spwndParent = WndNewParent;
- if ( Wnd->style & WS_CHILD &&
+ if ( Wnd->style & WS_CHILD &&
Wnd->spwndOwner &&
Wnd->spwndOwner->ExStyle & WS_EX_TOPMOST )
{
}
+ 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);
+ }
+ }
+ 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);
+ }
+ }
+ }
+
if (WndOldParent == UserGetMessageWindow() || WndNewParent == UserGetMessageWindow())
swFlags |= SWP_NOACTIVATE;
* 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 X %d Y %d\n",pt.x, pt.y);
if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL);
return WndOldParent;
if (hWndChild == IntGetDesktopWindow())
{
+ ERR("UserSetParent Access Denied!\n");
EngSetLastError(ERROR_ACCESS_DENIED);
return( NULL);
}
{
if (!(WndParent = UserGetWindowObject(hWndNewParent)))
{
+ ERR("UserSetParent Bad New Parent!\n");
return( NULL);
}
}
if (!(Wnd = UserGetWindowObject(hWndChild)))
{
+ ERR("UserSetParent Bad Child!\n");
return( NULL);
}
}
BOOL FASTCALL
-IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
+IntSetSystemMenu(PWND Window, PMENU Menu)
{
- PMENU_OBJECT OldMenu;
+ PMENU OldMenu;
if(Window->SystemMenu)
{
OldMenu = IntGetMenuObject(Window->SystemMenu);
if(OldMenu)
{
- OldMenu->MenuInfo.Flags &= ~ MF_SYSMENU;
+ OldMenu->fFlags &= ~ MNF_SYSDESKMN;
IntReleaseMenuObject(OldMenu);
}
}
if(Menu)
{
/* FIXME: Check window style, propably return FALSE? */
- Window->SystemMenu = Menu->MenuInfo.Self;
- Menu->MenuInfo.Flags |= MF_SYSMENU;
+ Window->SystemMenu = Menu->head.h;
+ Menu->fFlags |= MNF_SYSDESKMN;
}
- else
+ else // Use spmenuSys too!
Window->SystemMenu = (HMENU)0;
return TRUE;
/* Allocates and initializes a window */
PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
- PLARGE_STRING WindowName,
- PCLS Class,
- PWND ParentWindow,
- PWND OwnerWindow,
- PVOID acbiBuffer)
+ PLARGE_STRING WindowName,
+ PCLS Class,
+ PWND ParentWindow,
+ PWND OwnerWindow,
+ PVOID acbiBuffer,
+ PDESKTOP pdeskCreated)
{
PWND pWnd = NULL;
HWND hWnd;
PTHREADINFO pti = NULL;
- PMENU_OBJECT SystemMenu;
+ PMENU SystemMenu;
BOOL MenuChanged;
BOOL bUnicodeWindow;
- pti = PsGetCurrentThreadWin32Thread();
+ pti = pdeskCreated ? gptiDesktopThread : GetW32ThreadInfo();
if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
- {
- if (ParentWindow)
+ { // Need both here for wine win.c test_CreateWindow.
+ //if (Cs->hwndParent && ParentWindow)
+ if (ParentWindow) // It breaks more tests..... WIP.
{
if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD &&
ParentWindow->ExStyle & WS_EX_LAYOUTRTL &&
*/
if ( Class->fnid != FNID_DIALOG )
{
- PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
- if (ppi->dwLayout & LAYOUT_RTL)
+ if (pti->ppi->dwLayout & LAYOUT_RTL)
{
Cs->dwExStyle |= WS_EX_LAYOUTRTL;
}
/* Allocate the new window */
pWnd = (PWND) UserCreateObject( gHandleTable,
- pti->rpdesk,
+ pdeskCreated ? pdeskCreated : pti->rpdesk,
+ pti,
(PHANDLE)&hWnd,
- otWindow,
+ TYPE_WINDOW,
sizeof(WND) + Class->cbwndExtra);
if (!pWnd)
goto AllocError;
}
- TRACE("Created object with handle %X\n", hWnd);
+ TRACE("Created window object with handle %p\n", hWnd);
- if (NULL == pti->rpdesk->DesktopWindow)
+ if (pdeskCreated && pdeskCreated->DesktopWindow == NULL )
{ /* HACK: Helper for win32csr/desktopbg.c */
/* If there is no desktop window yet, we must be creating it */
- pti->rpdesk->DesktopWindow = hWnd;
- pti->rpdesk->pDeskInfo->spwnd = pWnd;
+ TRACE("CreateWindow setting desktop.\n");
+ pdeskCreated->DesktopWindow = hWnd;
+ pdeskCreated->pDeskInfo->spwnd = pWnd;
}
/*
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,
+ UserGetSystemMetrics( SM_CXSMICON ),
+ UserGetSystemMetrics( SM_CYSMICON ), 0 );
+ TRACE("IntCreateWindow hIconSmIntern %p\n",Class->hIconSmIntern);
+ Class->CSF_flags |= CSF_CACHEDSMICON;
+ }
+
if (pWnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
if (!CallProc)
{
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
- ERR("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd);
+ ERR("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %p\n", hWnd);
}
else
{
{
SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE);
if(SystemMenu)
- {
- pWnd->SystemMenu = SystemMenu->MenuInfo.Self;
+ { // spmenuSys
+ pWnd->SystemMenu = SystemMenu->head.h;
IntReleaseMenuObject(SystemMenu);
}
}
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)
+ {
+ //ERR("CreateWindow Owner in.\n");
+ UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE);
+ }
+ }
+
/* Insert the window into the thread's window list. */
InsertTailList (&pti->WindowListHead, &pWnd->ThreadListEntry);
AllocError:
ERR("IntCreateWindow Allocation Error.\n");
+ SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
+Error:
if(pWnd)
UserDereferenceObject(pWnd);
-
- SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
return NULL;
}
PWINSTATION_OBJECT WinSta;
PCLS Class = NULL;
SIZE Size;
- POINT MaxPos;
+ POINT MaxSize, MaxPos, MinTrack, MaxTrack;
CBT_CREATEWNDW * pCbtCreate;
LRESULT Result;
USER_REFERENCE_ENTRY ParentRef, Ref;
pCbtCreate = NULL;
/* Get the class and reference it */
- Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
+ Class = IntGetAndReferenceClass(ClassName, Cs->hInstance, FALSE);
if(!Class)
{
ERR("Failed to find class %wZ\n", ClassName);
}
/* Now find the parent and the owner window */
- hWndParent = IntGetDesktopWindow();
+ hWndParent = pti->rpdesk->pDeskInfo->spwnd->head.h;
hWndOwner = NULL;
if (Cs->hwndParent == HWND_MESSAGE)
{
- Cs->hwndParent = hWndParent = IntGetMessageWindow();
+ Cs->hwndParent = hWndParent = pti->rpdesk->spwndMessage->head.h;
}
else if (Cs->hwndParent)
{
Class,
ParentWindow,
OwnerWindow,
- acbiBuffer);
+ acbiBuffer,
+ NULL);
if(!Window)
{
ERR("IntCreateWindow failed!\n");
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;
if ((Cs->style & WS_THICKFRAME) || !(Cs->style & (WS_POPUP | WS_CHILD)))
{
- POINT MaxSize, MaxPos, MinTrack, MaxTrack;
-
co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack, &MaxTrack);
if (Size.cx > MaxTrack.x) Size.cx = MaxTrack.x;
if (Size.cy > MaxTrack.y) Size.cy = MaxTrack.y;
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");
ParentWindow->rcClient.left,
ParentWindow->rcClient.top);
}
+*/
+ /* correct child window coordinates if mirroring on parent is enabled */
+ if (ParentWindow != NULL)
+ {
+ if ( ((Cs->style & WS_CHILD) == WS_CHILD) &&
+ ((ParentWindow->ExStyle & WS_EX_LAYOUTRTL) == WS_EX_LAYOUTRTL))
+ {
+ Window->rcWindow.right = ParentWindow->rcClient.right - (Window->rcWindow.left - ParentWindow->rcClient.left);
+ Window->rcWindow.left = Window->rcWindow.right - Size.cx;
+ }
+ }
+
Window->rcClient = Window->rcWindow;
/* Link the window */
IntLinkHwnd(Window, hwndInsertAfter);
}
+ if (!(Window->state2 & WNDS2_WIN31COMPAT))
+ {
+ if (Class->style & CS_PARENTDC && !(ParentWindow->style & WS_CLIPCHILDREN))
+ Window->style &= ~(WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
+ }
+
+ if ((Window->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+ {
+ if ( !IntIsTopLevelWindow(Window) )
+ {
+ if (pti != Window->spwndParent->head.pti)
+ {
+ //ERR("CreateWindow Parent in.\n");
+ UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE);
+ }
+ }
+ }
+
/* Send the NCCREATE message */
Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
if (!Result)
}
/* 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);
/* 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 */
}
}
- TRACE("co_UserCreateWindowEx(): Created window %X\n", hWnd);
+ TRACE("co_UserCreateWindowEx(): Created window %p\n", hWnd);
ret = Window;
cleanup:
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Cleanup and fail */
- ExFreePool(pvBuffer);
+ ExFreePoolWithTag(pvBuffer, TAG_STRING);
_SEH2_YIELD(return _SEH2_GetExceptionCode();)
}
_SEH2_END
ASSERT(plstrWindowName);
+ if ( (dwStyle & (WS_POPUP|WS_CHILD)) != WS_CHILD)
+ {
+ /* check hMenu is valid handle */
+ if (hMenu && !ValidateHandle(hMenu, TYPE_MENU))
+ {
+ /* error is set in ValidateHandle */
+ return NULL;
+ }
+ }
+
/* Copy the window name to kernel mode */
Status = ProbeAndCaptureLargeString(&lstrWindowName, plstrWindowName);
if (!NT_SUCCESS(Status))
BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
{
HWND hWnd;
+ PWND pwndTemp;
PTHREADINFO ti;
MSG msg;
TRACE("co_UserDestroyWindow \n");
/* Check for owner thread */
- if ( (Window->head.pti->pEThread != PsGetCurrentThread()) ||
- Window->head.pti != PsGetCurrentThreadWin32Thread() )
+ if ( Window->head.pti != PsGetCurrentThreadWin32Thread())
{
- EngSetLastError(ERROR_ACCESS_DENIED);
- return FALSE;
+ /* Check if we are destroying the desktop window */
+ if (! ((Window->head.rpdesk->dwDTFlags & DF_DESTROYED) && Window == Window->head.rpdesk->pDeskInfo->spwnd))
+ {
+ EngSetLastError(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
}
/* If window was created successfully and it is hooked */
}
}
+ if (Window->pcls->atomClassName != gpsi->atomSysClass[ICLS_IME])
+ {
+ if ((Window->style & (WS_POPUP|WS_CHILD)) != WS_CHILD)
+ {
+ if (Window->spwndOwner)
+ {
+ //ERR("DestroyWindow Owner out.\n");
+ UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE);
+ }
+ }
+ }
+
/* Inform the parent */
if (Window->style & WS_CHILD)
{
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))
+ {
+ //ERR("DestroyWindow Parent out.\n");
+ 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)
* Check if this window is the Shell's Desktop Window. If so set hShellWindow to NULL
*/
- if ((ti != NULL) & (ti->pDeskInfo != NULL))
+ if ((ti != NULL) && (ti->pDeskInfo != NULL))
{
if (ti->pDeskInfo->hShellWindow == hWnd)
{
}
}
- ExFreePool(Children);
+ ExFreePoolWithTag(Children, USERTAG_WINDOWLIST);
}
if (! GotOne)
{
RETURN(ret);
CLEANUP:
- TRACE("Leave NtUserDestroyWindow, ret=%i\n",_ret_);
+ TRACE("Leave NtUserDestroyWindow, ret=%u\n", _ret_);
UserLeave();
END_CLEANUP;
}
}
}
}
- ExFreePool(List);
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
return Ret;
}
}
- ExFreePool(List);
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
}
}
else
RETURN( Ret);
CLEANUP:
- TRACE("Leave NtUserFindWindowEx, ret %i\n",_ret_);
+ TRACE("Leave NtUserFindWindowEx, ret %p\n", _ret_);
UserLeave();
END_CLEANUP;
}
for (;;)
{
- PWND Parent;
-
Parent = IntGetParent(WndAncestor);
if (!Parent)
RETURN(Ancestor ? Ancestor->head.h : NULL);
CLEANUP:
- TRACE("Leave NtUserGetAncestor, ret=%i\n",_ret_);
+ TRACE("Leave NtUserGetAncestor, ret=%p\n", _ret_);
UserLeave();
END_CLEANUP;
}
-
+////
+//// ReactOS work around! Keep it the sames as in Combo.c and Controls.h
+////
+/* combo state struct */
+typedef struct
+{
+ HWND self;
+ HWND owner;
+ UINT dwStyle;
+ HWND hWndEdit;
+ HWND hWndLBox;
+ UINT wState;
+ HFONT hFont;
+ RECT textRect;
+ RECT buttonRect;
+ RECT droppedRect;
+ INT droppedIndex;
+ INT fixedOwnerDrawHeight;
+ INT droppedWidth; /* last two are not used unless set */
+ INT editHeight; /* explicitly */
+ LONG UIState;
+} HEADCOMBO,*LPHEADCOMBO;
+
+// Window Extra data container.
+typedef struct _WND2CBOX
+{
+ WND;
+ LPHEADCOMBO pCBox;
+} WND2CBOX, *PWND2CBOX;
+
+#define CBF_BUTTONDOWN 0x0002
+////
+////
+////
BOOL
APIENTRY
NtUserGetComboBoxInfo(
PCOMBOBOXINFO pcbi)
{
PWND Wnd;
+ PPROCESSINFO ppi;
+ BOOL NotSameppi = FALSE;
+ BOOL Ret = TRUE;
DECLARE_RETURN(BOOL);
TRACE("Enter NtUserGetComboBoxInfo\n");
}
_SEH2_END;
+ if (pcbi->cbSize < sizeof(COMBOBOXINFO))
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN(FALSE);
+ }
+
// Pass the user pointer, it was already probed.
- RETURN( (BOOL) co_IntSendMessage( Wnd->head.h, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
+ if ((Wnd->pcls->atomClassName != gpsi->atomSysClass[ICLS_COMBOBOX]) && Wnd->fnid != FNID_COMBOBOX)
+ {
+ RETURN( (BOOL) co_IntSendMessage( Wnd->head.h, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
+ }
+
+ ppi = PsGetCurrentProcessWin32Process();
+ NotSameppi = ppi != Wnd->head.pti->ppi;
+ if (NotSameppi)
+ {
+ KeAttachProcess(&Wnd->head.pti->ppi->peProcess->Pcb);
+ }
+
+ _SEH2_TRY
+ {
+ LPHEADCOMBO lphc = ((PWND2CBOX)Wnd)->pCBox;
+ pcbi->rcItem = lphc->textRect;
+ pcbi->rcButton = lphc->buttonRect;
+ pcbi->stateButton = 0;
+ if (lphc->wState & CBF_BUTTONDOWN)
+ pcbi->stateButton |= STATE_SYSTEM_PRESSED;
+ if (RECTL_bIsEmptyRect(&lphc->buttonRect))
+ pcbi->stateButton |= STATE_SYSTEM_INVISIBLE;
+ pcbi->hwndCombo = lphc->self;
+ pcbi->hwndItem = lphc->hWndEdit;
+ pcbi->hwndList = lphc->hWndLBox;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = FALSE;
+ SetLastNtError(_SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ RETURN( Ret);
CLEANUP:
+ if (NotSameppi) KeDetachProcess();
TRACE("Leave NtUserGetComboBoxInfo, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
-
+////
+//// ReactOS work around! Keep it the sames as in Listbox.c
+////
+/* Listbox structure */
+typedef struct
+{
+ HWND self; /* Our own window handle */
+ HWND owner; /* Owner window to send notifications to */
+ UINT style; /* Window style */
+ INT width; /* Window width */
+ INT height; /* Window height */
+ VOID *items; /* Array of items */
+ INT nb_items; /* Number of items */
+ INT top_item; /* Top visible item */
+ INT selected_item; /* Selected item */
+ INT focus_item; /* Item that has the focus */
+ INT anchor_item; /* Anchor item for extended selection */
+ INT item_height; /* Default item height */
+ INT page_size; /* Items per listbox page */
+ INT column_width; /* Column width for multi-column listboxes */
+} LB_DESCR;
+
+// Window Extra data container.
+typedef struct _WND2LB
+{
+ WND;
+ LB_DESCR * pLBiv;
+} WND2LB, *PWND2LB;
+////
+////
+////
DWORD
APIENTRY
NtUserGetListBoxInfo(
HWND hWnd)
{
PWND Wnd;
+ PPROCESSINFO ppi;
+ BOOL NotSameppi = FALSE;
+ DWORD Ret = 0;
DECLARE_RETURN(DWORD);
TRACE("Enter NtUserGetListBoxInfo\n");
RETURN( 0 );
}
- RETURN( (DWORD) co_IntSendMessage( Wnd->head.h, LB_GETLISTBOXINFO, 0, 0 ));
+ if ((Wnd->pcls->atomClassName != gpsi->atomSysClass[ICLS_LISTBOX]) && Wnd->fnid != FNID_LISTBOX)
+ {
+ RETURN( (DWORD) co_IntSendMessage( Wnd->head.h, LB_GETLISTBOXINFO, 0, 0 ));
+ }
+
+ // wine lisbox:test_GetListBoxInfo lb_getlistboxinfo = 0, should not send a message!
+ ppi = PsGetCurrentProcessWin32Process();
+ NotSameppi = ppi != Wnd->head.pti->ppi;
+ if (NotSameppi)
+ {
+ KeAttachProcess(&Wnd->head.pti->ppi->peProcess->Pcb);
+ }
+
+ _SEH2_TRY
+ {
+ LB_DESCR *descr = ((PWND2LB)Wnd)->pLBiv;
+ // See Controls ListBox.c:LB_GETLISTBOXINFO must match...
+ if (descr->style & LBS_MULTICOLUMN) //// ReactOS
+ Ret = descr->page_size * descr->column_width;
+ else
+ Ret = descr->page_size;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Ret = 0;
+ SetLastNtError(_SEH2_GetExceptionCode());
+ }
+ _SEH2_END;
+
+ RETURN( Ret);
CLEANUP:
- TRACE("Leave NtUserGetListBoxInfo, ret=%i\n",_ret_);
+ if (NotSameppi) KeDetachProcess();
+ TRACE("Leave NtUserGetListBoxInfo, ret=%lu\n", _ret_);
UserLeave();
END_CLEANUP;
}
RETURN( co_UserSetParent(hWndChild, hWndNewParent));
CLEANUP:
- TRACE("Leave NtUserSetParent, ret=%i\n",_ret_);
+ TRACE("Leave NtUserSetParent, ret=%p\n", _ret_);
UserLeave();
END_CLEANUP;
}
}
UserRefObjectCo(WndShell, &Ref);
+ WndShell->state2 |= WNDS2_BOTTOMMOST;
co_WinPosSetWindowPos(WndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
WinStaObject->ShellWindow = hwndShell;
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);
NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
{
PWND Window;
- PMENU_OBJECT Menu;
+ PMENU Menu;
DECLARE_RETURN(HMENU);
TRACE("Enter NtUserGetSystemMenu\n");
RETURN(NULL);
}
- RETURN(Menu->MenuInfo.Self);
+ RETURN(Menu->head.h);
CLEANUP:
- TRACE("Leave NtUserGetSystemMenu, ret=%i\n",_ret_);
+ TRACE("Leave NtUserGetSystemMenu, ret=%p\n", _ret_);
UserLeave();
END_CLEANUP;
}
{
BOOL Result = FALSE;
PWND Window;
- PMENU_OBJECT Menu;
+ PMENU Menu;
DECLARE_RETURN(BOOL);
TRACE("Enter NtUserSetSystemMenu\n");
LONG OldValue;
STYLESTRUCT Style;
- if (hWnd == IntGetDesktopWindow())
- {
- EngSetLastError(STATUS_ACCESS_DENIED);
- return( 0);
- }
-
if (!(Window = UserGetWindowObject(hWnd)))
{
return( 0);
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;
break;
default:
- ERR("NtUserSetWindowLong(): Unsupported index %d\n", Index);
+ ERR("NtUserSetWindowLong(): Unsupported index %lu\n", Index);
EngSetLastError(ERROR_INVALID_INDEX);
OldValue = 0;
break;
TRACE("Enter NtUserSetWindowLong\n");
UserEnterExclusive();
+ if (hWnd == IntGetDesktopWindow())
+ {
+ EngSetLastError(STATUS_ACCESS_DENIED);
+ RETURN( 0);
+ }
+
RETURN( co_UserSetWindowLong(hWnd, Index, NewValue, Ansi));
CLEANUP:
TRACE("Enter NtUserSetWindowWord\n");
UserEnterExclusive();
+ if (hWnd == IntGetDesktopWindow())
+ {
+ EngSetLastError(STATUS_ACCESS_DENIED);
+ RETURN( 0);
+ }
+
if (!(Window = UserGetWindowObject(hWnd)))
{
RETURN( 0);
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)
{
RETURN( OldValue);
CLEANUP:
- TRACE("Leave NtUserSetWindowWord, ret=%i\n",_ret_);
+ TRACE("Leave NtUserSetWindowWord, ret=%u\n", _ret_);
UserLeave();
END_CLEANUP;
}
DWORD APIENTRY
NtUserQueryWindow(HWND hWnd, DWORD Index)
{
+/* Console Leader Process CID Window offsets */
+#define GWLP_CONSOLE_LEADER_PID 0
+#define GWLP_CONSOLE_LEADER_TID 4
+
PWND pWnd;
DWORD Result;
DECLARE_RETURN(UINT);
switch(Index)
{
case QUERY_WINDOW_UNIQUE_PROCESS_ID:
- Result = (DWORD)IntGetWndProcessId(pWnd);
+ {
+ if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
+ (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) )
+ {
+ // IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_PID)
+ Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_PID)));
+ }
+ else
+ {
+ Result = (DWORD)IntGetWndProcessId(pWnd);
+ }
break;
+ }
case QUERY_WINDOW_UNIQUE_THREAD_ID:
- Result = (DWORD)IntGetWndThreadId(pWnd);
+ {
+ if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
+ (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) )
+ {
+ // IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_TID)
+ Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_TID)));
+ }
+ else
+ {
+ Result = (DWORD)IntGetWndThreadId(pWnd);
+ }
break;
+ }
case QUERY_WINDOW_ACTIVE:
Result = (DWORD)(pWnd->head.pti->MessageQueue->spwndActive ? UserHMGetHandle(pWnd->head.pti->MessageQueue->spwndActive) : 0);
break;
case QUERY_WINDOW_ISHUNG:
- Result = (DWORD)MsqIsHung(pWnd->head.pti->MessageQueue);
+ Result = (DWORD)MsqIsHung(pWnd->head.pti);
break;
case QUERY_WINDOW_REAL_ID:
RETURN( Result);
CLEANUP:
- TRACE("Leave NtUserQueryWindow, ret=%i\n",_ret_);
+ TRACE("Leave NtUserQueryWindow, ret=%u\n", _ret_);
UserLeave();
END_CLEANUP;
}
RETURN( Ret);
CLEANUP:
- TRACE("Leave NtUserRegisterWindowMessage, ret=%i\n",_ret_);
+ TRACE("Leave NtUserRegisterWindowMessage, ret=%u\n", _ret_);
UserLeave();
END_CLEANUP;
}
/* 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;
END_CLEANUP;
}
-
+/*
+ API Call
+*/
BOOL
FASTCALL
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;
count++;
while (--count >= 0)
{
- if (!(pWnd = UserGetWindowObject( win_array[count] )))
+ if (!(pWnd = ValidateHwndNoErr( win_array[count] )))
continue;
if (pWnd->spwndOwner != OwnerWnd)
continue;
}
}
- ExFreePool( win_array );
+ ExFreePoolWithTag(win_array, USERTAG_WINDOWLIST);
+ TRACE("Leave ShowOwnedPopups\n");
return TRUE;
}