diff --git a/reactos/lib/user32/controls/regcontrol.c b/reactos/lib/user32/controls/regcontrol.c index 05f5ee1dac7..82c1ad12c80 100644 --- a/reactos/lib/user32/controls/regcontrol.c +++ b/reactos/lib/user32/controls/regcontrol.c @@ -1,4 +1,4 @@ -/* $Id: regcontrol.c,v 1.17 2003/12/07 23:02:57 gvg Exp $ +/* $Id: regcontrol.c,v 1.18 2004/03/27 10:46:32 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS User32 @@ -65,8 +65,8 @@ ControlsInit(LPCWSTR ClassName) &MDICLIENT_builtin_class, #if 0 &MENU_builtin_class, - &SCROLL_builtin_class, #endif + &SCROLL_builtin_class, &BUTTON_builtin_class, &LISTBOX_builtin_class, &EDIT_builtin_class, diff --git a/reactos/lib/user32/controls/scrollbar.c b/reactos/lib/user32/controls/scrollbar.c index 2e06abc573c..78232f2d247 100644 --- a/reactos/lib/user32/controls/scrollbar.c +++ b/reactos/lib/user32/controls/scrollbar.c @@ -36,6 +36,7 @@ #include #include #include +#include #include /* GLOBAL VARIABLES ***********************************************************/ @@ -54,6 +55,12 @@ #define SCROLL_TIMER 0 /* Scroll timer id */ + /* Minimum size of the rectangle between the arrows */ +#define SCROLL_MIN_RECT 4 + + /* Minimum size of the thumb in pixels */ +#define SCROLL_MIN_THUMB 6 + /* Thumb-tracking info */ static HWND ScrollTrackingWin = 0; static INT ScrollTrackingBar = 0; @@ -66,6 +73,24 @@ static BOOL ScrollTrackVertical; HBRUSH DefWndControlColor(HDC hDC, UINT ctlType); +static LRESULT WINAPI ScrollBarWndProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + +/********************************************************************* + * scrollbar class descriptor + */ +const struct builtin_class_descr SCROLL_builtin_class = +{ + L"ScrollBar", /* name */ + CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, /* style, Wine included CS_DBLCLK but then didn't + handle any WM_xBUTTONDBLCLK messages */ + ScrollBarWndProc, /* procW */ + NULL, /* procA (winproc is Unicode only) */ + sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO), /* extra */ + IDC_ARROW, /* cursor */ + 0 /* brush */ +}; + /* PRIVATE FUNCTIONS **********************************************************/ @@ -269,67 +294,92 @@ IntScrollDrawMovingThumb(HDC Dc, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical) ScrollMovingThumb = ! ScrollMovingThumb; } -void -IntDrawScrollBar(HWND hWnd, HDC hDC, INT nBar) +STATIC LONG FASTCALL +IntScrollGetObjectId(INT SBType) { - INT ThumbSize; - SCROLLBARINFO Info; - BOOL Vertical; + if (SB_VERT == SBType) + { + return OBJID_VSCROLL; + } + if (SB_HORZ == SBType) + { + return OBJID_HSCROLL; + } - /* - * Get scroll bar info. - */ + return OBJID_CLIENT; +} - Info.cbSize = sizeof(SCROLLBARINFO); - switch (nBar) - { +STATIC BOOL FASTCALL +IntGetScrollBarInfo(HWND Wnd, INT Bar, PSCROLLBARINFO ScrollBarInfo) +{ + ScrollBarInfo->cbSize = sizeof(SCROLLBARINFO); + + return NtUserGetScrollBarInfo(Wnd, IntScrollGetObjectId(Bar), ScrollBarInfo); +} + +void +IntDrawScrollBar(HWND Wnd, HDC DC, INT Bar) +{ + INT ThumbSize; + SCROLLBARINFO Info; + BOOL Vertical; + + /* + * Get scroll bar info. + */ + switch (Bar) + { case SB_HORZ: - Vertical = FALSE; - NtUserGetScrollBarInfo(hWnd, OBJID_HSCROLL, &Info); - break; + Vertical = FALSE; + break; case SB_VERT: - Vertical = TRUE; - NtUserGetScrollBarInfo(hWnd, OBJID_VSCROLL, &Info); - break; + Vertical = TRUE; + break; case SB_CTL: - Vertical = (GetWindowLongW(hWnd, GWL_STYLE) & SBS_VERT) != 0; - NtUserGetScrollBarInfo(hWnd, OBJID_CLIENT, &Info); - break; - } - - if (IsRectEmpty(&Info.rcScrollBar)) - { + Vertical = (GetWindowLongW(Wnd, GWL_STYLE) & SBS_VERT) != 0; + break; + } + if (! IntGetScrollBarInfo(Wnd, Bar, &Info)) + { return; - } + } + + if (IsRectEmpty(&Info.rcScrollBar)) + { + return; + } - ThumbSize = Info.xyThumbBottom - Info.xyThumbTop; + ThumbSize = Info.xyThumbBottom - Info.xyThumbTop; - /* - * Draw the arrows. - */ + /* + * Draw the arrows. + */ + if (Info.dxyLineButton) + { + IntDrawScrollArrows(DC, &Info, Vertical); + } - if (Info.dxyLineButton) - IntDrawScrollArrows(hDC, &Info, Vertical); + /* + * Draw the interior. + */ + IntDrawScrollInterior(Wnd, DC, Bar, Vertical, &Info); - /* - * Draw the interior. - */ - - IntDrawScrollInterior(hWnd, hDC, nBar, Vertical, &Info); - - /* - * If scroll bar has focus, reposition the caret. - */ - - if (hWnd == GetFocus() && nBar == SB_CTL) - { - if (nBar == SB_HORZ) - SetCaretPos(Info.dxyLineButton + 1, Info.rcScrollBar.top + 1); - else if (nBar == SB_VERT) - SetCaretPos(Info.rcScrollBar.top + 1, Info.dxyLineButton + 1); - } + /* + * If scroll bar has focus, reposition the caret. + */ + if (Wnd == GetFocus() && SB_CTL == Bar) + { + if (Vertical) + { + SetCaretPos(Info.rcScrollBar.top + 1, Info.dxyLineButton + 1); + } + else + { + SetCaretPos(Info.dxyLineButton + 1, Info.rcScrollBar.top + 1); + } + } } STATIC BOOL FASTCALL @@ -350,29 +400,6 @@ IntScrollPtInRectEx(LPRECT Rect, POINT Pt, BOOL Vertical) return PtInRect(&TempRect, Pt); } -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) { @@ -440,6 +467,162 @@ IntScrollHitTest(PSCROLLBARINFO ScrollBarInfo, BOOL Vertical, POINT Pt, BOOL Dra return SCROLL_THUMB; } + +/*********************************************************************** + * IntScrollGetScrollBarRect + * + * Compute the scroll bar rectangle, in drawing coordinates (i.e. client + * coords for SB_CTL, window coords for SB_VERT and SB_HORZ). + * 'arrowSize' returns the width or height of an arrow (depending on + * the orientation of the scrollbar), 'thumbSize' returns the size of + * the thumb, and 'thumbPos' returns the position of the thumb + * relative to the left or to the top. + * Return TRUE if the scrollbar is vertical, FALSE if horizontal. + */ +STATIC BOOL FASTCALL +IntScrollGetScrollBarRect(HWND Wnd, INT Bar, RECT *Rect, + INT *ArrowSize, INT *ThumbSize, + INT *ThumbPos) +{ + INT Pixels; + BOOL Vertical; + RECT ClientRect; + RECT WindowRect; + DWORD Style, ExStyle; + + GetClientRect(Wnd, &ClientRect); + if (SB_HORZ == Bar || SB_VERT == Bar) + { + ClientToScreen(Wnd, (LPPOINT) &ClientRect.left); + ClientToScreen(Wnd, (LPPOINT) &ClientRect.right); + GetWindowRect(Wnd, &WindowRect); + } + Style = GetWindowLongW(Wnd, GWL_STYLE); + + switch (Bar) + { + case SB_HORZ: + Rect->left = ClientRect.left - WindowRect.left; + Rect->top = ClientRect.bottom - WindowRect.top; + Rect->right = ClientRect.right - WindowRect.left; + Rect->bottom = Rect->top + GetSystemMetrics(SM_CYHSCROLL); + if (0 != (Style & WS_BORDER)) + { + Rect->left--; + Rect->right++; + } + else if (0 != (Style & WS_VSCROLL)) + { + Rect->right++; + } + Vertical = FALSE; + break; + + case SB_VERT: + ExStyle = GetWindowLongW(Wnd, GWL_EXSTYLE); + if (0 != (ExStyle & WS_EX_LEFTSCROLLBAR)) + { + Rect->left = ClientRect.left - WindowRect.left - GetSystemMetrics(SM_CXVSCROLL); + } + else + { + Rect->left = ClientRect.right - WindowRect.left; + } + Rect->top = ClientRect.top - WindowRect.top; + Rect->right = Rect->left + GetSystemMetrics(SM_CXVSCROLL); + Rect->bottom = ClientRect.bottom - WindowRect.top; + if (0 != (Style & WS_BORDER)) + { + Rect->top--; + Rect->bottom++; + } + else if (0 != (Style & WS_HSCROLL)) + { + Rect->bottom++; + } + Vertical = TRUE; + break; + + case SB_CTL: + *Rect = ClientRect; + Vertical = (0 != (Style & SBS_VERT)); + break; + + default: + return FALSE; + } + + if (Vertical) + { + Pixels = Rect->bottom - Rect->top; + } + else + { + Pixels = Rect->right - Rect->left; + } + + if (Pixels <= 2 * GetSystemMetrics(SM_CXVSCROLL) + SCROLL_MIN_RECT) + { + if (SCROLL_MIN_RECT < Pixels) + { + *ArrowSize = (Pixels - SCROLL_MIN_RECT) / 2; + } + else + { + *ArrowSize = 0; + } + *ThumbPos = *ThumbSize = 0; + } + else + { + SCROLLINFO Info; + + NtUserGetScrollInfo(Wnd, Bar, &Info); + *ArrowSize = GetSystemMetrics(SM_CXVSCROLL); + Pixels -= (2 * GetSystemMetrics(SM_CXVSCROLL)); + + if (0 != Info.nPage) + { + *ThumbSize = MulDiv(Pixels, Info.nPage, (Info.nMax - Info.nMin + 1)); + if (*ThumbSize < SCROLL_MIN_THUMB) + { + *ThumbSize = SCROLL_MIN_THUMB; + } + } + else + { + *ThumbSize = GetSystemMetrics(SM_CXVSCROLL); + } + +#if 0 /* FIXME */ + if (((pixels -= *ThumbSize ) < 0) || + ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH)) +#else + if ((Pixels -= *ThumbSize ) < 0) +#endif + { + /* Rectangle too small or scrollbar disabled -> no thumb */ + *ThumbPos = *ThumbSize = 0; + } + else + { + INT Max = Info.nMax - max(Info.nPage - 1, 0); + if (Max <= Info.nMin) + { + *ThumbPos = *ArrowSize; + } + else + { + *ThumbPos = *ArrowSize + + MulDiv(Pixels, (Info.nPos - Info.nMin), + (Max - Info.nMin)); + } + } + } + + return Vertical; +} + /*********************************************************************** * IntScrollGetThumbVal * @@ -512,6 +695,79 @@ STATIC POINT IntScrollClipPos(PRECT Rect, POINT Pt) return Pt; } +/*********************************************************************** + * IntScrollDrawSizeGrip + * + * Draw the size grip. + */ +STATIC void FASTCALL +IntScrollDrawSizeGrip(HWND Wnd, HDC Dc) +{ + RECT Rect; + + GetClientRect(Wnd, &Rect); + FillRect(Dc, &Rect, GetSysColorBrush(COLOR_SCROLLBAR)); + Rect.left = max(Rect.left, Rect.right - GetSystemMetrics(SM_CXVSCROLL) - 1); + Rect.top = max(Rect.top, Rect.bottom - GetSystemMetrics(SM_CYHSCROLL) - 1); + DrawFrameControl(Dc, &Rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); +} + + + +/*********************************************************************** + * IntScrollHandleKbdEvent + * + * Handle a keyboard event (only for SB_CTL scrollbars with focus). + */ +STATIC void FASTCALL +IntScrollHandleKbdEvent( + HWND Wnd /* [in] Handle of window with scrollbar(s) */, + WPARAM wParam /* [in] Variable input including enable state */, + LPARAM lParam /* [in] Variable input including input point */) +{ + DPRINT("Wnd=%p wParam=%d lParam=%ld\n", Wnd, wParam, lParam); + + /* hide caret on first KEYDOWN to prevent flicker */ + if (0 == (lParam & PFD_DOUBLEBUFFER_DONTCARE)) + { + HideCaret(Wnd); + } + + switch(wParam) + { + case VK_PRIOR: + wParam = SB_PAGEUP; + break; + + case VK_NEXT: + wParam = SB_PAGEDOWN; + break; + + case VK_HOME: + wParam = SB_TOP; + break; + + case VK_END: + wParam = SB_BOTTOM; + break; + + case VK_UP: + wParam = SB_LINEUP; + break; + + case VK_DOWN: + wParam = SB_LINEDOWN; + break; + + default: + return; + } + + SendMessageW(GetParent(Wnd), + (0 != (GetWindowLongW(Wnd, GWL_STYLE ) & SBS_VERT) ? + WM_VSCROLL : WM_HSCROLL), wParam, (LPARAM) Wnd); +} + /*********************************************************************** * IntScrollHandleScrollEvent * @@ -799,6 +1055,122 @@ IntScrollHandleScrollEvent(HWND Wnd, INT SBType, UINT Msg, POINT Pt) } +/*********************************************************************** + * IntScrollCreateScrollBar + * + * Create a scroll bar + */ +static void IntScrollCreateScrollBar( + HWND Wnd /* [in] Handle of window with scrollbar(s) */, + LPCREATESTRUCTW lpCreate /* [in] The style and place of the scroll bar */) +{ + SCROLLINFO Info; + + Info.cbSize = sizeof(SCROLLINFO); + Info.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + 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 **************************************************/ /*********************************************************************** @@ -871,6 +1243,211 @@ ScrollTrackScrollBar(HWND Wnd, INT SBType, POINT Pt) 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); + } + } + return 0; +#endif + + 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 SetScrollInfo(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 ***********************************************************/ /* @@ -904,45 +1481,38 @@ GetScrollInfo(HWND Wnd, INT SBType, LPSCROLLINFO lpsi) * @implemented */ INT STDCALL -GetScrollPos(HWND hWnd, INT nBar) +GetScrollPos(HWND Wnd, INT Bar) { - SCROLLINFO ScrollInfo; - - ScrollInfo.cbSize = sizeof(SCROLLINFO); - ScrollInfo.fMask = SIF_POS; - if (! NtUserGetScrollInfo(hWnd, nBar, &ScrollInfo)) - { - return 0; - } + DPRINT("Wnd=%p Bar=%d\n", Wnd, Bar); - return ScrollInfo.nPos; + /* 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 hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos) +GetScrollRange(HWND Wnd, int Bar, LPINT MinPos, LPINT MaxPos) { - BOOL Result; - SCROLLINFO ScrollInfo; - - if (NULL == lpMinPos || NULL == lpMaxPos) + 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) { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + return SendMessageW(Wnd, SBM_GETRANGE, (WPARAM) MinPos, (LPARAM) MaxPos); } - - ScrollInfo.cbSize = sizeof(SCROLLINFO); - ScrollInfo.fMask = SIF_RANGE; - Result = NtUserGetScrollInfo(hWnd, nBar, &ScrollInfo); - if (Result) + else { - *lpMinPos = ScrollInfo.nMin; - *lpMaxPos = ScrollInfo.nMax; + return IntScrollGetScrollRange(Wnd, Bar, MinPos, MaxPos); } - - return Result; } /* diff --git a/reactos/subsys/win32k/ntuser/scrollbar.c b/reactos/subsys/win32k/ntuser/scrollbar.c index e3f97e8b0de..91f5b5d26a1 100644 --- a/reactos/subsys/win32k/ntuser/scrollbar.c +++ b/reactos/subsys/win32k/ntuser/scrollbar.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: scrollbar.c,v 1.27 2004/02/19 21:12:09 weiden Exp $ +/* $Id: scrollbar.c,v 1.28 2004/03/27 10:46:31 gvg Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -177,247 +177,244 @@ IntCalculateThumb(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi, LPS return TRUE; } -BOOL FASTCALL +static BOOL FASTCALL IntGetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPSCROLLINFO lpsi) { UINT Mask; LPSCROLLINFO psi; PSCROLLBARINFO Info; - switch(nBar) - { - case SB_HORZ: - Info = Window->pHScroll; - if(Info) + switch (nBar) + { + case SB_HORZ: + Info = Window->pHScroll; break; - /* fall through */ - case SB_VERT: - Info = Window->pVScroll; - if(Info) + case SB_VERT: + Info = Window->pVScroll; break; - /* fall through */ - case SB_CTL: - /* FIXME - Send a SBM_GETSCROLLINFO message to the window. Fail if the window - doesn't handle the message - */ - return 0; - - Info = Window->wExtra; - if(Info) + case SB_CTL: + if (Window->ExtraDataSize < sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO)) + { + Info = NULL; + } + else + { + Info = (PSCROLLBARINFO) Window->ExtraData; + } break; - /* fall through */ - default: + default: + DPRINT1("Trying to get scrollinfo for unknown scrollbar type %d", nBar); + return FALSE; + } + + if (NULL == Info) + { + DPRINT1("No scrollinfo available\n"); return FALSE; - } + } - psi = (LPSCROLLINFO)((PSCROLLBARINFO)(Info + 1)); + psi = (LPSCROLLINFO)(Info + 1); - if(lpsi->fMask == SIF_ALL) - Mask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS; + if (lpsi->fMask == SIF_ALL) + { + Mask = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS; + } else - Mask = lpsi->fMask; + { + Mask = lpsi->fMask; + } - if(Mask & SIF_PAGE) - { - lpsi->nPage = psi->nPage; - } + if (0 != (Mask & SIF_PAGE)) + { + lpsi->nPage = psi->nPage; + } - if(Mask & SIF_POS) - { - lpsi->nPos = psi->nPos; - } + if (0 != (Mask & SIF_POS)) + { + lpsi->nPos = psi->nPos; + } - if(Mask & SIF_RANGE) - { - lpsi->nMin = psi->nMin; - lpsi->nMax = psi->nMax; - } + if (0 != (Mask & SIF_RANGE)) + { + lpsi->nMin = psi->nMin; + lpsi->nMax = psi->nMax; + } - if(Mask & SIF_TRACKPOS) - { - lpsi->nTrackPos = psi->nTrackPos; - } + if (0 != (Mask & SIF_TRACKPOS)) + { + lpsi->nTrackPos = psi->nTrackPos; + } return TRUE; } -DWORD FASTCALL +static DWORD FASTCALL IntSetScrollInfo(PWINDOW_OBJECT Window, INT nBar, LPCSCROLLINFO lpsi, BOOL bRedraw) { - /* - * Update the scrollbar state and set action flags according to - * what has to be done graphics wise. - */ + /* + * Update the scrollbar state and set action flags according to + * what has to be done graphics wise. + */ - LPSCROLLINFO Info; - PSCROLLBARINFO psbi; + LPSCROLLINFO Info; + PSCROLLBARINFO psbi; /* UINT new_flags;*/ - BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */ + BOOL bChangeParams = FALSE; /* don't show/hide scrollbar if params don't change */ - if (lpsi->cbSize != sizeof(SCROLLINFO) && - lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos))) - { + if (lpsi->cbSize != sizeof(SCROLLINFO) && + lpsi->cbSize != (sizeof(SCROLLINFO) - sizeof(lpsi->nTrackPos))) + { SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; - } - if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) - { + } + if (lpsi->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) + { SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; - } - switch(nBar) - { + } + switch (nBar) + { case SB_HORZ: - if (Window->pHScroll == NULL) - { + if (NULL == Window->pHScroll) + { SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; - } - psbi = Window->pHScroll; - Info = (LPSCROLLINFO)(Window->pHScroll + 1); - break; + } + psbi = Window->pHScroll; + break; case SB_VERT: - if (Window->pVScroll == NULL) - { + if (NULL == Window->pVScroll) + { SetLastWin32Error(ERROR_INVALID_PARAMETER); return 0; - } - psbi = Window->pVScroll; - Info = (LPSCROLLINFO)(Window->pVScroll + 1); - break; + } + psbi = Window->pVScroll; + break; case SB_CTL: - UNIMPLEMENTED; - break; + if (Window->ExtraDataSize < sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO)) + { + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return 0; + } + psbi = (PSCROLLBARINFO) Window->ExtraData; + break; default: - SetLastWin32Error(ERROR_INVALID_PARAMETER); - return 0; - } + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return 0; + } - /* Set the page size */ - if (lpsi->fMask & SIF_PAGE) - { + Info = (LPSCROLLINFO)(psbi + 1); + + /* Set the page size */ + if (0 != (lpsi->fMask & SIF_PAGE)) + { if (Info->nPage != lpsi->nPage) - { - Info->nPage = lpsi->nPage; -#if 0 - *Action |= SA_SSI_REFRESH; -#endif - bChangeParams = TRUE; - } - } + { + Info->nPage = lpsi->nPage; + bChangeParams = TRUE; + } + } - /* Set the scroll pos */ - if (lpsi->fMask & SIF_POS) - { + /* Set the scroll pos */ + if (0 != (lpsi->fMask & SIF_POS)) + { if (Info->nPos != lpsi->nPos) - { - Info->nPos = lpsi->nPos; -#if 0 - *Action |= SA_SSI_REFRESH; -#endif - } - } + { + Info->nPos = lpsi->nPos; + } + } - /* Set the scroll range */ - if (lpsi->fMask & SIF_RANGE) - { + /* Set the scroll range */ + if (0 != (lpsi->fMask & SIF_RANGE)) + { /* Invalid range -> range is set to (0,0) */ if (lpsi->nMin > lpsi->nMax || - (UINT)(lpsi->nMax - lpsi->nMin) >= 0x80000000) - { - Info->nMin = 0; - Info->nMax = 0; - bChangeParams = TRUE; - } - else - { - if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax) - { -#if 0 - *Action |= SA_SSI_REFRESH; -#endif - Info->nMin = lpsi->nMin; - Info->nMax = lpsi->nMax; - bChangeParams = TRUE; - } - } - } + 0x80000000 <= (UINT)(lpsi->nMax - lpsi->nMin)) + { + Info->nMin = 0; + Info->nMax = 0; + bChangeParams = TRUE; + } + else if (Info->nMin != lpsi->nMin || Info->nMax != lpsi->nMax) + { + Info->nMin = lpsi->nMin; + Info->nMax = lpsi->nMax; + bChangeParams = TRUE; + } + } - /* Make sure the page size is valid */ - if (Info->nPage < 0) - { + /* Make sure the page size is valid */ + if (Info->nPage < 0) + { Info->nPage = 0; - } - else if (Info->nPage > Info->nMax - Info->nMin + 1) - { + } + else if (Info->nMax - Info->nMin + 1 < Info->nPage) + { Info->nPage = Info->nMax - Info->nMin + 1; - } + } - /* Make sure the pos is inside the range */ - if (Info->nPos < Info->nMin) - { + /* Make sure the pos is inside the range */ + if (Info->nPos < Info->nMin) + { Info->nPos = Info->nMin; - } - else if (Info->nPos > Info->nMax - max(Info->nPage - 1, 0)) - { + } + else if (Info->nPos > Info->nMax - max(Info->nPage - 1, 0)) + { Info->nPos = Info->nMax - max(Info->nPage - 1, 0); - } + } - /* - * Don't change the scrollbar state if SetScrollInfo is just called - * with SIF_DISABLENOSCROLL - */ - if (!(lpsi->fMask & SIF_ALL)) - { + /* + * Don't change the scrollbar state if SetScrollInfo is just called + * with SIF_DISABLENOSCROLL + */ + if (0 == (lpsi->fMask & SIF_ALL)) + { return Info->nPos; - } + } - /* Check if the scrollbar should be hidden or disabled */ - if (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL)) - { -/* new_flags = Info->flags;*/ + /* Check if the scrollbar should be hidden or disabled */ + if (0 != (lpsi->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))) + { if (Info->nMin >= Info->nMax - max(Info->nPage - 1, 0)) - { - /* Hide or disable scroll-bar */ - if (lpsi->fMask & SIF_DISABLENOSCROLL) - { + { + /* Hide or disable scroll-bar */ + if (0 != (lpsi->fMask & SIF_DISABLENOSCROLL)) + { /* new_flags = ESB_DISABLE_BOTH;*/ -#if 0 - *Action |= SA_SSI_REFRESH; -#endif - } - else if ((nBar != SB_CTL) && bChangeParams) - { - NtUserShowScrollBar(Window->Self, nBar, FALSE); - return Info->nPos; - } - } + } + else if ((nBar != SB_CTL) && bChangeParams) + { + NtUserShowScrollBar(Window->Self, nBar, FALSE); + return Info->nPos; + } + } else /* Show and enable scroll-bar */ - { + { /* new_flags = 0;*/ - if ((nBar != SB_CTL) && bChangeParams) - NtUserShowScrollBar(Window->Self, nBar, TRUE); - } + if ((nBar != SB_CTL) && bChangeParams) + { + NtUserShowScrollBar(Window->Self, nBar, TRUE); + } + } #if 0 if (infoPtr->flags != new_flags) /* check arrow flags */ - { - infoPtr->flags = new_flags; - *Action |= SA_SSI_REPAINT_ARROWS; - } + { + infoPtr->flags = new_flags; + *Action |= SA_SSI_REPAINT_ARROWS; + } #endif - } + } - if (bRedraw) - { + if (bRedraw) + { RECT UpdateRect = psbi->rcScrollBar; UpdateRect.left -= Window->ClientRect.left - Window->WindowRect.left; UpdateRect.right -= Window->ClientRect.left - Window->WindowRect.left; UpdateRect.top -= Window->ClientRect.top - Window->WindowRect.top; UpdateRect.bottom -= Window->ClientRect.top - Window->WindowRect.top; IntRedrawWindow(Window, &UpdateRect, 0, RDW_INVALIDATE | RDW_FRAME); - } + } /* Return current position */ return Info->nPos; @@ -431,44 +428,38 @@ IntGetScrollBarInfo(PWINDOW_OBJECT Window, LONG idObject, PSCROLLBARINFO psbi) LPSCROLLINFO psi; switch(idObject) - { - case OBJID_HSCROLL: - if(Window->pHScroll) - { + { + case OBJID_HSCROLL: Bar = SB_HORZ; sbi = Window->pHScroll; break; - } - /* fall through */ - case OBJID_VSCROLL: - if(Window->pVScroll) - { + case OBJID_VSCROLL: Bar = SB_VERT; sbi = Window->pVScroll; break; - } - /* fall through */ - case OBJID_CLIENT: - - /* FIXME - Send a SBM_GETSCROLLBARINFO message if Window is not a system scrollbar. - If the window doesn't handle the message return FALSE. - */ - return FALSE; - - if(Window->wExtra) - { + case OBJID_CLIENT: Bar = SB_CTL; - sbi = Window->wExtra; + if (Window->ExtraDataSize < sizeof(SCROLLBARINFO) + sizeof(SCROLLINFO)) + { + sbi = NULL; + } + else + { + sbi = (PSCROLLBARINFO) Window->ExtraData; + } break; - } - /* fall through */ - default: + default: + SetLastWin32Error(ERROR_INVALID_PARAMETER); + return FALSE; + } + + if (NULL == sbi) + { SetLastWin32Error(ERROR_INVALID_PARAMETER); return FALSE; - } + } - psi = (LPSCROLLINFO)((PSCROLLBARINFO)(sbi + 1)); + psi = (LPSCROLLINFO)(sbi + 1); IntGetScrollBarRect(Window, Bar, &(sbi->rcScrollBar)); IntCalculateThumb(Window, Bar, sbi, psi);