Mercurial > ecos
diff packages/services/gfx/mw/current/src/mwin/winlib/scrlbar.c @ 208:e0c0827131d1 ecos
Merge from eCos master repository on 2002-05-20-20:11:54-BST
| author | jlarmour |
|---|---|
| date | Mon, 20 May 2002 22:19:26 +0000 |
| parents | |
| children |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/services/gfx/mw/current/src/mwin/winlib/scrlbar.c @@ -0,0 +1,1140 @@ +/* + * Copyright (c) 2000 Greg Haerr <greg@censoft.com> + * Portions Copyright (c) 1999, 2000, Wei Yongming. + * jmt: scrollbar thumb ported + * + * Microwindows win32 Scrollbars control + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#define MWINCLUDECOLORS /* jmt: for color macros */ +#include "windows.h" +#include "wintern.h" +#include "wintools.h" + +/* scrollbar status/positions*/ +#define SBS_UNKNOWN 0x0000 +#define SBS_LEFTARROW 0x0001 +#define SBS_RIGHTARROW 0x0002 +#define SBS_LEFTSPACE 0x0004 +#define SBS_RIGHTSPACE 0x0008 +#define SBS_HORZTHUMB 0x0010 +#define SBS_UPARROW 0x0020 +#define SBS_DOWNARROW 0x0040 +#define SBS_UPSPACE 0x0080 +#define SBS_DOWNSPACE 0x0100 +#define SBS_VERTTHUMB 0x0200 +#define SBS_MASK 0x03ff +#define SBS_DISABLED 0x4000 +#define SBS_HIDE 0x8000 + + +#define MWM_DEFBARLEN 18 +#define MWM_MINBARLEN 8 + +static LRESULT CALLBACK +ScrollbarControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); + + +int WINAPI MwRegisterScrollbarControl(HINSTANCE hInstance) +{ + WNDCLASS wc; + + wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_GLOBALCLASS; + wc.lpfnWndProc = (WNDPROC)ScrollbarControlProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = NULL; + wc.hCursor = 0; /*LoadCursor(NULL, IDC_ARROW);*/ + wc.hbrBackground= GetStockObject(WHITE_BRUSH); + wc.lpszMenuName = NULL; + wc.lpszClassName= "SCROLLBAR"; + + return RegisterClass(&wc); +} + +static DWORD GetWindowStyle (HWND hwnd) +{ + return hwnd->style; +} + +static int +wndGetBorder(HWND hwnd) +{ + if (hwnd->style & WS_BORDER) { + if ((hwnd->style & WS_CAPTION) == WS_CAPTION) + return mwSYSMETRICS_CXFRAME; + return mwSYSMETRICS_CXBORDER; + } + return 0; +} + +static BOOL +wndGetVScrollBarRect (HWND hwnd, RECT* rcVBar) +{ + int cx,cy; RECT rc; + MWSCROLLBARINFO* pData; + + pData = (MWSCROLLBARINFO *)hwnd->userdata; + rc = hwnd->winrect; + cx=rc.right-rc.left; + cy=rc.bottom-rc.top; + + rcVBar->left = hwnd->winrect.right - cx + - wndGetBorder (hwnd); + rcVBar->right = hwnd->winrect.right - wndGetBorder (hwnd); + rcVBar->top = hwnd->winrect.top; + rcVBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd); + + return TRUE; +} + +static BOOL +wndGetHScrollBarRect (HWND hwnd, RECT* rcHBar) +{ + int cx,cy; RECT rc; + MWSCROLLBARINFO* pData; + + pData = (MWSCROLLBARINFO *)hwnd->userdata; + rc = hwnd->winrect; + cx=rc.right-rc.left; + cy=rc.bottom-rc.top; + + rcHBar->top = hwnd->winrect.bottom - cy + - wndGetBorder (hwnd); + rcHBar->bottom = hwnd->winrect.bottom - wndGetBorder (hwnd); + rcHBar->left = hwnd->winrect.left; + rcHBar->right = hwnd->winrect.right - wndGetBorder (hwnd); + + return TRUE; +} + +void +MwPaintScrollbars(HWND hwnd, HDC hdc, DWORD style) +{ + BOOL vertbar = (style==SBS_VERT); + BOOL horzbar = (style==SBS_HORZ); + BOOL fGotDC = FALSE; + RECT rc,rc2; + + POINT p3[3]; + int shrink=2; + + int start = 0; + RECT rcHBar, rcVBar; + + int cx,cy; + MWSCROLLBARINFO* pData; + + pData = (MWSCROLLBARINFO *)hwnd->userdata; + rc = hwnd->winrect; + cx=rc.right-rc.left; + cy=rc.bottom-rc.top; + + if (!hdc && (horzbar || vertbar)) { + hdc = GetWindowDC(hwnd); + fGotDC = TRUE; + } + + if (vertbar) { + +#if 1 + /* bkgnd */ + rc2.left=rc.left; rc2.right=rc2.left+ cx; + rc2.top=rc.top; + rc2.bottom=rc2.top+ cx; + FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1)); + rc2.top=rc.bottom- cx; + rc2.bottom=rc2.top+ cx; + FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1)); +#endif + /* up */ + Draw3dUpDownState(hdc, rc.left, rc.top, + cx, cx, + pData->status & SBS_UPARROW); + /* down */ + Draw3dUpDownState(hdc, rc.left,rc.bottom-cx, + cx, cx, + pData->status & SBS_DOWNARROW); +/* jmt: draw arrows */ + SelectObject(hdc,GetStockObject(BLACK_BRUSH)); + /* up */ + p3[0].x= rc.left + (cx/2) - 1; + p3[0].y= rc.top + 2 + shrink; + p3[1].x= rc.left + 2 + shrink - 1; + p3[1].y= rc.top + (cx-4) - shrink; + p3[2].x= rc.left + (cx-4) - shrink; + p3[2].y= rc.top + (cx-4) - shrink; + Polygon(hdc,p3,3); + /* down */ + p3[0].x= rc.left + (cx/2) - 1; + p3[0].y= rc.bottom - 4 - shrink; + p3[1].x= rc.left + 2 + shrink - 1; + p3[1].y= rc.bottom-cx + 2 + shrink; + p3[2].x= rc.left + (cx-4) - shrink; + p3[2].y= rc.bottom-cx + 2 + shrink; + Polygon(hdc,p3,3); + + /* draw moving bar */ + + wndGetVScrollBarRect (hwnd, &rcVBar); + rcVBar.left -- ; + /*rcVBar.right -- ;*/ + + start = rcVBar.top + cx + pData->barStart; + + if (start + pData->barLen > rcVBar.bottom) + start = rcVBar.bottom - pData->barLen; + + if (pData->barLen == 0) + pData->barLen=rc.bottom-rc.top-(cx*2); + + /* bkgnd */ + rc2.left=rc.left; rc2.right=rc.right/*-1*/; + rc2.top=rc.top+cx; + rc2.bottom=start; + if (rc2.bottom>rc2.top) + FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); + + rc2.top=start+pData->barLen; + rc2.bottom=rc.bottom-cx; + if (rc2.bottom>rc2.top) + FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); + + Draw3dUpFrame (hdc, rcVBar.left, start, rcVBar.right, + start + pData->barLen); + /*printf("barv:(l,t,r,b):(%d,%d,%d,%d)\n", + rcVBar.left, start, rcVBar.right, + start + pData->barLen);*/ + + } + if (horzbar) { +#if 1 + /* bkgnd */ + rc2.top=rc.top; rc2.bottom=rc2.top+ cy; + rc2.left=rc.left; + rc2.right=rc2.left+ cy; + FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1)); + rc2.left=rc.right- cy; + rc2.right=rc2.left+ cy; + FillRect(hdc, &rc2, (HBRUSH)(COLOR_BTNFACE+1)); +#endif + /* left */ + Draw3dUpDownState(hdc, rc.left, rc.top, + cy, cy, + pData->status & SBS_LEFTARROW); + /* right */ + Draw3dUpDownState(hdc, rc.right-cy, rc.top, + cy, cy, + pData->status & SBS_RIGHTARROW); +/* jmt: draw arrows */ + SelectObject(hdc,GetStockObject(BLACK_BRUSH)); + /* left */ + p3[0].x= rc.left + 2 + shrink; + p3[0].y= rc.top + (cy/2) ; + p3[1].x= rc.left + (cy-4) - shrink ; + p3[1].y= rc.top + 2 + shrink; + p3[2].x= rc.left + (cy-4) - shrink; + p3[2].y= rc.bottom - 4 - shrink + 1; + Polygon(hdc,p3,3); + /* right */ + p3[0].x= rc.right - 4 - shrink; + p3[0].y= rc.top + (cy/2) ; + p3[1].x= rc.right-cy + 2 + shrink ; + p3[1].y= rc.top + 2 + shrink; + p3[2].x= rc.right-cy + 2 + shrink; + p3[2].y= rc.bottom - 4 - shrink + 1; + Polygon(hdc,p3,3); + + /* draw moving bar. */ + + wndGetHScrollBarRect (hwnd, &rcHBar); + rcHBar.top -- ; + /*rcHBar.bottom -- ;*/ + + start = rcHBar.left + cy + pData->barStart; + + if (start + pData->barLen > rcHBar.right) + start = rcHBar.right - pData->barLen; + + if (pData->barLen == 0) + pData->barLen=rc.right-rc.left-(cy*2); + + /* bkgnd */ + rc2.top=rc.top; rc2.bottom=rc.bottom/*-1*/; + rc2.left=rc.left+cy; + rc2.right=start; + if (rc2.right>rc2.left) + FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); + + rc2.left=start+pData->barLen; + rc2.right=rc.right-cy; + if (rc2.right>rc2.left) + FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH)); + + Draw3dUpFrame (hdc, start, rcHBar.top, start + pData->barLen, + rcHBar.bottom); + /*printf("barh:(l,t,r,b):(%d,%d,%d,%d)\n", + start, rcHBar.top, start + pData->barLen, + rcHBar.bottom);*/ + } + + if (fGotDC) + ReleaseDC(hwnd, hdc); +} + +/* handle a non-client message for a scrollbar*/ +void +MwHandleMessageScrollbar(HWND hwnd, WPARAM hitcode, LPARAM lParam, UINT msg, DWORD style) +{ + int pos = SBS_UNKNOWN; + BOOL vertbar = (style==SBS_VERT); + BOOL horzbar = (style==SBS_HORZ); + int * pStat; + POINT pt; + RECT rc; + + static BOOL bDraw; + + static int downPos = SBS_UNKNOWN; + static int sbCode; + int newThumbPos; + + int itemMoveable,itemCount,itemVisible,moveRange; /* jmt:2k0819 */ + int moveTop,moveBottom,moveLeft,moveRight; /* jmt:2k0819 */ + + int cx,cy; + MWSCROLLBARINFO* pData; + + pData = (MWSCROLLBARINFO *)hwnd->userdata; + rc = hwnd->winrect; + cx=rc.right-rc.left; + cy=rc.bottom-rc.top; + + POINTSTOPOINT(pt, lParam); + for (;;) { /* use for() to allow break statement*/ + if (vertbar) + { + pStat = &pData->status; + rc = hwnd->winrect; + rc.bottom = rc.top + cx; + if (PtInRect(&rc, pt)) + { + pos = SBS_UPARROW; + break; + } + rc.bottom = hwnd->winrect.bottom; + rc.top = rc.bottom - cx; + if (PtInRect(&rc, pt)) + { + pos = SBS_DOWNARROW; + break; + } + pos = SBS_VERTTHUMB; + } else if (horzbar) + { + pStat = &pData->status; + rc = hwnd->winrect; + rc.right = rc.left + cy; + if (PtInRect(&rc, pt)) { + pos = SBS_LEFTARROW; + break; + } + rc.right = hwnd->winrect.right; + rc.left = rc.right - cy; + if (PtInRect(&rc, pt)) { + pos = SBS_RIGHTARROW; + break; + } + pos = SBS_HORZTHUMB; + } else + return; + break; + } + + if (pos == SBS_UNKNOWN) + return; + + *pStat &= ~SBS_MASK; /* remove stray mouse states*/ + + if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK) + *pStat |= pos; + else *pStat &= ~pos; + + if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK) + bDraw=TRUE; + + if (bDraw) + MwPaintScrollbars(hwnd, NULL,style); + + if (pos == SBS_UPARROW || pos == SBS_LEFTARROW) /* jmt:2k0820 */ + { + if (pData->curPos != pData->minPos) + sbCode = SB_LINEUP; + } + else if (pos == SBS_DOWNARROW || pos == SBS_RIGHTARROW) /* jmt:2k0820 */ + { + if (pData->curPos != pData->maxPos) + sbCode = SB_LINEDOWN; + } + else if (pos == SBS_VERTTHUMB || pos == SBS_HORZTHUMB) + { + sbCode = SB_THUMBTRACK; + } + + switch(msg) + { + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONDBLCLK: + downPos = pos; + break; + + case WM_NCMOUSEMOVE: + if (vertbar) + { + if (sbCode == SB_THUMBTRACK && downPos == SBS_VERTTHUMB) + { + /* jmt(2k0819): new algorithm for SB_THUMBTRACK */ + + rc = hwnd->winrect; + moveTop = rc.top + cx; + moveBottom = hwnd->winrect.bottom - cx; + moveRange = moveBottom - moveTop; + + itemCount = pData->maxPos - pData->minPos + 1; + itemVisible = pData->pageStep; + itemMoveable = itemCount - itemVisible + 1; + + newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange; + printf("((%d-%d)*%d)/%d=%d\n", + pt.y,moveTop,itemMoveable,moveRange,newThumbPos); + + if ( newThumbPos >= pData->minPos && + newThumbPos <= pData->maxPos) + { + SendMessage (hwnd, + WM_VSCROLL, SB_THUMBTRACK, newThumbPos); + + SendMessage (GetParent(hwnd), + WM_VSCROLL, SB_THUMBTRACK, newThumbPos); + } + break; + } + } + if (horzbar) + { + if (sbCode == SB_THUMBTRACK && downPos == SBS_HORZTHUMB) + { + /* jmt(2k0819): new algorithm for SB_THUMBTRACK */ + + rc = hwnd->winrect; + moveLeft = rc.left + cy; + moveRight = hwnd->winrect.right - cy; + moveRange = moveRight - moveLeft; + + itemCount = pData->maxPos - pData->minPos + 1; + itemVisible = pData->pageStep; + itemMoveable = itemCount - itemVisible + 1; + + newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange; + printf("((%d-%d)*%d)/%d=%d\n", + pt.y,moveLeft,itemMoveable,moveRange,newThumbPos); + + if ( newThumbPos >= pData->minPos && + newThumbPos <= pData->maxPos) + { + SendMessage (hwnd, + WM_HSCROLL, SB_THUMBTRACK, newThumbPos); + + SendMessage (GetParent(hwnd), + WM_HSCROLL, SB_THUMBTRACK, newThumbPos); + } + break; + } + } + break; + + case WM_NCLBUTTONUP: + bDraw=FALSE; + downPos = SBS_UNKNOWN; + + if (sbCode==SB_THUMBTRACK) + { + if (vertbar) + { + /* jmt(2k0819): new algorithm for SB_THUMBTRACK */ + + rc = hwnd->winrect; + moveTop = rc.top + cx; + moveBottom = hwnd->winrect.bottom - cx; + moveRange = moveBottom - moveTop; + + itemCount = pData->maxPos - pData->minPos + 1; + itemVisible = pData->pageStep; + itemMoveable = itemCount - itemVisible + 1; + + newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange; + printf("((%d-%d)*%d)/%d=%d\n", + pt.y,moveTop,itemMoveable,moveRange,newThumbPos); + + if ( newThumbPos >= pData->minPos && + newThumbPos <= pData->maxPos) + { + SendMessage (hwnd, + WM_VSCROLL, SB_THUMBTRACK, newThumbPos); + + SendMessage (GetParent(hwnd), + WM_VSCROLL, SB_THUMBTRACK, newThumbPos); + } + break; /* case */ + } + if (horzbar) + { + /* jmt(2k0819): new algorithm for SB_THUMBTRACK */ + + rc = hwnd->winrect; + moveLeft = rc.left + cy; + moveRight = hwnd->winrect.right - cy; + moveRange = moveRight - moveLeft; + + itemCount = pData->maxPos - pData->minPos + 1; + itemVisible = pData->pageStep; + itemMoveable = itemCount - itemVisible + 1; + + newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange; + printf("((%d-%d)*%d)/%d=%d\n", + pt.y,moveLeft,itemMoveable,moveRange,newThumbPos); + + if ( newThumbPos >= pData->minPos && + newThumbPos <= pData->maxPos) + { + SendMessage (hwnd, + WM_HSCROLL, SB_THUMBTRACK, newThumbPos); + + SendMessage (GetParent(hwnd), + WM_HSCROLL, SB_THUMBTRACK, newThumbPos); + } + break; /* case */ + } + } + else + { + if (vertbar) + { + SendMessage (hwnd, WM_VSCROLL, sbCode, 0); + SendMessage (GetParent(hwnd), WM_VSCROLL, sbCode, 0); + } + if (horzbar) + { + SendMessage (hwnd, WM_HSCROLL, sbCode, 0); + SendMessage (GetParent(hwnd), WM_HSCROLL, sbCode, 0); + } + } + break; + } +} + + +static BOOL +PtInRect2(const RECT *lprc, int x, int y) +{ + POINT p; + + p.x = x; + p.y = y; + return PtInRect(lprc, p); +} + +static void +wndScrollBarPos (HWND hwnd, BOOL bIsHBar, RECT* rcBar) /* jmt: 2k0820 */ +{ + UINT moveRange; + PMWSCROLLBARINFO pSBar; + int cx,cy; + RECT rc; + + rc = hwnd->winrect; + cx=rc.right-rc.left; + cy=rc.bottom-rc.top; + pSBar = (MWSCROLLBARINFO *)hwnd->userdata; + + if (pSBar->minPos == pSBar->maxPos) { + pSBar->status |= SBS_HIDE; + return; + } + + if (bIsHBar) + moveRange = (rcBar->right - rcBar->left) - (cy << 1); + else + moveRange = (rcBar->bottom - rcBar->top) - (cx << 1); + + + if (pSBar->pageStep == 0) + { + pSBar->barLen = MWM_DEFBARLEN; + + if (pSBar->barLen > moveRange) + pSBar->barLen = MWM_MINBARLEN; + } + else + { + pSBar->barLen = moveRange * pSBar->pageStep / + (pSBar->maxPos - pSBar->minPos + 1); + if (pSBar->barLen < MWM_MINBARLEN) + pSBar->barLen = MWM_MINBARLEN; + } + + pSBar->barStart = moveRange * (pSBar->curPos - pSBar->minPos) / + (pSBar->maxPos - pSBar->minPos + 1); + + + if (pSBar->barStart + pSBar->barLen > moveRange) + pSBar->barStart = moveRange - pSBar->barLen; + + + if (pSBar->barStart < 0) + pSBar->barStart = 0; +} + +static PMWSCROLLBARINFO wndGetScrollBar (HWND pWin) /* jmt: 2k0820 */ +{ + MWSCROLLBARINFO* pData; + + pData = (MWSCROLLBARINFO *)pWin->userdata; + + if (!strcmp(pWin->pClass->lpszClassName,"SCROLLBAR")) + return pData; + else + return NULL; +} + +BOOL EnableScrollBarEx (HWND hWnd, int iSBar, BOOL bEnable) /* jmt: iSBar not used */ +{ + PMWSCROLLBARINFO pSBar; + HWND pWin; + BOOL bPrevState; + RECT rcBar; + + DWORD dwStyle; /* jmt:2k0820 */ + + pWin = (HWND)hWnd; + + if ( !(pSBar = wndGetScrollBar (pWin)) ) + return FALSE; + + bPrevState = !(pSBar->status & SBS_DISABLED); + + if (bEnable && !bPrevState) + pSBar->status &= ~SBS_DISABLED; + else if (!bEnable && bPrevState) + pSBar->status |= SBS_DISABLED; + else + return FALSE; + + dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ + + if (dwStyle == SBS_VERT) + { + wndGetVScrollBarRect (pWin, &rcBar); + rcBar.left --; + rcBar.right --; + } + else + { + wndGetHScrollBarRect (pWin, &rcBar); + rcBar.top --; + rcBar.bottom --; + } +#if 0 + SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar)); +#else + MwPaintScrollbars(hWnd,NULL,dwStyle); /* a must */ +#endif + + return TRUE; +} + +BOOL GetScrollPosEx (HWND hWnd, int iSBar, int* pPos) /* jmt: iSBar not used */ +{ + PMWSCROLLBARINFO pSBar; + HWND pWin; + + pWin = (HWND)hWnd; + + if ( !(pSBar = wndGetScrollBar (pWin)) ) + return FALSE; + + *pPos = pSBar->curPos; + return TRUE; +} + +BOOL GetScrollRangeEx (HWND hWnd, int iSBar, int* pMinPos, int* pMaxPos) /* jmt: iSBar not used */ +{ + PMWSCROLLBARINFO pSBar; + HWND pWin; + + pWin = (HWND)hWnd; + + if ( !(pSBar = wndGetScrollBar (pWin)) ) + return FALSE; + + *pMinPos = pSBar->minPos; + *pMaxPos = pSBar->maxPos; + return TRUE; +} + +BOOL SetScrollPosEx (HWND hWnd, int iSBar, int iNewPos) /* jmt: iSBar not used */ +{ + PMWSCROLLBARINFO pSBar; + HWND pWin; + RECT rcBar; + + DWORD dwStyle; /* jmt:2k0820 */ + + pWin = (HWND)hWnd; + + if ( !(pSBar = wndGetScrollBar (pWin)) ) + return FALSE; + + if (iNewPos < pSBar->minPos) + pSBar->curPos = pSBar->minPos; + else + pSBar->curPos = iNewPos; + + { + int max = pSBar->maxPos; + max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0; + + if (pSBar->curPos > max) + pSBar->curPos = max; + } + + dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ + + if (dwStyle == SBS_VERT) + { + wndGetVScrollBarRect (pWin, &rcBar); + rcBar.left --; + rcBar.right --; + } + else + { + wndGetHScrollBarRect (pWin, &rcBar); + rcBar.top --; + rcBar.bottom --; + } + + wndScrollBarPos (pWin, dwStyle == SBS_HORZ, &rcBar); + +#if 0 + SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar)); +#else + MwPaintScrollbars(hWnd,NULL,dwStyle); /* a must */ +#endif + return TRUE; +} + +BOOL SetScrollRangeEx (HWND hWnd, int iSBar, int iMinPos, int iMaxPos) /* jmt: iSBar not used */ +{ + PMWSCROLLBARINFO pSBar; + HWND pWin; + RECT rcBar; + + DWORD dwStyle; /* jmt:2k0820 */ + + pWin = (HWND)hWnd; + + if ( !(pSBar = wndGetScrollBar (pWin)) ) + return FALSE; + + pSBar->minPos = (iMinPos < iMaxPos)?iMinPos:iMaxPos; + pSBar->maxPos = (iMinPos > iMaxPos)?iMinPos:iMaxPos; + + /* validate parameters. */ + if (pSBar->curPos < pSBar->minPos) + pSBar->curPos = pSBar->minPos; + + if (pSBar->pageStep <= 0) + pSBar->pageStep = 0; + else if (pSBar->pageStep > (pSBar->maxPos - pSBar->minPos + 1)) + pSBar->pageStep = pSBar->maxPos - pSBar->minPos + 1; + + { + int max = pSBar->maxPos; + max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0; + + if (pSBar->curPos > max) + pSBar->curPos = max; + } + + dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ + + if (dwStyle == SBS_VERT) + { + wndGetVScrollBarRect (pWin, &rcBar); + rcBar.left --; + rcBar.right --; + } + else + { + wndGetHScrollBarRect (pWin, &rcBar); + rcBar.top --; + rcBar.bottom --; + } + wndScrollBarPos (pWin, dwStyle == SBS_HORZ, &rcBar); + +#if 0 + SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar)); +#else + MwPaintScrollbars(hWnd,NULL,dwStyle); /* a must */ +#endif + + return TRUE; +} + +BOOL SetScrollInfoEx (HWND hWnd, int iSBar, + LPCSCROLLINFO lpsi, BOOL fRedraw) /* jmt: iSBar not used */ +{ + PMWSCROLLBARINFO pSBar; + HWND pWin; + RECT rcBar; + + DWORD dwStyle; /* jmt:2k0820 */ + + pWin = (HWND)hWnd; + + if ( !(pSBar = wndGetScrollBar (pWin)) ) + return FALSE; + + if( lpsi->fMask & SIF_RANGE ) + { + pSBar->minPos = (lpsi->nMin < lpsi->nMax)?lpsi->nMin:lpsi->nMax; + pSBar->maxPos = (lpsi->nMin < lpsi->nMax)?lpsi->nMax:lpsi->nMin; + } + + if( lpsi->fMask & SIF_POS ) + pSBar->curPos = lpsi->nPos; + + if( lpsi->fMask & SIF_PAGE ) + pSBar->pageStep = lpsi->nPage; + + /* validate parameters. */ + if (pSBar->curPos < pSBar->minPos) + pSBar->curPos = pSBar->minPos; + + if (pSBar->pageStep <= 0) + pSBar->pageStep = 0; + else if (pSBar->pageStep > (pSBar->maxPos - pSBar->minPos + 1)) + pSBar->pageStep = pSBar->maxPos - pSBar->minPos + 1; + + { + int max = pSBar->maxPos; + max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0; + + if (pSBar->curPos > max) + pSBar->curPos = max; + } + + dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ + + if(fRedraw) + { + if (dwStyle == SBS_VERT) + { + wndGetVScrollBarRect (pWin, &rcBar); + rcBar.left --; + rcBar.right --; + } + else + { + wndGetHScrollBarRect (pWin, &rcBar); + rcBar.top --; + rcBar.bottom --; + } + wndScrollBarPos (pWin, dwStyle == SBS_HORZ, &rcBar); + +#if 0 + SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar)); +#else + MwPaintScrollbars(hWnd,NULL,dwStyle); /* a must */ +#endif + } + + return TRUE; +} + +BOOL GetScrollInfoEx(HWND hWnd, int iSBar, LPSCROLLINFO lpsi) /* jmt: iSBar not used */ +{ + PMWSCROLLBARINFO pSBar; + HWND pWin; + + pWin = (HWND)hWnd; + + if ( !(pSBar = wndGetScrollBar (pWin)) ) + return FALSE; + + if( lpsi->fMask & SIF_RANGE ) + { + lpsi->nMin = pSBar->minPos; + lpsi->nMax = pSBar->maxPos; + } + + if( lpsi->fMask & SIF_POS ) + { + lpsi->nPos = pSBar->curPos; + } + + if( lpsi->fMask & SIF_PAGE ) + lpsi->nPage = pSBar->pageStep; + + return TRUE; +} + +BOOL ShowScrollBarEx (HWND hWnd, int iSBar, BOOL bShow) /* jmt: iSBar not used */ +{ + PMWSCROLLBARINFO pSBar; + HWND pWin; + BOOL bPrevState; + RECT rcBar; + + DWORD dwStyle; /* jmt:2k0820 */ + + pWin = (HWND)hWnd; + + if ( !(pSBar = wndGetScrollBar (pWin)) ) + return FALSE; + + bPrevState = !(pSBar->status & SBS_HIDE); + + if (bShow && !bPrevState) + pSBar->status &= ~SBS_HIDE; + else if (!bShow && bPrevState) + pSBar->status |= SBS_HIDE; + else + return FALSE; + +#if 0 /* fix: no WM_CHANGESIZE */ + SendMessage (hWnd, WM_CHANGESIZE, 0, 0); +#endif + + dwStyle = (GetWindowStyle (hWnd) & SBS_TYPEMASK); /* jmt: 2k0820 */ + + if (dwStyle == SBS_VERT) + wndGetVScrollBarRect (pWin, &rcBar); + else + wndGetHScrollBarRect (pWin, &rcBar); + + { + RECT rcWin, rcClient; + + memcpy (&rcWin, &pWin->winrect.left, sizeof (RECT)); + + rcClient.left = 0; + rcClient.top = 0; + rcClient.right = pWin->clirect.right - pWin->clirect.left; + rcClient.bottom = pWin->clirect.bottom - pWin->clirect.top; +#if 0 /* fix: no WM_SIZECHANGED */ + SendMessage (hWnd, WM_SIZECHANGED, + (WPARAM)&rcWin, (LPARAM)&rcClient); +#endif + } + + if (bShow) { + SendMessage (hWnd, WM_NCPAINT, 0, 0); + } + else { + rcBar.left -= pWin->clirect.left; + rcBar.top -= pWin->clirect.top; + rcBar.right -= pWin->clirect.left; + rcBar.bottom -= pWin->clirect.top; + SendMessage (hWnd, WM_NCPAINT, 0, 0); + InvalidateRect (hWnd, &rcBar, TRUE); + } + + return TRUE; +} + +static void sbSetScrollInfo (HWND hwnd, PMWSCROLLBARINFO pData, BOOL fRedraw) /* jmt:2k0820 */ +{ + SCROLLINFO si; + + int itemCount,itemVisibles; + + itemCount = pData->maxPos - pData->minPos + 1; + itemVisibles = pData->pageStep; + + if (itemVisibles >= itemCount) + { + SetScrollPosEx (hwnd, 0, 0); /* jmt: arg2 not used */ + EnableScrollBarEx (hwnd, 0, FALSE); /* jmt: arg2 not used */ + return; + } + + si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + si.nMax = itemCount - 1; + si.nMin = 0; + + si.nPage = itemVisibles; /* jmt(2k0819): new algorithm for SB_THUMBTRACK */ + + si.nPos = pData->curPos; + + SetScrollInfoEx (hwnd, 0, &si, fRedraw); /* jmt: arg2 not used */ + EnableScrollBarEx (hwnd, 0, TRUE); /* jmt: arg2 not used */ +} + +static LRESULT CALLBACK +ScrollbarControlProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) /* jmt:2k0820 */ +{ + DWORD dwStyle; + MWSCROLLBARINFO* pData; + + int moveRange; + RECT rcBar; + + dwStyle = (GetWindowStyle (hwnd) & SBS_TYPEMASK); + switch (message) + { + case WM_CREATE: + if (!(pData = malloc (sizeof (MWSCROLLBARINFO)))) + { + fprintf(stderr, "Create scroll bar control failure!\n"); + return -1; + } + + pData->minPos=0; /* min value of scroll range.*/ + /* max value of scroll range.*/ + pData->maxPos=0; + if (dwStyle==SBS_VERT) + moveRange=((hwnd->winrect.bottom-hwnd->winrect.top) + -((hwnd->winrect.right-hwnd->winrect.left)<<1)); + else + moveRange=((hwnd->winrect.right-hwnd->winrect.left) + -((hwnd->winrect.bottom-hwnd->winrect.top)<<1)); + if (moveRange > MWM_MINBARLEN) + { + + + pData->maxPos=moveRange / MWM_MINBARLEN; + if( (moveRange % MWM_MINBARLEN) ) + pData->maxPos++; + } + printf("maxPos=%d\n",pData->maxPos); + + pData->curPos=0; /* current scroll pos.*/ + + /* steps per page.*/ + pData->pageStep=1; + if ( (pData->maxPos - 2) > 1) + pData->pageStep = pData->maxPos - 2; + printf("pageStep=%d\n",pData->pageStep); + + pData->barStart=0; /* start pixel of bar.*/ + pData->barLen=MWM_MINBARLEN; /* length of bar.*/ + pData->status=SBS_UNKNOWN; /* status of scroll bar.*/ +#if 0 /* jmt: must handle WM_MOVE */ + pData->rc=hwnd->winrect; /* screen coordinates position*/ +#endif + hwnd->userdata = (DWORD)pData; + + if (dwStyle == SBS_VERT) + { + wndGetVScrollBarRect (hwnd, &rcBar); + rcBar.left --; + rcBar.right --; + } + else + { + wndGetHScrollBarRect (hwnd, &rcBar); + rcBar.top --; + rcBar.bottom --; + } + /* adjust pData->barLen */ + wndScrollBarPos (hwnd, dwStyle == SBS_HORZ, &rcBar); + + break; + + case WM_DESTROY: + free ((void *)(hwnd->userdata)); + break; + + case WM_PAINT: + MwPaintScrollbars(hwnd,NULL,dwStyle); + break; + + case WM_NCLBUTTONDOWN: + case WM_NCLBUTTONDBLCLK: + case WM_NCMOUSEMOVE: + case WM_NCLBUTTONUP: + MwHandleMessageScrollbar(hwnd, wParam, lParam, message, dwStyle); + break; + + case WM_HSCROLL: + case WM_VSCROLL: + { + int newTop,itemCount,itemVisibles; + + pData = (MWSCROLLBARINFO *)hwnd->userdata; + newTop = pData->curPos; + itemCount = pData->maxPos - pData->minPos + 1; + itemVisibles = pData->pageStep; + + switch(wParam) + { + case SB_LINEDOWN: +#define ITEM_BOTTOM(x) (x->curPos + itemVisibles - 1) + if (ITEM_BOTTOM (pData) < (itemCount - 1 )) + { + newTop ++; + } + break; + + case SB_LINEUP: + if (pData->curPos > 0) + { + newTop --; + } + break; + + case SB_PAGEDOWN: + if ((pData->curPos + (itemVisibles << 1)) <= + itemCount) + newTop += itemVisibles; + else + newTop = itemCount - itemVisibles; + + if (newTop < 0) + return 0; + + break; + + case SB_PAGEUP: + if (pData->curPos >= itemVisibles) + newTop -= itemVisibles; + else + newTop = 0; + + break; + + case SB_THUMBTRACK: + newTop = (int)lParam; + break; + } + + pData->curPos = newTop; + + SendMessage (hwnd, WM_PAINT, 0, 0); + + sbSetScrollInfo (hwnd, pData, TRUE); + + return 0; + } + break; + + default: + return DefWindowProc (hwnd, message, wParam, lParam); + } + return 0; +} +
