⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 winpos.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
      }
   }

   if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
      co_IntPostOrSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);

   return TRUE;
}

LRESULT FASTCALL
co_WinPosGetNonClientSize(PWINDOW_OBJECT Window, RECT* WindowRect, RECT* ClientRect)
{
   LRESULT Result;

   ASSERT_REFS_CO(Window);
   
   *ClientRect = *WindowRect;
   Result = co_IntSendMessage(Window->hSelf, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect);

   FixClientRect(ClientRect, WindowRect);

   return Result;
}

BOOLEAN FASTCALL
co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
{
   BOOLEAN WasVisible;
   UINT Swp = 0;
   RECT NewPos;
   BOOLEAN ShowFlag;
   //  HRGN VisibleRgn;

   ASSERT_REFS_CO(Window);

   WasVisible = (Window->Style & WS_VISIBLE) != 0;

   switch (Cmd)
   {
      case SW_HIDE:
         {
            if (!WasVisible)
            {
               return(FALSE);
            }
            Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
            if (Window->hSelf != UserGetActiveWindow())
               Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
            break;
         }

      case SW_SHOWMINNOACTIVE:
         Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
         /* Fall through. */
      case SW_SHOWMINIMIZED:
         Swp |= SWP_SHOWWINDOW;
         /* Fall through. */
      case SW_MINIMIZE:
         {
            Swp |= SWP_NOACTIVATE;
            if (!(Window->Style & WS_MINIMIZE))
            {
               Swp |= co_WinPosMinMaximize(Window, SW_MINIMIZE, &NewPos) |
                      SWP_FRAMECHANGED;
            }
            else
            {
               Swp |= SWP_NOSIZE | SWP_NOMOVE;
               if (! WasVisible)
               {
                  Swp |= SWP_FRAMECHANGED;
               }
            }
            break;
         }

      case SW_SHOWMAXIMIZED:
         {
            Swp |= SWP_SHOWWINDOW;
            if (!(Window->Style & WS_MAXIMIZE))
            {
               Swp |= co_WinPosMinMaximize(Window, SW_MAXIMIZE, &NewPos) |
                      SWP_FRAMECHANGED;
            }
            else
            {
               Swp |= SWP_NOSIZE | SWP_NOMOVE;
               if (! WasVisible)
               {
                  Swp |= SWP_FRAMECHANGED;
               }
            }
            break;
         }

      case SW_SHOWNA:
         Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
         /* Fall through. */
      case SW_SHOW:
         Swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
         /* Don't activate the topmost window. */
         break;

      case SW_SHOWNOACTIVATE:
         //Swp |= SWP_NOZORDER;
         Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
         /* Fall through. */
      case SW_SHOWNORMAL:
      case SW_SHOWDEFAULT:
      case SW_RESTORE:
         Swp |= SWP_SHOWWINDOW;
         if (Window->Style & (WS_MINIMIZE | WS_MAXIMIZE))
         {
            Swp |= co_WinPosMinMaximize(Window, SW_RESTORE, &NewPos) |
                   SWP_FRAMECHANGED;
         }
         else
         {
            Swp |= SWP_NOSIZE | SWP_NOMOVE;
            if (! WasVisible)
            {
               Swp |= SWP_FRAMECHANGED;
            }
         }
         break;
   }

   ShowFlag = (Cmd != SW_HIDE);
   
   if (ShowFlag != WasVisible)
   {
      co_IntSendMessage(Window->hSelf, WM_SHOWWINDOW, ShowFlag, 0);
   }

   /* We can't activate a child window */
   if ((Window->Style & WS_CHILD) &&
         !(Window->ExStyle & WS_EX_MDICHILD))
   {
      Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
   }

   co_WinPosSetWindowPos(Window, 0 != (Window->ExStyle & WS_EX_TOPMOST)
                         ? HWND_TOPMOST : HWND_TOP,
                         NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, LOWORD(Swp));

   if (Cmd == SW_HIDE)
   {
      PWINDOW_OBJECT ThreadFocusWindow;
      
      /* FIXME: This will cause the window to be activated irrespective
       * of whether it is owned by the same thread. Has to be done
       * asynchronously.
       */

      if (Window->hSelf == UserGetActiveWindow())
      {
         co_WinPosActivateOtherWindow(Window);
      }


      //temphack
      ThreadFocusWindow = UserGetWindowObject(IntGetThreadFocusWindow());
      
      /* Revert focus to parent */
      if (ThreadFocusWindow && (Window == ThreadFocusWindow ||
            IntIsChildWindow(Window, ThreadFocusWindow)))
      {
         //faxme: as long as we have ref on Window, we also, indirectly, have ref on parent...
         co_UserSetFocus(Window->Parent);
      }
   }

   /* FIXME: Check for window destruction. */

   if ((Window->Flags & WINDOWOBJECT_NEED_SIZE) &&
         !(Window->Status & WINDOWSTATUS_DESTROYING))
   {
      WPARAM wParam = SIZE_RESTORED;

      Window->Flags &= ~WINDOWOBJECT_NEED_SIZE;
      if (Window->Style & WS_MAXIMIZE)
      {
         wParam = SIZE_MAXIMIZED;
      }
      else if (Window->Style & WS_MINIMIZE)
      {
         wParam = SIZE_MINIMIZED;
      }

      co_IntSendMessage(Window->hSelf, WM_SIZE, wParam,
                        MAKELONG(Window->ClientRect.right -
                                 Window->ClientRect.left,
                                 Window->ClientRect.bottom -
                                 Window->ClientRect.top));
      co_IntSendMessage(Window->hSelf, WM_MOVE, 0,
                        MAKELONG(Window->ClientRect.left,
                                 Window->ClientRect.top));
      IntEngWindowChanged(Window, WOC_RGN_CLIENT);
      
   }

   /* Activate the window if activation is not requested and the window is not minimized */
   /*
     if (!(Swp & (SWP_NOACTIVATE | SWP_HIDEWINDOW)) && !(Window->Style & WS_MINIMIZE))
       {
         WinPosChangeActiveWindow(Wnd, FALSE);
       }
   */
   return(WasVisible);
}


#if 0

/* find child of 'parent' that contains the given point (in parent-relative coords) */
PWINDOW_OBJECT child_window_from_point(PWINDOW_OBJECT parent, int x, int y )
{
    PWINDOW_OBJECT Wnd;// = parent->FirstChild;

//    LIST_FOR_EACH_ENTRY( Wnd, &parent->children, struct window, entry )
    for (Wnd = parent->FirstChild; Wnd; Wnd = Wnd->NextSibling)
    {
        if (!IntPtInWindow( Wnd, x, y )) continue;  /* skip it */

        /* if window is minimized or disabled, return at once */
        if (Wnd->Style & (WS_MINIMIZE|WS_DISABLED)) return Wnd;

        /* if point is not in client area, return at once */
        if (x < Wnd->ClientRect.left || x >= Wnd->ClientRect.right ||
            y < Wnd->ClientRect.top || y >= Wnd->ClientRect.bottom)
            return Wnd;

        return child_window_from_point( Wnd, x - Wnd->ClientRect.left, y - Wnd->ClientRect.top );
    }
    return parent;  /* not found any child */
}
#endif

/* wine server: child_window_from_point 

Caller must dereference the "returned" Window
*/
static
VOID FASTCALL
co_WinPosSearchChildren(
   PWINDOW_OBJECT ScopeWin, 
   PUSER_MESSAGE_QUEUE OnlyHitTests, 
   POINT *Point,
   PWINDOW_OBJECT* Window,    
   USHORT *HitTest
   )
{
   PWINDOW_OBJECT Current;
   HWND *List, *phWnd;
   USER_REFERENCE_ENTRY Ref;
   
   ASSERT_REFS_CO(ScopeWin);

   if ((List = IntWinListChildren(ScopeWin)))
   {
      for (phWnd = List; *phWnd; ++phWnd)
      {
         if (!(Current = UserGetWindowObject(*phWnd)))
            continue;

         if (!(Current->Style & WS_VISIBLE))
         {
            continue;
         }

         if ((Current->Style & (WS_POPUP | WS_CHILD | WS_DISABLED)) ==
               (WS_CHILD | WS_DISABLED))
         {
            continue;
         }

         if (!IntPtInWindow(Current, Point->x, Point->y)) 
         {
             continue;
         }
        
         if (*Window) UserDerefObject(*Window);
         *Window = Current;
         UserRefObject(*Window);
         
         if (Current->Style & WS_MINIMIZE)
         {
            *HitTest = HTCAPTION;
            break;
         }

         if (Current->Style & WS_DISABLED)
         {
            *HitTest = HTERROR;
            break;
         }

         UserRefObjectCo(Current, &Ref);
         
         if (OnlyHitTests && (Current->MessageQueue == OnlyHitTests))
         {
            *HitTest = co_IntSendMessage(Current->hSelf, WM_NCHITTEST, 0,
                                         MAKELONG(Point->x, Point->y));
            if ((*HitTest) == (USHORT)HTTRANSPARENT)
            {
               UserDerefObjectCo(Current);
               continue;
            }
         }
         else
            *HitTest = HTCLIENT;

         if (Point->x >= Current->ClientRect.left &&
               Point->x < Current->ClientRect.right &&
               Point->y >= Current->ClientRect.top &&
               Point->y < Current->ClientRect.bottom)
         {
            co_WinPosSearchChildren(Current, OnlyHitTests, Point, Window, HitTest);
         }
         
         UserDerefObjectCo(Current);

         break;
      }
      ExFreePool(List);
   } 
}

