Author: jimtabor Date: Sun Apr 13 23:53:34 2014 New Revision: 62744
URL: http://svn.reactos.org/svn/reactos?rev=62744&view=rev Log: [Win32k] - 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.
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.c trunk/reactos/win32ss/user/ntuser/cursoricon.h trunk/reactos/win32ss/user/ntuser/cursoricon_new.c trunk/reactos/win32ss/user/ntuser/defwnd.c trunk/reactos/win32ss/user/ntuser/input.h trunk/reactos/win32ss/user/ntuser/monitor.c trunk/reactos/win32ss/user/ntuser/monitor.h trunk/reactos/win32ss/user/ntuser/win32.h
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursori... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/cursoricon.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/cursoricon.c [iso-8859-1] Sun Apr 13 23:53:34 2014 @@ -330,6 +330,55 @@ } }
+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
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursori... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/cursoricon.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/cursoricon.h [iso-8859-1] Sun Apr 13 23:53:34 2014 @@ -113,6 +113,8 @@ 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)
Modified: trunk/reactos/win32ss/user/ntuser/cursoricon_new.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/cursori... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/cursoricon_new.c [iso-8859-1] Sun Apr 13 23:53:34 2014 @@ -246,6 +246,66 @@ } }
+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
Modified: trunk/reactos/win32ss/user/ntuser/defwnd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/defwnd.... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/defwnd.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/defwnd.c [iso-8859-1] Sun Apr 13 23:53:34 2014 @@ -11,6 +11,26 @@ #include <windowsx.h>
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 @@ -132,7 +152,6 @@
return IntGetSysColorBrush(COLOR_WINDOW); } -
LRESULT FASTCALL DefWndHandleWindowPosChanging(PWND pWnd, WINDOWPOS* Pos) @@ -163,27 +182,27 @@ LRESULT FASTCALL DefWndHandleWindowPosChanged(PWND pWnd, WINDOWPOS* Pos) { - RECT Rect; - LONG style = pWnd->style; - - IntGetClientRect(pWnd, &Rect); - IntMapWindowPoints(pWnd, (style & WS_CHILD ? IntGetParent(pWnd) : NULL), (LPPOINT) &Rect, 2); - - if (!(Pos->flags & SWP_NOCLIENTMOVE)) - { + RECT Rect; + LONG style = pWnd->style; + + IntGetClientRect(pWnd, &Rect); + IntMapWindowPoints(pWnd, (style & WS_CHILD ? IntGetParent(pWnd) : NULL), (LPPOINT) &Rect, 2); + + 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 @@ 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 @@ 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 @@ { 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; @@ -243,6 +798,39 @@
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 @@ UserDerefObjectCo(Wnd->spwndParent); break;
+ case WM_CLOSE: + co_UserDestroyWindow(Wnd); + break; + case WM_CTLCOLORMSGBOX: case WM_CTLCOLOREDIT: case WM_CTLCOLORLISTBOX: @@ -316,6 +908,51 @@ 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); @@ -329,6 +966,46 @@ Point.x = GET_X_LPARAM(lParam); Point.y = GET_Y_LPARAM(lParam); 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: @@ -430,7 +1107,6 @@ { if (!hIcon) hIcon = gpsi->hIconSmWindows; // Both are IDI_WINLOGO Small if (!hIcon) hIcon = gpsi->hIconWindows; // Reg size. - hIcon = (HICON)1; } return hIcon; }
Modified: trunk/reactos/win32ss/user/ntuser/input.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/input.h... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/input.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/input.h [iso-8859-1] Sun Apr 13 23:53:34 2014 @@ -97,6 +97,5 @@ ((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;
Modified: trunk/reactos/win32ss/user/ntuser/monitor.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/monitor... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/monitor.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/monitor.c [iso-8859-1] Sun Apr 13 23:53:34 2014 @@ -467,6 +467,35 @@ 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 ***********************************************************/
Modified: trunk/reactos/win32ss/user/ntuser/monitor.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/monitor... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/monitor.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/monitor.h [iso-8859-1] Sun Apr 13 23:53:34 2014 @@ -29,5 +29,6 @@ PMONITOR NTAPI UserGetMonitorObject(IN HMONITOR); PMONITOR NTAPI UserGetPrimaryMonitor(VOID); PMONITOR NTAPI UserMonitorFromRect(PRECTL,DWORD); +PMONITOR FASTCALL UserMonitorFromPoint(POINT,DWORD);
/* EOF */
Modified: trunk/reactos/win32ss/user/ntuser/win32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/win32.h... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/win32.h [iso-8859-1] Sun Apr 13 23:53:34 2014 @@ -125,7 +125,7 @@
/* 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 @@ struct _CURICON_OBJECT* pCursorCache; LUID luidSession; USERSTARTUPINFO usi; + PVOID pW32Job; DWORD dwLayout; DWORD dwRegisteredClasses; /* ReactOS */