]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/mwin/winsbar.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / mwin / winsbar.c
1 /*
2  * Copyright (c) 2000 Greg Haerr <greg@censoft.com>
3  * Portions Copyright (c) 1999, 2000, Wei Yongming.
4  * jmt: scrollbar thumb ported
5  *
6  * Microwindows win32 NonClient Scrollbars
7  */
8 #define MWINCLUDECOLORS
9 #include "windows.h"
10 #include "wintern.h"
11 #include "wintools.h"
12 #include <stdlib.h>
13 #include <string.h>
14 #include <stdio.h>
15
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
31
32 #define HSCROLLBARVISIBLE(hwnd) ((hwnd)->style & WS_HSCROLL)
33 #define VSCROLLBARVISIBLE(hwnd) ((hwnd)->style & WS_VSCROLL)
34
35 /* 
36  * Adjust client area smaller if scrollbars visible.
37  * Also, compute the NC hittest regions for the scrollbars.
38  */
39 void
40 MwAdjustNCScrollbars(HWND hwnd)
41 {
42         BOOL    vertbar = VSCROLLBARVISIBLE(hwnd);
43         BOOL    horzbar = HSCROLLBARVISIBLE(hwnd);
44
45         if (vertbar) {
46                 hwnd->clirect.right -= mwSYSMETRICS_CXVSCROLL;
47                 if (horzbar)
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;
54         } else
55                 SetRectEmpty(&hwnd->vscroll.rc);
56         if (horzbar) {
57                 if (!vertbar)
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;
64         } else
65                 SetRectEmpty(&hwnd->hscroll.rc);
66 }
67
68 static int
69 wndGetBorder(HWND hwnd)
70 {
71         if (hwnd->style & WS_BORDER)  {
72                 if ((hwnd->style & WS_CAPTION) == WS_CAPTION)
73                         return mwSYSMETRICS_CXFRAME;
74                 return mwSYSMETRICS_CXBORDER;
75         }
76         return 0;
77 }
78
79 static BOOL
80 wndGetVScrollBarRect (HWND hwnd, RECT* rcVBar)
81 {
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);
88
89         if (hwnd->style & WS_HSCROLL && !(hwnd->hscroll.status & SBS_HIDE))
90             rcVBar->bottom -= mwSYSMETRICS_CYHSCROLL;
91         
92         return TRUE;
93     }
94     
95     return FALSE;
96 }
97
98 static BOOL
99 wndGetHScrollBarRect (HWND hwnd, RECT* rcHBar)
100 {
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);
107
108         if (hwnd->style & WS_VSCROLL && !(hwnd->vscroll.status & SBS_HIDE))
109             rcHBar->right -= mwSYSMETRICS_CXVSCROLL;
110
111         return TRUE;
112     }
113     
114     return FALSE;
115 }
116
117 void
118 MwPaintNCScrollbars(HWND hwnd, HDC hdc)
119 {
120         BOOL    vertbar = VSCROLLBARVISIBLE(hwnd);
121         BOOL    horzbar = HSCROLLBARVISIBLE(hwnd);
122         BOOL    fGotDC = FALSE;
123         RECT    rc,rc2;
124
125         POINT   p3[3];
126         int     shrink=2;
127
128         int start = 0;
129         RECT rcHBar, rcVBar;
130
131
132         if (!hdc && (horzbar || vertbar)) {
133                 hdc = GetWindowDC(hwnd);
134                 fGotDC = TRUE;
135         }
136
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));
143         }
144         if (vertbar) {
145                 rc = hwnd->vscroll.rc;
146 #if 1
147                 /* bkgnd */
148                 rc2.left=rc.left; rc2.right=rc2.left+ mwSYSMETRICS_CXVSCROLL;
149                 rc2.top=rc.top;
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));
155 #endif
156                 /* up */
157                 Draw3dUpDownState(hdc, rc.left, rc.top,
158                         mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
159                         hwnd->vscroll.status & SBS_UPARROW);
160                 /* down */
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));
166                 /* up */
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;
173                 Polygon(hdc,p3,3);
174                 /* down */
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;
181                 Polygon(hdc,p3,3);
182
183                 /* draw moving bar */
184
185                 wndGetVScrollBarRect (hwnd, &rcVBar);
186                 rcVBar.left -- ;
187                 rcVBar.right -- ;
188
189                 start = rcVBar.top + mwSYSMETRICS_CYVSCROLL + hwnd->vscroll.barStart;
190                     
191                 if (start + hwnd->vscroll.barLen > rcVBar.bottom)
192                         start = rcVBar.bottom - hwnd->vscroll.barLen;
193
194                 if (hwnd->vscroll.barLen == 0)
195                         hwnd->vscroll.barLen=rc.bottom-rc.top-(mwSYSMETRICS_CYVSCROLL*2); 
196                 
197                 /* bkgnd */
198                 rc2.left=rc.left; rc2.right=rc.right/*-1*/;
199                 rc2.top=rc.top+mwSYSMETRICS_CYHSCROLL;
200                 rc2.bottom=start;
201                 if (rc2.bottom>rc2.top)
202                         FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));   
203
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));   
208
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);*/
214         }
215         if (horzbar) {
216                 rc = hwnd->hscroll.rc;
217
218 #if 1
219                 /* bkgnd */
220                 rc2.top=rc.top; rc2.bottom=rc2.top+ mwSYSMETRICS_CYHSCROLL;
221                 rc2.left=rc.left;
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));
227 #endif
228
229                 /* left */
230                 Draw3dUpDownState(hdc, rc.left, rc.top,
231                         mwSYSMETRICS_CXVSCROLL, mwSYSMETRICS_CYHSCROLL,
232                         hwnd->hscroll.status & SBS_LEFTARROW);
233                 /* right */
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));
239                 /* left */
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;
246                 Polygon(hdc,p3,3);
247                 /* right */
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;
254                 Polygon(hdc,p3,3);
255
256                 /* draw moving bar. */
257
258                 wndGetHScrollBarRect (hwnd, &rcHBar);
259                 rcHBar.top -- ;
260                 rcHBar.bottom -- ;
261
262                 start = rcHBar.left + mwSYSMETRICS_CXHSCROLL + hwnd->hscroll.barStart;
263
264                 if (start + hwnd->hscroll.barLen > rcHBar.right)
265                         start = rcHBar.right - hwnd->hscroll.barLen;
266
267                 if (hwnd->hscroll.barLen == 0)
268                         hwnd->hscroll.barLen=rc.right-rc.left-(mwSYSMETRICS_CXHSCROLL*2); 
269
270                 /* bkgnd */
271                 rc2.top=rc.top; rc2.bottom=rc.bottom/*-1*/;
272                 rc2.left=rc.left+mwSYSMETRICS_CXVSCROLL;
273                 rc2.right=start;
274                 if (rc2.right>rc2.left)
275                         FillRect(hdc, &rc2, (HBRUSH)GetStockObject(DKGRAY_BRUSH));   
276
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));   
281
282                 Draw3dUpFrame (hdc, start, rcHBar.top, start + hwnd->hscroll.barLen,
283                         rcHBar.bottom);
284                 /*printf("barh:(l,t,r,b):(%d,%d,%d,%d)\n",
285                         start, rcHBar.top, start + hwnd->hscroll.barLen,
286                         rcHBar.bottom);*/
287
288         }
289
290         if (fGotDC)
291                 ReleaseDC(hwnd, hdc);
292 }
293
294 /* handle a non-client message for a scrollbar*/
295 void
296 MwHandleNCMessageScrollbar(HWND hwnd, UINT msg, WPARAM hitcode, LPARAM lParam)
297 {
298         int     pos = SBS_UNKNOWN;
299         BOOL    vertbar = VSCROLLBARVISIBLE(hwnd);
300         BOOL    horzbar = HSCROLLBARVISIBLE(hwnd);
301         int *   pStat;
302         POINT   pt;
303         RECT    rc;
304
305         static BOOL bDraw;
306
307         static int downPos = SBS_UNKNOWN;
308         static int sbCode;
309         int newThumbPos;
310
311         int itemMoveable,itemCount,itemVisible,moveRange;       /* jmt:2k0819 */
312         int moveTop,moveBottom,moveLeft,moveRight;      /* jmt:2k0819 */
313
314         POINTSTOPOINT(pt, lParam);
315         for (;;) {      /* use for() to allow break statement*/
316                 if (hitcode == HTVSCROLL && vertbar) 
317                 {
318                         pStat = &hwnd->vscroll.status;
319                         rc = hwnd->vscroll.rc;
320                         rc.bottom = rc.top + mwSYSMETRICS_CYVSCROLL;
321                         if (PtInRect(&rc, pt)) 
322                         {
323                                 pos = SBS_UPARROW;
324                                 break;
325                         }
326                         rc.bottom = hwnd->vscroll.rc.bottom;
327                         rc.top = rc.bottom - mwSYSMETRICS_CYVSCROLL;
328                         if (PtInRect(&rc, pt)) 
329                         {
330                                 pos = SBS_DOWNARROW;
331                                 break;
332                         }
333                         pos = SBS_VERTTHUMB;
334                 } else if (hitcode == HTHSCROLL && horzbar) 
335                 {
336                         pStat = &hwnd->hscroll.status;
337                         rc = hwnd->hscroll.rc;
338                         rc.right = rc.left + mwSYSMETRICS_CXHSCROLL;
339                         if (PtInRect(&rc, pt)) {
340                                 pos = SBS_LEFTARROW;
341                                 break;
342                         }
343                         rc.right = hwnd->hscroll.rc.right;
344                         rc.left = rc.right - mwSYSMETRICS_CXHSCROLL;
345                         if (PtInRect(&rc, pt)) {
346                                 pos = SBS_RIGHTARROW;
347                                 break;
348                         }
349                         pos = SBS_HORZTHUMB;
350                 } else
351                         return;
352                 break;
353         }
354
355         if (pos == SBS_UNKNOWN)
356                 return;
357
358         *pStat &= ~SBS_MASK;            /* remove stray mouse states*/
359
360         if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK)       /* jmt:2k0819 */
361                 *pStat |= pos;
362         else *pStat &= ~pos;
363
364         if (msg == WM_NCLBUTTONDOWN || msg == WM_NCLBUTTONDBLCLK)       /* jmt:2k0819 */
365                 bDraw=TRUE;
366
367         if (bDraw)
368                 MwPaintNCScrollbars(hwnd, NULL);
369
370         if (pos == SBS_UPARROW || pos == SBS_LEFTARROW)         /* jmt:2k0820 */
371         {
372                 if (hwnd->vscroll.curPos != hwnd->vscroll.minPos)
373                         sbCode = SB_LINEUP;
374         }
375         else if (pos == SBS_DOWNARROW || pos == SBS_RIGHTARROW)         /* jmt:2k0820 */
376         {
377                 if (hwnd->vscroll.curPos != hwnd->vscroll.maxPos)
378                         sbCode = SB_LINEDOWN;
379         }
380         else if (pos == SBS_VERTTHUMB || pos == SBS_HORZTHUMB)
381         {
382                 sbCode = SB_THUMBTRACK;
383         }
384
385         switch(msg)
386         {
387         case WM_NCLBUTTONDOWN:
388         case WM_NCLBUTTONDBLCLK:        /* jmt:2k0819 */
389             downPos = pos;
390 #if MWCLIENT
391             InvalidateRect(hwnd,NULL,TRUE);
392 #endif
393         break;
394
395         case WM_NCMOUSEMOVE:    /* jmt:2k0819 */
396             if (hitcode == HTVSCROLL && vertbar) 
397             {
398                 if (sbCode == SB_THUMBTRACK && downPos == SBS_VERTTHUMB)
399                 {
400                         /* jmt(2k0819): new algorithm for SB_THUMBTRACK */
401
402                         rc = hwnd->vscroll.rc;
403                         moveTop = rc.top + mwSYSMETRICS_CYVSCROLL;
404                         moveBottom = hwnd->vscroll.rc.bottom - mwSYSMETRICS_CYVSCROLL;
405                         moveRange = moveBottom - moveTop;
406
407                         itemCount = hwnd->vscroll.maxPos - hwnd->vscroll.minPos + 1;
408                         itemVisible = hwnd->vscroll.pageStep;
409                         itemMoveable = itemCount - itemVisible + 1;
410
411                         newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange;
412                         printf("((%d-%d)*%d)/%d=%d\n",
413                                 pt.y,moveTop,itemMoveable,moveRange,newThumbPos);
414
415                         if ( newThumbPos >= hwnd->vscroll.minPos &&
416                              newThumbPos <= hwnd->vscroll.maxPos)
417                                 SendMessage (hwnd,
418                                         WM_VSCROLL, SB_THUMBTRACK, newThumbPos);
419                         break;
420                 }
421             }
422
423             if (hitcode == HTHSCROLL && horzbar) 
424             {
425                 if (sbCode == SB_THUMBTRACK && downPos == SBS_HORZTHUMB)
426                 {
427                         /* jmt(2k0819): new algorithm for SB_THUMBTRACK */
428
429                         rc = hwnd->hscroll.rc;
430                         moveLeft = rc.left + mwSYSMETRICS_CXHSCROLL;
431                         moveRight = hwnd->hscroll.rc.right - mwSYSMETRICS_CXHSCROLL;
432                         moveRange = moveRight - moveLeft;
433
434                         itemCount = hwnd->hscroll.maxPos - hwnd->hscroll.minPos + 1;
435                         itemVisible = hwnd->hscroll.pageStep;
436                         itemMoveable = itemCount - itemVisible + 1;
437
438                         newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange;
439                         printf("((%d-%d)*%d)/%d=%d\n",
440                                 pt.y,moveLeft,itemMoveable,moveRange,newThumbPos);
441     
442                         if ( newThumbPos >= hwnd->hscroll.minPos &&
443                              newThumbPos <= hwnd->hscroll.maxPos)
444                                 SendMessage (hwnd,
445                                         WM_HSCROLL, SB_THUMBTRACK, newThumbPos);
446                         break;
447                 }
448              }
449
450         break;
451
452         case WM_NCLBUTTONUP:    /* jmt:2k0819 */
453             bDraw=FALSE;
454             downPos = SBS_UNKNOWN;
455
456             if (sbCode==SB_THUMBTRACK)
457             {
458                     if (hitcode == HTVSCROLL && vertbar) 
459                     {
460                         /* jmt(2k0819): new algorithm for SB_THUMBTRACK */
461
462                         rc = hwnd->vscroll.rc;
463                         moveTop = rc.top + mwSYSMETRICS_CYVSCROLL;
464                         moveBottom = hwnd->vscroll.rc.bottom - mwSYSMETRICS_CYVSCROLL;
465                         moveRange = moveBottom - moveTop;
466
467                         itemCount = hwnd->vscroll.maxPos - hwnd->vscroll.minPos + 1;
468                         itemVisible = hwnd->vscroll.pageStep;
469                         itemMoveable = itemCount - itemVisible + 1;
470
471                         newThumbPos = ((pt.y - moveTop) * itemMoveable) / moveRange;
472                         printf("((%d-%d)*%d)/%d=%d\n",
473                                 pt.y,moveTop,itemMoveable,moveRange,newThumbPos);
474
475                         if ( newThumbPos >= hwnd->vscroll.minPos &&
476                              newThumbPos <= hwnd->vscroll.maxPos)
477                                 SendMessage (hwnd,
478                                         WM_VSCROLL, SB_THUMBTRACK, newThumbPos);
479                         break;
480                     }
481
482                     if (hitcode == HTHSCROLL && horzbar) 
483                     {
484                         /* jmt(2k0819): new algorithm for SB_THUMBTRACK */
485
486                         rc = hwnd->hscroll.rc;
487                         moveLeft = rc.left + mwSYSMETRICS_CXHSCROLL;
488                         moveRight = hwnd->hscroll.rc.right - mwSYSMETRICS_CXHSCROLL;
489                         moveRange = moveRight - moveLeft;
490
491                         itemCount = hwnd->hscroll.maxPos - hwnd->hscroll.minPos + 1;
492                         itemVisible = hwnd->hscroll.pageStep;
493                         itemMoveable = itemCount - itemVisible + 1;
494
495                         newThumbPos = ((pt.x - moveLeft) * itemMoveable) / moveRange;
496                         printf("((%d-%d)*%d)/%d=%d\n",
497                                 pt.y,moveLeft,itemMoveable,moveRange,newThumbPos);
498     
499                         if ( newThumbPos >= hwnd->hscroll.minPos &&
500                              newThumbPos <= hwnd->hscroll.maxPos)
501                                 SendMessage (hwnd,
502                                         WM_HSCROLL, SB_THUMBTRACK, newThumbPos);
503                         break;
504                     }
505              }
506              else       /* jmt:2k0820 */
507              {
508                     if (hitcode == HTVSCROLL && vertbar) 
509                         SendMessage (hwnd, WM_VSCROLL, sbCode, 0);
510
511                     if (hitcode == HTHSCROLL && horzbar) 
512                         SendMessage (hwnd, WM_HSCROLL, sbCode, 0);
513              }
514         break;
515         }
516
517 }
518
519
520 static BOOL
521 PtInRect2(const RECT *lprc, int x, int y)
522 {
523         POINT   p;
524
525         p.x = x;
526         p.y = y;
527         return PtInRect(lprc, p);
528 }
529
530 #if 1   /* 0000 */
531
532
533 static void
534 wndScrollBarPos (HWND hwnd, BOOL bIsHBar, RECT* rcBar)
535 {
536     UINT moveRange;
537     PMWSCROLLBARINFO pSBar;
538
539     if (bIsHBar)
540         pSBar = &hwnd->hscroll;
541     else
542         pSBar = &hwnd->vscroll;
543
544     if (pSBar->minPos == pSBar->maxPos) {
545         pSBar->status |= SBS_HIDE;
546         return;
547     }
548
549     if (bIsHBar)
550         moveRange = (rcBar->right - rcBar->left) - (mwSYSMETRICS_CXHSCROLL<<1);
551     else
552         moveRange = (rcBar->bottom - rcBar->top) - (mwSYSMETRICS_CYVSCROLL<<1);
553
554 #define MWM_DEFBARLEN   18
555 #define MWM_MINBARLEN   8
556
557     if (pSBar->pageStep == 0) 
558     {
559         pSBar->barLen = MWM_DEFBARLEN;
560
561         if (pSBar->barLen > moveRange)
562             pSBar->barLen = MWM_MINBARLEN;
563     }
564     else 
565     {
566         pSBar->barLen = moveRange * pSBar->pageStep /
567               (pSBar->maxPos - pSBar->minPos + 1);
568         if (pSBar->barLen < MWM_MINBARLEN)
569             pSBar->barLen = MWM_MINBARLEN;
570     }
571
572     pSBar->barStart = moveRange * (pSBar->curPos - pSBar->minPos) /
573        (pSBar->maxPos - pSBar->minPos + 1);
574
575
576     if (pSBar->barStart + pSBar->barLen > moveRange)
577         pSBar->barStart = moveRange - pSBar->barLen;
578
579
580     if (pSBar->barStart < 0)
581         pSBar->barStart = 0;
582 }
583
584 static PMWSCROLLBARINFO wndGetScrollBar (HWND pWin, int iSBar)
585 {
586     if (iSBar == SB_HORZ) {
587         if (pWin->style & WS_HSCROLL)
588             return &pWin->hscroll;
589     }
590     else if (iSBar == SB_VERT) {
591         if (pWin->style & WS_VSCROLL)
592             return &pWin->vscroll;
593     }
594
595     return NULL;
596 }
597
598 BOOL  EnableScrollBar (HWND hWnd, int iSBar, BOOL bEnable)
599 {
600     PMWSCROLLBARINFO pSBar;
601     HWND pWin;
602     BOOL bPrevState;
603     RECT rcBar;
604     
605     pWin = (HWND)hWnd;
606     
607     if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
608         return FALSE;
609
610     bPrevState = !(pSBar->status & SBS_DISABLED);
611
612     if (bEnable && !bPrevState)
613         pSBar->status &= ~SBS_DISABLED;
614     else if (!bEnable && bPrevState)
615         pSBar->status |= SBS_DISABLED;
616     else
617         return FALSE;
618
619     if (iSBar == SB_VERT)
620     {
621         wndGetVScrollBarRect (pWin, &rcBar);
622         rcBar.left --;
623         rcBar.right --;
624     }
625     else
626     {
627         wndGetHScrollBarRect (pWin, &rcBar);
628         rcBar.top  --;
629         rcBar.bottom --;
630     }
631 #if 0
632     SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar));
633 #else
634     MwPaintNCScrollbars(hWnd,NULL);     /* a must */
635 #endif
636
637     return TRUE;
638 }
639
640 BOOL  GetScrollPos (HWND hWnd, int iSBar, int* pPos)
641 {
642     PMWSCROLLBARINFO pSBar;
643     HWND pWin;
644     
645     pWin = (HWND)hWnd;
646     
647     if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
648         return FALSE;
649
650     *pPos = pSBar->curPos;
651     return TRUE;
652 }
653
654 BOOL  GetScrollRange (HWND hWnd, int iSBar, int* pMinPos, int* pMaxPos)
655 {
656     PMWSCROLLBARINFO pSBar;
657     HWND pWin;
658     
659     pWin = (HWND)hWnd;
660     
661     if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
662         return FALSE;
663
664     *pMinPos = pSBar->minPos;
665     *pMaxPos = pSBar->maxPos;
666     return TRUE;
667 }
668
669 BOOL  SetScrollPos (HWND hWnd, int iSBar, int iNewPos)
670 {
671     PMWSCROLLBARINFO pSBar;
672     HWND pWin;
673     RECT rcBar;
674     
675     pWin = (HWND)hWnd;
676     
677     if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
678         return FALSE;
679
680     if (iNewPos < pSBar->minPos)
681         pSBar->curPos = pSBar->minPos;
682     else
683         pSBar->curPos = iNewPos;
684
685     {
686         int max = pSBar->maxPos;
687         max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0;
688
689         if (pSBar->curPos > max)
690             pSBar->curPos = max;
691     }
692     
693     if (iSBar == SB_VERT)
694     {
695         wndGetVScrollBarRect (pWin, &rcBar);
696         rcBar.left --;
697         rcBar.right --;
698     }
699     else
700     {
701         wndGetHScrollBarRect (pWin, &rcBar);
702         rcBar.top  --;
703         rcBar.bottom --;
704     }
705
706     wndScrollBarPos (pWin, iSBar == SB_HORZ, &rcBar);
707
708 #if 0
709     SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar));
710 #else
711     MwPaintNCScrollbars(hWnd,NULL);     /* a must */
712 #endif
713     return TRUE;
714 }
715
716 BOOL  SetScrollRange (HWND hWnd, int iSBar, int iMinPos, int iMaxPos)
717 {
718     PMWSCROLLBARINFO pSBar;
719     HWND pWin;
720     RECT rcBar;
721     
722     pWin = (HWND)hWnd;
723     
724     if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
725         return FALSE;
726
727     pSBar->minPos = (iMinPos < iMaxPos)?iMinPos:iMaxPos;
728     pSBar->maxPos = (iMinPos > iMaxPos)?iMinPos:iMaxPos;
729     
730     /* validate parameters. */
731     if (pSBar->curPos < pSBar->minPos)
732         pSBar->curPos = pSBar->minPos;
733
734     if (pSBar->pageStep <= 0)
735         pSBar->pageStep = 0;
736     else if (pSBar->pageStep > (pSBar->maxPos - pSBar->minPos + 1))
737         pSBar->pageStep = pSBar->maxPos - pSBar->minPos + 1;
738     
739     {
740         int max = pSBar->maxPos;
741         max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0;
742
743         if (pSBar->curPos > max)
744             pSBar->curPos = max;
745     }
746
747     if (iSBar == SB_VERT)
748     {
749         wndGetVScrollBarRect (pWin, &rcBar);
750         rcBar.left --;
751         rcBar.right --;
752     }
753     else
754     {
755         wndGetHScrollBarRect (pWin, &rcBar);
756         rcBar.top  --;
757         rcBar.bottom --;
758     }
759     wndScrollBarPos (pWin, iSBar == SB_HORZ, &rcBar);
760
761 #if 0
762     SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar));
763 #else
764     MwPaintNCScrollbars(hWnd,NULL);     /* a must */
765 #endif
766
767     return TRUE;
768 }
769
770 BOOL  SetScrollInfo (HWND hWnd, int iSBar, 
771                 LPCSCROLLINFO lpsi, BOOL fRedraw)
772 {
773     PMWSCROLLBARINFO pSBar;
774     HWND pWin;
775     RECT rcBar;
776     
777     pWin = (HWND)hWnd;
778     
779     if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
780         return FALSE;
781         
782     if( lpsi->fMask & SIF_RANGE )
783     {
784         pSBar->minPos = (lpsi->nMin < lpsi->nMax)?lpsi->nMin:lpsi->nMax;
785         pSBar->maxPos = (lpsi->nMin < lpsi->nMax)?lpsi->nMax:lpsi->nMin;
786     }
787     
788     if( lpsi->fMask & SIF_POS )
789         pSBar->curPos = lpsi->nPos;
790     
791     if( lpsi->fMask & SIF_PAGE )
792         pSBar->pageStep = lpsi->nPage;
793
794     /* validate parameters. */
795     if (pSBar->curPos < pSBar->minPos)
796         pSBar->curPos = pSBar->minPos;
797
798     if (pSBar->pageStep <= 0)
799         pSBar->pageStep = 0;
800     else if (pSBar->pageStep > (pSBar->maxPos - pSBar->minPos + 1))
801         pSBar->pageStep = pSBar->maxPos - pSBar->minPos + 1;
802     
803     {
804         int max = pSBar->maxPos;
805         max -= ((pSBar->pageStep - 1) > 0)?(pSBar->pageStep - 1):0;
806
807         if (pSBar->curPos > max)
808             pSBar->curPos = max;
809     }
810
811     if(fRedraw)
812     {
813         if (iSBar == SB_VERT)
814         {
815             wndGetVScrollBarRect (pWin, &rcBar);
816             rcBar.left --;
817             rcBar.right --;
818         }
819         else
820         {
821             wndGetHScrollBarRect (pWin, &rcBar);
822             rcBar.top --;
823             rcBar.bottom --;
824         }
825         wndScrollBarPos (pWin, iSBar == SB_HORZ, &rcBar);
826
827 #if 0
828         SendMessage (hWnd, WM_NCPAINT, 0, (LPARAM)(&rcBar));
829 #else
830         MwPaintNCScrollbars(hWnd,NULL); /* a must */
831 #endif
832     }
833     
834     return TRUE;
835 }
836
837 BOOL  GetScrollInfo(HWND hWnd, int iSBar, LPSCROLLINFO lpsi)
838 {
839     PMWSCROLLBARINFO pSBar;
840     HWND pWin;
841     
842     pWin = (HWND)hWnd;
843     
844     if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
845         return FALSE;
846         
847     if( lpsi->fMask & SIF_RANGE )
848     {
849         lpsi->nMin = pSBar->minPos;
850         lpsi->nMax = pSBar->maxPos;
851     }
852     
853     if( lpsi->fMask & SIF_POS )
854     {
855         lpsi->nPos = pSBar->curPos;
856     }
857     
858     if( lpsi->fMask & SIF_PAGE )
859         lpsi->nPage = pSBar->pageStep;
860     
861     return TRUE;
862 }
863
864 BOOL  ShowScrollBar (HWND hWnd, int iSBar, BOOL bShow)
865 {
866     PMWSCROLLBARINFO pSBar;
867     HWND pWin;
868     BOOL bPrevState;
869     RECT rcBar;
870     
871     pWin = (HWND)hWnd;
872     
873     if ( !(pSBar = wndGetScrollBar (pWin, iSBar)) )
874         return FALSE;
875
876     bPrevState = !(pSBar->status & SBS_HIDE);
877
878     if (bShow && !bPrevState)
879         pSBar->status &= ~SBS_HIDE;
880     else if (!bShow && bPrevState)
881         pSBar->status |= SBS_HIDE;
882     else
883         return FALSE;
884 #if 0   /* fix: no WM_CHANGESIZE */
885     SendMessage (hWnd, WM_CHANGESIZE, 0, 0);
886 #endif
887     if (iSBar == SB_VERT)
888         wndGetVScrollBarRect (pWin, &rcBar);
889     else
890         wndGetHScrollBarRect (pWin, &rcBar);
891
892     {
893         RECT rcWin, rcClient;
894         
895         memcpy (&rcWin, &pWin->winrect.left, sizeof (RECT));
896         
897         rcClient.left = 0;
898         rcClient.top  = 0;
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);
904 #endif
905     }
906     
907     if (bShow) {
908         SendMessage (hWnd, WM_NCPAINT, 0, 0);
909     }
910     else {
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);
917     }
918
919     return TRUE;
920 }
921 #endif