/* wine: WINPOS_WindowFromPoint */
USHORT FASTCALL
co_WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint,
                         PWINDOW_OBJECT* Window)
{
   HWND DesktopWindowHandle;
   PWINDOW_OBJECT DesktopWindow;
   POINT Point = *WinPoint;
   USHORT HitTest;

   ASSERT_REFS_CO(ScopeWin);

   *Window = NULL;

   if(!ScopeWin)
   {
      DPRINT1("WinPosWindowFromPoint(): ScopeWin == NULL!\n");
      return(HTERROR);
   }

   if (ScopeWin->Style & WS_DISABLED)
   {
      return(HTERROR);
   }

   /* Translate the point to the space of the scope window. */
   DesktopWindowHandle = IntGetDesktopWindow();
   if((DesktopWindowHandle != ScopeWin->hSelf) &&
         (DesktopWindow = UserGetWindowObject(DesktopWindowHandle)))
   {
      Point.x += ScopeWin->ClientRect.left - DesktopWindow->ClientRect.left;
      Point.y += ScopeWin->ClientRect.top - DesktopWindow->ClientRect.top;
   }

   HitTest = HTNOWHERE;

   co_WinPosSearchChildren(ScopeWin, OnlyHitTests, &Point, Window, &HitTest);

   return ((*Window) ? HitTest : HTNOWHERE);
}

BOOL
STDCALL
NtUserGetMinMaxInfo(
   HWND hWnd,
   MINMAXINFO *MinMaxInfo,
   BOOL SendMessage)
{
   POINT Size;
   PINTERNALPOS InternalPos;
   PWINDOW_OBJECT Window = NULL;
   MINMAXINFO SafeMinMax;
   NTSTATUS Status;
   DECLARE_RETURN(BOOL);
   USER_REFERENCE_ENTRY Ref;

   DPRINT("Enter NtUserGetMinMaxInfo\n");
   UserEnterExclusive();

   if(!(Window = UserGetWindowObject(hWnd)))
   {
      RETURN( FALSE);
   }

   UserRefObjectCo(Window, &Ref);

   Size.x = Window->WindowRect.left;
   Size.y = Window->WindowRect.top;
   InternalPos = WinPosInitInternalPos(Window, &Size,
                                       &Window->WindowRect);
   if(InternalPos)
   {
      if(SendMessage)
      {
         co_WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition,
                                &SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
      }
      else
      {
         WinPosFillMinMaxInfoStruct(Window, &SafeMinMax);
      }
      Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
      if(!NT_SUCCESS(Status))
      {
         SetLastNtError(Status);
         RETURN( FALSE);
      }

      RETURN( TRUE);
   }

   RETURN( FALSE);

CLEANUP:
   if (Window) UserDerefObjectCo(Window);

   DPRINT("Leave NtUserGetMinMaxInfo, ret=%i\n",_ret_);
   UserLeave();
   END_CLEANUP;
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -