+ UserDrawWindowFrame(hdc, rect, GetSystemMetrics(SM_CXFRAME),
+ GetSystemMetrics(SM_CYFRAME), PATINVERT );
+ }
+ else DrawFocusRect( hdc, rect );
+}
+
+VOID STATIC
+DefWndDoSizeMove(HWND hwnd, WORD wParam)
+{
+ MSG msg;
+ RECT sizingRect, mouseRect, origRect;
+ HDC hdc;
+ LONG hittest = (LONG)(wParam & 0x0f);
+ HCURSOR hDragCursor = 0, hOldCursor = 0;
+ POINT minTrack, maxTrack;
+ POINT capturePoint, pt;
+ ULONG Style = GetWindowLongW(hwnd, GWL_STYLE);
+ ULONG ExStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
+ BOOL thickframe = UserHasThickFrameStyle(Style, ExStyle);
+ BOOL iconic = Style & WS_MINIMIZE;
+ BOOL moved = FALSE;
+ DWORD dwPoint = GetMessagePos();
+ BOOL DragFullWindows = FALSE;
+ HWND hWndParent;
+
+ SystemParametersInfoA(SPI_GETDRAGFULLWINDOWS, 0, &DragFullWindows, 0);
+
+ pt.x = SLOWORD(dwPoint);
+ pt.y = SHIWORD(dwPoint);
+ capturePoint = pt;
+
+ if (IsZoomed(hwnd) || !IsWindowVisible(hwnd))
+ {
+ return;
+ }
+
+ if ((wParam & 0xfff0) == SC_MOVE)
+ {
+ if (!hittest)
+ {
+ hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
+ }
+ if (!hittest)
+ {
+ return;
+ }
+ }
+ else /* SC_SIZE */
+ {
+ if (!thickframe)
+ {
+ return;
+ }
+ if (hittest && hittest != HTSYSMENU)
+ {
+ hittest += 2;
+ }
+ else
+ {
+ SetCapture(hwnd);
+ hittest = DefWndStartSizeMove(hwnd, wParam, &capturePoint);
+ if (!hittest)
+ {
+ ReleaseCapture();
+ return;
+ }
+ }
+ }
+
+ if (Style & WS_CHILD)
+ {
+ hWndParent = GetParent(hwnd);
+ }
+
+ /* Get min/max info */
+
+ WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
+ GetWindowRect(hwnd, &sizingRect);
+ origRect = sizingRect;
+ if (Style & WS_CHILD)
+ {
+ GetClientRect(hWndParent, &mouseRect );
+ }
+ else
+ {
+ SetRect(&mouseRect, 0, 0, GetSystemMetrics(SM_CXSCREEN),
+ GetSystemMetrics(SM_CYSCREEN));
+ }
+ if (ON_LEFT_BORDER(hittest))
+ {
+ mouseRect.left = max( mouseRect.left, sizingRect.right-maxTrack.x );
+ mouseRect.right = min( mouseRect.right, sizingRect.right-minTrack.x );
+ }
+ else if (ON_RIGHT_BORDER(hittest))
+ {
+ mouseRect.left = max( mouseRect.left, sizingRect.left+minTrack.x );
+ mouseRect.right = min( mouseRect.right, sizingRect.left+maxTrack.x );
+ }
+ if (ON_TOP_BORDER(hittest))
+ {
+ mouseRect.top = max( mouseRect.top, sizingRect.bottom-maxTrack.y );
+ mouseRect.bottom = min( mouseRect.bottom,sizingRect.bottom-minTrack.y);
+ }
+ else if (ON_BOTTOM_BORDER(hittest))
+ {
+ mouseRect.top = max( mouseRect.top, sizingRect.top+minTrack.y );
+ mouseRect.bottom = min( mouseRect.bottom, sizingRect.top+maxTrack.y );
+ }
+ if (Style & WS_CHILD)
+ {
+ MapWindowPoints( hWndParent, 0, (LPPOINT)&mouseRect, 2 );
+ }
+ SendMessageA( hwnd, WM_ENTERSIZEMOVE, 0, 0 );
+
+ if (GetCapture() != hwnd) SetCapture( hwnd );
+
+ if (Style & WS_CHILD)
+ {
+ /* Retrieve a default cache DC (without using the window style) */
+ hdc = GetDCEx(hWndParent, 0, DCX_CACHE);
+ }
+ else
+ {
+ hdc = GetDC( 0 );
+ }
+
+ if( iconic ) /* create a cursor for dragging */
+ {
+ HICON hIcon = (HICON)GetClassLongW(hwnd, GCL_HICON);
+ if(!hIcon) hIcon = (HICON)SendMessageW( hwnd, WM_QUERYDRAGICON, 0, 0L);
+ if( hIcon ) hDragCursor = CursorIconToCursor( hIcon, TRUE );
+ if( !hDragCursor ) iconic = FALSE;
+ }
+
+ /* invert frame if WIN31_LOOK to indicate mouse click on caption */
+ if( !iconic && !DragFullWindows)
+ {
+ UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+ }
+
+ while(1)
+ {
+ int dx = 0, dy = 0;
+
+ GetMessageW(&msg, 0, 0, 0);
+
+ /* 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_PAINT)
+ {
+ if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+ UpdateWindow( msg.hwnd );
+ if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+ continue;
+ }
+
+ if ((msg.message != WM_KEYDOWN) && (msg.message != WM_MOUSEMOVE))
+ 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 );
+ pt.y = max( pt.y, mouseRect.top );
+ pt.y = min( pt.y, mouseRect.bottom );
+
+ 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 = SetCursor(hDragCursor);
+ ShowCursor( TRUE );
+ WinPosShowIconTitle( hwnd, FALSE );
+ }
+ }
+
+ if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
+ else
+ {
+ RECT newRect = sizingRect;
+ WPARAM wpSizingHit = 0;
+
+ if (hittest == HTCAPTION) OffsetRect( &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;
+ if(!iconic && !DragFullWindows) UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+ capturePoint = pt;
+
+ /* determine the hit location */
+ if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
+ wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
+ SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
+
+ if (!iconic)
+ {
+ if(!DragFullWindows)
+ UserDrawMovingFrame( hdc, &newRect, thickframe );
+ else {
+ /* To avoid any deadlocks, all the locks on the windows
+ structures must be suspended before the SetWindowPos */
+ SetWindowPos( hwnd, 0, newRect.left, newRect.top,
+ newRect.right - newRect.left,
+ newRect.bottom - newRect.top,
+ ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
+ }
+ }
+ sizingRect = newRect;
+ }
+ }
+ }
+
+ ReleaseCapture();
+ if( iconic )
+ {
+ if( moved ) /* restore cursors, show icon title later on */
+ {
+ ShowCursor( FALSE );
+ SetCursor( hOldCursor );
+ }
+ DestroyCursor( hDragCursor );
+ }
+ else if(!DragFullWindows)
+ UserDrawMovingFrame( hdc, &sizingRect, thickframe );
+
+ if (Style & WS_CHILD)
+ ReleaseDC( hWndParent, hdc );
+ else
+ ReleaseDC( 0, hdc );
+
+ SendMessageA( hwnd, WM_EXITSIZEMOVE, 0, 0 );
+ SendMessageA( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 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)
+ SetWindowPos( hwnd, 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)
+ SetWindowPos( hwnd, 0, origRect.left, origRect.top,
+ origRect.right - origRect.left,
+ origRect.bottom - origRect.top,
+ ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
+ }
+ }
+
+ if( IsWindow(hwnd) )
+ if( Style & WS_MINIMIZE )
+ {
+ /* Single click brings up the system menu when iconized */
+
+ if( !moved )
+ {
+ if( Style & WS_SYSMENU )
+ SendMessageA( hwnd, WM_SYSCOMMAND,
+ SC_MOUSEMENU + HTSYSMENU, MAKELONG(pt.x,pt.y));
+ }
+ else WinPosShowIconTitle( hwnd, TRUE );
+ }
+}
+
+
+LRESULT
+DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
+{
+ switch (wParam & 0xfff0)
+ {
+ case SC_MOVE:
+ case SC_SIZE:
+ DefWndDoSizeMove(hWnd, wParam);
+ break;
+ case SC_CLOSE:
+ SendMessageA(hWnd, WM_CLOSE, 0, 0);
+ break;
+ case SC_MOUSEMENU:
+ MenuTrackMouseMenuBar(hWnd, wParam, Pt);
+ break;
+ case SC_KEYMENU:
+ MenuTrackKbdMenuBar(hWnd, wParam, Pt.x);
+ break;
+ default:
+ /* FIXME: Implement */
+ UNIMPLEMENTED;
+ break;
+ }
+
+ return(0);
+}
+
+
+VOID
+DefWndAdjustRect(RECT* Rect, ULONG Style, BOOL Menu, ULONG ExStyle)
+{
+ if (Style & WS_ICONIC)
+ {
+ return;