if (message >= 8*sizeof(message_pointer_flags)) return FALSE;
return (message_pointer_flags[message / 32] & SET(message)) != 0;
}
+#undef SET
#define MMS_SIZE_WPARAM -1
#define MMS_SIZE_WPARAMWCHAR -2
co_HOOK_CallHooks( WH_CALLWNDPROCRET, HC_ACTION, SameThread, (LPARAM)&CWPR );
}
+static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPARAM lparam )
+{
+ LRESULT lRes;
+
+ if (!pWnd ||
+ pWnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ pWnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
+ return 0;
+
+ ERR("Internal Event Msg %p\n",msg);
+
+ switch(msg)
+ {
+ case WM_ASYNC_SHOWWINDOW:
+ return co_WinPosShowWindow( pWnd, wparam );
+ case WM_ASYNC_SETWINDOWPOS:
+ {
+ PWINDOWPOS winpos = (PWINDOWPOS)lparam;
+ if (!winpos) return 0;
+ lRes = co_WinPosSetWindowPos( pWnd,
+ winpos->hwndInsertAfter,
+ winpos->x,
+ winpos->y,
+ winpos->cx,
+ winpos->cy,
+ winpos->flags);
+ ExFreePoolWithTag(winpos, USERTAG_SWP);
+ return lRes;
+ }
+ }
+ return 0;
+}
+
LRESULT FASTCALL
IntDispatchMessage(PMSG pMsg)
{
// Need a window!
if ( !Window ) return 0;
+ if (pMsg->message == WM_PAINT) Window->state |= WNDS_PAINTNOTPROCESSED;
+
+ if ( Window->state & WNDS_SERVERSIDEWINDOWPROC )
+ {
+ TRACE("Dispatch: Server Side Window Procedure\n");
+ }
+
/* Since we are doing a callback on the same thread right away, there is
no need to copy the lparam to kernel mode and then back to usermode.
We just pretend it isn't a pointer */
if (pMsg->message == WM_PAINT)
{
+ Window->state2 &= ~WNDS2_WMPAINTSENT;
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
co_UserGetUpdateRgn( Window, hrgn, TRUE );
PWND DesktopWindow;
ULONG i;
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
if (List != NULL)
UserPostMessage(DesktopWindow->head.h, Msg, wParam, lParam);
for (i = 0; List[i]; i++)
{
+ PWND pwnd = UserGetWindowObject(List[i]);
+ if (!pwnd) continue;
+
+ if ( pwnd->fnid == FNID_MENU || // Also need pwnd->pcls->atomClassName == gaOleMainThreadWndClass
+ pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] )
+ continue;
+
UserPostMessage(List[i], Msg, wParam, lParam);
}
ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
return TRUE;
}
-
LRESULT FASTCALL
co_IntSendMessage( HWND hWnd,
UINT Msg,
INT lParamBufferSize;
LPARAM lParamPacked;
PTHREADINFO Win32Thread;
- ULONG_PTR Result = 0;
+ ULONG_PTR Hi, Lo, Result = 0;
DECLARE_RETURN(LRESULT);
USER_REFERENCE_ENTRY Ref;
Win32Thread = PsGetCurrentThreadWin32Thread();
-
- if ( NULL != Win32Thread &&
+ if ( Win32Thread &&
Window->head.pti->MessageQueue == Win32Thread->MessageQueue)
{
if (Win32Thread->TIF_flags & TIF_INCLEANUP)
RETURN( FALSE);
}
+ if (Msg & 0x80000000)
+ {
+ ERR("SMTS: Internal Message!\n");
+ Result = (ULONG_PTR)handle_internal_message( Window, Msg, wParam, lParam );
+ if (uResult) *uResult = Result;
+ RETURN( TRUE);
+ }
+
+ // Only happens when calling the client!
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+ if ( Window->state & WNDS_SERVERSIDEWINDOWPROC )
+ {
+ TRACE("SMT: Server Side Window Procedure\n");
+ IoGetStackLimits(&Lo, &Hi);
+ // Handle it here. Safeguard against excessive recursions.
+ if (((ULONG_PTR)&uResult - Lo) < 4096 )
+ {
+ ERR("Server Callback Exceeded Stack!\n");
+ RETURN( FALSE);
+ }
+ /* Return after server side call, IntCallWndProcRet will not be called. */
+ }
/* See if this message type is present in the table */
MsgMemoryEntry = FindMsgMemory(Msg);
if (NULL == MsgMemoryEntry)
{
- lParamBufferSize = -1;
+ lParamBufferSize = -1;
}
else
{
- lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
+ lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
}
if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, FALSE)))
{
- ERR("Failed to pack message parameters\n");
- RETURN( FALSE);
+ ERR("Failed to pack message parameters\n");
+ RETURN( FALSE);
}
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
*uResult = Result;
}
- IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
-
if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
{
ERR("Failed to unpack message parameters\n");
RETURN( TRUE);
}
+ // Only happens when calling the client!
+ IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult);
+
RETURN( TRUE);
}
EngSetLastError(ERROR_TIMEOUT);
RETURN( FALSE);
}
- else if (! NT_SUCCESS(Status))
+ else if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( FALSE);
HWND *Children;
HWND *Child;
- if (HWND_BROADCAST != hWnd)
+ if (hWnd != HWND_BROADCAST && hWnd != HWND_TOPMOST)
{
return co_IntSendMessageTimeoutSingle(hWnd, Msg, wParam, lParam, uFlags, uTimeout, uResult);
}
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ DesktopWindow = UserGetDesktopWindow();
if (NULL == DesktopWindow)
{
- EngSetLastError(ERROR_INTERNAL_ERROR);
- return 0;
+ EngSetLastError(ERROR_INTERNAL_ERROR);
+ return 0;
}
- /* Send message to the desktop window too! */
- co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ if (hWnd != HWND_TOPMOST)
+ {
+ /* Send message to the desktop window too! */
+ co_IntSendMessageTimeoutSingle(DesktopWindow->head.h, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ }
Children = IntWinListChildren(DesktopWindow);
if (NULL == Children)
for (Child = Children; NULL != *Child; Child++)
{
- co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ if (hWnd == HWND_TOPMOST)
+ {
+ DesktopWindow = UserGetWindowObject(*Child);
+ if (DesktopWindow && DesktopWindow->ExStyle & WS_EX_TOPMOST)
+ {
+ ERR("HWND_TOPMOST Found\n");
+ co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ }
+ }
+ else
+ {
+ PWND pwnd = UserGetWindowObject(*Child);
+ if (!pwnd) continue;
+
+ if ( pwnd->fnid == FNID_MENU ||
+ pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] )
+ continue;
+
+ co_IntSendMessageTimeoutSingle(*Child, Msg, wParam, lParam, uFlags, uTimeout, uResult);
+ }
}
ExFreePool(Children);
LPARAM lParam)
{
ULONG_PTR Result = 0;
- co_IntSendMessageWithCallBack(hWnd,
- Msg,
- wParam,
- lParam,
- NULL,
- 0,
- &Result);
+ if (!co_IntSendMessageWithCallBack( hWnd,
+ Msg,
+ wParam,
+ lParam,
+ NULL,
+ 0,
+ &Result))
+ {
+ Result = ((ULONG_PTR)-1);
+ }
return Result;
}
/* MSDN:
RETURN(FALSE);
}
+ if (Msg & 0x80000000)
+ {
+ ERR("SMWCB: Internal Message!\n");
+ Result = (ULONG_PTR)handle_internal_message( Window, Msg, wParam, lParam );
+ if (uResult) *uResult = Result;
+ RETURN( TRUE);
+ }
+
IntCallWndProc( Window, hWnd, Msg, wParam, lParam);
+ if ( Window->state & WNDS_SERVERSIDEWINDOWPROC )
+ {
+ TRACE("SMWCB: Server Side Window Procedure\n");
+ }
+
Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc,
!Window->Unicode,
hWnd,
END_CLEANUP;
}
-/* This function posts a message if the destination's message queue belongs to
-another thread, otherwise it sends the message. It does not support broadcast
-messages! */
+
+/*
+ This HACK function posts a message if the destination's message queue belongs to
+ another thread, otherwise it sends the message. It does not support broadcast
+ messages!
+*/
LRESULT FASTCALL
co_IntPostOrSendMessage( HWND hWnd,
UINT Msg,
MSG KernelModeMsg;
PMSGMEMORY MsgMemoryEntry;
- if (HWND_BROADCAST != hWnd)
+ if (hWnd != HWND_BROADCAST && hWnd != HWND_TOPMOST)
{
Window = UserGetWindowObject(hWnd);
if ( !Window )
PWND DesktopWindow;
ULONG i;
- DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ DesktopWindow = UserGetDesktopWindow();
List = IntWinListChildren(DesktopWindow);
if (List != NULL)
UserSendNotifyMessage(DesktopWindow->head.h, Msg, wParam, lParam);
for (i = 0; List[i]; i++)
{
- Ret = UserSendNotifyMessage(List[i], Msg, wParam, lParam);
+ PWND pwnd = UserGetWindowObject(List[i]);
+ if (!pwnd) continue;
+
+ if ( pwnd->fnid == FNID_MENU ||
+ pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_SWITCH] )
+ continue;
+
+ Ret = UserSendNotifyMessage(List[i], Msg, wParam, lParam);
}
ExFreePool(List);
}
}
else
{
- ULONG_PTR lResult = 0;
- Ret = co_IntSendMessageWithCallBack( hWnd,
- Msg,
- wParam,
- lParam,
- NULL,
- 0,
- &lResult);
+ Ret = co_IntSendMessageNoWait( hWnd, Msg, wParam, lParam);
+ if (-1 == (int) Ret || !Ret) Ret = FALSE;
}
return Ret;
}
ULONG i;
UINT fuFlags;
- pwndDesk = UserGetWindowObject(IntGetDesktopWindow());
+ pwndDesk = UserGetDesktopWindow();
List = IntWinListChildren(pwndDesk);
if (parm.flags & BSF_QUERY)
(SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
#define EMPTYPOINT(pt) ((pt).x == -1 && (pt).y == -1)
+#define PLACE_MIN 0x0001
+#define PLACE_MAX 0x0002
+#define PLACE_RECT 0x0004
/* FUNCTIONS *****************************************************************/
if (WndTo) UserDerefObjectCo(WndTo);
}
+BOOL
+FASTCALL
+WinPosShowIconTitle( PWND pWnd, BOOL bShow )
+{
+ HICON hIcon;
+ if (!pWnd->pcls || pWnd->fnid == FNID_DESKTOP) return FALSE;
+ if (!hIcon) hIcon = pWnd->pcls->hIconSm;
+ if (!hIcon) hIcon = pWnd->pcls->hIcon;
+ if (!hIcon) return FALSE;
+
+ if ( bShow )
+ {
+ // FIXME: Draw ICON!
+ }
+ else if (hIcon)
+ return FALSE;
+
+ return FALSE;
+}
UINT
FASTCALL
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Child, &Ref);
- co_WinPosSetWindowPos(Child, 0, x + (xspacing - UserGetSystemMetrics(SM_CXICON)) / 2,
- y - yspacing - UserGetSystemMetrics(SM_CYICON) / 2
- , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
+ co_WinPosSetWindowPos( Child,
+ 0,
+ x + (xspacing - UserGetSystemMetrics(SM_CXICON)) / 2,
+ y - yspacing - UserGetSystemMetrics(SM_CYICON) / 2,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
UserDerefObjectCo(Child);
static VOID FASTCALL
WinPosFindIconPos(PWND Window, POINT *Pos)
{
- ERR("WinPosFindIconPos FIXME!\n");
+ RECT rect, rectParent;
+ PWND pwndChild, pwndParent;
+ HRGN hrgn, tmp;
+ int xspacing, yspacing;
+
+ pwndParent = Window->spwndParent;
+ if (pwndParent == UserGetDesktopWindow())
+ {
+ /* ReactOS doesn't support iconic minimize to desktop */
+ Pos->x = Pos->y = -32000;
+ return;
+ }
+
+ IntGetClientRect( pwndParent, &rectParent );
+ if ((Pos->x >= rectParent.left) && (Pos->x + UserGetSystemMetrics(SM_CXICON) < rectParent.right) &&
+ (Pos->y >= rectParent.top) && (Pos->y + UserGetSystemMetrics(SM_CYICON) < rectParent.bottom))
+ return; /* The icon already has a suitable position */
+
+ xspacing = UserGetSystemMetrics(SM_CXICONSPACING);
+ yspacing = UserGetSystemMetrics(SM_CYICONSPACING);
+
+ /* Check if another icon already occupies this spot */
+ /* FIXME: this is completely inefficient */
+
+ hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
+ tmp = IntSysCreateRectRgn( 0, 0, 0, 0 );
+ for (pwndChild = pwndParent->spwndChild; pwndChild; pwndChild = pwndChild->spwndNext)
+ {
+ if (pwndChild == Window) continue;
+ if ((pwndChild->style & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE))
+ continue;
+ if ( pwndChild->spwndParent )
+ {
+ PWND Parent = pwndChild->spwndParent;
+ rect.left = rect.top = 0;
+ rect.right = Parent->rcWindow.right - Parent->rcWindow.left;
+ rect.bottom = Parent->rcWindow.bottom - Parent->rcWindow.top;
+ NtGdiSetRectRgn( tmp, rect.left, rect.top, rect.right, rect.bottom );
+ NtGdiCombineRgn( hrgn, hrgn, tmp, RGN_OR );
+ }
+ }
+ GreDeleteObject( tmp );
+
+ for (rect.bottom = rectParent.bottom; rect.bottom >= yspacing; rect.bottom -= yspacing)
+ {
+ for (rect.left = rectParent.left; rect.left <= rectParent.right - xspacing; rect.left += xspacing)
+ {
+ rect.right = rect.left + xspacing;
+ rect.top = rect.bottom - yspacing;
+ if (!IntRectInRegion( hrgn, &rect ))
+ {
+ /* No window was found, so it's OK for us */
+ Pos->x = rect.left + (xspacing - UserGetSystemMetrics(SM_CXICON)) / 2;
+ Pos->y = rect.top + (yspacing - UserGetSystemMetrics(SM_CYICON)) / 2;
+ GreDeleteObject( hrgn );
+ return;
+ }
+ }
+ }
+ GreDeleteObject( hrgn );
+ Pos->x = Pos->y = 0;
+ return;
}
VOID FASTCALL
-WinPosInitInternalPos(PWND Wnd, POINT *pt, RECTL *RestoreRect)
+WinPosInitInternalPos(PWND Wnd, RECTL *RestoreRect)
{
- PWND Parent;
- UINT XInc, YInc;
+ POINT Size;
+ RECTL Rect = *RestoreRect;
+
+ if (Wnd->spwndParent != UserGetDesktopWindow())
+ {
+ RECTL_vOffsetRect(&Rect,
+ -Wnd->spwndParent->rcClient.left,
+ -Wnd->spwndParent->rcClient.top);
+ }
+
+ Size.x = Rect.left;
+ Size.y = Rect.top;
if (!Wnd->InternalPosInitialized)
{
- RECTL WorkArea;
+ // FIXME: Use check point Atom..
+ Wnd->InternalPos.flags = 0;
+ Wnd->InternalPos.MaxPos.x = Wnd->InternalPos.MaxPos.y = -1;
+ Wnd->InternalPos.IconPos.x = Wnd->InternalPos.IconPos.y = -1;
+ Wnd->InternalPos.NormalRect = Rect;
+ Wnd->InternalPosInitialized = TRUE;
+ }
+
+ if (Wnd->style & WS_MINIMIZE)
+ {
+ Wnd->InternalPos.IconPos = Size;
+ Wnd->InternalPos.flags |= WPF_MININIT;
+ }
+ else if (Wnd->style & WS_MAXIMIZE)
+ {
+ Wnd->InternalPos.flags |= WPF_MAXINIT;
- Parent = Wnd->spwndParent;
- if(Parent)
+ if ( Wnd->spwndParent == Wnd->head.rpdesk->pDeskInfo->spwnd )
{
- if(IntIsDesktopWindow(Parent))
- UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
+ if (Wnd->state & WNDS_MAXIMIZESTOMONITOR)
+ {
+ Wnd->InternalPos.flags &= ~WPF_MAXINIT;
+ Wnd->InternalPos.MaxPos.x = Wnd->InternalPos.MaxPos.y = -1;
+ }
else
- WorkArea = Parent->rcClient;
+ {
+ RECTL WorkArea;
+ PMONITOR pmonitor = IntMonitorFromRect(&Rect, MONITOR_DEFAULTTOPRIMARY );
+
+ // FIXME: support DPI aware, rcWorkDPI/Real etc..
+ if (!(Wnd->style & WS_MAXIMIZEBOX) || (Wnd->state & WNDS_HASCAPTION) || pmonitor->cFullScreen)
+ WorkArea = pmonitor->rcMonitor;
+ else
+ WorkArea = pmonitor->rcWork;
+
+ Wnd->InternalPos.MaxPos.x = Rect.left - WorkArea.left;
+ Wnd->InternalPos.MaxPos.y = Rect.top - WorkArea.top;
+ TRACE("WinPosIP 2 X %d Y %d\n",Wnd->InternalPos.MaxPos.x,Wnd->InternalPos.MaxPos.y);
+ }
}
else
- UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
+ Wnd->InternalPos.MaxPos = Size;
+ }
+ else
+ {
+ Wnd->InternalPos.NormalRect = Rect;
+ }
+}
- Wnd->InternalPos.NormalRect = Wnd->rcWindow;
- IntGetWindowBorderMeasures(Wnd, &XInc, &YInc);
- Wnd->InternalPos.MaxPos.x = WorkArea.left - XInc;
- Wnd->InternalPos.MaxPos.y = WorkArea.top - YInc;
- Wnd->InternalPos.IconPos.x = WorkArea.left;
- Wnd->InternalPos.IconPos.y = WorkArea.bottom - UserGetSystemMetrics(SM_CYMINIMIZED);
+BOOL
+FASTCALL
+IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
+{
+ if (!Wnd) return FALSE;
- Wnd->InternalPosInitialized = TRUE;
+ if(lpwndpl->length != sizeof(WINDOWPLACEMENT))
+ {
+ return FALSE;
}
- if (Wnd->style & WS_MINIMIZE)
+
+ lpwndpl->flags = 0;
+
+ WinPosInitInternalPos(Wnd, &Wnd->rcWindow);
+
+ lpwndpl->showCmd = SW_HIDE;
+
+ if ( Wnd->style & WS_MINIMIZE )
+ lpwndpl->showCmd = SW_SHOWMINIMIZED;
+ else
+ lpwndpl->showCmd = ( Wnd->style & WS_MAXIMIZE ) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
+
+ lpwndpl->rcNormalPosition = Wnd->InternalPos.NormalRect;
+
+ if (Wnd->InternalPos.flags & WPF_MININIT) // Return if it was set!
{
- Wnd->InternalPos.IconPos = *pt;
+ lpwndpl->ptMinPosition.x = Wnd->InternalPos.IconPos.x;
+ lpwndpl->ptMinPosition.y = Wnd->InternalPos.IconPos.y;
}
- else if (Wnd->style & WS_MAXIMIZE)
+ else
+ lpwndpl->ptMinPosition.x = lpwndpl->ptMinPosition.y = -1;
+
+ if ( Wnd->InternalPos.flags & WPF_MAXINIT && // Return if set and not maximized to monitor!
+ !(Wnd->state & WNDS_MAXIMIZESTOMONITOR))
+ {
+ lpwndpl->ptMaxPosition.x = Wnd->InternalPos.MaxPos.x;
+ lpwndpl->ptMaxPosition.y = Wnd->InternalPos.MaxPos.y;
+ }
+ else
+ lpwndpl->ptMaxPosition.x = lpwndpl->ptMaxPosition.y = -1;
+
+ if ( Wnd->spwndParent == Wnd->head.rpdesk->pDeskInfo->spwnd &&
+ !(Wnd->ExStyle & WS_EX_TOOLWINDOW))
+ {
+ PMONITOR pmonitor = IntMonitorFromRect(&lpwndpl->rcNormalPosition, MONITOR_DEFAULTTOPRIMARY );
+
+ // FIXME: support DPI aware, rcWorkDPI/Real etc..
+ if (Wnd->InternalPos.flags & WPF_MININIT)
+ {
+ lpwndpl->ptMinPosition.x -= (pmonitor->rcWork.left - pmonitor->rcMonitor.left);
+ lpwndpl->ptMinPosition.y -= (pmonitor->rcWork.top - pmonitor->rcMonitor.top);
+ }
+ RECTL_vOffsetRect(&lpwndpl->rcNormalPosition,
+ pmonitor->rcMonitor.left - pmonitor->rcWork.left,
+ pmonitor->rcMonitor.top - pmonitor->rcWork.top);
+ }
+
+ if ( Wnd->InternalPos.flags & WPF_RESTORETOMAXIMIZED || Wnd->style & WS_MAXIMIZE )
+ lpwndpl->flags |= WPF_RESTORETOMAXIMIZED;
+
+ if ( ((Wnd->style & (WS_CHILD|WS_POPUP)) == WS_CHILD) && Wnd->InternalPos.flags & WPF_SETMINPOSITION)
+ lpwndpl->flags |= WPF_SETMINPOSITION;
+
+ return TRUE;
+}
+
+/* make sure the specified rect is visible on screen */
+static void make_rect_onscreen( RECT *rect )
+{
+ PMONITOR pmonitor = IntMonitorFromRect( rect, MONITOR_DEFAULTTONEAREST ); // Wine uses this.
+
+ // FIXME: support DPI aware, rcWorkDPI/Real etc..
+ if (!pmonitor) return;
+ /* FIXME: map coordinates from rcWork to rcMonitor */
+ if (rect->right <= pmonitor->rcWork.left)
+ {
+ rect->right += pmonitor->rcWork.left - rect->left;
+ rect->left = pmonitor->rcWork.left;
+ }
+ else if (rect->left >= pmonitor->rcWork.right)
+ {
+ rect->left += pmonitor->rcWork.right - rect->right;
+ rect->right = pmonitor->rcWork.right;
+ }
+ if (rect->bottom <= pmonitor->rcWork.top)
+ {
+ rect->bottom += pmonitor->rcWork.top - rect->top;
+ rect->top = pmonitor->rcWork.top;
+ }
+ else if (rect->top >= pmonitor->rcWork.bottom)
+ {
+ rect->top += pmonitor->rcWork.bottom - rect->bottom;
+ rect->bottom = pmonitor->rcWork.bottom;
+ }
+}
+
+/* make sure the specified point is visible on screen */
+static void make_point_onscreen( POINT *pt )
+{
+ RECT rect;
+
+ RECTL_vSetRect( &rect, pt->x, pt->y, pt->x + 1, pt->y + 1 );
+ make_rect_onscreen( &rect );
+ pt->x = rect.left;
+ pt->y = rect.top;
+}
+
+BOOL FASTCALL
+IntSetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *wpl, UINT Flags)
+{
+ BOOL sAsync;
+ UINT SWP_Flags;
+
+ if ( Flags & PLACE_MIN) make_point_onscreen( &wpl->ptMinPosition );
+ if ( Flags & PLACE_MAX) make_point_onscreen( &wpl->ptMaxPosition );
+ if ( Flags & PLACE_RECT) make_rect_onscreen( &wpl->rcNormalPosition );
+
+ if (!Wnd || Wnd == Wnd->head.rpdesk->pDeskInfo->spwnd) return FALSE;
+
+ if ( Flags & PLACE_MIN ) Wnd->InternalPos.IconPos = wpl->ptMinPosition;
+ if ( Flags & PLACE_MAX ) Wnd->InternalPos.MaxPos = wpl->ptMaxPosition;
+ if ( Flags & PLACE_RECT) Wnd->InternalPos.NormalRect = wpl->rcNormalPosition;
+
+ SWP_Flags = SWP_NOZORDER | SWP_NOACTIVATE | ((wpl->flags & WPF_ASYNCWINDOWPLACEMENT) ? SWP_ASYNCWINDOWPOS : 0);
+
+ if (Wnd->style & WS_MINIMIZE )
+ {
+ if (Flags & PLACE_MIN)
+ {
+ co_WinPosSetWindowPos(Wnd, HWND_TOP,
+ wpl->ptMinPosition.x, wpl->ptMinPosition.y, 0, 0,
+ SWP_NOSIZE | SWP_Flags);
+ Wnd->InternalPos.flags |= WPF_MININIT;
+ }
+ }
+ else if (Wnd->style & WS_MAXIMIZE )
+ {
+ if (Flags & PLACE_MAX)
+ {
+ co_WinPosSetWindowPos(Wnd, HWND_TOP,
+ wpl->ptMaxPosition.x, wpl->ptMaxPosition.y, 0, 0,
+ SWP_NOSIZE | SWP_Flags);
+ Wnd->InternalPos.flags |= WPF_MAXINIT;
+ }
+ }
+ else if (Flags & PLACE_RECT)
{
- Wnd->InternalPos.MaxPos = *pt;
+ co_WinPosSetWindowPos(Wnd, HWND_TOP,
+ wpl->rcNormalPosition.left, wpl->rcNormalPosition.top,
+ wpl->rcNormalPosition.right - wpl->rcNormalPosition.left,
+ wpl->rcNormalPosition.bottom - wpl->rcNormalPosition.top,
+ SWP_Flags);
}
- else if (RestoreRect != NULL)
+
+ sAsync = (Wnd->head.pti->MessageQueue != gptiCurrent->MessageQueue && wpl->flags & WPF_ASYNCWINDOWPLACEMENT);
+
+ if ( sAsync )
+ co_IntSendMessageNoWait( UserHMGetHandle(Wnd), WM_ASYNC_SHOWWINDOW, wpl->showCmd, 0 );
+ else
+ co_WinPosShowWindow(Wnd, wpl->showCmd);
+
+ if ( Wnd->style & WS_MINIMIZE && !sAsync )
{
- Wnd->InternalPos.NormalRect = *RestoreRect;
+ if ( wpl->flags & WPF_SETMINPOSITION )
+ Wnd->InternalPos.flags |= WPF_SETMINPOSITION;
+
+ if ( wpl->flags & WPF_RESTORETOMAXIMIZED )
+ Wnd->InternalPos.flags |= WPF_RESTORETOMAXIMIZED;
}
+ return TRUE;
}
UINT FASTCALL
co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
{
POINT Size;
+ WINDOWPLACEMENT wpl;
UINT SwpFlags = 0;
ASSERT_REFS_CO(Wnd);
- Size.x = Wnd->rcWindow.left;
- Size.y = Wnd->rcWindow.top;
- WinPosInitInternalPos(Wnd, &Size, &Wnd->rcWindow);
+ wpl.length = sizeof(wpl);
+ IntGetWindowPlacement( Wnd, &wpl );
if (co_HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)Wnd->head.h, ShowFlag))
{
}
if (Wnd->style & WS_MINIMIZE)
{
+ if (ShowFlag == SW_MINIMIZE) return SWP_NOSIZE | SWP_NOMOVE;
+
if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0))
{
return(SWP_NOSIZE | SWP_NOMOVE);
{
if (Wnd->style & WS_MAXIMIZE)
{
- Wnd->state2 |= WNDS2_MAXIMIZEBUTTONDOWN;
+ Wnd->InternalPos.flags |= WPF_RESTORETOMAXIMIZED;
Wnd->style &= ~WS_MAXIMIZE;
}
else
{
- Wnd->state2 &= ~WNDS2_MAXIMIZEBUTTONDOWN;
+ Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
}
co_UserRedrawWindow(Wnd, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
RDW_NOINTERNALPAINT);
Wnd->style |= WS_MINIMIZE;
- WinPosFindIconPos(Wnd, &Wnd->InternalPos.IconPos);
- RECTL_vSetRect(NewPos, Wnd->InternalPos.IconPos.x, Wnd->InternalPos.IconPos.y,
+ WinPosFindIconPos(Wnd, &wpl.ptMinPosition);
+ RECTL_vSetRect(NewPos, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
UserGetSystemMetrics(SM_CXMINIMIZED),
UserGetSystemMetrics(SM_CYMINIMIZED));
SwpFlags |= SWP_NOCOPYBITS;
case SW_MAXIMIZE:
{
- co_WinPosGetMinMaxInfo(Wnd, &Size, &Wnd->InternalPos.MaxPos,
- NULL, NULL);
+ co_WinPosGetMinMaxInfo(Wnd, &Size, &wpl.ptMaxPosition, NULL, NULL);
+
TRACE("Maximize: %d,%d %dx%d\n",
- Wnd->InternalPos.MaxPos.x, Wnd->InternalPos.MaxPos.y, Size.x, Size.y);
+ wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
if (Wnd->style & WS_MINIMIZE)
{
Wnd->style &= ~WS_MINIMIZE;
}
Wnd->style |= WS_MAXIMIZE;
- RECTL_vSetRect(NewPos, Wnd->InternalPos.MaxPos.x, Wnd->InternalPos.MaxPos.y,
- Size.x, Size.y);
+ RECTL_vSetRect(NewPos, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
break;
}
if (Wnd->style & WS_MINIMIZE)
{
Wnd->style &= ~WS_MINIMIZE;
- if (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN)
+ if (Wnd->InternalPos.flags & WPF_RESTORETOMAXIMIZED)
{
- co_WinPosGetMinMaxInfo(Wnd, &Size,
- &Wnd->InternalPos.MaxPos, NULL, NULL);
+ co_WinPosGetMinMaxInfo(Wnd, &Size, &wpl.ptMaxPosition, NULL, NULL);
+
Wnd->style |= WS_MAXIMIZE;
- RECTL_vSetRect(NewPos, Wnd->InternalPos.MaxPos.x,
- Wnd->InternalPos.MaxPos.y, Size.x, Size.y);
+ RECTL_vSetRect(NewPos, wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, Size.x, Size.y);
break;
}
else
{
- *NewPos = Wnd->InternalPos.NormalRect;
+ *NewPos = wpl.rcNormalPosition;
NewPos->right -= NewPos->left;
NewPos->bottom -= NewPos->top;
break;
return 0;
}
Wnd->style &= ~WS_MAXIMIZE;
- Wnd->state2 &= ~WNDS2_MAXIMIZEBUTTONDOWN;
- *NewPos = Wnd->InternalPos.NormalRect;
+ Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
+ *NewPos = wpl.rcNormalPosition;
NewPos->right -= NewPos->left;
NewPos->bottom -= NewPos->top;
break;
MinMax.ptMaxPosition.x = -xinc;
MinMax.ptMaxPosition.y = -yinc;
- if (!EMPTYPOINT(Window->InternalPos.MaxPos)) MinMax.ptMaxPosition = Window->InternalPos.MaxPos;
+ if (!EMPTYPOINT(Window->InternalPos.MaxPos)) MinMax.ptMaxPosition = Window->InternalPos.MaxPos;
co_IntSendMessage(Window->head.h, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
if ( Window->head.h == IntGetDesktopWindow() &&
Window->head.pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
{
+ ERR("Desktop Window...\n");
return FALSE;
}
bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
ASSERT_REFS_CO(Window);
*ClientRect = *WindowRect;
- Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect);
+ Result = co_IntSendMessage(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect);
FixClientRect(ClientRect, WindowRect);
void FASTCALL
co_WinPosSendSizeMove(PWND Wnd)
{
+ RECTL Rect;
+ LPARAM lParam;
WPARAM wParam = SIZE_RESTORED;
+ IntGetClientRect(Wnd, &Rect);
+
Wnd->state &= ~WNDS_SENDSIZEMOVEMSGS;
if (Wnd->style & WS_MAXIMIZE)
{
wParam = SIZE_MINIMIZED;
}
- co_IntSendMessageNoWait(Wnd->head.h, WM_SIZE, wParam,
- MAKELONG(Wnd->rcClient.right -
- Wnd->rcClient.left,
- Wnd->rcClient.bottom -
- Wnd->rcClient.top));
- co_IntSendMessageNoWait(Wnd->head.h, WM_MOVE, 0,
- MAKELONG(Wnd->rcClient.left,
- Wnd->rcClient.top));
+ co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam, MAKELONG(Rect.right-Rect.left, Rect.bottom-Rect.top));
+
+ 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);
+
+ co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_MOVE, 0, lParam);
IntEngWindowChanged(Wnd, WOC_RGN_CLIENT);
}
break;
case SW_SHOWNOACTIVATE:
- Wnd->state2 &= ~WNDS2_MAXIMIZEBUTTONDOWN;
+ Wnd->InternalPos.flags &= ~WPF_RESTORETOMAXIMIZED;
//Swp |= SWP_NOZORDER;
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
return retvalue;
}
-BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp )
+BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp, BOOL sAsync )
{
PSMWP pDWP;
PCVR winpos;
UserRefObjectCo(pwnd, &Ref);
- res = co_WinPosSetWindowPos( pwnd,
- winpos->pos.hwndInsertAfter,
- winpos->pos.x,
- winpos->pos.y,
- winpos->pos.cx,
- winpos->pos.cy,
- winpos->pos.flags);
+ if ( sAsync )
+ {
+ LRESULT lRes;
+ PWINDOWPOS ppos = ExAllocatePoolWithTag(PagedPool, sizeof(WINDOWPOS), USERTAG_SWP);
+ if ( ppos )
+ {
+ *ppos = winpos->pos;
+ /* Yes it's a pointer inside Win32k! */
+ lRes = co_IntSendMessageNoWait( winpos->pos.hwnd, WM_ASYNC_SETWINDOWPOS, 0, (LPARAM)ppos);
+ /* We handle this the same way as Event Hooks and Hooks. */
+ if ( -1 == (int) lRes )
+ {
+ ExFreePoolWithTag(ppos, USERTAG_SWP);
+ }
+ }
+ }
+ else
+ res = co_WinPosSetWindowPos( pwnd,
+ winpos->pos.hwndInsertAfter,
+ winpos->pos.x,
+ winpos->pos.y,
+ winpos->pos.cx,
+ winpos->pos.cy,
+ winpos->pos.flags);
UserDerefObjectCo(pwnd);
}
return res;
}
+
/*
* @implemented
*/
BOOL Ret;
TRACE("Enter NtUserEndDeferWindowPosEx\n");
UserEnterExclusive();
- Ret = IntEndDeferWindowPosEx(WinPosInfo);
+ Ret = IntEndDeferWindowPosEx(WinPosInfo, (BOOL)Unknown1);
TRACE("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret);
UserLeave();
return Ret;
return Ret;
}
+/*
+ * @implemented
+ */
+DWORD APIENTRY
+NtUserGetInternalWindowPos( HWND hWnd,
+ LPRECT rectWnd,
+ LPPOINT ptIcon)
+{
+ PWND Window;
+ DWORD Ret = 0;
+ BOOL Hit = FALSE;
+ WINDOWPLACEMENT wndpl;
+
+ UserEnterShared();
+
+ if (!(Window = UserGetWindowObject(hWnd)))
+ {
+ Hit = FALSE;
+ goto Exit;
+ }
+
+ _SEH2_TRY
+ {
+ if(rectWnd)
+ {
+ ProbeForWrite(rectWnd,
+ sizeof(RECT),
+ 1);
+ }
+ if(ptIcon)
+ {
+ ProbeForWrite(ptIcon,
+ sizeof(POINT),
+ 1);
+ }
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Hit = TRUE;
+ }
+ _SEH2_END;
+
+ wndpl.length = sizeof(WINDOWPLACEMENT);
+
+ if (IntGetWindowPlacement(Window, &wndpl) && !Hit)
+ {
+ _SEH2_TRY
+ {
+ if (rectWnd)
+ {
+ RtlCopyMemory(rectWnd, &wndpl.rcNormalPosition , sizeof(RECT));
+ }
+ if (ptIcon)
+ {
+ RtlCopyMemory(ptIcon, &wndpl.ptMinPosition, sizeof(POINT));
+ }
+
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ Hit = TRUE;
+ }
+ _SEH2_END;
+
+ if (!Hit) Ret = wndpl.showCmd;
+ }
+Exit:
+ UserLeave();
+ return Ret;
+}
+
+/*
+ * @implemented
+ */
+BOOL APIENTRY
+NtUserGetWindowPlacement(HWND hWnd,
+ WINDOWPLACEMENT *lpwndpl)
+{
+ PWND Wnd;
+ WINDOWPLACEMENT Safepl;
+ NTSTATUS Status;
+ DECLARE_RETURN(BOOL);
+
+ TRACE("Enter NtUserGetWindowPlacement\n");
+ UserEnterShared();
+
+ if (!(Wnd = UserGetWindowObject(hWnd)))
+ {
+ RETURN( FALSE);
+ }
+
+ Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( FALSE);
+ }
+ if(Safepl.length != sizeof(WINDOWPLACEMENT))
+ {
+ RETURN( FALSE);
+ }
+
+ IntGetWindowPlacement(Wnd, &Safepl);
+
+ Status = MmCopyToCaller(lpwndpl, &Safepl, sizeof(WINDOWPLACEMENT));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ RETURN( FALSE);
+ }
+
+ RETURN( TRUE);
+
+CLEANUP:
+ TRACE("Leave NtUserGetWindowPlacement, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
DWORD
APIENTRY
NtUserMinMaximize(
if (GreIsHandleValid(hRgn))
{
hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
-
- NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY);
+ /* The coordinates of a window's window region are relative to the
+ upper-left corner of the window, not the client area of the window. */
+ NtGdiCombineRgn( hrgnCopy, hRgn, 0, RGN_COPY);
}
else
RETURN( 0);
hrgnCopy = NULL;
}
- /* Delete the region passed by the caller */
- GreDeleteObject(hRgn);
-
if (Window->hrgnClip)
{
/* Delete no longer needed region handle */
END_CLEANUP;
}
+/*
+ * @implemented
+ */
+DWORD APIENTRY
+NtUserSetInternalWindowPos(
+ HWND hwnd,
+ UINT showCmd,
+ LPRECT lprect,
+ LPPOINT lppt)
+{
+ WINDOWPLACEMENT wndpl;
+ UINT flags;
+ PWND Wnd;
+ RECT rect;
+ POINT pt = {0};
+ DECLARE_RETURN(BOOL);
+ USER_REFERENCE_ENTRY Ref;
+
+ TRACE("Enter NtUserSetWindowPlacement\n");
+ UserEnterExclusive();
+
+ if (!(Wnd = UserGetWindowObject(hwnd)) || // FIXME:
+ Wnd == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ Wnd == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
+ {
+ RETURN( FALSE);
+ }
+
+ _SEH2_TRY
+ {
+ if (lppt)
+ {
+ ProbeForRead(lppt, sizeof(POINT), 1);
+ RtlCopyMemory(&pt, lppt, sizeof(POINT));
+ }
+ if (lprect)
+ {
+ ProbeForRead(lprect, sizeof(RECT), 1);
+ RtlCopyMemory(&rect, lprect, sizeof(RECT));
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(RETURN( FALSE));
+ }
+ _SEH2_END
+
+ wndpl.length = sizeof(wndpl);
+ wndpl.showCmd = showCmd;
+ wndpl.flags = flags = 0;
+
+ if ( lppt )
+ {
+ flags |= PLACE_MIN;
+ wndpl.flags |= WPF_SETMINPOSITION;
+ wndpl.ptMinPosition = pt;
+ }
+ if ( lprect )
+ {
+ flags |= PLACE_RECT;
+ wndpl.rcNormalPosition = rect;
+ }
+
+ UserRefObjectCo(Wnd, &Ref);
+ IntSetWindowPlacement(Wnd, &wndpl, flags);
+ UserDerefObjectCo(Wnd);
+ RETURN(TRUE);
+
+CLEANUP:
+ TRACE("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
+}
+
/*
* @implemented
*/
{
PWND Wnd;
WINDOWPLACEMENT Safepl;
+ UINT Flags;
DECLARE_RETURN(BOOL);
USER_REFERENCE_ENTRY Ref;
RETURN( FALSE);
}
+ Flags = PLACE_MAX | PLACE_RECT;
+ if (Safepl.flags & WPF_SETMINPOSITION) Flags |= PLACE_MIN;
UserRefObjectCo(Wnd, &Ref);
-
- if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
- {
- co_WinPosSetWindowPos(Wnd, NULL,
- Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
- Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left,
- Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
-
- /* FIXME - change window status */
- co_WinPosShowWindow(Wnd, Safepl.showCmd);
-
- Wnd->InternalPosInitialized = TRUE;
- Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition;
- Wnd->InternalPos.IconPos = Safepl.ptMinPosition;
- Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition;
-
+ IntSetWindowPlacement(Wnd, &Safepl, Flags);
UserDerefObjectCo(Wnd);
RETURN(TRUE);
}
/*
- * @unimplemented
+ * @implemented
*/
BOOL APIENTRY
NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow)
{
-#if 0
- STUB
- return 0;
-#else
- return NtUserShowWindow(hWnd, nCmdShow);
-#endif
+ PWND Window;
+ BOOL ret;
+ DECLARE_RETURN(BOOL);
+ USER_REFERENCE_ENTRY Ref;
+
+ TRACE("Enter NtUserShowWindowAsync\n");
+ UserEnterExclusive();
+
+ if (!(Window = UserGetWindowObject(hWnd)) || // FIXME:
+ Window == IntGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
+ Window == IntGetMessageWindow() ) // pWnd->fnid == FNID_MESSAGEWND
+ {
+ RETURN(FALSE);
+ }
+
+ if ( nCmdShow > SW_MAX )
+ {
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ RETURN(FALSE);
+ }
+
+ UserRefObjectCo(Window, &Ref);
+ ret = co_IntSendMessageNoWait( hWnd, WM_ASYNC_SHOWWINDOW, nCmdShow, 0 );
+ UserDerefObjectCo(Window);
+ if (-1 == (int) ret || !ret) ret = FALSE;
+
+ RETURN(ret);
+
+CLEANUP:
+ TRACE("Leave NtUserShowWindowAsync, ret=%i\n",_ret_);
+ UserLeave();
+ END_CLEANUP;
}
/*
END_CLEANUP;
}
-//// Ugly NtUser API ////
-BOOL
-APIENTRY
-NtUserGetMinMaxInfo(
- HWND hWnd,
- MINMAXINFO *MinMaxInfo,
- BOOL SendMessage)
+
+/*
+ * @implemented
+ */
+HWND APIENTRY
+NtUserWindowFromPoint(LONG X, LONG Y)
{
- POINT Size;
- PWND Window = NULL;
- MINMAXINFO SafeMinMax;
- NTSTATUS Status;
- BOOL ret;
+ POINT pt;
+ HWND Ret;
+ PWND DesktopWindow = NULL, Window = NULL;
+ USHORT hittest;
+ DECLARE_RETURN(HWND);
USER_REFERENCE_ENTRY Ref;
- TRACE("Enter NtUserGetMinMaxInfo\n");
+ TRACE("Enter NtUserWindowFromPoint\n");
UserEnterExclusive();
- if(!(Window = UserGetWindowObject(hWnd)))
+ if ((DesktopWindow = UserGetWindowObject(IntGetDesktopWindow())))
{
- ret = FALSE;
- goto cleanup;
- }
+ //PTHREADINFO pti;
- UserRefObjectCo(Window, &Ref);
+ pt.x = X;
+ pt.y = Y;
- Size.x = Window->rcWindow.left;
- Size.y = Window->rcWindow.top;
- WinPosInitInternalPos(Window, &Size,
- &Window->rcWindow);
+ //hmm... threads live on desktops thus we have a reference on the desktop and indirectly the desktop window
+ //its possible this referencing is useless, thou it shouldnt hurt...
+ UserRefObjectCo(DesktopWindow, &Ref);
- co_WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition,
- &SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
+ //pti = PsGetCurrentThreadWin32Thread();
+ Window = co_WinPosWindowFromPoint(DesktopWindow, &pt, &hittest);
- Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
- if(!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- ret = FALSE;
- goto cleanup;
+ if(Window)
+ {
+ Ret = Window->head.h;
+
+ RETURN( Ret);
+ }
}
- ret = TRUE;
+ RETURN( NULL);
-cleanup:
- if (Window) UserDerefObjectCo(Window);
+CLEANUP:
+ if (Window) UserDereferenceObject(Window);
+ if (DesktopWindow) UserDerefObjectCo(DesktopWindow);
- TRACE("Leave NtUserGetMinMaxInfo, ret=%i\n", ret);
+ TRACE("Leave NtUserWindowFromPoint, ret=%i\n",_ret_);
UserLeave();
- return ret;
+ END_CLEANUP;
}
/* EOF */