[WIN32SS:NTUSER] Implement "Window Snap" feature (#1226)
[reactos.git] / win32ss / user / ntuser / defwnd.c
index 8be87b0..d00d9aa 100644 (file)
@@ -307,7 +307,7 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
       {
          if (pWnd->pcls->spcur)
          {
-            UserSetCursor(pWnd->pcls->spcur, FALSE);
+            IntSystemSetCursor(pWnd->pcls->spcur);
         }
         return FALSE;
       }
@@ -319,7 +319,7 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
          {
             break;
          }
-         UserSetCursor(SYSTEMCUR(SIZEWE), FALSE);
+         IntSystemSetCursor(SYSTEMCUR(SIZEWE));
          return TRUE;
       }
 
@@ -330,7 +330,7 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
          {
             break;
          }
-         UserSetCursor(SYSTEMCUR(SIZENS), FALSE);
+         IntSystemSetCursor(SYSTEMCUR(SIZENS));
          return TRUE;
        }
 
@@ -341,7 +341,7 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
          {
             break;
          }
-         UserSetCursor(SYSTEMCUR(SIZENWSE), FALSE);
+         IntSystemSetCursor(SYSTEMCUR(SIZENWSE));
          return TRUE;
        }
 
@@ -352,11 +352,11 @@ DefWndHandleSetCursor(PWND pWnd, WPARAM wParam, LPARAM lParam)
          {
             break;
          }
-         UserSetCursor(SYSTEMCUR(SIZENESW), FALSE);
+         IntSystemSetCursor(SYSTEMCUR(SIZENESW));
          return TRUE;
        }
    }
-   UserSetCursor(SYSTEMCUR(ARROW), FALSE);
+   IntSystemSetCursor(SYSTEMCUR(ARROW));
    return FALSE;
 }
 
@@ -619,14 +619,6 @@ IntDefWindowProc(
          if (!Wnd->spwndOwner) break;
          if (LOWORD(lParam))
          {
-            if (wParam)
-            {
-               if (!(Wnd->state & WNDS_HIDDENPOPUP)) break;
-               Wnd->state &= ~WNDS_HIDDENPOPUP;
-            }
-            else
-                Wnd->state |= WNDS_HIDDENPOPUP;
-
             co_WinPosShowWindow(Wnd, wParam ? SW_SHOWNOACTIVATE : SW_HIDE);
          }
          break;
@@ -721,6 +713,16 @@ IntDefWindowProc(
            ERR("WM_NCRBUTTONUP\n");
           break;
 
+      case WM_XBUTTONUP:
+      case WM_NCXBUTTONUP:
+          if (HIWORD(wParam) == XBUTTON1 || HIWORD(wParam) == XBUTTON2)
+          {
+              co_IntSendMessage(UserHMGetHandle(Wnd), WM_APPCOMMAND, (WPARAM)UserHMGetHandle(Wnd),
+                                MAKELPARAM(LOWORD(wParam), FAPPCOMMAND_MOUSE | HIWORD(wParam)));
+          }
+          break;
+
+
       case WM_CONTEXTMENU:
       {
             if (Wnd->style & WS_CHILD)
@@ -779,6 +781,92 @@ IntDefWindowProc(
                co_IntSendMessage(UserHMGetHandle(Wnd), WM_CONTEXTMENU, (WPARAM)UserHMGetHandle(Wnd), MAKELPARAM(-1, -1));
             }
          }
+         if (IS_KEY_DOWN(gafAsyncKeyState, VK_LWIN) || IS_KEY_DOWN(gafAsyncKeyState, VK_RWIN))
+         {
+            PWND topWnd = UserGetWindowObject(UserGetForegroundWindow());
+            
+            if (topWnd)
+            {
+               if (wParam == VK_DOWN)
+               {
+                  co_IntSendMessage(UserHMGetHandle(topWnd), WM_SYSCOMMAND, (topWnd->style & WS_MAXIMIZE) ? SC_RESTORE : SC_MINIMIZE, lParam);
+               }    
+               else
+               if (wParam == VK_UP)
+               {
+                  RECT currentRect = (topWnd->InternalPos.NormalRect.right == topWnd->InternalPos.NormalRect.left) || 
+                                     (topWnd->InternalPos.NormalRect.top == topWnd->InternalPos.NormalRect.bottom)
+                                       ? topWnd->rcWindow 
+                                       : topWnd->InternalPos.NormalRect;
+                  co_IntSendMessage(UserHMGetHandle(topWnd), WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+                  
+                  // save normal rect if maximazing snapped window
+                  topWnd->InternalPos.NormalRect = currentRect;
+               }
+               else
+               if (wParam == VK_LEFT || wParam == VK_RIGHT)
+               {
+                  RECT snapRect;
+                  RECT normalRect;
+                  RECT windowRect;
+                  BOOL snapped = FALSE;
+                  normalRect = topWnd->InternalPos.NormalRect;
+                  snapped = (normalRect.left != 0 
+                          && normalRect.right != 0
+                          && normalRect.top != 0
+                          && normalRect.bottom != 0);
+
+                  if (topWnd->style & WS_MAXIMIZE)
+                  {
+                     co_IntSendMessage(UserHMGetHandle(topWnd), WM_SYSCOMMAND, SC_RESTORE, lParam);
+                     snapped = FALSE;
+                  }
+                  
+                  windowRect = topWnd->rcWindow;
+
+                  UserSystemParametersInfo(SPI_GETWORKAREA, 0, &snapRect, 0);
+                  if (wParam == VK_LEFT)
+                  {
+                     snapRect.right = (snapRect.right - snapRect.left) / 2 + snapRect.left;
+                  }
+                  else // VK_RIGHT
+                  {
+                     snapRect.left = (snapRect.right - snapRect.left) / 2 + snapRect.left;
+                  }
+
+                  if (snapped)
+                  {
+                     // if window was snapped but moved to other location - restore normal size
+                     if (snapRect.left != windowRect.left ||
+                         snapRect.right != windowRect.right ||
+                         snapRect.top != windowRect.top ||
+                         snapRect.bottom != windowRect.bottom)
+                     {
+                        RECT empty = {0, 0, 0, 0};
+                        co_WinPosSetWindowPos(topWnd,
+                                        0,
+                                        normalRect.left,
+                                        normalRect.top,
+                                        normalRect.right - normalRect.left,
+                                        normalRect.bottom - normalRect.top,
+                                        0);
+                        topWnd->InternalPos.NormalRect = empty;
+                     }
+                  }
+                  else
+                  {
+                     co_WinPosSetWindowPos(topWnd,
+                                        0,
+                                        snapRect.left,
+                                        snapRect.top,
+                                        snapRect.right - snapRect.left,
+                                        snapRect.bottom - snapRect.top,
+                                        0);
+                     topWnd->InternalPos.NormalRect = windowRect;
+                  }
+               }
+            }
+         }
          break;
 
       case WM_SYSKEYDOWN:
@@ -957,7 +1045,7 @@ IntDefWindowProc(
          if (!hBrush) return 0;
          if (hBrush <= (HBRUSH)COLOR_MENUBAR)
          {
-            hBrush = IntGetSysColorBrush((INT)hBrush);
+            hBrush = IntGetSysColorBrush(HandleToUlong(hBrush));
          }
          if (Wnd->pcls->style & CS_PARENTDC)
          {