/* 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. */ BOOL FASTCALL IntGetScrollBarRect (PWND Wnd, INT nBar, RECTL *lprect) { BOOL vertical; RECTL ClientRect = Wnd->rcClient; RECTL WindowRect = Wnd->rcWindow; switch (nBar) { case SB_HORZ: lprect->left = ClientRect.left - WindowRect.left; lprect->top = ClientRect.bottom - WindowRect.top; lprect->right = ClientRect.right - WindowRect.left; lprect->bottom = lprect->top + UserGetSystemMetrics (SM_CYHSCROLL); vertical = FALSE; break; case SB_VERT: if(Wnd->ExStyle & WS_EX_LEFTSCROLLBAR) { lprect->right = ClientRect.left - WindowRect.left; lprect->left = lprect->right - UserGetSystemMetrics(SM_CXVSCROLL); } else { lprect->left = ClientRect.right - WindowRect.left; lprect->right = lprect->left + UserGetSystemMetrics(SM_CXVSCROLL); } lprect->top = ClientRect.top - WindowRect.top; lprect->bottom = ClientRect.bottom - WindowRect.top; vertical = TRUE; break; case SB_CTL: IntGetClientRect (Wnd, lprect); vertical = ((Wnd->style & SBS_VERT) != 0); break; default: return FALSE; } return vertical; }
BOOL FASTCALL IntCalculateThumb(PWND Wnd, LONG idObject, PSCROLLBARINFO psbi, PSBDATA pSBData) { INT Thumb, ThumbBox, ThumbPos, cxy, mx; RECTL ClientRect; switch(idObject) { case SB_HORZ: Thumb = UserGetSystemMetrics(SM_CXHSCROLL); cxy = psbi->rcScrollBar.right - psbi->rcScrollBar.left; break; case SB_VERT: Thumb = UserGetSystemMetrics(SM_CYVSCROLL); cxy = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top; break; case SB_CTL: IntGetClientRect(Wnd, &ClientRect); if(Wnd->style & SBS_VERT) { Thumb = UserGetSystemMetrics(SM_CYVSCROLL); cxy = ClientRect.bottom - ClientRect.top; } else { Thumb = UserGetSystemMetrics(SM_CXHSCROLL); cxy = ClientRect.right - ClientRect.left; } break; default: return FALSE; } ThumbPos = Thumb; /* Calculate Thumb */ if(cxy <= (2 * Thumb)) { Thumb = cxy / 2; psbi->xyThumbTop = 0; psbi->xyThumbBottom = 0; ThumbPos = Thumb; } else { ThumbBox = pSBData->page ? MINTRACKTHUMB : UserGetSystemMetrics(SM_CXHTHUMB); cxy -= (2 * Thumb); if(cxy >= ThumbBox) { if(pSBData->page) { ThumbBox = max(EngMulDiv(cxy, pSBData->page, pSBData->posMax - pSBData->posMin + 1), ThumbBox); } if(cxy > ThumbBox) { mx = pSBData->posMax - max(pSBData->page - 1, 0); if(pSBData->posMin < mx) ThumbPos = Thumb + EngMulDiv(cxy - ThumbBox, pSBData->pos - pSBData->posMin, mx - pSBData->posMin); else ThumbPos = Thumb + ThumbBox; } psbi->xyThumbTop = ThumbPos; psbi->xyThumbBottom = ThumbPos + ThumbBox; } else { psbi->xyThumbTop = 0; psbi->xyThumbBottom = 0; } } psbi->dxyLineButton = Thumb; return TRUE; }
BOOL FASTCALL IntGetScrollBarRect (PWND Wnd, INT nBar, RECTL *lprect) { BOOL vertical; *lprect = Wnd->rcClient; RECTL_vOffsetRect( lprect, -Wnd->rcWindow.left, -Wnd->rcWindow.top ); if (Wnd->ExStyle & WS_EX_LAYOUTRTL) mirror_rect( &Wnd->rcWindow, lprect ); switch (nBar) { case SB_HORZ: lprect->top = lprect->bottom; lprect->bottom += UserGetSystemMetrics (SM_CYHSCROLL); if (Wnd->style & WS_BORDER) { lprect->left--; lprect->right++; } else if (Wnd->style & WS_VSCROLL) { lprect->right++; } vertical = FALSE; break; case SB_VERT: if(Wnd->ExStyle & WS_EX_LEFTSCROLLBAR) { lprect->right = lprect->left; lprect->left -= UserGetSystemMetrics(SM_CXVSCROLL); } else { lprect->left = lprect->right; lprect->right += UserGetSystemMetrics(SM_CXVSCROLL); } if (Wnd->style & WS_BORDER) { lprect->top--; lprect->bottom++; } else if (Wnd->style & WS_HSCROLL) { lprect->bottom++; } vertical = TRUE; break; case SB_CTL: IntGetClientRect (Wnd, lprect); vertical = !!(Wnd->style & SBS_VERT); break; default: return FALSE; } return vertical; }