Beispiel #1
0
LRESULT
DefWndNCCalcSize(HWND hWnd, BOOL CalcSizeStruct, RECT *Rect)
{
   LRESULT Result = 0;
   DWORD Style = GetClassLongPtrW(hWnd, GCL_STYLE);
   DWORD ExStyle;
   SIZE WindowBorders;
   RECT OrigRect;

   if (Rect == NULL)
   {
      return Result;
   }
   OrigRect = *Rect;

   if (CalcSizeStruct)
   {
      if (Style & CS_VREDRAW)
      {
         Result |= WVR_VREDRAW;
      }
      if (Style & CS_HREDRAW)
      {
         Result |= WVR_HREDRAW;
      }
      Result |= WVR_VALIDRECTS;
   }

   Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
   ExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE);

   if (!(Style & WS_MINIMIZE))
   {
      HMENU menu = GetMenu(hWnd);

      if (UserHasWindowEdge(Style, ExStyle))
      {
         UserGetWindowBorders(Style, ExStyle, &WindowBorders, FALSE);
         InflateRect(Rect, -WindowBorders.cx, -WindowBorders.cy);
      } else
      if ((ExStyle & WS_EX_STATICEDGE) || (Style & WS_BORDER))
      {
         InflateRect(Rect, -1, -1);
      }

      if ((Style & WS_CAPTION) == WS_CAPTION)
      {
         if (ExStyle & WS_EX_TOOLWINDOW)
            Rect->top += GetSystemMetrics(SM_CYSMCAPTION);
         else
            Rect->top += GetSystemMetrics(SM_CYCAPTION);
      }

      if (menu && !(Style & WS_CHILD))
      {
         HDC hDC = GetWindowDC(hWnd);
         if(hDC)
         {
           RECT CliRect = *Rect;
           CliRect.bottom -= OrigRect.top;
           CliRect.right -= OrigRect.left;
           CliRect.left -= OrigRect.left;
           CliRect.top -= OrigRect.top;
           Rect->top += MenuDrawMenuBar(hDC, &CliRect, hWnd, TRUE);
           ReleaseDC(hWnd, hDC);
         }
      }

      if (ExStyle & WS_EX_CLIENTEDGE)
      {
         InflateRect(Rect, -2 * GetSystemMetrics(SM_CXBORDER),
            -2 * GetSystemMetrics(SM_CYBORDER));
      }

      if(Style & (WS_VSCROLL | WS_HSCROLL))
      {
        SCROLLBARINFO sbi;
        SETSCROLLBARINFO ssbi;

        sbi.cbSize = sizeof(SCROLLBARINFO);
        if((Style & WS_VSCROLL) && NtUserGetScrollBarInfo(hWnd, OBJID_VSCROLL, &sbi))
        {
          int i;
          LONG sx = Rect->right;

          sx -= GetSystemMetrics(SM_CXVSCROLL);
          for(i = 0; i <= CCHILDREN_SCROLLBAR; i++)
            ssbi.rgstate[i] = sbi.rgstate[i];
          if(sx <= Rect->left)
            ssbi.rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
          else
            ssbi.rgstate[0] &= ~STATE_SYSTEM_OFFSCREEN;
          NtUserSetScrollBarInfo(hWnd, OBJID_VSCROLL, &ssbi);
          if(ssbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN)
            Style &= ~WS_VSCROLL;
        }
        else
          Style &= ~WS_VSCROLL;

        if((Style & WS_HSCROLL) && NtUserGetScrollBarInfo(hWnd, OBJID_HSCROLL, &sbi))
        {
          int i;
          LONG sy = Rect->bottom;

          sy -= GetSystemMetrics(SM_CYHSCROLL);
          for(i = 0; i <= CCHILDREN_SCROLLBAR; i++)
            ssbi.rgstate[i] = sbi.rgstate[i];
          if(sy <= Rect->top)
            ssbi.rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
          else
            ssbi.rgstate[0] &= ~STATE_SYSTEM_OFFSCREEN;
          NtUserSetScrollBarInfo(hWnd, OBJID_HSCROLL, &ssbi);
          if(ssbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN)
            Style &= ~WS_HSCROLL;
        }
        else
          Style &= ~WS_HSCROLL;
      }

      if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL))
      {
         if ((ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
            Rect->left += GetSystemMetrics(SM_CXVSCROLL);
         else
            Rect->right -= GetSystemMetrics(SM_CXVSCROLL);
         Rect->bottom -= GetSystemMetrics(SM_CYHSCROLL);
      }
      else
      {
         if (Style & WS_VSCROLL)
         {
            if ((ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
               Rect->left += GetSystemMetrics(SM_CXVSCROLL);
            else
               Rect->right -= GetSystemMetrics(SM_CXVSCROLL);
         }
         else if (Style & WS_HSCROLL)
            Rect->bottom -= GetSystemMetrics(SM_CYHSCROLL);
      }
      if (Rect->top > Rect->bottom)
         Rect->bottom = Rect->top;
      if (Rect->left > Rect->right)
         Rect->right = Rect->left;
   }
   else
   {
      Rect->right = Rect->left;
      Rect->bottom = Rect->top;
   }

   return Result;
}
Beispiel #2
0
/***********************************************************************
 *           IntScrollHandleScrollEvent
 *
 * Handle a mouse or timer event for the scrollbar.
 * 'Pt' is the location of the mouse event in drawing coordinates
 */
static VOID FASTCALL
IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt)
{
  static POINT PrevPt;           /* Previous mouse position for timer events */
  static UINT TrackThumbPos;     /* Thumb position when tracking started. */
  static INT LastClickPos;       /* Position in the scroll-bar of the last
                                    button-down event. */
  static INT LastMousePos;       /* Position in the scroll-bar of the last
                                    mouse event. */

  DWORD HitTest;
  HWND WndOwner, WndCtl;
  BOOL Vertical;
  HDC Dc;
  SCROLLBARINFO ScrollBarInfo;
  SETSCROLLBARINFO NewInfo;

  if (! IntGetScrollBarInfo(Wnd, SBType, &ScrollBarInfo))
    {
      return;
    }
  if (SCROLL_NOWHERE == ScrollTrackHitTest && WM_LBUTTONDOWN != Msg)
    {
      return;
    }

  NewInfo.nTrackPos = ScrollTrackingVal;
  NewInfo.reserved = ScrollBarInfo.reserved;
  memcpy(NewInfo.rgstate, ScrollBarInfo.rgstate, (CCHILDREN_SCROLLBAR + 1) * sizeof(DWORD));

  if (SB_CTL == SBType
      && 0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & (SBS_SIZEGRIP | SBS_SIZEBOX)))
    {
      switch(Msg)
        {
          case WM_LBUTTONDOWN:  /* Initialise mouse tracking */
            HideCaret(Wnd);  /* hide caret while holding down LBUTTON */
            SetCapture(Wnd);
            PrevPt = Pt;
            ScrollTrackHitTest = HitTest = SCROLL_THUMB;
            break;
          case WM_MOUSEMOVE:
            GetClientRect(GetParent(GetParent(Wnd)), &ScrollBarInfo.rcScrollBar);
            PrevPt = Pt;
            break;
          case WM_LBUTTONUP:
            ReleaseCapture();
            ScrollTrackHitTest = HitTest = SCROLL_NOWHERE;
            if (Wnd == GetFocus())
              {
                ShowCaret(Wnd);
              }
            break;
          case WM_SYSTIMER:
            Pt = PrevPt;
            break;
          }
      return;
    }

  Dc = GetDCEx(Wnd, 0, DCX_CACHE | ((SB_CTL == SBType) ? 0 : DCX_WINDOW));
  if (SB_VERT == SBType)
    {
      Vertical = TRUE;
    }
  else if (SB_HORZ == SBType)
    {
      Vertical = FALSE;
    }
  else
    {
      Vertical = (0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & SBS_VERT));
    }
  WndOwner = (SB_CTL == SBType) ? GetParent(Wnd) : Wnd;
  WndCtl   = (SB_CTL == SBType) ? Wnd : NULL;

  switch (Msg)
    {
      case WM_LBUTTONDOWN:  /* Initialise mouse tracking */
        HideCaret(Wnd);     /* hide caret while holding down LBUTTON */
        ScrollTrackVertical = Vertical;
        ScrollTrackHitTest  = HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, FALSE );
        LastClickPos  = Vertical ? (Pt.y - ScrollBarInfo.rcScrollBar.top)
                        : (Pt.x - ScrollBarInfo.rcScrollBar.left);
        LastMousePos  = LastClickPos;
        TrackThumbPos = ScrollBarInfo.xyThumbTop;
        PrevPt = Pt;
        if (SB_CTL == SBType && 0 != (GetWindowLongPtrW(Wnd, GWL_STYLE) & WS_TABSTOP))
          {
            SetFocus(Wnd);
          }
        SetCapture(Wnd);
        ScrollBarInfo.rgstate[ScrollTrackHitTest] |= STATE_SYSTEM_PRESSED;
        NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest];
        NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
        break;

      case WM_MOUSEMOVE:
        HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, TRUE);
        PrevPt = Pt;
        break;

      case WM_LBUTTONUP:
        HitTest = SCROLL_NOWHERE;
        ReleaseCapture();
        /* if scrollbar has focus, show back caret */
        if (Wnd == GetFocus())
          {
            ShowCaret(Wnd);
          }
        ScrollBarInfo.rgstate[ScrollTrackHitTest] &= ~STATE_SYSTEM_PRESSED;
        NewInfo.rgstate[ScrollTrackHitTest] = ScrollBarInfo.rgstate[ScrollTrackHitTest];
        NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
        break;

      case WM_SYSTIMER:
        Pt = PrevPt;
        HitTest = IntScrollHitTest(&ScrollBarInfo, Vertical, Pt, FALSE);
        break;

      default:
          return;  /* Should never happen */
    }

  switch (ScrollTrackHitTest)
    {
      case SCROLL_NOWHERE:  /* No tracking in progress */
        break;

      case SCROLL_TOP_ARROW:
        if (HitTest == ScrollTrackHitTest)
          {
            if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg))
              {
                SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
                             SB_LINEUP, (LPARAM) WndCtl);
              }
	    SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ?
                           SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
                           (TIMERPROC) NULL);
          }
        else
          {
            KillSystemTimer(Wnd, SCROLL_TIMER);
          }
        break;

      case SCROLL_TOP_RECT:
        if (HitTest == ScrollTrackHitTest)
          {
            if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg))
              {
                SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
                             SB_PAGEUP, (LPARAM) WndCtl);
              }
            SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ?
                           SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
                           (TIMERPROC) NULL);
          }
        else
          {
            KillSystemTimer(Wnd, SCROLL_TIMER);
          }
        break;

      case SCROLL_THUMB:
        if (WM_LBUTTONDOWN == Msg)
          {
            ScrollTrackingWin = Wnd;
            ScrollTrackingBar = SBType;
            ScrollTrackingPos = TrackThumbPos + LastMousePos - LastClickPos;
            ScrollTrackingVal = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo,
                                                     Vertical, ScrollTrackingPos);
            NewInfo.nTrackPos = ScrollTrackingVal;
            NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
            IntScrollDrawMovingThumb(Dc, &ScrollBarInfo, Vertical);
          }
        else if (WM_LBUTTONUP == Msg)
          {
            ScrollTrackingWin = 0;
            ScrollTrackingVal = 0;
            IntDrawScrollInterior(Wnd, Dc, SBType, Vertical, &ScrollBarInfo);
          }
        else  /* WM_MOUSEMOVE */
          {
            UINT Pos;

            if (! IntScrollPtInRectEx(&ScrollBarInfo.rcScrollBar, Pt, Vertical))
              {
                Pos = LastClickPos;
              }
            else
              {
                Pt = IntScrollClipPos(&ScrollBarInfo.rcScrollBar, Pt);
		Pos = Vertical ? (Pt.y - ScrollBarInfo.rcScrollBar.top)
                               : (Pt.x - ScrollBarInfo.rcScrollBar.left);
              }
            if (Pos != LastMousePos || ! ScrollMovingThumb)
              {
                LastMousePos = Pos;
                ScrollTrackingPos = TrackThumbPos + Pos - LastClickPos;
                ScrollTrackingVal = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo,
                                                         Vertical, ScrollTrackingPos);
                NewInfo.nTrackPos = ScrollTrackingVal;
                NtUserSetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), &NewInfo);
                IntScrollDrawMovingThumb(Dc, &ScrollBarInfo, Vertical);
                SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
                             MAKEWPARAM(SB_THUMBTRACK, ScrollTrackingVal),
                             (LPARAM) WndCtl);
             }
        }
        break;

      case SCROLL_BOTTOM_RECT:
        if (HitTest == ScrollTrackHitTest)
          {
            if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg))
              {
                SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
                             SB_PAGEDOWN, (LPARAM) WndCtl);
              }
            SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ?
                           SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
                           (TIMERPROC) NULL);
          }
        else
          {
            KillSystemTimer(Wnd, SCROLL_TIMER);
          }
        break;

      case SCROLL_BOTTOM_ARROW:
        if (HitTest == ScrollTrackHitTest)
          {
            if ((WM_LBUTTONDOWN == Msg) || (WM_SYSTIMER == Msg))
              {
                SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
                             SB_LINEDOWN, (LPARAM) WndCtl);
              }
	    SetSystemTimer(Wnd, SCROLL_TIMER, (WM_LBUTTONDOWN == Msg) ?
                           SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
                           (TIMERPROC) NULL);
          }
        else
          {
            KillSystemTimer(Wnd, SCROLL_TIMER);
          }
        break;
    }

  if (WM_LBUTTONDOWN == Msg)
    {
      if (SCROLL_THUMB == HitTest)
        {
          UINT Val = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical,
                                          TrackThumbPos + LastMousePos - LastClickPos);
          SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
                       MAKEWPARAM(SB_THUMBTRACK, Val), (LPARAM) WndCtl);
        }
    }

  if (WM_LBUTTONUP == Msg)
    {
      HitTest = ScrollTrackHitTest;
      ScrollTrackHitTest = SCROLL_NOWHERE;  /* Terminate tracking */

      if (SCROLL_THUMB == HitTest)
        {
          UINT Val = IntScrollGetThumbVal(Wnd, SBType, &ScrollBarInfo, Vertical,
                                          TrackThumbPos + LastMousePos - LastClickPos);
          SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
                       MAKEWPARAM(SB_THUMBPOSITION, Val), (LPARAM) WndCtl);
        }
      SendMessageW(WndOwner, Vertical ? WM_VSCROLL : WM_HSCROLL,
                   SB_ENDSCROLL, (LPARAM) WndCtl);
    }

  ReleaseDC(Wnd, Dc);
}