Use unadjusted rect (the one calculated before sending WM_SIZING) for sizing calculat...
[reactos.git] / reactos / lib / user32 / windows / defwnd.c
index 4554f17..b478cf5 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: defwnd.c,v 1.144 2004/08/15 21:36:29 chorns Exp $
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS user32.dll
@@ -41,70 +41,46 @@ void FASTCALL MenuInitSysMenuPopup(HMENU Menu, DWORD Style, DWORD ClsStyle, LONG
 
 /* GLOBALS *******************************************************************/
 
-/* TODO:  widgets will be cached here.
-static HBITMAP hbClose;
-static HBITMAP hbCloseD;
-static HBITMAP hbMinimize;
-static HBITMAP hbMinimizeD;
-static HBITMAP hbRestore;
-static HBITMAP hbRestoreD;
-static HBITMAP hbMaximize;
-static HBITMAP hbScrUp;
-static HBITMAP hbScrDwn;
-static HBITMAP hbScrLeft;
-static HBITMAP hbScrRight;
-*/
-
-
-static COLORREF SysColors[] =
-{
-  RGB(212, 208, 200), /* COLOR_SCROLLBAR  */
-  RGB(58, 110, 165),  /* COLOR_BACKGROUND  */
-  RGB(10, 36, 106),   /* COLOR_ACTIVECAPTION  */
-  RGB(128, 128, 128), /* COLOR_INACTIVECAPTION  */
-  RGB(212, 208, 200), /* COLOR_MENU  */
-  RGB(255, 255, 255), /* COLOR_WINDOW  */
-  RGB(0, 0, 0),       /* COLOR_WINDOWFRAME  */
-  RGB(0, 0, 0),       /* COLOR_MENUTEXT  */
-  RGB(0, 0, 0),       /* COLOR_WINDOWTEXT  */
-  RGB(255, 255, 255), /* COLOR_CAPTIONTEXT  */
-  RGB(212, 208, 200), /* COLOR_ACTIVEBORDER  */
-  RGB(212, 208, 200), /* COLOR_INACTIVEBORDER  */
-  RGB(128, 128, 128), /* COLOR_APPWORKSPACE  */
-  RGB(10, 36, 106),   /* COLOR_HIGHLIGHT  */
-  RGB(255, 255, 255), /* COLOR_HIGHLIGHTTEXT  */
-  RGB(212, 208, 200), /* COLOR_BTNFACE  */
-  RGB(128, 128, 128), /* COLOR_BTNSHADOW  */
-  RGB(128, 128, 128), /* COLOR_GRAYTEXT  */
-  RGB(0, 0, 0),       /* COLOR_BTNTEXT  */
-  RGB(212, 208, 200), /* COLOR_INACTIVECAPTIONTEXT  */
-  RGB(255, 255, 255), /* COLOR_BTNHIGHLIGHT  */
-  RGB(64, 64, 64),    /* COLOR_3DDKSHADOW  */
-  RGB(212, 208, 200), /* COLOR_3DLIGHT  */
-  RGB(0, 0, 0),       /* COLOR_INFOTEXT  */
-  RGB(255, 255, 225), /* COLOR_INFOBK  */
-  RGB(181, 181, 181), /* COLOR_UNKNOWN  */
-  RGB(0, 0, 128),     /* COLOR_HOTLIGHT  */
-  RGB(166, 202, 240), /* COLOR_GRADIENTACTIVECAPTION  */
-  RGB(192, 192, 192), /* COLOR_GRADIENTINACTIVECAPTION  */
-  RGB(49, 106, 197),  /* COLOR_MENUHILIGHT  */
-  RGB(236, 233, 216)  /* COLOR_MENUBAR  */
-};
-
-#define NUM_SYSCOLORS (sizeof(SysColors) / sizeof(SysColors[0]))
+COLORREF SysColors[NUM_SYSCOLORS] = {0};
+HPEN SysPens[NUM_SYSCOLORS] = {0};
+HBRUSH SysBrushes[NUM_SYSCOLORS] = {0};
 
 /* Bits in the dwKeyData */
 #define KEYDATA_ALT   0x2000
 
 /* FUNCTIONS *****************************************************************/
 
+void
+InitStockObjects(void)
+{
+  /* FIXME - Instead of copying the stuff to usermode we should map the tables to
+             userland. The current implementation has one big flaw: the system color
+             table doesn't get updated when another process changes them. That's why
+             we should rather map the table into usermode. But it only affects the
+             SysColors table - the pens, brushes and stock objects are not affected
+             as their handles never change. But it'd be faster to map them, too. */
+  if(SysBrushes[0] == NULL)
+  {
+    /* only initialize once */
+    NtUserGetSysColors(SysColors, NUM_SYSCOLORS);
+    NtUserGetSysColorPens(SysPens, NUM_SYSCOLORS);
+    NtUserGetSysColorBrushes(SysBrushes, NUM_SYSCOLORS);
+  }
+}
+
 /*
  * @implemented
  */
 DWORD STDCALL
 GetSysColor(int nIndex)
 {
+  if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
+  {
     return SysColors[nIndex];
+  }
+  
+  SetLastError(ERROR_INVALID_PARAMETER);
+  return 0;
 }
 
 /*
@@ -113,22 +89,13 @@ GetSysColor(int nIndex)
 HPEN STDCALL
 GetSysColorPen(int nIndex)
 {
-  static HPEN SysPens[NUM_SYSCOLORS];
-
-  if (nIndex < 0 || NUM_SYSCOLORS < nIndex)
-    {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return NULL;
-    }
-
-  /* FIXME should register this object with DeleteObject() so it
-     can't be deleted */
-  if (NULL == SysPens[nIndex])
-    {
-      SysPens[nIndex] = CreatePen(PS_SOLID, 1, SysColors[nIndex]);
-    }
+  if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
+  {
+    return SysPens[nIndex];
+  }
 
-  return SysPens[nIndex];
+  SetLastError(ERROR_INVALID_PARAMETER);
+  return NULL;
 }
 
 /*
@@ -137,89 +104,51 @@ GetSysColorPen(int nIndex)
 HBRUSH STDCALL
 GetSysColorBrush(int nIndex)
 {
-  static HBRUSH SysBrushes[NUM_SYSCOLORS];
-
-  if (nIndex < 0 || NUM_SYSCOLORS < nIndex)
-    {
-      SetLastError(ERROR_INVALID_PARAMETER);
-      return NULL;
-    }
-
-  /* FIXME should register this object with DeleteObject() so it
-     can't be deleted */
-  if (NULL == SysBrushes[nIndex])
-    {
-      SysBrushes[nIndex] = (HBRUSH) ((DWORD) CreateSolidBrush(SysColors[nIndex]) | 0x00800000);
-    }
+  if(nIndex >= 0 && nIndex <= NUM_SYSCOLORS)
+  {
+    return SysBrushes[nIndex];
+  }
 
