- Move the system command Move and Size to Win32k. Fix most redraw issues. ATM this will be plugged in after User32 DefWnd cleanup.
- Move more DefWindowProc functions into Win32k, these too will been needed soon.
- Added more server side support functions.
- See CORE-7447.

svn path=/trunk/; revision=62744
This commit is contained in:
James Tabor 2014-04-13 23:53:34 +00:00
parent 1823418a80
commit bd3046315a
8 changed files with 842 additions and 25 deletions

View file

@ -330,6 +330,55 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
}
}
HCURSOR FASTCALL
IntSetCursor(
HCURSOR hCursor)
{
PCURICON_OBJECT pcurOld, pcurNew;
HCURSOR hOldCursor = NULL;
if (hCursor)
{
pcurNew = UserGetCurIconObject(hCursor);
if (!pcurNew)
{
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
goto leave;
}
}
else
{
pcurNew = NULL;
}
pcurOld = UserSetCursor(pcurNew, FALSE);
if (pcurOld)
{
hOldCursor = (HCURSOR)pcurOld->Self;
UserDereferenceObject(pcurOld);
}
leave:
return hOldCursor;
}
BOOL FASTCALL
IntDestroyCursor(
HANDLE hCurIcon,
BOOL bForce)
{
PCURICON_OBJECT CurIcon;
BOOL ret;
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
{
return FALSE;
}
ret = IntDestroyCurIconObject(CurIcon, PsGetCurrentProcessWin32Process());
/* Note: IntDestroyCurIconObject will remove our reference for us! */
return ret;
}
/*
* @implemented

View file

@ -113,6 +113,8 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
BOOL UserSetCursorPos( INT x, INT y, DWORD flags, ULONG_PTR dwExtraInfo, BOOL Hook);
BOOL APIENTRY UserClipCursor(RECTL *prcl);
PSYSTEM_CURSORINFO IntGetSysCursorInfo(VOID);
HCURSOR FASTCALL IntSetCursor(HCURSOR hCursor);
BOOL FASTCALL IntDestroyCursor(HANDLE hCurIcon, BOOL bForce);
#define IntReleaseCurIconObject(CurIconObj) \
UserDereferenceObject(CurIconObj)

View file

@ -246,6 +246,66 @@ IntCleanupCurIcons(struct _EPROCESS *Process, PPROCESSINFO Win32Process)
}
}
HCURSOR FASTCALL
IntSetCursor(
HCURSOR hCursor)
{
PCURICON_OBJECT pcurOld, pcurNew;
HCURSOR hOldCursor = NULL;
if (hCursor)
{
pcurNew = UserGetCurIconObject(hCursor);
if (!pcurNew)
{
EngSetLastError(ERROR_INVALID_CURSOR_HANDLE);
goto leave;
}
pcurNew->CURSORF_flags |= CURSORF_CURRENT;
}
else
{
pcurNew = NULL;
}
pcurOld = UserSetCursor(pcurNew, FALSE);
if (pcurOld)
{
hOldCursor = pcurOld->head.h;
pcurOld->CURSORF_flags &= ~CURSORF_CURRENT;
if(UserObjectInDestroy(hOldCursor))
{
/* Destroy it once and for all */
IntDestroyCurIconObject(pcurOld, TRUE);
hOldCursor = NULL;
}
else
{
UserDereferenceObject(pcurOld);
}
}
leave:
return hOldCursor;
}
BOOL FASTCALL
IntDestroyCursor(
HANDLE hCurIcon,
BOOL bForce)
{
PCURICON_OBJECT CurIcon;
BOOL ret;
if (!(CurIcon = UserGetCurIconObject(hCurIcon)))
{
RETURN(FALSE);
}
ret = IntDestroyCurIconObject(CurIcon, bForce);
/* Note: IntDestroyCurIconObject will remove our reference for us! */
return ret;
}
/*
* @implemented

View file

@ -12,6 +12,26 @@
DBG_DEFAULT_CHANNEL(UserDefwnd);
#define UserHasDlgFrameStyle(Style, ExStyle) \
(((ExStyle) & WS_EX_DLGMODALFRAME) || \
(((Style) & WS_DLGFRAME) && (!((Style) & WS_THICKFRAME))))
#define UserHasThickFrameStyle(Style, ExStyle) \
(((Style) & WS_THICKFRAME) && \
(!(((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)))
#define UserHasThinFrameStyle(Style, ExStyle) \
(((Style) & WS_BORDER) || (!((Style) & (WS_CHILD | WS_POPUP))))
#define ON_LEFT_BORDER(hit) \
(((hit) == HTLEFT) || ((hit) == HTTOPLEFT) || ((hit) == HTBOTTOMLEFT))
#define ON_RIGHT_BORDER(hit) \
(((hit) == HTRIGHT) || ((hit) == HTTOPRIGHT) || ((hit) == HTBOTTOMRIGHT))
#define ON_TOP_BORDER(hit) \
(((hit) == HTTOP) || ((hit) == HTTOPLEFT) || ((hit) == HTTOPRIGHT))
#define ON_BOTTOM_BORDER(hit) \
(((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
// Client Shutdown messages
#define MCS_SHUTDOWNTIMERS 1
#define MCS_QUERYENDSESSION 2
@ -133,7 +153,6 @@ DefWndControlColor(HDC hDC, UINT ctlType)
return IntGetSysColorBrush(COLOR_WINDOW);
}
LRESULT FASTCALL
DefWndHandleWindowPosChanging(PWND pWnd, WINDOWPOS* Pos)
{
@ -163,27 +182,27 @@ DefWndHandleWindowPosChanging(PWND pWnd, WINDOWPOS* Pos)
LRESULT FASTCALL
DefWndHandleWindowPosChanged(PWND pWnd, WINDOWPOS* Pos)
{
RECT Rect;
LONG style = pWnd->style;
RECT Rect;
LONG style = pWnd->style;
IntGetClientRect(pWnd, &Rect);
IntMapWindowPoints(pWnd, (style & WS_CHILD ? IntGetParent(pWnd) : NULL), (LPPOINT) &Rect, 2);
IntGetClientRect(pWnd, &Rect);
IntMapWindowPoints(pWnd, (style & WS_CHILD ? IntGetParent(pWnd) : NULL), (LPPOINT) &Rect, 2);
if (!(Pos->flags & SWP_NOCLIENTMOVE))
{
if (!(Pos->flags & SWP_NOCLIENTMOVE))
{
co_IntSendMessage(UserHMGetHandle(pWnd), WM_MOVE, 0, MAKELONG(Rect.left, Rect.top));
}
}
if (!(Pos->flags & SWP_NOCLIENTSIZE) || (Pos->flags & SWP_STATECHANGED))
{
if (!(Pos->flags & SWP_NOCLIENTSIZE) || (Pos->flags & SWP_STATECHANGED))
{
if (style & WS_MINIMIZE) co_IntSendMessage(UserHMGetHandle(pWnd), WM_SIZE, SIZE_MINIMIZED, 0 );
else
{
WPARAM wp = (style & WS_MAXIMIZE) ? SIZE_MAXIMIZED : SIZE_RESTORED;
co_IntSendMessage(UserHMGetHandle(pWnd), WM_SIZE, wp, MAKELONG(Rect.right - Rect.left, Rect.bottom - Rect.top));
}
}
return 0;
}
return 0;
}
VOID FASTCALL
@ -192,12 +211,12 @@ UserDrawWindowFrame(HDC hdc,
ULONG width,
ULONG height)
{
HBRUSH hbrush = NtGdiSelectBrush( hdc, gpsi->hbrGray );
NtGdiPatBlt( hdc, rect->left, rect->top, rect->right - rect->left - width, height, PATINVERT );
NtGdiPatBlt( hdc, rect->left, rect->top + height, width, rect->bottom - rect->top - height, PATINVERT );
NtGdiPatBlt( hdc, rect->left + width, rect->bottom - 1, rect->right - rect->left - width, -height, PATINVERT );
NtGdiPatBlt( hdc, rect->right - 1, rect->top, -width, rect->bottom - rect->top - height, PATINVERT );
NtGdiSelectBrush( hdc, hbrush );
HBRUSH hbrush = NtGdiSelectBrush( hdc, gpsi->hbrGray );
NtGdiPatBlt( hdc, rect->left, rect->top, rect->right - rect->left - width, height, PATINVERT );
NtGdiPatBlt( hdc, rect->left, rect->top + height, width, rect->bottom - rect->top - height, PATINVERT );
NtGdiPatBlt( hdc, rect->left + width, rect->bottom - 1, rect->right - rect->left - width, -height, PATINVERT );
NtGdiPatBlt( hdc, rect->right - 1, rect->top, -width, rect->bottom - rect->top - height, PATINVERT );
NtGdiSelectBrush( hdc, hbrush );
}
VOID FASTCALL
@ -205,10 +224,503 @@ UserDrawMovingFrame(HDC hdc,
RECTL *rect,
BOOL thickframe)
{
if (thickframe) UserDrawWindowFrame(hdc, rect, UserGetSystemMetrics(SM_CXFRAME), UserGetSystemMetrics(SM_CYFRAME));
else UserDrawWindowFrame(hdc, rect, 1, 1);
if (thickframe) UserDrawWindowFrame(hdc, rect, UserGetSystemMetrics(SM_CXFRAME), UserGetSystemMetrics(SM_CYFRAME));
else UserDrawWindowFrame(hdc, rect, 1, 1);
}
/***********************************************************************
* NC_GetInsideRect
*
* Get the 'inside' rectangle of a window, i.e. the whole window rectangle
* but without the borders (if any).
*/
void FASTCALL
NC_GetInsideRect(PWND Wnd, RECT *rect)
{
ULONG Style;
ULONG ExStyle;
Style = Wnd->style;
ExStyle = Wnd->ExStyle;
rect->top = rect->left = 0;
rect->right = Wnd->rcWindow.right - Wnd->rcWindow.left;
rect->bottom = Wnd->rcWindow.bottom - Wnd->rcWindow.top;
if (Style & WS_ICONIC) return;
/* Remove frame from rectangle */
if (UserHasThickFrameStyle(Style, ExStyle ))
{
RECTL_vInflateRect(rect, -UserGetSystemMetrics(SM_CXFRAME), -UserGetSystemMetrics(SM_CYFRAME));
}
else
{
if (UserHasDlgFrameStyle(Style, ExStyle ))
{
RECTL_vInflateRect(rect, -UserGetSystemMetrics(SM_CXDLGFRAME), -UserGetSystemMetrics(SM_CYDLGFRAME));
/* FIXME: this isn't in NC_AdjustRect? why not? */
if (ExStyle & WS_EX_DLGMODALFRAME)
RECTL_vInflateRect( rect, -1, 0 );
}
else
{
if (UserHasThinFrameStyle(Style, ExStyle))
{
RECTL_vInflateRect(rect, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER));
}
}
}
/* We have additional border information if the window
* is a child (but not an MDI child) */
if ((Style & WS_CHILD) && !(ExStyle & WS_EX_MDICHILD))
{
if (ExStyle & WS_EX_CLIENTEDGE)
RECTL_vInflateRect (rect, -UserGetSystemMetrics(SM_CXEDGE), -UserGetSystemMetrics(SM_CYEDGE));
if (ExStyle & WS_EX_STATICEDGE)
RECTL_vInflateRect (rect, -UserGetSystemMetrics(SM_CXBORDER), -UserGetSystemMetrics(SM_CYBORDER));
}
}
LONG FASTCALL
DefWndStartSizeMove(PWND Wnd, WPARAM wParam, POINT *capturePoint)
{
LONG hittest = 0;
POINT pt;
MSG msg;
RECT rectWindow;
ULONG Style = Wnd->style;
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
rectWindow = Wnd->rcWindow;
if ((wParam & 0xfff0) == SC_MOVE)
{
/* Move pointer at the center of the caption */
RECT rect = rectWindow;
/* Note: to be exactly centered we should take the different types
* of border into account, but it shouldn't make more than a few pixels
* of difference so let's not bother with that */
if (Style & WS_SYSMENU)
rect.left += UserGetSystemMetrics(SM_CXSIZE) + 1;
if (Style & WS_MINIMIZEBOX)
rect.right -= UserGetSystemMetrics(SM_CXSIZE) + 1;
if (Style & WS_MAXIMIZEBOX)
rect.right -= UserGetSystemMetrics(SM_CXSIZE) + 1;
pt.x = (rect.right + rect.left) / 2;
pt.y = rect.top + UserGetSystemMetrics(SM_CYSIZE)/2;
hittest = HTCAPTION;
*capturePoint = pt;
}
else /* SC_SIZE */
{
pt.x = pt.y = 0;
while (!hittest)
{
if (!co_IntGetPeekMessage(&msg, 0, 0, 0, PM_REMOVE, TRUE)) return 0;
if (IntCallMsgFilter( &msg, MSGF_SIZE )) continue;
switch(msg.message)
{
case WM_MOUSEMOVE:
//// Clamp the mouse position to the window rectangle when starting a window resize.
pt.x = min( max( msg.pt.x, rectWindow.left ), rectWindow.right - 1 );
pt.y = min( max( msg.pt.y, rectWindow.top ), rectWindow.bottom - 1 );
hittest = GetNCHitEx(Wnd, pt);
if ((hittest < HTLEFT) || (hittest > HTBOTTOMRIGHT)) hittest = 0;
break;
case WM_LBUTTONUP:
return 0;
case WM_KEYDOWN:
switch (msg.wParam)
{
case VK_UP:
hittest = HTTOP;
pt.x = (rectWindow.left+rectWindow.right)/2;
pt.y = rectWindow.top + UserGetSystemMetrics(SM_CYFRAME) / 2;
break;
case VK_DOWN:
hittest = HTBOTTOM;
pt.x = (rectWindow.left+rectWindow.right)/2;
pt.y = rectWindow.bottom - UserGetSystemMetrics(SM_CYFRAME) / 2;
break;
case VK_LEFT:
hittest = HTLEFT;
pt.x = rectWindow.left + UserGetSystemMetrics(SM_CXFRAME) / 2;
pt.y = (rectWindow.top+rectWindow.bottom)/2;
break;
case VK_RIGHT:
hittest = HTRIGHT;
pt.x = rectWindow.right - UserGetSystemMetrics(SM_CXFRAME) / 2;
pt.y = (rectWindow.top+rectWindow.bottom)/2;
break;
case VK_RETURN:
case VK_ESCAPE:
return 0;
}
default:
IntTranslateKbdMessage( &msg, 0 );
pti->TIF_flags |= TIF_MOVESIZETRACKING;
IntDispatchMessage( &msg );
pti->TIF_flags |= TIF_MOVESIZETRACKING;
break;
}
}
*capturePoint = pt;
}
UserSetCursorPos(pt.x, pt.y, 0, 0, FALSE);
co_IntSendMessage(UserHMGetHandle(Wnd), WM_SETCURSOR, (WPARAM)UserHMGetHandle(Wnd), MAKELONG(hittest, WM_MOUSEMOVE));
return hittest;
}
//
// System Command Size and Move
//
// Perform SC_MOVE and SC_SIZE commands.
//
VOID FASTCALL
DefWndDoSizeMove(PWND pwnd, WORD wParam)
{
MSG msg;
RECT sizingRect, mouseRect, origRect, unmodRect;
HDC hdc;
LONG hittest = (LONG)(wParam & 0x0f);
HCURSOR hDragCursor = 0, hOldCursor = 0;
POINT minTrack, maxTrack;
POINT capturePoint, pt;
ULONG Style, ExStyle;
BOOL thickframe;
BOOL iconic;
BOOL moved = FALSE;
BOOL DragFullWindows = FALSE;
PWND pWndParent = NULL;
WPARAM syscommand = (wParam & 0xfff0);
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
//PMONITOR mon = 0; Don't port sync from wine!!! This breaks explorer task bar sizing!!
// The task bar can grow in size and can not reduce due to the change
// in the work area.
Style = pwnd->style;
ExStyle = pwnd->ExStyle;
iconic = (Style & WS_MINIMIZE) != 0;
if ((Style & WS_MAXIMIZE) || !IntIsWindowVisible(pwnd)) return;
thickframe = UserHasThickFrameStyle(Style, ExStyle) && !iconic;
//
// Show window contents while dragging the window, get flag from registry data.
//
UserSystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
pt.x = pti->ptLast.x;
pt.y = pti->ptLast.y;
capturePoint = pt;
UserClipCursor( NULL );
TRACE("pwnd %p command %04lx, hittest %d, pos %d,%d\n",
pwnd, syscommand, hittest, pt.x, pt.y);
if (syscommand == SC_MOVE)
{
if (!hittest) hittest = DefWndStartSizeMove(pwnd, wParam, &capturePoint);
if (!hittest) return;
}
else /* SC_SIZE */
{
if (!thickframe) return;
if (hittest && (syscommand != SC_MOUSEMENU))
{
hittest += (HTLEFT - WMSZ_LEFT);
}
else
{
co_UserSetCapture(UserHMGetHandle(pwnd));
hittest = DefWndStartSizeMove(pwnd, wParam, &capturePoint);
if (!hittest)
{
IntReleaseCapture();
return;
}
}
}
/* Get min/max info */
co_WinPosGetMinMaxInfo(pwnd, NULL, NULL, &minTrack, &maxTrack);
sizingRect = pwnd->rcWindow;
origRect = sizingRect;
if (Style & WS_CHILD)
{
pWndParent = IntGetParent(pwnd);
IntGetClientRect( pWndParent, &mouseRect );
IntMapWindowPoints( pWndParent, 0, (LPPOINT)&mouseRect, 2 );
IntMapWindowPoints( 0, pWndParent, (LPPOINT)&sizingRect, 2 );
unmodRect = sizingRect;
}
else
{
if (!(ExStyle & WS_EX_TOPMOST))
{
UserSystemParametersInfo(SPI_GETWORKAREA, 0, &mouseRect, 0);
}
else
{
RECTL_vSetRect(&mouseRect, 0, 0, UserGetSystemMetrics(SM_CXSCREEN), UserGetSystemMetrics(SM_CYSCREEN));
}
unmodRect = sizingRect;
}
if (ON_LEFT_BORDER(hittest))
{
mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x+capturePoint.x-sizingRect.left );
mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x+capturePoint.x-sizingRect.left );
}
else if (ON_RIGHT_BORDER(hittest))
{
mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x+capturePoint.x-sizingRect.right );
mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x+capturePoint.x-sizingRect.right );
}
if (ON_TOP_BORDER(hittest))
{
mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y+capturePoint.y-sizingRect.top );
mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y+capturePoint.y-sizingRect.top);
}
else if (ON_BOTTOM_BORDER(hittest))
{
mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y+capturePoint.y-sizingRect.bottom );
mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y+capturePoint.y-sizingRect.bottom );
}
hdc = UserGetDCEx( pWndParent, 0, DCX_CACHE );
if ( iconic ) /* create a cursor for dragging */
{
hDragCursor = pwnd->pcls->hIcon;;
if ( !hDragCursor ) hDragCursor = (HCURSOR)co_IntSendMessage( UserHMGetHandle(pwnd), WM_QUERYDRAGICON, 0, 0 );
if ( !hDragCursor ) iconic = FALSE;
}
/* repaint the window before moving it around */
co_UserRedrawWindow( pwnd, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN);
IntNotifyWinEvent( EVENT_SYSTEM_MOVESIZESTART, pwnd, OBJID_WINDOW, CHILDID_SELF, 0);
co_IntSendMessage( UserHMGetHandle(pwnd), WM_ENTERSIZEMOVE, 0, 0 );
MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, UserHMGetHandle(pwnd));
if (IntGetCapture() != UserHMGetHandle(pwnd)) co_UserSetCapture( UserHMGetHandle(pwnd) );
pwnd->head.pti->TIF_flags |= TIF_MOVESIZETRACKING;
for(;;)
{
int dx = 0, dy = 0;
if (!co_IntGetPeekMessage(&msg, 0, 0, 0, PM_REMOVE, TRUE)) break;
if (IntCallMsgFilter( &msg, MSGF_SIZE )) continue;
/* Exit on button-up, Return, or Esc */
if ((msg.message == WM_LBUTTONUP) ||
((msg.message == WM_KEYDOWN) &&
((msg.wParam == VK_RETURN) || (msg.wParam == VK_ESCAPE)))) break;
if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
{
IntTranslateKbdMessage( &msg , 0 );
IntDispatchMessage( &msg );
continue; /* We are not interested in other messages */
}
pt = msg.pt;
if (msg.message == WM_KEYDOWN) switch(msg.wParam)
{
case VK_UP: pt.y -= 8; break;
case VK_DOWN: pt.y += 8; break;
case VK_LEFT: pt.x -= 8; break;
case VK_RIGHT: pt.x += 8; break;
}
pt.x = max( pt.x, mouseRect.left );
pt.x = min( pt.x, mouseRect.right - 1 );
pt.y = max( pt.y, mouseRect.top );
pt.y = min( pt.y, mouseRect.bottom - 1 );
dx = pt.x - capturePoint.x;
dy = pt.y - capturePoint.y;
if (dx || dy)
{
if ( !moved )
{
moved = TRUE;
if ( iconic ) /* ok, no system popup tracking */
{
hOldCursor = IntSetCursor(hDragCursor);
UserShowCursor( TRUE );
}
else if(!DragFullWindows)
UserDrawMovingFrame( hdc, &sizingRect, thickframe );
}
if (msg.message == WM_KEYDOWN) UserSetCursorPos(pt.x, pt.y, 0, 0, FALSE);
else
{
RECT newRect = unmodRect;
if (!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
if (hittest == HTCAPTION) RECTL_vOffsetRect( &newRect, dx, dy );
if (ON_LEFT_BORDER(hittest)) newRect.left += dx;
else if (ON_RIGHT_BORDER(hittest)) newRect.right += dx;
if (ON_TOP_BORDER(hittest)) newRect.top += dy;
else if (ON_BOTTOM_BORDER(hittest)) newRect.bottom += dy;
capturePoint = pt;
//
// Save the new position to the unmodified rectangle. This allows explorer task bar
// sizing. Explorer will forces back the position unless a certain amount of sizing
// has occurred.
//
unmodRect = newRect;
/* determine the hit location */
if (syscommand == SC_SIZE)
{
WPARAM wpSizingHit = 0;
if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
co_IntSendMessage( UserHMGetHandle(pwnd), WM_SIZING, wpSizingHit, (LPARAM)&newRect );
}
else
co_IntSendMessage( UserHMGetHandle(pwnd), WM_MOVING, 0, (LPARAM)&newRect );
if (!iconic)
{
if (!DragFullWindows)
UserDrawMovingFrame( hdc, &newRect, thickframe );
else
{ // Moving the whole window now!
PWND pwndTemp;
//// This causes the mdi child window to jump up when it is moved.
//IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 );
co_WinPosSetWindowPos( pwnd,
0,
newRect.left,
newRect.top,
newRect.right - newRect.left,
newRect.bottom - newRect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
// Update all the windows after the move or size, including this window.
for ( pwndTemp = pwnd->head.rpdesk->pDeskInfo->spwnd->spwndChild;
pwndTemp;
pwndTemp = pwndTemp->spwndNext )
{
RECTL rect;
// Only the windows that overlap will be redrawn.
if (RECTL_bIntersectRect( &rect, &pwnd->rcWindow, &pwndTemp->rcWindow ))
{
co_UserRedrawWindow( pwndTemp, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN);
}
}
}
}
sizingRect = newRect;
}
}
}
pwnd->head.pti->TIF_flags &= ~TIF_MOVESIZETRACKING;
IntReleaseCapture();
if ( iconic )
{
if ( moved ) /* restore cursors, show icon title later on */
{
UserShowCursor( FALSE );
IntSetCursor( hOldCursor );
}
IntDestroyCursor( hDragCursor, FALSE );
}
else if ( moved && !DragFullWindows )
UserDrawMovingFrame( hdc, &sizingRect, thickframe );
UserReleaseDC(NULL, hdc, FALSE);
//// This causes the mdi child window to jump up when it is moved.
//if (pWndParent) IntMapWindowPoints( 0, pWndParent, (POINT *)&sizingRect, 2 );
if (co_HOOK_CallHooks(WH_CBT, HCBT_MOVESIZE, (WPARAM)UserHMGetHandle(pwnd), (LPARAM)&sizingRect))
{
ERR("DoSizeMove : WH_CBT Call Hook return!\n");
moved = FALSE;
}
IntNotifyWinEvent( EVENT_SYSTEM_MOVESIZEEND, pwnd, OBJID_WINDOW, CHILDID_SELF, 0);
MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, NULL);
co_IntSendMessage( UserHMGetHandle(pwnd), WM_EXITSIZEMOVE, 0, 0 );
//// wine mdi hack
co_IntSendMessage( UserHMGetHandle(pwnd), WM_SETVISIBLE, !!(pwnd->style & WS_MINIMIZE), 0L);
////
/* window moved or resized */
if (moved)
{
/* if the moving/resizing isn't canceled call SetWindowPos
* with the new position or the new size of the window
*/
if (!((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) )
{
/* NOTE: SWP_NOACTIVATE prevents document window activation in Word 6 */
if (!DragFullWindows || iconic )
{
co_WinPosSetWindowPos( pwnd,
0,
sizingRect.left,
sizingRect.top,
sizingRect.right - sizingRect.left,
sizingRect.bottom - sizingRect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
}
}
else
{ /* restore previous size/position */
if ( DragFullWindows )
{
co_WinPosSetWindowPos( pwnd,
0,
origRect.left,
origRect.top,
origRect.right - origRect.left,
origRect.bottom - origRect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
}
}
}
if ( IntIsWindow(UserHMGetHandle(pwnd)) )
if ( iconic )
{
/* Single click brings up the system menu when iconized */
if ( !moved )
{
if( Style & WS_SYSMENU )
co_IntSendMessage( UserHMGetHandle(pwnd), WM_SYSCOMMAND, SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
}
}
}
//
// Handle a WM_SYSCOMMAND message. Called from DefWindowProc().
//
LRESULT FASTCALL
DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
{
@ -227,15 +739,58 @@ DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
{
case SC_MOVE:
case SC_SIZE:
//DefWndDoSizeMove(pWnd, wParam);
ERR("SC_MOVESIZE\n");
DefWndDoSizeMove(pWnd, wParam);
break;
case SC_MINIMIZE:
if (UserHMGetHandle(pWnd) == UserGetActiveWindow())
IntShowOwnedPopups(pWnd,FALSE); // This is done in ShowWindow! Need to retest!
co_WinPosShowWindow( pWnd, SW_MINIMIZE );
break;
case SC_MAXIMIZE:
if (((pWnd->style & WS_MINIMIZE) != 0) && UserHMGetHandle(pWnd) == UserGetActiveWindow())
IntShowOwnedPopups(pWnd,TRUE);
co_WinPosShowWindow( pWnd, SW_MAXIMIZE );
break;
case SC_RESTORE:
if (((pWnd->style & WS_MINIMIZE) != 0) && UserHMGetHandle(pWnd) == UserGetActiveWindow())
IntShowOwnedPopups(pWnd,TRUE);
co_WinPosShowWindow( pWnd, SW_RESTORE );
break;
case SC_CLOSE:
return co_IntSendMessage(UserHMGetHandle(pWnd), WM_CLOSE, 0, 0);
case SC_SCREENSAVE:
ERR("Screensaver Called!\n");
UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_START_SCREENSAVE, 0); // always lParam 0 == not Secure
break;
case SC_HOTKEY:
{
USER_REFERENCE_ENTRY Ref;
pWnd = ValidateHwndNoErr((HWND)lParam);
if (pWnd)
{
if (pWnd->spwndLastActive)
{
pWnd = pWnd->spwndLastActive;
}
UserRefObjectCo(pWnd, &Ref);
co_IntSetForegroundWindow(pWnd);
UserDerefObjectCo(pWnd);
if (pWnd->style & WS_MINIMIZE)
{
UserPostMessage(UserHMGetHandle(pWnd), WM_SYSCOMMAND, SC_RESTORE, 0);
}
}
}
break;
default:
// We do not support anything else here so we should return normal even when sending a hook.
return 0;
@ -244,6 +799,39 @@ DefWndHandleSysCommand(PWND pWnd, WPARAM wParam, LPARAM lParam)
return(Hook ? 1 : 0); // Don't call us again from user space.
}
VOID FASTCALL DefWndPrint( PWND pwnd, HDC hdc, ULONG uFlags)
{
/*
* Visibility flag.
*/
if ( (uFlags & PRF_CHECKVISIBLE) &&
!IntIsWindowVisible(pwnd) )
return;
/*
* Unimplemented flags.
*/
if ( (uFlags & PRF_CHILDREN) ||
(uFlags & PRF_OWNED) ||
(uFlags & PRF_NONCLIENT) )
{
FIXME("WM_PRINT message with unsupported flags\n");
}
/*
* Background
*/
if ( uFlags & PRF_ERASEBKGND)
co_IntSendMessage(UserHMGetHandle(pwnd), WM_ERASEBKGND, (WPARAM)hdc, 0);
/*
* Client area
*/
if ( uFlags & PRF_CLIENT)
co_IntSendMessage(UserHMGetHandle(pwnd), WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
}
/*
Win32k counterpart of User DefWindowProc
*/
@ -304,6 +892,10 @@ IntDefWindowProc(
UserDerefObjectCo(Wnd->spwndParent);
break;
case WM_CLOSE:
co_UserDestroyWindow(Wnd);
break;
case WM_CTLCOLORMSGBOX:
case WM_CTLCOLOREDIT:
case WM_CTLCOLORLISTBOX:
@ -316,6 +908,51 @@ IntDefWindowProc(
case WM_CTLCOLOR:
return (LRESULT) DefWndControlColor((HDC)wParam, HIWORD(lParam));
case WM_ACTIVATE:
/* The default action in Windows is to set the keyboard focus to
* the window, if it's being activated and not minimized */
if (LOWORD(wParam) != WA_INACTIVE &&
!(Wnd->style & WS_MINIMIZE))
{
//ERR("WM_ACTIVATE %p\n",hWnd);
co_UserSetFocus(Wnd);
}
break;
case WM_MOUSEWHEEL:
if (Wnd->style & WS_CHILD)
{
HWND hwndParent;
PWND pwndParent = IntGetParent(Wnd);
hwndParent = pwndParent ? UserHMGetHandle(pwndParent) : NULL;
return co_IntSendMessage( hwndParent, WM_MOUSEWHEEL, wParam, lParam);
}
break;
case WM_ERASEBKGND:
case WM_ICONERASEBKGND:
{
RECT Rect;
HBRUSH hBrush = Wnd->pcls->hbrBackground;
if (!hBrush) return 0;
if (hBrush <= (HBRUSH)COLOR_MENUBAR)
{
hBrush = IntGetSysColorBrush((INT)hBrush);
}
if (Wnd->pcls->style & CS_PARENTDC)
{
/* can't use GetClipBox with a parent DC or we fill the whole parent */
IntGetClientRect(Wnd, &Rect);
GreDPtoLP((HDC)wParam, (LPPOINT)&Rect, 2);
}
else
{
GdiGetClipBox((HDC)wParam, &Rect);
}
FillRect((HDC)wParam, &Rect, hBrush);
return (1);
}
case WM_GETHOTKEY:
//ERR("WM_GETHOTKEY\n");
return DefWndGetHotKey(Wnd);
@ -331,6 +968,46 @@ IntDefWindowProc(
return GetNCHitEx(Wnd, Point);
}
case WM_PRINT:
{
DefWndPrint(Wnd, (HDC)wParam, lParam);
return (0);
}
case WM_PAINTICON:
case WM_PAINT:
{
PAINTSTRUCT Ps;
HDC hDC;
/* If already in Paint and Client area is not empty just return. */
if (Wnd->state2 & WNDS2_STARTPAINT && !RECTL_bIsEmptyRect(&Wnd->rcClient))
{
ERR("In Paint and Client area is not empty!\n");
return 0;
}
hDC = IntBeginPaint(Wnd, &Ps);
if (hDC)
{
HICON hIcon;
if (((Wnd->style & WS_MINIMIZE) != 0) && (hIcon = Wnd->pcls->hIcon))
{
RECT ClientRect;
INT x, y;
PCURICON_OBJECT pIcon;
if (!(pIcon = UserGetCurIconObject(hIcon))) return 0;
ERR("Doing Paint and Client area is empty!\n");
IntGetClientRect(Wnd, &ClientRect);
x = (ClientRect.right - ClientRect.left - UserGetSystemMetrics(SM_CXICON)) / 2;
y = (ClientRect.bottom - ClientRect.top - UserGetSystemMetrics(SM_CYICON)) / 2;
UserDrawIconEx( hDC, x, y, pIcon, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE );
}
IntEndPaint(Wnd, &Ps);
}
return (0);
}
case WM_SYNCPAINT:
{
HRGN hRgn;
@ -430,7 +1107,6 @@ HICON FASTCALL NC_IconForWindow( PWND pWnd )
{
if (!hIcon) hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small
if (!hIcon) hIcon = gpsi->hIconWindows; // Reg size.
hIcon = (HICON)1;
}
return hIcon;
}

View file

@ -97,6 +97,5 @@ extern BYTE gafAsyncKeyState[256 * 2 / 8]; // 2 bits per key
((ks)[GET_KS_BYTE(vk)] | GET_KS_LOCK_BIT(vk)) : \
((ks)[GET_KS_BYTE(vk)] & ~GET_KS_LOCK_BIT(vk)))
extern PKL gspklBaseLayout;
extern KEYBOARD_ATTRIBUTES gKeyboardInfo;

View file

@ -467,6 +467,35 @@ cleanup:
return UserGetMonitorObject(hMonitor);
}
PMONITOR
FASTCALL
UserMonitorFromPoint(
IN POINT pt,
IN DWORD dwFlags)
{
RECTL rc;
HMONITOR hMonitor = NULL;
/* Check if flags are valid */
if (dwFlags != MONITOR_DEFAULTTONULL &&
dwFlags != MONITOR_DEFAULTTOPRIMARY &&
dwFlags != MONITOR_DEFAULTTONEAREST)
{
EngSetLastError(ERROR_INVALID_FLAGS);
return NULL;
}
/* Fill rect (bottom-right exclusive) */
rc.left = pt.x;
rc.right = pt.x + 1;
rc.top = pt.y;
rc.bottom = pt.y + 1;
/* Find intersecting monitor */
IntGetMonitorsFromRect(&rc, &hMonitor, NULL, 1, dwFlags);
return UserGetMonitorObject(hMonitor);
}
/* PUBLIC FUNCTIONS ***********************************************************/

View file

@ -29,5 +29,6 @@ NTSTATUS NTAPI UserUpdateMonitorSize(IN HDEV hDev);
PMONITOR NTAPI UserGetMonitorObject(IN HMONITOR);
PMONITOR NTAPI UserGetPrimaryMonitor(VOID);
PMONITOR NTAPI UserMonitorFromRect(PRECTL,DWORD);
PMONITOR FASTCALL UserMonitorFromPoint(POINT,DWORD);
/* EOF */

View file

@ -125,7 +125,7 @@ typedef struct _THREADINFO
/* Queue of messages posted to the queue. */
LIST_ENTRY PostedMessagesListHead; // mlPost
UINT fsChangeBitsRemoved;
UINT cWindows;
UINT cVisWindows;
LIST_ENTRY aphkStart[NB_HOOKS];
@ -238,6 +238,7 @@ typedef struct _PROCESSINFO
struct _CURICON_OBJECT* pCursorCache;
LUID luidSession;
USERSTARTUPINFO usi;
PVOID pW32Job;
DWORD dwLayout;
DWORD dwRegisteredClasses;
/* ReactOS */