mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 13:10:39 +00:00
Scrollbar implementation
svn path=/trunk/; revision=7625
This commit is contained in:
parent
eb5f406f20
commit
fa6209cc0f
4 changed files with 736 additions and 170 deletions
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/* $Id $
|
||||||
|
*
|
||||||
* ReactOS User32 Library
|
* ReactOS User32 Library
|
||||||
* - ScrollBar control
|
* - ScrollBar control
|
||||||
*
|
*
|
||||||
|
@ -6,7 +7,7 @@
|
||||||
* Copyright 2003 Thomas Weidenmueller
|
* Copyright 2003 Thomas Weidenmueller
|
||||||
* Copyright 2003 Filip Navara
|
* Copyright 2003 Filip Navara
|
||||||
*
|
*
|
||||||
* Portions based on Wine code.
|
* Based on Wine code.
|
||||||
*
|
*
|
||||||
* Copyright 1993 Martin Ayotte
|
* Copyright 1993 Martin Ayotte
|
||||||
* Copyright 1994, 1996 Alexandre Julliard
|
* Copyright 1994, 1996 Alexandre Julliard
|
||||||
|
@ -35,6 +36,7 @@
|
||||||
#include <draw.h>
|
#include <draw.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <rosrtl/minmax.h>
|
||||||
|
|
||||||
/* GLOBAL VARIABLES ***********************************************************/
|
/* GLOBAL VARIABLES ***********************************************************/
|
||||||
|
|
||||||
|
@ -46,15 +48,33 @@
|
||||||
#define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */
|
#define SCROLL_BOTTOM_RECT 0x04 /* Rectangle between the thumb and the bottom arrow */
|
||||||
#define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */
|
#define SCROLL_BOTTOM_ARROW 0x05 /* Bottom or right arrow */
|
||||||
|
|
||||||
|
#define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when
|
||||||
|
holding the button down */
|
||||||
|
#define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
|
||||||
|
|
||||||
|
#define SCROLL_TIMER 0 /* Scroll timer id */
|
||||||
|
|
||||||
|
/* Thumb-tracking info */
|
||||||
|
static HWND ScrollTrackingWin = 0;
|
||||||
|
static INT ScrollTrackingBar = 0;
|
||||||
|
static INT ScrollTrackingPos = 0;
|
||||||
|
static INT ScrollTrackingVal = 0;
|
||||||
|
static BOOL ScrollMovingThumb = FALSE;
|
||||||
|
|
||||||
|
static DWORD ScrollTrackHitTest = SCROLL_NOWHERE;
|
||||||
|
static BOOL ScrollTrackVertical;
|
||||||
|
|
||||||
HBRUSH DefWndControlColor(HDC hDC, UINT ctlType);
|
HBRUSH DefWndControlColor(HDC hDC, UINT ctlType);
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
||||||
INT ArrowSize, PSCROLLBARINFO ScrollBarInfo)
|
PSCROLLBARINFO ScrollBarInfo)
|
||||||
{
|
{
|
||||||
INT ThumbSize = ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
|
INT ThumbSize = ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
|
||||||
|
INT ThumbTop = ScrollBarInfo->xyThumbTop;
|
||||||
RECT Rect;
|
RECT Rect;
|
||||||
HPEN hSavePen;
|
HPEN hSavePen;
|
||||||
HBRUSH hSaveBrush, hBrush;
|
HBRUSH hSaveBrush, hBrush;
|
||||||
|
@ -87,8 +107,8 @@ IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
||||||
/* Calculate the scroll rectangle */
|
/* Calculate the scroll rectangle */
|
||||||
if (Vertical)
|
if (Vertical)
|
||||||
{
|
{
|
||||||
Rect.top = ScrollBarInfo->rcScrollBar.top + ArrowSize;
|
Rect.top = ScrollBarInfo->rcScrollBar.top + ScrollBarInfo->dxyLineButton;
|
||||||
Rect.bottom = ScrollBarInfo->rcScrollBar.bottom - ArrowSize;
|
Rect.bottom = ScrollBarInfo->rcScrollBar.bottom - ScrollBarInfo->dxyLineButton;
|
||||||
Rect.left = ScrollBarInfo->rcScrollBar.left;
|
Rect.left = ScrollBarInfo->rcScrollBar.left;
|
||||||
Rect.right = ScrollBarInfo->rcScrollBar.right;
|
Rect.right = ScrollBarInfo->rcScrollBar.right;
|
||||||
}
|
}
|
||||||
|
@ -96,8 +116,8 @@ IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
||||||
{
|
{
|
||||||
Rect.top = ScrollBarInfo->rcScrollBar.top;
|
Rect.top = ScrollBarInfo->rcScrollBar.top;
|
||||||
Rect.bottom = ScrollBarInfo->rcScrollBar.bottom;
|
Rect.bottom = ScrollBarInfo->rcScrollBar.bottom;
|
||||||
Rect.left = ScrollBarInfo->rcScrollBar.left + ArrowSize;
|
Rect.left = ScrollBarInfo->rcScrollBar.left + ScrollBarInfo->dxyLineButton;
|
||||||
Rect.right = ScrollBarInfo->rcScrollBar.right - ArrowSize;
|
Rect.right = ScrollBarInfo->rcScrollBar.right - ScrollBarInfo->dxyLineButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw the scroll rectangles and thumb */
|
/* Draw the scroll rectangles and thumb */
|
||||||
|
@ -112,7 +132,7 @@ IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollBarInfo->xyThumbTop -= ArrowSize;
|
ThumbTop -= ScrollBarInfo->dxyLineButton;
|
||||||
|
|
||||||
if (ScrollBarInfo->dxyLineButton)
|
if (ScrollBarInfo->dxyLineButton)
|
||||||
{
|
{
|
||||||
|
@ -121,18 +141,18 @@ IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
||||||
if (ThumbSize)
|
if (ThumbSize)
|
||||||
{
|
{
|
||||||
PatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
|
PatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
|
||||||
ScrollBarInfo->xyThumbTop, TopSelected ? BLACKNESS : PATCOPY);
|
ThumbTop, TopSelected ? BLACKNESS : PATCOPY);
|
||||||
Rect.top += ScrollBarInfo->xyThumbTop;
|
Rect.top += ThumbTop;
|
||||||
PatBlt(hDC, Rect.left, Rect.top + ThumbSize, Rect.right - Rect.left,
|
PatBlt(hDC, Rect.left, Rect.top + ThumbSize, Rect.right - Rect.left,
|
||||||
Rect.bottom - Rect.top - ThumbSize, BottomSelected ? BLACKNESS : PATCOPY);
|
Rect.bottom - Rect.top - ThumbSize, BottomSelected ? BLACKNESS : PATCOPY);
|
||||||
Rect.bottom = Rect.top + ThumbSize;
|
Rect.bottom = Rect.top + ThumbSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ScrollBarInfo->xyThumbTop)
|
if (ThumbTop)
|
||||||
{
|
{
|
||||||
PatBlt(hDC, Rect.left, ScrollBarInfo->dxyLineButton,
|
PatBlt(hDC, Rect.left, ScrollBarInfo->dxyLineButton,
|
||||||
Rect.right - Rect.left, Rect.bottom - Rect.bottom, PATCOPY);
|
Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -140,9 +160,9 @@ IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
||||||
{
|
{
|
||||||
if (ThumbSize)
|
if (ThumbSize)
|
||||||
{
|
{
|
||||||
PatBlt(hDC, Rect.left, Rect.top, ScrollBarInfo->xyThumbTop,
|
PatBlt(hDC, Rect.left, Rect.top, ThumbTop,
|
||||||
Rect.bottom - Rect.top, TopSelected ? BLACKNESS : PATCOPY);
|
Rect.bottom - Rect.top, TopSelected ? BLACKNESS : PATCOPY);
|
||||||
Rect.left += ScrollBarInfo->xyThumbTop;
|
Rect.left += ThumbTop;
|
||||||
PatBlt(hDC, Rect.left + ThumbSize, Rect.top,
|
PatBlt(hDC, Rect.left + ThumbSize, Rect.top,
|
||||||
Rect.right - Rect.left - ThumbSize, Rect.bottom - Rect.top,
|
Rect.right - Rect.left - ThumbSize, Rect.bottom - Rect.top,
|
||||||
BottomSelected ? BLACKNESS : PATCOPY);
|
BottomSelected ? BLACKNESS : PATCOPY);
|
||||||
|
@ -150,7 +170,7 @@ IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ScrollBarInfo->xyThumbTop)
|
if (ThumbTop)
|
||||||
{
|
{
|
||||||
PatBlt(hDC, ScrollBarInfo->dxyLineButton, Rect.top,
|
PatBlt(hDC, ScrollBarInfo->dxyLineButton, Rect.top,
|
||||||
Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
|
Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
|
||||||
|
@ -168,46 +188,90 @@ IntDrawScrollInterior(HWND hWnd, HDC hDC, INT nBar, BOOL Vertical,
|
||||||
SelectObject(hDC, hSaveBrush);
|
SelectObject(hDC, hSaveBrush);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
STATIC VOID FASTCALL
|
||||||
IntDrawScrollArrows(HDC hDC, PSCROLLBARINFO ScrollBarInfo, LPRECT Rect,
|
IntDrawScrollArrows(HDC hDC, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
|
||||||
INT ArrowSize, BOOL Vertical)
|
|
||||||
{
|
{
|
||||||
RECT RectLT, RectRB;
|
RECT RectLT, RectRB;
|
||||||
INT ScrollDirFlagLT, ScrollDirFlagRB;
|
INT ScrollDirFlagLT, ScrollDirFlagRB;
|
||||||
|
|
||||||
RectLT = RectRB = *Rect;
|
RectLT = RectRB = ScrollBarInfo->rcScrollBar;
|
||||||
if (Vertical)
|
if (Vertical)
|
||||||
{
|
{
|
||||||
ScrollDirFlagLT = DFCS_SCROLLUP;
|
ScrollDirFlagLT = DFCS_SCROLLUP;
|
||||||
ScrollDirFlagRB = DFCS_SCROLLDOWN;
|
ScrollDirFlagRB = DFCS_SCROLLDOWN;
|
||||||
RectLT.bottom = RectLT.top + ArrowSize;
|
RectLT.bottom = RectLT.top + ScrollBarInfo->dxyLineButton;
|
||||||
RectRB.top = RectRB.bottom - ArrowSize;
|
RectRB.top = RectRB.bottom - ScrollBarInfo->dxyLineButton;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ScrollDirFlagLT = DFCS_SCROLLLEFT;
|
ScrollDirFlagLT = DFCS_SCROLLLEFT;
|
||||||
ScrollDirFlagRB = DFCS_SCROLLRIGHT;
|
ScrollDirFlagRB = DFCS_SCROLLRIGHT;
|
||||||
RectLT.right = RectLT.left + ArrowSize;
|
RectLT.right = RectLT.left + ScrollBarInfo->dxyLineButton;
|
||||||
RectRB.left = RectRB.right - ArrowSize;
|
RectRB.left = RectRB.right - ScrollBarInfo->dxyLineButton;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_PRESSED)
|
if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_PRESSED)
|
||||||
|
{
|
||||||
ScrollDirFlagLT |= DFCS_PUSHED | DFCS_FLAT;
|
ScrollDirFlagLT |= DFCS_PUSHED | DFCS_FLAT;
|
||||||
|
}
|
||||||
if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE)
|
if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE)
|
||||||
|
{
|
||||||
ScrollDirFlagLT |= DFCS_INACTIVE;
|
ScrollDirFlagLT |= DFCS_INACTIVE;
|
||||||
|
}
|
||||||
if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_PRESSED)
|
if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_PRESSED)
|
||||||
|
{
|
||||||
ScrollDirFlagRB |= DFCS_PUSHED | DFCS_FLAT;
|
ScrollDirFlagRB |= DFCS_PUSHED | DFCS_FLAT;
|
||||||
|
}
|
||||||
if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE)
|
if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE)
|
||||||
|
{
|
||||||
ScrollDirFlagRB |= DFCS_INACTIVE;
|
ScrollDirFlagRB |= DFCS_INACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
DrawFrameControl(hDC, &RectLT, DFC_SCROLL, ScrollDirFlagLT);
|
DrawFrameControl(hDC, &RectLT, DFC_SCROLL, ScrollDirFlagLT);
|
||||||
DrawFrameControl(hDC, &RectRB, DFC_SCROLL, ScrollDirFlagRB);
|
DrawFrameControl(hDC, &RectRB, DFC_SCROLL, ScrollDirFlagRB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC VOID FASTCALL
|
||||||
|
IntScrollDrawMovingThumb(HDC Dc, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
|
||||||
|
{
|
||||||
|
INT Pos = ScrollTrackingPos;
|
||||||
|
INT MaxSize;
|
||||||
|
INT OldTop;
|
||||||
|
|
||||||
|
if (Vertical)
|
||||||
|
{
|
||||||
|
MaxSize = ScrollBarInfo->rcScrollBar.bottom - ScrollBarInfo->rcScrollBar.top;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MaxSize = ScrollBarInfo->rcScrollBar.right - ScrollBarInfo->rcScrollBar.left;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaxSize -= ScrollBarInfo->dxyLineButton + ScrollBarInfo->xyThumbBottom
|
||||||
|
- ScrollBarInfo->xyThumbTop;
|
||||||
|
|
||||||
|
if (Pos < ScrollBarInfo->dxyLineButton)
|
||||||
|
{
|
||||||
|
Pos = ScrollBarInfo->dxyLineButton;
|
||||||
|
}
|
||||||
|
else if (MaxSize < Pos)
|
||||||
|
{
|
||||||
|
Pos = MaxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
OldTop = ScrollBarInfo->xyThumbTop;
|
||||||
|
ScrollBarInfo->xyThumbBottom = Pos + ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
|
||||||
|
ScrollBarInfo->xyThumbTop = Pos;
|
||||||
|
IntDrawScrollInterior(ScrollTrackingWin, Dc, ScrollTrackingBar, Vertical, ScrollBarInfo);
|
||||||
|
ScrollBarInfo->xyThumbBottom = OldTop + ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
|
||||||
|
ScrollBarInfo->xyThumbTop = OldTop;
|
||||||
|
|
||||||
|
ScrollMovingThumb = ! ScrollMovingThumb;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
IntDrawScrollBar(HWND hWnd, HDC hDC, INT nBar)
|
IntDrawScrollBar(HWND hWnd, HDC hDC, INT nBar)
|
||||||
{
|
{
|
||||||
INT ArrowSize = 0;
|
|
||||||
INT ThumbSize;
|
INT ThumbSize;
|
||||||
SCROLLBARINFO Info;
|
SCROLLBARINFO Info;
|
||||||
BOOL Vertical;
|
BOOL Vertical;
|
||||||
|
@ -240,21 +304,20 @@ IntDrawScrollBar(HWND hWnd, HDC hDC, INT nBar)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrowSize = Info.dxyLineButton;
|
|
||||||
ThumbSize = Info.xyThumbBottom - Info.xyThumbTop;
|
ThumbSize = Info.xyThumbBottom - Info.xyThumbTop;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draw the arrows.
|
* Draw the arrows.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (ArrowSize)
|
if (Info.dxyLineButton)
|
||||||
IntDrawScrollArrows(hDC, &Info, &Info.rcScrollBar, ArrowSize, Vertical);
|
IntDrawScrollArrows(hDC, &Info, Vertical);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draw the interior.
|
* Draw the interior.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
IntDrawScrollInterior(hWnd, hDC, nBar, Vertical, ArrowSize, &Info);
|
IntDrawScrollInterior(hWnd, hDC, nBar, Vertical, &Info);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If scroll bar has focus, reposition the caret.
|
* If scroll bar has focus, reposition the caret.
|
||||||
|
@ -269,81 +332,545 @@ IntDrawScrollBar(HWND hWnd, HDC hDC, INT nBar)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
STATIC BOOL FASTCALL
|
||||||
IntScrollPtInRectEx(LPRECT lpRect, POINT pt, BOOL Vertical)
|
IntScrollPtInRectEx(LPRECT Rect, POINT Pt, BOOL Vertical)
|
||||||
{
|
{
|
||||||
RECT Rect = *lpRect;
|
RECT TempRect = *Rect;
|
||||||
if (Vertical)
|
if (Vertical)
|
||||||
{
|
{
|
||||||
Rect.left -= lpRect->right - lpRect->left;
|
TempRect.left -= Rect->right - Rect->left;
|
||||||
Rect.right += lpRect->right - lpRect->left;
|
TempRect.right += Rect->right - Rect->left;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Rect.top -= lpRect->bottom - lpRect->top;
|
TempRect.top -= Rect->bottom - Rect->top;
|
||||||
Rect.bottom += lpRect->bottom - lpRect->top;
|
TempRect.bottom += Rect->bottom - Rect->top;
|
||||||
}
|
|
||||||
return PtInRect(&Rect, pt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD
|
return PtInRect(&TempRect, Pt);
|
||||||
IntScrollHitTest(HWND hWnd, INT nBar, POINT pt, BOOL bDragging)
|
}
|
||||||
|
|
||||||
|
STATIC LONG FASTCALL
|
||||||
|
IntScrollGetObjectId(INT SBType)
|
||||||
|
{
|
||||||
|
if (SB_VERT == SBType)
|
||||||
|
{
|
||||||
|
return OBJID_VSCROLL;
|
||||||
|
}
|
||||||
|
if (SB_HORZ == SBType)
|
||||||
|
{
|
||||||
|
return OBJID_HSCROLL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OBJID_CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC BOOL FASTCALL
|
||||||
|
IntGetScrollBarInfo(HWND Wnd, INT SBType, PSCROLLBARINFO ScrollBarInfo)
|
||||||
|
{
|
||||||
|
ScrollBarInfo->cbSize = sizeof(SCROLLBARINFO);
|
||||||
|
|
||||||
|
return NtUserGetScrollBarInfo(Wnd, IntScrollGetObjectId(SBType), ScrollBarInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC DWORD FASTCALL
|
||||||
|
IntScrollHitTest(PSCROLLBARINFO ScrollBarInfo, BOOL Vertical, POINT Pt, BOOL Dragging)
|
||||||
{
|
{
|
||||||
SCROLLBARINFO ScrollButtonInfo;
|
|
||||||
RECT WindowRect;
|
|
||||||
INT ArrowSize, ThumbSize, ThumbPos;
|
INT ArrowSize, ThumbSize, ThumbPos;
|
||||||
BOOL Vertical = (nBar == SB_VERT); /* FIXME - ((Window->Style & SBS_VERT) != 0) */
|
|
||||||
|
|
||||||
NtUserGetWindowRect(hWnd, &WindowRect);
|
if ((Dragging && ! IntScrollPtInRectEx(&ScrollBarInfo->rcScrollBar, Pt, Vertical)) ||
|
||||||
|
! PtInRect(&ScrollBarInfo->rcScrollBar, Pt))
|
||||||
ScrollButtonInfo.cbSize = sizeof(SCROLLBARINFO);
|
|
||||||
NtUserGetScrollBarInfo(hWnd, Vertical ? OBJID_VSCROLL : OBJID_HSCROLL,
|
|
||||||
&ScrollButtonInfo);
|
|
||||||
|
|
||||||
OffsetRect(&ScrollButtonInfo.rcScrollBar, WindowRect.left, WindowRect.top);
|
|
||||||
|
|
||||||
if ((bDragging && !IntScrollPtInRectEx(&ScrollButtonInfo.rcScrollBar, pt, Vertical)) ||
|
|
||||||
!PtInRect(&ScrollButtonInfo.rcScrollBar, pt))
|
|
||||||
{
|
{
|
||||||
return SCROLL_NOWHERE;
|
return SCROLL_NOWHERE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ThumbPos = ScrollButtonInfo.xyThumbTop;
|
ThumbPos = ScrollBarInfo->xyThumbTop;
|
||||||
ThumbSize = ScrollButtonInfo.xyThumbBottom - ThumbPos;
|
ThumbSize = ScrollBarInfo->xyThumbBottom - ThumbPos;
|
||||||
ArrowSize = ScrollButtonInfo.dxyLineButton;
|
ArrowSize = ScrollBarInfo->dxyLineButton;
|
||||||
|
|
||||||
if (Vertical)
|
if (Vertical)
|
||||||
{
|
{
|
||||||
if (pt.y < ScrollButtonInfo.rcScrollBar.top + ArrowSize)
|
if (Pt.y < ScrollBarInfo->rcScrollBar.top + ArrowSize)
|
||||||
|
{
|
||||||
return SCROLL_TOP_ARROW;
|
return SCROLL_TOP_ARROW;
|
||||||
if (pt.y >= ScrollButtonInfo.rcScrollBar.bottom - ArrowSize)
|
}
|
||||||
|
if (ScrollBarInfo->rcScrollBar.bottom - ArrowSize <= Pt.y)
|
||||||
|
{
|
||||||
return SCROLL_BOTTOM_ARROW;
|
return SCROLL_BOTTOM_ARROW;
|
||||||
if (!ThumbPos)
|
}
|
||||||
|
if (0 == ThumbPos)
|
||||||
|
{
|
||||||
return SCROLL_TOP_RECT;
|
return SCROLL_TOP_RECT;
|
||||||
pt.y -= ScrollButtonInfo.rcScrollBar.top;
|
}
|
||||||
if (pt.y < ThumbPos)
|
Pt.y -= ScrollBarInfo->rcScrollBar.top;
|
||||||
|
if (Pt.y < ThumbPos)
|
||||||
|
{
|
||||||
return SCROLL_TOP_RECT;
|
return SCROLL_TOP_RECT;
|
||||||
if (pt.y >= ThumbPos + ThumbSize)
|
}
|
||||||
|
if (ThumbPos + ThumbSize <= Pt.y)
|
||||||
|
{
|
||||||
return SCROLL_BOTTOM_RECT;
|
return SCROLL_BOTTOM_RECT;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (pt.x < ScrollButtonInfo.rcScrollBar.left + ArrowSize)
|
if (Pt.x < ScrollBarInfo->rcScrollBar.left + ArrowSize)
|
||||||
|
{
|
||||||
return SCROLL_TOP_ARROW;
|
return SCROLL_TOP_ARROW;
|
||||||
if (pt.x >= ScrollButtonInfo.rcScrollBar.right - ArrowSize)
|
}
|
||||||
|
if (ScrollBarInfo->rcScrollBar.right - ArrowSize <= Pt.x)
|
||||||
|
{
|
||||||
return SCROLL_BOTTOM_ARROW;
|
return SCROLL_BOTTOM_ARROW;
|
||||||
if (!ThumbPos)
|
}
|
||||||
|
if (0 == ThumbPos)
|
||||||
|
{
|
||||||
return SCROLL_TOP_RECT;
|
return SCROLL_TOP_RECT;
|
||||||
pt.x -= ScrollButtonInfo.rcScrollBar.left;
|
}
|
||||||
if (pt.x < ThumbPos)
|
Pt.x -= ScrollBarInfo->rcScrollBar.left;
|
||||||
|
if (Pt.x < ThumbPos)
|
||||||
|
{
|
||||||
return SCROLL_TOP_RECT;
|
return SCROLL_TOP_RECT;
|
||||||
if (pt.x >= ThumbPos + ThumbSize)
|
}
|
||||||
|
if (ThumbPos + ThumbSize <= Pt.x)
|
||||||
|
{
|
||||||
return SCROLL_BOTTOM_RECT;
|
return SCROLL_BOTTOM_RECT;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SCROLL_THUMB;
|
return SCROLL_THUMB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* IntScrollGetThumbVal
|
||||||
|
*
|
||||||
|
* Compute the current scroll position based on the thumb position in pixels
|
||||||
|
* from the top of the scroll-bar.
|
||||||
|
*/
|
||||||
|
STATIC UINT FASTCALL
|
||||||
|
IntScrollGetThumbVal(HWND Wnd, INT SBType, PSCROLLBARINFO ScrollBarInfo,
|
||||||
|
BOOL Vertical, INT Pos)
|
||||||
|
{
|
||||||
|
SCROLLINFO si;
|
||||||
|
INT Pixels = Vertical ? ScrollBarInfo->rcScrollBar.bottom
|
||||||
|
- ScrollBarInfo->rcScrollBar.top
|
||||||
|
: ScrollBarInfo->rcScrollBar.right
|
||||||
|
- ScrollBarInfo->rcScrollBar.left;
|
||||||
|
|
||||||
|
si.cbSize = sizeof(SCROLLINFO);
|
||||||
|
si.fMask = SIF_RANGE | SIF_PAGE;
|
||||||
|
NtUserGetScrollInfo(Wnd, SBType, &si);
|
||||||
|
if ((Pixels -= 2 * ScrollBarInfo->dxyLineButton) <= 0)
|
||||||
|
{
|
||||||
|
return si.nMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((Pixels -= (ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop)) <= 0)
|
||||||
|
{
|
||||||
|
return si.nMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pos = RtlRosMax(0, Pos - ScrollBarInfo->dxyLineButton);
|
||||||
|
if (Pixels < Pos)
|
||||||
|
{
|
||||||
|
Pos = Pixels;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 == si.nPage)
|
||||||
|
{
|
||||||
|
Pos *= si.nMax - si.nMin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Pos *= si.nMax - si.nMin - si.nPage + 1;
|
||||||
|
}
|
||||||
|
return si.nMin + ((Pos + Pixels / 2) / Pixels);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* IntScrollClipPos
|
||||||
|
*/
|
||||||
|
STATIC POINT IntScrollClipPos(PRECT Rect, POINT Pt)
|
||||||
|
{
|
||||||
|
if (Pt.x < Rect->left)
|
||||||
|
{
|
||||||
|
Pt.x = Rect->left;
|
||||||
|
}
|
||||||
|
else if (Rect->right < Pt.x)
|
||||||
|
{
|
||||||
|
Pt.x = Rect->right;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pt.y < Rect->top)
|
||||||
|
{
|
||||||
|
Pt.y = Rect->top;
|
||||||
|
}
|
||||||
|
else if (Rect->bottom < Pt.y)
|
||||||
|
{
|
||||||
|
Pt.y = Rect->bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* 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 != (GetWindowLongW(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 != (GetWindowLongW(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 != (GetWindowLongW(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* USER32 INTERNAL FUNCTIONS **************************************************/
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* ScrollTrackScrollBar
|
||||||
|
*
|
||||||
|
* Track a mouse button press on a scroll-bar.
|
||||||
|
* pt is in screen-coordinates for non-client scroll bars.
|
||||||
|
*/
|
||||||
|
VOID FASTCALL
|
||||||
|
ScrollTrackScrollBar(HWND Wnd, INT SBType, POINT Pt)
|
||||||
|
{
|
||||||
|
MSG Msg;
|
||||||
|
RECT WindowRect;
|
||||||
|
UINT XOffset, YOffset;
|
||||||
|
POINT TopLeft;
|
||||||
|
|
||||||
|
if (SB_CTL != SBType)
|
||||||
|
{
|
||||||
|
NtUserGetWindowRect(Wnd, &WindowRect);
|
||||||
|
|
||||||
|
Pt.x -= WindowRect.left;
|
||||||
|
Pt.y -= WindowRect.top;
|
||||||
|
|
||||||
|
TopLeft.x = WindowRect.left;
|
||||||
|
TopLeft.y = WindowRect.top;
|
||||||
|
ScreenToClient(Wnd, &TopLeft);
|
||||||
|
XOffset = - TopLeft.x;
|
||||||
|
YOffset = - TopLeft.y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
XOffset = 0;
|
||||||
|
YOffset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntScrollHandleScrollEvent(Wnd, SBType, WM_LBUTTONDOWN, Pt);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (! GetMessageW(&Msg, 0, 0, 0))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (CallMsgFilterW(&Msg, MSGF_SCROLLBAR))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(Msg.message)
|
||||||
|
{
|
||||||
|
case WM_SYSTIMER:
|
||||||
|
case WM_LBUTTONUP:
|
||||||
|
case WM_MOUSEMOVE:
|
||||||
|
Pt.x = LOWORD(Msg.lParam) + XOffset;
|
||||||
|
Pt.y = HIWORD(Msg.lParam) + YOffset;
|
||||||
|
IntScrollHandleScrollEvent(Wnd, SBType, Msg.message, Pt);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TranslateMessage(&Msg);
|
||||||
|
DispatchMessageW(&Msg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! IsWindow(Wnd))
|
||||||
|
{
|
||||||
|
ReleaseCapture();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (WM_LBUTTONUP != Msg.message);
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -368,9 +895,9 @@ GetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
GetScrollInfo(HWND hWnd, INT nBar, LPSCROLLINFO lpsi)
|
GetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO lpsi)
|
||||||
{
|
{
|
||||||
return NtUserGetScrollInfo(hWnd, nBar, lpsi);
|
return NtUserGetScrollInfo(Wnd, SBType, lpsi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -383,11 +910,14 @@ GetScrollPos(HWND hWnd, INT nBar)
|
||||||
|
|
||||||
ScrollInfo.cbSize = sizeof(SCROLLINFO);
|
ScrollInfo.cbSize = sizeof(SCROLLINFO);
|
||||||
ScrollInfo.fMask = SIF_POS;
|
ScrollInfo.fMask = SIF_POS;
|
||||||
if (NtUserGetScrollInfo(hWnd, nBar, &ScrollInfo))
|
if (! NtUserGetScrollInfo(hWnd, nBar, &ScrollInfo))
|
||||||
return ScrollInfo.nPos;
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ScrollInfo.nPos;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -397,7 +927,7 @@ GetScrollRange(HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos)
|
||||||
BOOL Result;
|
BOOL Result;
|
||||||
SCROLLINFO ScrollInfo;
|
SCROLLINFO ScrollInfo;
|
||||||
|
|
||||||
if (!lpMinPos || !lpMaxPos)
|
if (NULL == lpMinPos || NULL == lpMaxPos)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -467,6 +997,7 @@ SetScrollRange(HWND hWnd, INT nBar, INT nMinPos, INT nMaxPos, BOOL bRedraw)
|
||||||
ScrollInfo.nMin = nMinPos;
|
ScrollInfo.nMin = nMinPos;
|
||||||
ScrollInfo.nMax = nMaxPos;
|
ScrollInfo.nMax = nMaxPos;
|
||||||
NtUserSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw);
|
NtUserSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
reactos/lib/user32/include/scroll.h
Normal file
14
reactos/lib/user32/include/scroll.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/* $Id: scroll.h,v 1.1 2004/01/14 21:28:24 gvg Exp $
|
||||||
|
*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS user32.dll
|
||||||
|
* FILE: include/user32.h
|
||||||
|
* PURPOSE: Global user32 definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef USER32_SCROLL_H_INCLUDED
|
||||||
|
#define USER32_SCROLL_H_INCLUDED
|
||||||
|
|
||||||
|
extern VOID FASTCALL ScrollTrackScrollBar(HWND Wnd, INT SBType, POINT Pt);
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: defwnd.c,v 1.121 2004/01/12 20:38:59 gvg Exp $
|
/* $Id: defwnd.c,v 1.122 2004/01/14 21:28:24 gvg Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS user32.dll
|
* PROJECT: ReactOS user32.dll
|
||||||
|
@ -16,8 +16,9 @@
|
||||||
#include <window.h>
|
#include <window.h>
|
||||||
#include <user32/wininternal.h>
|
#include <user32/wininternal.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <menu.h>
|
|
||||||
#include <cursor.h>
|
#include <cursor.h>
|
||||||
|
#include <menu.h>
|
||||||
|
#include <scroll.h>
|
||||||
#include <winpos.h>
|
#include <winpos.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
@ -29,7 +30,6 @@ LRESULT DefWndNCActivate(HWND hWnd, WPARAM wParam);
|
||||||
LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
|
LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
|
||||||
LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
LRESULT DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||||
LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
LRESULT DefWndNCLButtonDblClk(HWND hWnd, WPARAM wParam, LPARAM lParam);
|
||||||
VOID DefWndTrackScrollBar(HWND hWnd, WPARAM wParam, POINT Point);
|
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
|
@ -748,6 +748,36 @@ DefWndDoSizeMove(HWND hwnd, WORD wParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* DefWndTrackScrollBar
|
||||||
|
*
|
||||||
|
* Track a mouse button press on the horizontal or vertical scroll-bar.
|
||||||
|
*/
|
||||||
|
STATIC VOID
|
||||||
|
DefWndTrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt)
|
||||||
|
{
|
||||||
|
INT ScrollBar;
|
||||||
|
|
||||||
|
if (SC_HSCROLL == (wParam & 0xfff0))
|
||||||
|
{
|
||||||
|
if (HTHSCROLL != (wParam & 0x0f))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ScrollBar = SB_HORZ;
|
||||||
|
}
|
||||||
|
else /* SC_VSCROLL */
|
||||||
|
{
|
||||||
|
if (HTVSCROLL != (wParam & 0x0f))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ScrollBar = SB_VERT;
|
||||||
|
}
|
||||||
|
ScrollTrackScrollBar(Wnd, ScrollBar, Pt );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
LRESULT
|
LRESULT
|
||||||
DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
|
DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
|
||||||
{
|
{
|
||||||
|
@ -792,6 +822,10 @@ DefWndHandleSysCommand(HWND hWnd, WPARAM wParam, POINT Pt)
|
||||||
case SC_KEYMENU:
|
case SC_KEYMENU:
|
||||||
MenuTrackKbdMenuBar(hWnd, wParam, Pt.x);
|
MenuTrackKbdMenuBar(hWnd, wParam, Pt.x);
|
||||||
break;
|
break;
|
||||||
|
case SC_VSCROLL:
|
||||||
|
case SC_HSCROLL:
|
||||||
|
DefWndTrackScrollBar(hWnd, wParam, Pt);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
/* FIXME: Implement */
|
/* FIXME: Implement */
|
||||||
|
@ -867,6 +901,7 @@ DefWndHandleWindowPosChanged(HWND hWnd, WINDOWPOS* Pos)
|
||||||
HBRUSH
|
HBRUSH
|
||||||
DefWndControlColor(HDC hDC, UINT ctlType)
|
DefWndControlColor(HDC hDC, UINT ctlType)
|
||||||
{
|
{
|
||||||
|
#if 0 /* FIXME: Re-enable when pattern brushes are implemented */
|
||||||
if (CTLCOLOR_SCROLLBAR == ctlType)
|
if (CTLCOLOR_SCROLLBAR == ctlType)
|
||||||
{
|
{
|
||||||
HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
|
HBRUSH hb = GetSysColorBrush(COLOR_SCROLLBAR);
|
||||||
|
@ -897,6 +932,7 @@ DefWndControlColor(HDC hDC, UINT ctlType)
|
||||||
UnrealizeObject(hb);
|
UnrealizeObject(hb);
|
||||||
return hb;
|
return hb;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
|
SetTextColor(hDC, GetSysColor(COLOR_WINDOWTEXT));
|
||||||
|
|
||||||
|
|
|
@ -715,7 +715,7 @@ DefWndNCHitTest(HWND hWnd, POINT Point)
|
||||||
TempRect2.left += GetSystemMetrics(SM_CXVSCROLL);
|
TempRect2.left += GetSystemMetrics(SM_CXVSCROLL);
|
||||||
else
|
else
|
||||||
TempRect2.right -= GetSystemMetrics(SM_CXVSCROLL);
|
TempRect2.right -= GetSystemMetrics(SM_CXVSCROLL);
|
||||||
if (PtInRect(&TempRect, Point))
|
if (PtInRect(&TempRect2, Point))
|
||||||
return HTHSCROLL;
|
return HTHSCROLL;
|
||||||
|
|
||||||
TempRect.top = TempRect2.top;
|
TempRect.top = TempRect2.top;
|
||||||
|
@ -755,19 +755,6 @@ DefWndNCHitTest(HWND hWnd, POINT Point)
|
||||||
return HTNOWHERE;
|
return HTNOWHERE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
DefWndDoScrollBarDown(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
POINT Point;
|
|
||||||
DWORD hit;
|
|
||||||
Point.x = GET_X_LPARAM(lParam);
|
|
||||||
Point.y = GET_Y_LPARAM(lParam);
|
|
||||||
|
|
||||||
hit = IntScrollHitTest(hWnd, (wParam == HTHSCROLL) ? SB_HORZ : SB_VERT, Point, FALSE);
|
|
||||||
|
|
||||||
SendMessageW(hWnd, WM_SYSCOMMAND, Msg + (UINT)wParam, lParam);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
DefWndDoButton(HWND hWnd, WPARAM wParam)
|
DefWndDoButton(HWND hWnd, WPARAM wParam)
|
||||||
{
|
{
|
||||||
|
@ -879,14 +866,12 @@ DefWndNCLButtonDown(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
case HTHSCROLL:
|
case HTHSCROLL:
|
||||||
{
|
{
|
||||||
DefWndDoScrollBarDown(hWnd, SC_HSCROLL, HTHSCROLL, lParam);
|
SendMessageW(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
|
||||||
//SendMessageW(hWnd, WM_SYSCOMMAND, SC_HSCROLL + HTHSCROLL, lParam);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HTVSCROLL:
|
case HTVSCROLL:
|
||||||
{
|
{
|
||||||
DefWndDoScrollBarDown(hWnd, SC_VSCROLL, HTVSCROLL, lParam);
|
SendMessageW(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
|
||||||
//SendMessageW(hWnd, WM_SYSCOMMAND, SC_VSCROLL + HTVSCROLL, lParam);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HTMINBUTTON:
|
case HTMINBUTTON:
|
||||||
|
|
Loading…
Reference in a new issue