-  return SysBrushes[nIndex];
+  SetLastError(ERROR_INVALID_PARAMETER);
+  return NULL;
 }
 
 /*
- * @unimplemented
- */
-/*
-LRESULT STDCALL
-DefFrameProcA( HWND hWnd,
-             HWND hWndMDIClient,
-             UINT uMsg,
-             WPARAM wParam,
-             LPARAM lParam )
-{
-    UNIMPLEMENTED;
-    return ((LRESULT)0);
-}
-*/
-
-/*
- * @unimplemented
+ * @implemented
  */
-/*
-LRESULT STDCALL
-DefFrameProcW(HWND hWnd,
-             HWND hWndMDIClient,
-             UINT uMsg,
-             WPARAM wParam,
-             LPARAM lParam)
-{
-    UNIMPLEMENTED;
-    return ((LRESULT)0);
-}
-*/
-
-ULONG
-UserHasAnyFrameStyle(ULONG Style, ULONG ExStyle)
-{
-    return ((Style & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) ||
-            (ExStyle & WS_EX_DLGMODALFRAME) ||
-            (!(Style & (WS_CHILD | WS_POPUP))));
-}
-
-ULONG
-UserHasDlgFrameStyle(ULONG Style, ULONG ExStyle)
-{
-    return ((ExStyle & WS_EX_DLGMODALFRAME) ||
-            ((Style & WS_DLGFRAME) && (!(Style & WS_THICKFRAME))));
-}
-
-ULONG
-UserHasThickFrameStyle(ULONG Style, ULONG ExStyle)
-{
-    return ((Style & WS_THICKFRAME) &&
-            (!((Style & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)));
-}
-
-ULONG
-UserHasThinFrameStyle(ULONG Style, ULONG ExStyle)
+BOOL
+STDCALL
+SetSysColors(
+  int cElements,
+  CONST INT *lpaElements,
+  CONST COLORREF *lpaRgbValues)
 {
-    return ((Style & WS_BORDER) || (!(Style & (WS_CHILD | WS_POPUP))));
-}
+  BOOL Ret;
+  struct
+  {
+    INT *Elements;
+    COLORREF *Colors;
+  } ChangeSysColors;
 
-ULONG
-UserHasBigFrameStyle(ULONG Style, ULONG ExStyle)
-{
-    return ((Style & (WS_THICKFRAME | WS_DLGFRAME)) ||
-            (ExStyle & WS_EX_DLGMODALFRAME));
+  ChangeSysColors.Elements = (INT*)lpaElements;
+  ChangeSysColors.Colors = (COLORREF*)lpaRgbValues;
+  
+  if(cElements > 0)
+  {
+    Ret = NtUserSetSysColors(&ChangeSysColors, cElements);
+    if(Ret)
+    {
+      /* FIXME - just change it in the usermode structure, too, instead of asking win32k again */
+      NtUserGetSysColors(SysColors, NUM_SYSCOLORS);
+    }
+  }
+  else
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    Ret = FALSE;
+  }
+  
+  return Ret;
 }
 
 void
@@ -272,6 +201,11 @@ UserGetInsideRectNC(HWND hWnd, RECT *rect)
 VOID
 DefWndSetRedraw(HWND hWnd, WPARAM wParam)
 {
+  if ((BOOL) wParam && 0 == (GetWindowLong(hWnd, GWL_STYLE) & WS_VISIBLE))
+    {
+      ShowWindow(hWnd, SW_NORMAL);
+    }
+
   UNIMPLEMENTED;
 }
 
@@ -285,7 +219,7 @@ DefWndHandleSetCursor(HWND hWnd, WPARAM wParam, LPARAM lParam, ULONG Style)
       return(0);
     }
 
-  switch(LOWORD(lParam))
+  switch((INT_PTR) LOWORD(lParam))
     {
     case HTERROR:
       {
@@ -484,7 +418,7 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam)
 {
   HRGN DesktopRgn;
   MSG msg;
-  RECT sizingRect, mouseRect, origRect, clipRect;
+  RECT sizingRect, mouseRect, origRect, clipRect, unmodRect;
   HDC hdc;
   LONG hittest = (LONG)(wParam & 0x0f);
   HCURSOR hDragCursor = 0, hOldCursor = 0;
@@ -553,6 +487,7 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam)
   
   WinPosGetMinMaxInfo(hwnd, NULL, NULL, &minTrack, &maxTrack);
   GetWindowRect(hwnd, &sizingRect);
+  GetWindowRect(hwnd, &unmodRect);  
   if (Style & WS_CHILD)
     {
       MapWindowPoints( 0, hWndParent, (LPPOINT)&sizingRect, 2 );
@@ -689,7 +624,7 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam)
          if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
          else
            {
-             RECT newRect = sizingRect;
+             RECT newRect = unmodRect;
              WPARAM wpSizingHit = 0;
              
              if (hittest == HTCAPTION) OffsetRect( &newRect, dx, dy );
@@ -703,6 +638,7 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam)
              /* determine the hit location */
              if (hittest >= HTLEFT && hittest <= HTBOTTOMRIGHT)
                wpSizingHit = WMSZ_LEFT + (hittest - HTLEFT);
+             unmodRect = newRect;
              SendMessageA( hwnd, WM_SIZING, wpSizingHit, (LPARAM)&newRect );
              
              if (!iconic)