2 * Copyright (c) 2000 Greg Haerr <greg@censoft.com>
3 * Portions Copyright (c) 1999, 2000, Wei Yongming.
4 * jmt: scrollbar thumb ported
6 * Microwindows win32 NonClient Scrollbars
8 #define MWINCLUDECOLORS
16 /* scrollbar status/positions*/
17 #define SBS_UNKNOWN 0x0000
18 #define SBS_LEFTARROW 0x0001
19 #define SBS_RIGHTARROW 0x0002
20 #define SBS_LEFTSPACE 0x0004
21 #define SBS_RIGHTSPACE 0x0008
22 #define SBS_HORZTHUMB 0x0010
23 #define SBS_UPARROW 0x0020
24 #define SBS_DOWNARROW 0x0040
25 #define SBS_UPSPACE 0x0080
26 #define SBS_DOWNSPACE 0x0100
27 #define SBS_VERTTHUMB 0x0200
28 #define SBS_MASK 0x03ff
29 #define SBS_DISABLED 0x4000
30 #define SBS_HIDE 0x8000
32 #define HSCROLLBARVISIBLE(hwnd) ((hwnd)->style & WS_HSCROLL)
33 #define VSCROLLBARVISIBLE(hwnd) ((hwnd)->style & WS_VSCROLL)
36 * Adjust client area smaller if scrollbars visible.
37 * Also, compute the NC hittest regions for the scrollbars.
40 MwAdjustNCScrollbars(HWND hwnd)
42 BOOL vertbar = VSCROLLBARVISIBLE(hwnd);
43 BOOL horzbar = HSCROLLBARVISIBLE(hwnd);
46 hwnd->clirect.right -= mwSYSMETRICS_CXVSCROLL;
48 hwnd->clirect.bottom -= mwSYSMETRICS_CYHSCROLL;
49 hwnd->vscroll.rc.left = hwnd->clirect.right;
50 hwnd->vscroll.rc.right = hwnd->clirect.right +
51 mwSYSMETRICS_CXVSCROLL;
52 hwnd->vscroll.rc.top = hwnd->clirect.top;
53 hwnd->vscroll.rc.bottom = hwnd->clirect.bottom;
55 SetRectEmpty(&hwnd->vscroll.rc);
58 hwnd->clirect.bottom -= mwSYSMETRICS_CYHSCROLL;
59 hwnd->hscroll.rc.top = hwnd->clirect.bottom;
60 hwnd->hscroll.rc.bottom = hwnd->clirect.bottom +
61 mwSYSMETRICS_CYHSCROLL;
62 hwnd->hscroll.rc.left = hwnd->clirect.left;
63 hwnd->hscroll.rc.right = hwnd->clirect.right;
65 SetRectEmpty(&hwnd->hscroll.rc);
69 wndGetBorder(HWND hwnd)
71 if (hwnd->style & WS_BORDER) {
72 if ((hwnd->style & WS_CAPTION) == WS_CAPTION)
73 return mwSYSMETRICS_CXFRAME;
74 return mwSYSMETRICS_CXBORDER;
80 wndGetVScrollBarRect (HWND hwnd, RECT* rcVBar)
82 if (hwnd->style & WS_VSCROLL) {
83 rcVBar->left = hwnd->winrect.right - mwSYSMETRICS_CXVSCROLL
84 - wndGetBorder (hwnd);
85 rcVBar->right = hwnd->winrect.right - wndGetBorder (hwnd);
86 rcVBar->top = hwnd->clirect.top;
87 rcVBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd);
89 if (hwnd->style & WS_HSCROLL && !(hwnd->hscroll.status & SBS_HIDE))
90 rcVBar->bottom -= mwSYSMETRICS_CYHSCROLL;
99 wndGetHScrollBarRect (HWND hwnd, RECT* rcHBar)
101 if (hwnd->style & WS_HSCROLL) {
102 rcHBar->top = hwnd->winrect.bottom - mwSYSMETRICS_CYHSCROLL
103 - wndGetBorder (hwnd);
104 rcHBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd);
105 rcHBar->left = hwnd->clirect.left;
106 rcHBar->right = hwnd->winrect.right - wndGetBorder (hwnd);
108 if (hwnd->style & WS_VSCROLL && !(hwnd->vscroll.status & SBS_HIDE))
109 rcHBar->right -= mwSYSMETRICS_CXVSCROLL;
118 MwPaintNCScrollbars(HWND hwnd, HDC hdc)
120 BOOL vertbar = VSCROLLBARVISIBLE(hwnd);
121 BOOL horzbar = HSCROLLBARVISIBLE(hwnd);
132 if (!hdc && (horzbar || vertbar)) {
133 hdc = GetWindowDC(hwnd);
137 if (horzbar && vertbar) {
138 rc.left = hwnd->clirect.right;
139 rc.top = hwnd->clirect.bottom;
140 rc.right = rc.left + mwSYSMETRICS_CXVSCROLL;
141 rc.bottom = rc.top + mwSYSMETRICS_CYHSCROLL;
142 FillRect(hdc, &rc, (HBRUSH)(COLOR_BTNFACE+1));
145 rc = hwnd->vscroll.rc;
148 rc2.left=rc.left; rc2.right=rc2.left+ mwSYSMETRICS_CXVSCROLL;
150 rc2.bottom=rc2.top+ mwSYSMETRICS_CYHSCROLL;
151 FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1));
152 rc2.top=rc.bottom- mwSYSMETRICS_CYHSCROLL;
153 rc2.bottom=rc2.top+ mwSYSMETRICS_CYHSCROLL;
154 FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1));
157 Draw3dUpDownState(hdc, rc.left, rc.top,
158 mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
159 hwnd->vscroll.status & SBS_UPARROW);
161 Draw3dUpDownState(hdc, rc.left,rc.bottom-mwSYSMETRICS_CYHSCROLL,
162 mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
163 hwnd->vscroll.status & SBS_DOWNARROW);
164 /* jmt: draw arrows */
165 SelectObject(hdc,GetStockObject(BLACK_BRUSH));
167 p3[0].x= rc.left + (mwSYSMETRICS_CXVSCROLL/2) - 1;
168 p3[0].y= rc.top + 2 + shrink;
169 p3[1].x= rc.left + 2 + shrink - 1;
170 p3[1].y= rc.top + (mwSYSMETRICS_CYHSCROLL-4) - shrink;
171 p3[2].x= rc.left + (mwSYSMETRICS_CXVSCROLL-4) - shrink;
172 p3[2].y= rc.top + (mwSYSMETRICS_CYHSCROLL-4) - shrink;
175 p3[0].x= rc.left + (mwSYSMETRICS_CXVSCROLL/2) - 1;
176 p3[0].y= rc.bottom - 4 - shrink;
177 p3[1].x= rc.left + 2 + shrink - 1;
178 p3[1].y= rc.bottom-mwSYSMETRICS_CYHSCROLL + 2 + shrink;
179 p3[2].x= rc.left + (mwSYSMETRICS_CXVSCROLL-4) - shrink;
180 p3[2].y= rc.bottom-mwSYSMETRICS_CYHSCROLL + 2 + shrink;
183 /* draw moving bar */
185 wndGetVScrollBarRect (hwnd, &rcVBar);
189 start = rcVBar.top + mwSYSMETRICS_CYVSCROLL + hwnd->vscroll.barStart;
191 if (start + hwnd->vscroll.barLen > rcVBar.bottom)
192 start = rcVBar.bottom - hwnd->vscroll.barLen;
194 if (hwnd->vscroll.barLen == 0)
195 hwnd->vscroll.barLen=rc.bottom-rc.top-(mwSYSMETRICS_CYVSCROLL*2);
198 rc2.left=rc.left; rc2.right=rc.right/*-1*/;
199 rc2.top=rc.top+mwSYSMETRICS_CYHSCROLL;
201 if (rc2.bottom>rc2.top)
202 FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
204 rc2.top=start+hwnd->vscroll.barLen;
205 rc2.bottom=rc.bottom-mwSYSMETRICS_CYHSCROLL;
206 if (rc2.bottom>rc2.top)
207 FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
209 Draw3dUpFrame (hdc, rcVBar.left, start, rcVBar.right,
210 start + hwnd->vscroll.barLen);
211 /*printf("barv:(l,t,r,b):(%d,%d,%d,%d)\n",
212 rcVBar.left, start, rcVBar.right,
213 start + hwnd->vscroll.barLen);*/
216 rc = hwnd->hscroll.rc;
220 rc2.top=rc.top; rc2.bottom=rc2.top+ mwSYSMETRICS_CYHSCROLL;
222 rc2.right=rc2.left+ mwSYSMETRICS_CXVSCROLL;
223 FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1));
224 rc2.left=rc.right- mwSYSMETRICS_CXVSCROLL;
225 rc2.right=rc2.left+ mwSYSMETRICS_CXVSCROLL;
226 FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1));
230 Draw3dUpDownState(hdc, rc.left, rc.top,
231 mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
232 hwnd->hscroll.status & SBS_LEFTARROW);
234 Draw3dUpDownState(hdc, rc.right-mwSYSMETRICS_CXVSCROLL, rc.top,
235 mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
236 hwnd->hscroll.status & SBS_RIGHTARROW);
237 /* jmt: draw arrows */
238 SelectObject(hdc,GetStockObject(BLACK_BRUSH));
240 p3[0].x= rc.left + 2 + shrink;
241 p3[0].y= rc.top + (mwSYSMETRICS_CYHSCROLL/2) ;
242 p3[1].x= rc.left + (mwSYSMETRICS_CXVSCROLL-4) - shrink ;
243 p3[1].y= rc.top + 2 + shrink;
244 p3[2].x= rc.left + (mwSYSMETRICS_CXVSCROLL-4) - shrink;
245 p3[2].y= rc.bottom - 4 - shrink + 1;
248 p3[0].x= rc.right - 4 - shrink;
249 p3[0].y= rc.top + (mwSYSMETRICS_CYHSCROLL/2) ;
250 p3[1].x= rc.right-mwSYSMETRICS_CXVSCROLL + 2 + shrink ;
251 p3[1].y= rc.top + 2 + shrink;
252 p3[2].x= rc.right-mwSYSMETRICS_CXVSCROLL + 2 + shrink;
253 p3[2].y= rc.bottom - 4 - shrink + 1;
256 /* draw moving bar. */
258 wndGetHScrollBarRect (hwnd, &rcHBar);
262 start = rcHBar.left + mwSYSMETRICS_CXHSCROLL + hwnd->hscroll.barStart;
264 if (start + hwnd->hscroll.barLen > rcHBar.right)
265 start = rcHBar.right - hwnd->hscroll.barLen;
267 if (hwnd->hscroll.barLen == 0)
268 hwnd->hscroll.barLen=rc.right-rc.left-(mwSYSMETRICS_CXHSCROLL*2);
271 rc2.top=rc.top; rc2.bottom=rc.bottom/*-1*/;
272 rc2.left=rc.left+mwSYSMETRICS_CXVSCROLL;
274 if (rc2.right>rc2.left)
275 FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
277 rc2.left=start+hwnd->hscroll.barLen;
278 rc2.right=rc.right-mwSYSMETRICS_CXVSCROLL;
279 if (rc2.right>rc2.left)
280 FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));
282 Draw3dUpFrame (hdc, start, rcHBar.top, start + hwnd->hscroll.barLen,
284 /*printf("barh:(l,t,r,b):(%d,%d,%d,%d)\n",
285 start, rcHBar.top, start + hwnd->hscroll.barLen,
291 ReleaseDC(hwnd, hdc);
294 /* handle a non-client message for a scrollbar*/
296 MwHandleNCMessageScrollbar(HWND hwnd, UINT msg, WPARAM hitcode, LPARAM lParam)
298 int pos = SBS_UNKNOWN;
299 BOOL vertbar = VSCROLLBARVISIBLE(hwnd);
300 BOOL horzbar = HSCROLLBARVISIBLE(hwnd);
307 static int downPos = SBS_UNKNOWN;
311 int itemMoveable,itemCount,itemVisible,moveRange; /* jmt:2k0819 */
312 int moveTop,moveBottom,moveLeft,moveRight; /* jmt:2k0819 */
314 POINTSTOPOINT(pt, lParam);
315 for (;;) { /* use for() to allow break statement*/
316 if (hitcode == HTVSCROLL && vertbar)
318 pStat = &hwnd->vscroll.status;
319 rc = hwnd->vscroll.rc;
320 rc.bottom = rc.top + mwSYSMETRICS_CYVSCROLL;
321 if (PtInRect(&rc, pt))
326 rc.bottom = hwnd->vscroll.rc.bottom;
327 rc.top = rc.bottom - mwSYSMETRICS_CYVSCROLL;
328 if (PtInRect(&rc, pt))
334 } else if (hitcode == HTHSCROLL && horzbar)
336 pStat = &hwnd->hscroll.status;
337 rc = hwnd->hscroll.rc;
338 rc.right = rc.left + mwSYSMETRICS_CXHSCROLL;
339 if (PtInRect(&rc, pt)) {
343 rc.right = hwnd->hscroll.rc.right;
344 rc.left = rc.right - mwSYSMETRICS_CXHSCROLL;
345 if (PtInRect(&rc, pt)) {
346 pos = SBS_RIGHTARROW;
355 if (pos == SBS_UNKNOWN)
358 *pStat &= ~SBS_MASK; /* remove stray mouse states*/
360 if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK) /* jmt:2k0819 */
364 if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK) /* jmt:2k0819 */
368 MwPaintNCScrollbars(hwnd, NULL);
370 if (pos == SBS_UPARROW || pos == SBS_LEFTARROW) /* jmt:2k0820 */
372 if (hwnd->vscroll.curPos != hwnd->vscroll.minPos)
375 else if (pos == SBS_DOWNARROW || pos == SBS_RIGHTARROW) /* jmt:2k0820 */
377 if (hwnd->vscroll.curPos != hwnd->vscroll.maxPos)
378 sbCode = SB_LINEDOWN;
380 else if (pos == SBS_VERTTHUMB || pos == SBS_HORZTHUMB)
382 sbCode = SB_THUMBTRACK;
387 case WM_NCLBUTTONDOWN:
388 case WM_NCLBUTTONDBLCLK: /* jmt:2k0819 */
391 InvalidateRect(hwnd,NULL,TRUE);
395 case WM_NCMOUSEMOVE: /* jmt:2k0819 */
396 if (hitcode == HTVSCROLL && vertbar)
398 if (sbCode == SB_THUMBTRACK && downPos == SBS_VERTTHUMB)
400 /* jmt(2k0819): new algorithm for SB_THUMBTRACK */
402 rc = hwnd->vscroll.rc;
403 moveTop = rc.top + mwSYSMETRICS_CYVSCROLL;
404 moveBottom = hwnd->vscroll.rc.bottom - mwSYSMETRICS_CYVSCROLL;
405 moveRange = moveBottom - moveTop;
407 itemCount = hwnd->vscroll.maxPos - hwnd->vscroll.minPos + 1;
408 itemVisible = hwnd->vscroll.pageStep;
409 itemMoveable = itemCount - itemVisible + 1;
411 newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange;
412 printf("((%d-%d)*%d)/%d=%d\n",
413 pt.y,moveTop,itemMoveable,moveRange,newThumbPos);
415 if ( newThumbPos >= hwnd->vscroll.minPos &&
416 newThumbPos <= hwnd->vscroll.maxPos)
418 WM_VSCROLL, SB_THUMBTRACK, newThumbPos);
423 if (hitcode == HTHSCROLL && horzbar)
425 if (sbCode == SB_THUMBTRACK && downPos == SBS_HORZTHUMB)
427 /* jmt(2k0819): new algorithm for SB_THUMBTRACK */
429 rc = hwnd->hscroll.rc;
430 moveLeft = rc.left + mwSYSMETRICS_CXHSCROLL;
431 moveRight = hwnd->hscroll.rc.right - mwSYSMETRICS_CXHSCROLL;
432 moveRange = moveRight - moveLeft;
434 itemCount = hwnd->hscroll.maxPos - hwnd->hscroll.minPos + 1;
435 itemVisible = hwnd->hscroll.pageStep;
436 itemMoveable = itemCount - itemVisible + 1;
438 newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange;
439 printf("((%d-%d)*%d)/%d=%d\n",
440 pt.y,moveLeft,itemMoveable,moveRange,newThumbPos);
442 if ( newThumbPos >= hwnd->hscroll.minPos &&
443 newThumbPos <= hwnd->hscroll.maxPos)
445 WM_HSCROLL, SB_THUMBTRACK, newThumbPos);
452 case WM_NCLBUTTONUP: /* jmt:2k0819 */
454 downPos = SBS_UNKNOWN;
456 if (sbCode==SB_THUMBTRACK)
458 if (hitcode == HTVSCROLL && vertbar)
460 /* jmt(2k0819): new algorithm for SB_THUMBTRACK */
462 rc = hwnd->vscroll.rc;
463 moveTop = rc.top + mwSYSMETRICS_CYVSCROLL;
464 moveBottom = hwnd->vscroll.rc.bottom - mwSYSMETRICS_CYVSCROLL;
465 moveRange = moveBottom - moveTop;
467 itemCount = hwnd->vscroll.maxPos - hwnd->vscroll.minPos + 1;
468 itemVisible = hwnd->vscroll.pageStep;
469 itemMoveable = itemCount - itemVisible + 1;
471 newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange;
472 printf("((%d-%d)*%d)/%d=%d\n",
473 pt.y,moveTop,itemMoveable,moveRange,newThumbPos);
475 if ( newThumbPos >= hwnd->vscroll.minPos &&
476 newThumbPos <= hwnd->vscroll.maxPos)
478 WM_VSCROLL, SB_THUMBTRACK, newThumbPos);
482 if (hitcode == HTHSCROLL && horzbar)
484 /* jmt(2k0819): new algorithm for SB_THUMBTRACK */
486 rc = hwnd->hscroll.rc;
487 moveLeft = rc.left + mwSYSMETRICS_CXHSCROLL;
488 moveRight = hwnd->hscroll.rc.right - mwSYSMETRICS_CXHSCROLL;
489 moveRange = moveRight - moveLeft;
491 itemCount = hwnd->hscroll.maxPos - hwnd->hscroll.minPos + 1;
492 itemVisible = hwnd->hscroll.pageStep;
493 itemMoveable = itemCount - itemVisible + 1;
495 newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange;
496 printf("((%d-%d)*%d)/%d=%d\n",
497 pt.y,moveLeft,itemMoveable,moveRange,newThumbPos);
499 if ( newThumbPos >= hwnd->hscroll.minPos &&
500 newThumbPos <= hwnd->hscroll.maxPos)
502 WM_HSCROLL, SB_THUMBTRACK, newThumbPos);
506 else /* jmt:2k0820 */
508 if (hitcode == HTVSCROLL && vertbar)
509 SendMessage (hwnd, WM_VSCROLL, sbCode, 0);
511 if (hitcode == HTHSCROLL && horzbar)
512 SendMessage (hwnd, WM_HSCROLL, sbCode, 0);
521 PtInRect2(const RECT *lprc, int x, int y)
527 return PtInRect(lprc, p);
534 wndScrollBarPos (HWND hwnd, BOOL bIsHBar, RECT* rcBar)
537 PMWSCROLLBARINFO pSBar;
540 pSBar = &hwnd->hscroll;
542 pSBar = &hwnd->vscroll;
544 if (pSBar->minPos == pSBar->maxPos) {
545 pSBar->status |= SBS_HIDE;
550 moveRange = (rcBar->right - rcBar->left) - (mwSYSMETRICS_CXHSCROLL<<1);
552 moveRange = (rcBar->bottom - rcBar->top) - (mwSYSMETRICS_CYVSCROLL<<1);
554 #define MWM_DEFBARLEN 18
555 #define MWM_MINBARLEN 8
557 if (pSBar->pageStep == 0)
559 pSBar->barLen = MWM_DEFBARLEN;
561 if (pSBar->barLen > moveRange)
562 pSBar->barLen = MWM_MINBARLEN;
566 pSBar->barLen = moveRange * pSBar->pageStep /
567 (pSBar->maxPos - pSBar->minPos + 1);
568 if (pSBar->barLen < MWM_MINBARLEN)
569 pSBar->barLen = MWM_MINBARLEN;
572 pSBar->barStart = moveRange * (pSBar->curPos - pSBar->minPos) /
573 (pSBar->maxPos - pSBar->minPos + 1);
576 if (pSBar->barStart + pSBar->barLen > moveRange)
577 pSBar->barStart = moveRange - pSBar->barLen;
580 if (pSBar->barStart < 0)
584 static PMWSCROLLBARINFO wndGetScrollBar (HWND pWin, int iSBar)
586 if (iSBar == SB_HORZ) {
587 if (pWin->style & WS_HSCROLL)
588 return &pWin->hscroll;
590 else if (iSBar == SB_VERT) {
591 if (pWin->style & WS_VSCROLL)
592 return &pWin->vscroll;
598 BOOL EnableScrollBar (HWND hWnd, int iSBar, BOOL bEnable)
600 PMWSCROLLBARINFO pSBar;
607 if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
610 bPrevState = !(pSBar->status & SBS_DISABLED);
612 if (bEnable && !bPrevState)
613 pSBar->status &= ~SBS_DISABLED;
614 else if (!bEnable && bPrevState)
615 pSBar->status |= SBS_DISABLED;
619 if (iSBar == SB_VERT)
621 wndGetVScrollBarRect (pWin, &rcBar);
627 wndGetHScrollBarRect (pWin, &rcBar);
632 SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar));
634 MwPaintNCScrollbars(hWnd,NULL); /* a must */
640 BOOL GetScrollPos (HWND hWnd, int iSBar, int* pPos)
642 PMWSCROLLBARINFO pSBar;
647 if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
650 *pPos = pSBar->curPos;
654 BOOL GetScrollRange (HWND hWnd, int iSBar, int* pMinPos, int* pMaxPos)
656 PMWSCROLLBARINFO pSBar;
661 if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
664 *pMinPos = pSBar->minPos;
665 *pMaxPos = pSBar->maxPos;
669 BOOL SetScrollPos (HWND hWnd, int iSBar, int iNewPos)
671 PMWSCROLLBARINFO pSBar;
677 if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
680 if (iNewPos < pSBar->minPos)
681 pSBar->curPos = pSBar->minPos;
683 pSBar->curPos = iNewPos;
686 int max = pSBar->maxPos;
687 max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0;
689 if (pSBar->curPos > max)
693 if (iSBar == SB_VERT)
695 wndGetVScrollBarRect (pWin, &rcBar);
701 wndGetHScrollBarRect (pWin, &rcBar);
706 wndScrollBarPos (pWin, iSBar == SB_HORZ, &rcBar);
709 SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar));
711 MwPaintNCScrollbars(hWnd,NULL); /* a must */
716 BOOL SetScrollRange (HWND hWnd, int iSBar, int iMinPos, int iMaxPos)
718 PMWSCROLLBARINFO pSBar;
724 if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
727 pSBar->minPos = (iMinPos < iMaxPos)?iMinPos:iMaxPos;
728 pSBar->maxPos = (iMinPos > iMaxPos)?iMinPos:iMaxPos;
730 /* validate parameters. */
731 if (pSBar->curPos < pSBar->minPos)
732 pSBar->curPos = pSBar->minPos;
734 if (pSBar->pageStep <= 0)
736 else if (pSBar->pageStep > (pSBar->maxPos - pSBar->minPos + 1))
737 pSBar->pageStep = pSBar->maxPos - pSBar->minPos + 1;
740 int max = pSBar->maxPos;
741 max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0;
743 if (pSBar->curPos > max)
747 if (iSBar == SB_VERT)
749 wndGetVScrollBarRect (pWin, &rcBar);
755 wndGetHScrollBarRect (pWin, &rcBar);
759 wndScrollBarPos (pWin, iSBar == SB_HORZ, &rcBar);
762 SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar));
764 MwPaintNCScrollbars(hWnd,NULL); /* a must */
770 BOOL SetScrollInfo (HWND hWnd, int iSBar,
771 LPCSCROLLINFO lpsi, BOOL fRedraw)
773 PMWSCROLLBARINFO pSBar;
779 if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
782 if( lpsi->fMask & SIF_RANGE )
784 pSBar->minPos = (lpsi->nMin < lpsi->nMax)?lpsi->nMin:lpsi->nMax;
785 pSBar->maxPos = (lpsi->nMin < lpsi->nMax)?lpsi->nMax:lpsi->nMin;
788 if( lpsi->fMask & SIF_POS )
789 pSBar->curPos = lpsi->nPos;
791 if( lpsi->fMask & SIF_PAGE )
792 pSBar->pageStep = lpsi->nPage;
794 /* validate parameters. */
795 if (pSBar->curPos < pSBar->minPos)
796 pSBar->curPos = pSBar->minPos;
798 if (pSBar->pageStep <= 0)
800 else if (pSBar->pageStep > (pSBar->maxPos - pSBar->minPos + 1))
801 pSBar->pageStep = pSBar->maxPos - pSBar->minPos + 1;
804 int max = pSBar->maxPos;
805 max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0;
807 if (pSBar->curPos > max)
813 if (iSBar == SB_VERT)
815 wndGetVScrollBarRect (pWin, &rcBar);
821 wndGetHScrollBarRect (pWin, &rcBar);
825 wndScrollBarPos (pWin, iSBar == SB_HORZ, &rcBar);
828 SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar));
830 MwPaintNCScrollbars(hWnd,NULL); /* a must */
837 BOOL GetScrollInfo(HWND hWnd, int iSBar, LPSCROLLINFO lpsi)
839 PMWSCROLLBARINFO pSBar;
844 if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
847 if( lpsi->fMask & SIF_RANGE )
849 lpsi->nMin = pSBar->minPos;
850 lpsi->nMax = pSBar->maxPos;
853 if( lpsi->fMask & SIF_POS )
855 lpsi->nPos = pSBar->curPos;
858 if( lpsi->fMask & SIF_PAGE )
859 lpsi->nPage = pSBar->pageStep;
864 BOOL ShowScrollBar (HWND hWnd, int iSBar, BOOL bShow)
866 PMWSCROLLBARINFO pSBar;
873 if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
876 bPrevState = !(pSBar->status & SBS_HIDE);
878 if (bShow && !bPrevState)
879 pSBar->status &= ~SBS_HIDE;
880 else if (!bShow && bPrevState)
881 pSBar->status |= SBS_HIDE;
884 #if 0 /* fix: no WM_CHANGESIZE */
885 SendMessage (hWnd, WM_CHANGESIZE, 0, 0);
887 if (iSBar == SB_VERT)
888 wndGetVScrollBarRect (pWin, &rcBar);
890 wndGetHScrollBarRect (pWin, &rcBar);
893 RECT rcWin, rcClient;
895 memcpy (&rcWin, &pWin->winrect.left, sizeof (RECT));
899 rcClient.right = pWin->clirect.right - pWin->clirect.left;
900 rcClient.bottom = pWin->clirect.bottom - pWin->clirect.top;
901 #if 0 /* fix: no WM_SIZECHANGED */
902 SendMessage/*SendAsyncMessage*/ (hWnd, WM_SIZECHANGED,
903 (WPARAM)&rcWin, (LPARAM)&rcClient);
908 SendMessage (hWnd, WM_NCPAINT, 0, 0);
911 rcBar.left -= pWin->clirect.left;
912 rcBar.top -= pWin->clirect.top;
913 rcBar.right -= pWin->clirect.left;
914 rcBar.bottom -= pWin->clirect.top;
915 SendMessage (hWnd, WM_NCPAINT, 0, 0);
916 InvalidateRect (hWnd, &rcBar, TRUE);