📄 scrollbar.c
字号:
Info.nMin = 0;
Info.nMax = 100;
Info.nPage = 0;
Info.nPos = 0;
Info.nTrackPos = 0;
NtUserSetScrollInfo(Wnd, SB_CTL, &Info, FALSE);
DPRINT("hwnd=%p lpCreate=%p\n", Wnd, lpCreate);
#if 0 /* FIXME */
if (lpCreate->style & WS_DISABLED)
{
info->flags = ESB_DISABLE_BOTH;
TRACE("Created WS_DISABLED scrollbar\n");
}
#endif
if (0 != (lpCreate->style & (SBS_SIZEGRIP | SBS_SIZEBOX)))
{
if (0 != (lpCreate->style & SBS_SIZEBOXTOPLEFTALIGN))
{
MoveWindow(Wnd, lpCreate->x, lpCreate->y, GetSystemMetrics(SM_CXVSCROLL) + 1,
GetSystemMetrics(SM_CYHSCROLL) + 1, FALSE);
}
else if (0 != (lpCreate->style & SBS_SIZEBOXBOTTOMRIGHTALIGN))
{
MoveWindow(Wnd, lpCreate->x + lpCreate->cx - GetSystemMetrics(SM_CXVSCROLL) - 1,
lpCreate->y + lpCreate->cy - GetSystemMetrics(SM_CYHSCROLL) - 1,
GetSystemMetrics(SM_CXVSCROLL) + 1,
GetSystemMetrics(SM_CYHSCROLL) + 1, FALSE);
}
}
else if (0 != (lpCreate->style & SBS_VERT))
{
if (0 != (lpCreate->style & SBS_LEFTALIGN))
{
MoveWindow(Wnd, lpCreate->x, lpCreate->y,
GetSystemMetrics(SM_CXVSCROLL) + 1, lpCreate->cy, FALSE);
}
else if (0 != (lpCreate->style & SBS_RIGHTALIGN))
{
MoveWindow(Wnd,
lpCreate->x + lpCreate->cx - GetSystemMetrics(SM_CXVSCROLL) - 1,
lpCreate->y,
GetSystemMetrics(SM_CXVSCROLL) + 1, lpCreate->cy, FALSE);
}
}
else /* SBS_HORZ */
{
if (0 != (lpCreate->style & SBS_TOPALIGN))
{
MoveWindow(Wnd, lpCreate->x, lpCreate->y,
lpCreate->cx, GetSystemMetrics(SM_CYHSCROLL) + 1, FALSE);
}
else if (0 != (lpCreate->style & SBS_BOTTOMALIGN))
{
MoveWindow(Wnd,
lpCreate->x,
lpCreate->y + lpCreate->cy - GetSystemMetrics(SM_CYHSCROLL) - 1,
lpCreate->cx, GetSystemMetrics(SM_CYHSCROLL) + 1, FALSE);
}
}
}
static INT FASTCALL
IntScrollGetScrollPos(HWND Wnd, INT Bar)
{
SCROLLINFO ScrollInfo;
ScrollInfo.cbSize = sizeof(SCROLLINFO);
ScrollInfo.fMask = SIF_POS;
if (! NtUserGetScrollInfo(Wnd, Bar, &ScrollInfo))
{
return 0;
}
return ScrollInfo.nPos;
}
static BOOL FASTCALL
IntScrollGetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos)
{
BOOL Result;
SCROLLINFO ScrollInfo;
if (NULL == MinPos || NULL == MaxPos)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
ScrollInfo.cbSize = sizeof(SCROLLINFO);
ScrollInfo.fMask = SIF_RANGE;
Result = NtUserGetScrollInfo(Wnd, Bar, &ScrollInfo);
if (Result)
{
*MinPos = ScrollInfo.nMin;
*MaxPos = ScrollInfo.nMax;
}
return Result;
}
/* 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);
}
/***********************************************************************
* ScrollBarWndProc
*/
static LRESULT WINAPI
ScrollBarWndProc(HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
if (! IsWindow(Wnd))
{
return 0;
}
switch (Msg)
{
case WM_CREATE:
IntScrollCreateScrollBar(Wnd, (LPCREATESTRUCTW) lParam);
break;
//#if 0 /* FIXME */
case WM_ENABLE:
{
// SCROLLBAR_INFO *infoPtr;
// if ((infoPtr = SCROLL_GetScrollBarInfo( hwnd, SB_CTL )))
// {
// infoPtr->flags = wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH;
// SCROLL_RefreshScrollBar(hwnd, SB_CTL, TRUE, TRUE);
// }
HDC hdc;
DbgPrint("ScrollBarWndProc WM_ENABLE\n");
NtUserEnableScrollBar(Wnd,SB_CTL,(wParam ? ESB_ENABLE_BOTH : ESB_DISABLE_BOTH));
/* Refresh Scrollbars. */
hdc = GetDCEx( Wnd, 0, DCX_CACHE );
if (!hdc) return 1;
IntDrawScrollBar( Wnd, hdc, SB_CTL);
ReleaseDC( Wnd, hdc );
}
return 0;
//#endif
case WM_LBUTTONDBLCLK:
case WM_LBUTTONDOWN:
{
POINT Pt;
Pt.x = (short)LOWORD(lParam);
Pt.y = (short)HIWORD(lParam);
ScrollTrackScrollBar(Wnd, SB_CTL, Pt);
}
break;
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
case WM_SYSTIMER:
{
POINT Pt;
Pt.x = (short)LOWORD(lParam);
Pt.y = (short)HIWORD(lParam);
IntScrollHandleScrollEvent(Wnd, SB_CTL, Msg, Pt);
}
break;
case WM_KEYDOWN:
IntScrollHandleKbdEvent(Wnd, wParam, lParam);
break;
case WM_KEYUP:
ShowCaret(Wnd);
break;
case WM_SETFOCUS:
{
/* Create a caret when a ScrollBar get focus */
RECT Rect;
int ArrowSize, ThumbSize, ThumbPos, Vertical;
Vertical = IntScrollGetScrollBarRect(Wnd, SB_CTL, &Rect,
&ArrowSize, &ThumbSize, &ThumbPos);
if (! Vertical)
{
CreateCaret(Wnd, (HBITMAP) 1, ThumbSize - 2, Rect.bottom - Rect.top - 2);
SetCaretPos(ThumbPos + 1, Rect.top + 1);
}
else
{
CreateCaret(Wnd, (HBITMAP) 1, Rect.right - Rect.left - 2, ThumbSize - 2);
SetCaretPos(Rect.top + 1, ThumbPos + 1);
}
ShowCaret(Wnd);
}
break;
case WM_KILLFOCUS:
{
RECT Rect;
int ArrowSize, ThumbSize, ThumbPos, Vertical;
Vertical = IntScrollGetScrollBarRect(Wnd, SB_CTL, &Rect,
&ArrowSize, &ThumbSize, &ThumbPos);
if (! Vertical)
{
Rect.left = ThumbPos + 1;
Rect.right = Rect.left + ThumbSize;
}
else
{
Rect.top = ThumbPos + 1;
Rect.bottom = Rect.top + ThumbSize;
}
HideCaret(Wnd);
InvalidateRect(Wnd, &Rect, FALSE);
DestroyCaret();
}
break;
case WM_ERASEBKGND:
return 1;
case WM_GETDLGCODE:
return DLGC_WANTARROWS; /* Windows returns this value */
case WM_PAINT:
{
PAINTSTRUCT Ps;
HDC Dc;
Dc = (0 != wParam ? (HDC) wParam : BeginPaint(Wnd, &Ps));
if (GetWindowLongW(Wnd, GWL_STYLE) & SBS_SIZEGRIP)
{
IntScrollDrawSizeGrip(Wnd, Dc);
}
else if (0 != (GetWindowLongW(Wnd, GWL_STYLE) & SBS_SIZEBOX))
{
RECT Rect;
GetClientRect(Wnd, &Rect);
FillRect(Dc, &Rect, GetSysColorBrush(COLOR_SCROLLBAR));
}
else
{
IntDrawScrollBar(Wnd, Dc, SB_CTL/*, TRUE, TRUE*/);
}
if (0 == wParam)
{
EndPaint(Wnd, &Ps);
}
}
break;
case SBM_SETPOS:
return SetScrollPos(Wnd, SB_CTL, wParam, (BOOL) lParam);
case SBM_GETPOS:
return IntScrollGetScrollPos(Wnd, SB_CTL);
case SBM_SETRANGE:
{
INT OldPos = IntScrollGetScrollPos(Wnd, SB_CTL);
SetScrollRange(Wnd, SB_CTL, wParam, lParam, FALSE);
if (OldPos != IntScrollGetScrollPos(Wnd, SB_CTL))
{
return OldPos;
}
}
return 0;
case SBM_GETRANGE:
return IntScrollGetScrollRange(Wnd, SB_CTL, (LPINT) wParam, (LPINT) lParam);
case SBM_ENABLE_ARROWS:
return EnableScrollBar(Wnd, SB_CTL, wParam);
case SBM_SETRANGEREDRAW:
{
INT OldPos = IntScrollGetScrollPos(Wnd, SB_CTL);
SetScrollRange(Wnd, SB_CTL, wParam, lParam, TRUE);
if (OldPos != IntScrollGetScrollPos(Wnd, SB_CTL))
{
return OldPos;
}
}
return 0;
case SBM_SETSCROLLINFO:
return NtUserSetScrollInfo(Wnd, SB_CTL, (SCROLLINFO *) lParam, wParam);
case SBM_GETSCROLLINFO:
return NtUserGetScrollInfo(Wnd, SB_CTL, (SCROLLINFO *) lParam);
case 0x00e5:
case 0x00e7:
case 0x00e8:
case 0x00eb:
case 0x00ec:
case 0x00ed:
case 0x00ee:
case 0x00ef:
DPRINT("unknown Win32 msg %04x wp=%08x lp=%08lx\n",
Msg, wParam, lParam );
break;
default:
if (WM_USER <= Msg)
{
DPRINT("unknown msg %04x wp=%04x lp=%08lx\n", Msg, wParam, lParam);
}
return DefWindowProcW(Wnd, Msg, wParam, lParam );
}
return 0;
}
/* PUBLIC FUNCTIONS ***********************************************************/
/*
* @implemented
*/
BOOL STDCALL
EnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows)
{
return NtUserEnableScrollBar(hWnd, wSBflags, wArrows);
}
/*
* @implemented
*/
BOOL STDCALL
GetScrollBarInfo(HWND hWnd, LONG idObject, PSCROLLBARINFO psbi)
{
return NtUserGetScrollBarInfo(hWnd, idObject, psbi);
}
/*
* @implemented
*/
BOOL STDCALL
GetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO Info)
{
if (SB_CTL == SBType)
{
return SendMessageW(Wnd, SBM_GETSCROLLINFO, 0, (LPARAM) Info);
}
else
{
return NtUserGetScrollInfo(Wnd, SBType, Info);
}
}
/*
* @implemented
*/
INT STDCALL
GetScrollPos(HWND Wnd, INT Bar)
{
DPRINT("Wnd=%p Bar=%d\n", Wnd, Bar);
/* Refer SB_CTL requests to the window */
if (SB_CTL == Bar)
{
return SendMessageW(Wnd, SBM_GETPOS, (WPARAM) 0, (LPARAM) 0);
}
else
{
return IntScrollGetScrollPos(Wnd, Bar);
}
}
/*
* @implemented
*/
BOOL STDCALL
GetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos)
{
DPRINT("Wnd=%x Bar=%d Min=%p Max=%p\n", Wnd, Bar, MinPos, MaxPos);
/* Refer SB_CTL requests to the window */
if (SB_CTL == Bar)
{
return SendMessageW(Wnd, SBM_GETRANGE, (WPARAM) MinPos, (LPARAM) MaxPos);
}
else
{
return IntScrollGetScrollRange(Wnd, Bar, MinPos, MaxPos);
}
}
/*
* @implemented
*/
INT STDCALL
SetScrollInfo(HWND Wnd, int SBType, LPCSCROLLINFO Info, BOOL bRedraw)
{
if (SB_CTL == SBType)
{
return SendMessageW(Wnd, SBM_SETSCROLLINFO, (WPARAM) bRedraw, (LPARAM) Info);
}
else
{
return NtUserSetScrollInfo(Wnd, SBType, Info, bRedraw);
}
}
/*
* @implemented
*/
INT STDCALL
SetScrollPos(HWND hWnd, INT nBar, INT nPos, BOOL bRedraw)
{
INT Result = 0;
SCROLLINFO ScrollInfo;
ScrollInfo.cbSize = sizeof(SCROLLINFO);
ScrollInfo.fMask = SIF_POS;
/*
* Call NtUserGetScrollInfo() to get the previous position that
* we will later return.
*/
if (NtUserGetScrollInfo(hWnd, nBar, &ScrollInfo))
{
Result = ScrollInfo.nPos;
if (Result != nPos)
{
ScrollInfo.nPos = nPos;
/* Finally set the new position */
NtUserSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw);
}
}
return Result;
}
/*
* @implemented
*/
BOOL STDCALL
SetScrollRange(HWND hWnd, INT nBar, INT nMinPos, INT nMaxPos, BOOL bRedraw)
{
SCROLLINFO ScrollInfo;
ScrollInfo.cbSize = sizeof(SCROLLINFO);
ScrollInfo.fMask = SIF_RANGE;
ScrollInfo.nMin = nMinPos;
ScrollInfo.nMax = nMaxPos;
NtUserSetScrollInfo(hWnd, nBar, &ScrollInfo, bRedraw);
return TRUE;
}
/*
* @implemented
*/
BOOL STDCALL
ShowScrollBar(HWND hWnd, INT wBar, BOOL bShow)
{
return NtUserShowScrollBar(hWnd, wBar, bShow);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -