source: trunk/src/user32/scroll.cpp@ 1528

Last change on this file since 1528 was 1525, checked in by cbratschi, 26 years ago

button, static, scroll and dialog fixes

File size: 53.3 KB
Line 
1/* $Id: scroll.cpp,v 1.17 1999-10-30 18:40:45 cbratschi Exp $ */
2/*
3 * Scrollbar control
4 *
5 * Copyright 1999 Christoph Bratschi
6 *
7 * Copyright 1993 Martin Ayotte
8 * Copyright 1994, 1996 Alexandre Julliard
9 *
10 * WINE version: 990923
11 *
12 * Status: complete
13 * Version: 5.00
14 */
15
16#include <stdlib.h>
17#include <os2win.h>
18#include "controls.h"
19#include "scroll.h"
20#include "win32wbase.h"
21#include "oslibwin.h"
22#include "initterm.h"
23#include "pmframe.h"
24
25#define SCROLL_MIN_RECT 4 /* Minimum size of the rectangle between the arrows */
26#define SCROLL_MIN_THUMB 6 /* Minimum size of the thumb in pixels */
27
28#define SCROLL_ARROW_THUMB_OVERLAP 0 /* Overlap between arrows and thumb */
29
30#define SCROLL_FIRST_DELAY 200 /* Delay (in ms) before first repetition when holding the button down */
31#define SCROLL_REPEAT_DELAY 50 /* Delay (in ms) between scroll repetitions */
32#define SCROLL_BLINK_DELAY 1000
33
34#define SCROLL_TIMER 0 /* Scroll timer id */
35#define BLINK_TIMER 1
36
37 /* Scroll-bar hit testing */
38enum SCROLL_HITTEST
39{
40 SCROLL_NOWHERE, /* Outside the scroll bar */
41 SCROLL_TOP_ARROW, /* Top or left arrow */
42 SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
43 SCROLL_THUMB, /* Thumb rectangle */
44 SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
45 SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
46};
47
48 /* What to do in SetScrollInfo() */
49#define SA_SSI_HIDE 0x0001
50#define SA_SSI_SHOW 0x0002
51#define SA_SSI_REPAINT_INTERIOR 0x0004
52#define SA_SSI_REPAINT_ARROWS 0x0008
53#define SA_SSI_MOVE_THUMB 0x0010
54#define SA_SSI_REFRESH 0x0020
55
56 /* Thumb-tracking info */
57static HWND SCROLL_TrackingWin = 0;
58static INT SCROLL_TrackingBar = 0;
59static INT SCROLL_TrackingPos = 0;
60static INT SCROLL_TrackingVal = 0;
61 /* Focus info */
62static HWND SCROLL_FocusWin = 0;
63static BOOL SCROLL_HasFocus = FALSE;
64static BOOL SCROLL_Highlighted = FALSE;
65static BOOL SCROLL_Scrolling = FALSE;
66
67 /* Hit test code of the last button-down event */
68static enum SCROLL_HITTEST SCROLL_trackHitTest;
69static enum SCROLL_HITTEST SCROLL_lastHitTest;
70static BOOL SCROLL_trackVertical;
71
72 /* Is the moving thumb being displayed? */
73static BOOL SCROLL_MovingThumb = FALSE;
74
75// Get the scrollbar handle: works only with frame/control handles
76
77static HWND SCROLL_GetScrollHandle(HWND hwnd,INT nBar)
78{
79 switch(nBar)
80 {
81 case SB_HORZ:
82 case SB_VERT:
83 {
84 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
85 if (!win32wnd) return 0;
86 if (nBar == SB_HORZ) return Win32BaseWindow::OS2ToWin32Handle(win32wnd->getHorzScrollHandle());
87 else return Win32BaseWindow::OS2ToWin32Handle(win32wnd->getVertScrollHandle());
88 }
89 case SB_CTL:
90 return hwnd;
91
92 default:
93 return 0;
94 }
95}
96
97static HWND SCROLL_GetFrameHandle(HWND hwnd)
98{
99 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
100
101 if (!win32wnd) return 0;
102 return Win32BaseWindow::GetWindowFromOS2FrameHandle(OSLibWinQueryWindow(win32wnd->getOS2WindowHandle(),QWOS_OWNER))->getWindowHandle();
103}
104
105// Get the infoPtr: works only with scrollbar handles
106
107static SCROLLBAR_INFO *SCROLL_GetInfoPtr( HWND hwnd, INT nBar )
108{
109 Win32BaseWindow *win32wnd;
110 HWND hwndFrame;
111
112 switch(nBar)
113 {
114 case SB_HORZ:
115 case SB_VERT:
116 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
117 if (!win32wnd) return NULL;
118 hwndFrame = OSLibWinQueryWindow(win32wnd->getOS2WindowHandle(),QWOS_OWNER);
119 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwndFrame);
120 if (!win32wnd) return NULL;
121 return win32wnd->getScrollInfo(nBar);
122
123 case SB_CTL:
124 return (SCROLLBAR_INFO*)GetInfoPtr(hwnd);
125 }
126
127 return NULL;
128}
129
130/* Scrollbar Functions */
131
132/***********************************************************************
133 * SCROLL_GetScrollBarRect
134 *
135 * Compute the scroll bar rectangle, in drawing coordinates (i.e. client
136 * coords for SB_CTL, window coords for SB_VERT and SB_HORZ).
137 * 'arrowSize' returns the width or height of an arrow (depending on
138 * the orientation of the scrollbar), 'thumbSize' returns the size of
139 * the thumb, and 'thumbPos' returns the position of the thumb
140 * relative to the left or to the top.
141 * Return TRUE if the scrollbar is vertical, FALSE if horizontal.
142 */
143static BOOL SCROLL_GetScrollBarRect( HWND hwnd, INT nBar, RECT *lprect,
144 INT *arrowSize, INT *thumbSize,
145 INT *thumbPos )
146{
147 INT pixels;
148 BOOL vertical;
149 RECT rectClient;
150
151 switch(nBar)
152 {
153 case SB_HORZ:
154 case SB_VERT:
155 GetClientRect( hwnd, lprect );
156 vertical = (nBar == SB_VERT);
157 break;
158
159 case SB_CTL:
160 {
161 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
162
163 GetClientRect( hwnd, lprect );
164 vertical = ((dwStyle & SBS_VERT) != 0);
165 break;
166 }
167
168 default:
169 return FALSE;
170 }
171
172 if (vertical) pixels = lprect->bottom - lprect->top;
173 else pixels = lprect->right - lprect->left;
174
175 if (pixels <= 2*GetSystemMetrics(SM_CXVSCROLL) + SCROLL_MIN_RECT)
176 {
177 if (pixels > SCROLL_MIN_RECT)
178 *arrowSize = (pixels - SCROLL_MIN_RECT) / 2;
179 else
180 *arrowSize = 0;
181 *thumbPos = *thumbSize = 0;
182 }
183 else
184 {
185 SCROLLBAR_INFO *info = SCROLL_GetInfoPtr( hwnd, nBar );
186
187 *arrowSize = GetSystemMetrics(SM_CXVSCROLL);
188 pixels -= (2 * (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP));
189
190 if (info->Page)
191 {
192 *thumbSize = pixels * info->Page / (info->MaxVal-info->MinVal+1);
193 if (*thumbSize < SCROLL_MIN_THUMB) *thumbSize = SCROLL_MIN_THUMB;
194 }
195 else *thumbSize = GetSystemMetrics(SM_CXVSCROLL);
196
197 if (((pixels -= *thumbSize ) < 0) ||
198 ((info->flags & ESB_DISABLE_BOTH) == ESB_DISABLE_BOTH))
199 {
200 /* Rectangle too small or scrollbar disabled -> no thumb */
201 *thumbPos = *thumbSize = 0;
202 }
203 else
204 {
205 INT max = info->MaxVal - MAX( info->Page-1, 0 );
206 if (info->MinVal >= max)
207 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
208 else
209 *thumbPos = *arrowSize - SCROLL_ARROW_THUMB_OVERLAP
210 + pixels * (info->CurVal-info->MinVal) / (max - info->MinVal);
211 }
212 }
213 return vertical;
214}
215
216/***********************************************************************
217 * SCROLL_PtInRectEx
218 */
219static BOOL SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical )
220{
221 RECT rect = *lpRect;
222
223 if (vertical)
224 {
225 INT w = lpRect->right-lpRect->left;
226
227 rect.left -= w;
228 rect.right += w;
229 } else
230 {
231 INT h = lpRect->bottom-lpRect->top;
232
233 rect.top -= h;
234 rect.bottom += h;
235 }
236
237 return PtInRect( &rect, pt );
238}
239
240/***********************************************************************
241 * SCROLL_HitTest
242 *
243 * Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!).
244 */
245static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, INT nBar,
246 POINT pt, BOOL bDragging )
247{
248 INT arrowSize, thumbSize, thumbPos;
249 RECT rect;
250
251 BOOL vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
252 &arrowSize, &thumbSize, &thumbPos );
253
254 if ( (bDragging && !SCROLL_PtInRectEx( &rect, pt, vertical )) ||
255 (!PtInRect( &rect, pt )) ) return SCROLL_NOWHERE;
256
257 if (vertical)
258 {
259 if (pt.y < rect.top + arrowSize) return SCROLL_TOP_ARROW;
260 if (pt.y >= rect.bottom - arrowSize) return SCROLL_BOTTOM_ARROW;
261 if (!thumbPos) return SCROLL_TOP_RECT;
262 pt.y -= rect.top;
263 if (pt.y < thumbPos) return SCROLL_TOP_RECT;
264 if (pt.y >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
265 }
266 else /* horizontal */
267 {
268 if (pt.x < rect.left + arrowSize) return SCROLL_TOP_ARROW;
269 if (pt.x >= rect.right - arrowSize) return SCROLL_BOTTOM_ARROW;
270 if (!thumbPos) return SCROLL_TOP_RECT;
271 pt.x -= rect.left;
272 if (pt.x < thumbPos) return SCROLL_TOP_RECT;
273 if (pt.x >= thumbPos + thumbSize) return SCROLL_BOTTOM_RECT;
274 }
275 return SCROLL_THUMB;
276}
277
278static void SCROLL_DrawTopArrow(HDC hdc,SCROLLBAR_INFO *infoPtr,RECT *rect,INT arrowSize,BOOL vertical,BOOL top_pressed)
279{
280 RECT r;
281
282 r = *rect;
283 if( vertical )
284 r.bottom = r.top + arrowSize;
285 else
286 r.right = r.left + arrowSize;
287
288 DrawFrameControl( hdc, &r, DFC_SCROLL,
289 (vertical ? DFCS_SCROLLUP : DFCS_SCROLLLEFT)
290 | (top_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0 )
291 | (infoPtr->flags&ESB_DISABLE_LTUP ? DFCS_INACTIVE : 0 ) );
292}
293
294static void SCROLL_DrawBottomArrow(HDC hdc,SCROLLBAR_INFO *infoPtr,RECT *rect,INT arrowSize,BOOL vertical,BOOL bottom_pressed)
295{
296 RECT r;
297
298 r = *rect;
299 if( vertical )
300 r.top = r.bottom-arrowSize;
301 else
302 r.left = r.right-arrowSize;
303
304 DrawFrameControl( hdc, &r, DFC_SCROLL,
305 (vertical ? DFCS_SCROLLDOWN : DFCS_SCROLLRIGHT)
306 | (bottom_pressed ? (DFCS_PUSHED | DFCS_FLAT) : 0 )
307 | (infoPtr->flags&ESB_DISABLE_RTDN ? DFCS_INACTIVE : 0) );
308}
309
310/***********************************************************************
311 * SCROLL_DrawArrows
312 *
313 * Draw the scroll bar arrows.
314 */
315static void SCROLL_DrawArrows( HDC hdc, SCROLLBAR_INFO *infoPtr,
316 RECT *rect, INT arrowSize, BOOL vertical,
317 BOOL top_pressed, BOOL bottom_pressed )
318{
319 SCROLL_DrawTopArrow(hdc,infoPtr,rect,arrowSize,vertical,top_pressed);
320 SCROLL_DrawBottomArrow(hdc,infoPtr,rect,arrowSize,vertical,bottom_pressed);
321}
322
323static void SCROLL_DrawInterior( HWND hwnd, HDC hdc, INT nBar,
324 RECT *rect, INT arrowSize,
325 INT thumbSize, INT thumbPos,
326 UINT flags, BOOL vertical,
327 BOOL top_selected, BOOL bottom_selected )
328{
329 RECT r;
330 HPEN hSavePen;
331 HBRUSH hSaveBrush,hBrush;
332
333 /* Select the correct brush and pen */
334
335 /* Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
336 * The window-owned scrollbars need to call DEFWND_ControlColor
337 * to correctly setup default scrollbar colors
338 */
339 if (nBar == SB_CTL) {
340 hBrush = (HBRUSH)SendMessageA( GetParent(hwnd), WM_CTLCOLORSCROLLBAR,
341 (WPARAM)hdc,(LPARAM)hwnd);
342 } else {
343 hBrush = (HBRUSH)SendMessageA( hwnd, WM_CTLCOLORSCROLLBAR,
344 (WPARAM)hdc,(LPARAM)hwnd);
345
346 }
347
348 hSavePen = SelectObject( hdc, GetSysColorPen(COLOR_WINDOWFRAME) );
349 hSaveBrush = SelectObject( hdc, hBrush );
350
351 /* Calculate the scroll rectangle */
352
353 r = *rect;
354 if (vertical)
355 {
356 r.top += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
357 r.bottom -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
358 }
359 else
360 {
361 r.left += arrowSize - SCROLL_ARROW_THUMB_OVERLAP;
362 r.right -= (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
363 }
364
365 /* Draw the scroll rectangles and thumb */
366 if (!thumbPos) /* No thumb to draw */
367 {
368 PatBlt( hdc, r.left, r.top,
369 r.right - r.left, r.bottom - r.top,
370 PATCOPY );
371
372 /* cleanup and return */
373 SelectObject( hdc, hSavePen );
374 SelectObject( hdc, hSaveBrush );
375 return;
376 }
377
378 if (vertical)
379 {
380 PatBlt( hdc, r.left, r.top,
381 r.right - r.left,
382 thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP),
383 top_selected ? 0x0f0000 : PATCOPY );
384 r.top += thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
385 PatBlt( hdc, r.left, r.top + thumbSize,
386 r.right - r.left,
387 r.bottom - r.top - thumbSize,
388 bottom_selected ? 0x0f0000 : PATCOPY );
389 r.bottom = r.top + thumbSize;
390 }
391 else /* horizontal */
392 {
393 PatBlt( hdc, r.left, r.top,
394 thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP),
395 r.bottom - r.top,
396 top_selected ? 0x0f0000 : PATCOPY );
397 r.left += thumbPos - (arrowSize - SCROLL_ARROW_THUMB_OVERLAP);
398 PatBlt( hdc, r.left + thumbSize, r.top,
399 r.right - r.left - thumbSize,
400 r.bottom - r.top,
401 bottom_selected ? 0x0f0000 : PATCOPY );
402 r.right = r.left + thumbSize;
403 }
404
405 /* Draw the thumb */
406
407 DrawEdge(hdc,&r,EDGE_RAISED,BF_RECT | BF_ADJUST);
408 FillRect(hdc,&r,(SCROLL_FocusWin == hwnd && SCROLL_Highlighted && !SCROLL_Scrolling) ? GetSysColorBrush(COLOR_3DSHADOW):GetSysColorBrush(COLOR_BTNFACE));
409
410 /* cleanup */
411 SelectObject( hdc, hSavePen );
412 SelectObject( hdc, hSaveBrush );
413}
414
415/***********************************************************************
416 * SCROLL_DrawMovingThumb
417 *
418 * Draw the moving thumb rectangle.
419 */
420static void SCROLL_DrawMovingThumb( HDC hdc, RECT *rect, BOOL vertical,
421 INT arrowSize, INT thumbSize )
422{
423 INT pos = SCROLL_TrackingPos;
424 INT max_size;
425
426 if( vertical )
427 max_size = rect->bottom - rect->top;
428 else
429 max_size = rect->right - rect->left;
430
431 max_size -= (arrowSize-SCROLL_ARROW_THUMB_OVERLAP) + thumbSize;
432
433 if( pos < (arrowSize-SCROLL_ARROW_THUMB_OVERLAP) )
434 pos = (arrowSize-SCROLL_ARROW_THUMB_OVERLAP);
435 else if( pos > max_size )
436 pos = max_size;
437
438 SCROLL_DrawInterior( SCROLL_TrackingWin, hdc, SCROLL_TrackingBar,
439 rect, arrowSize, thumbSize, pos,
440 0, vertical, FALSE, FALSE );
441}
442
443/***********************************************************************
444 * SCROLL_ClipPos
445 */
446static POINT SCROLL_ClipPos( LPRECT lpRect, POINT pt )
447{
448 if( pt.x < lpRect->left )
449 pt.x = lpRect->left;
450 else
451 if( pt.x >= lpRect->right )
452 pt.x = lpRect->right-1;
453
454 if( pt.y < lpRect->top )
455 pt.y = lpRect->top;
456 else
457 if( pt.y >= lpRect->bottom )
458 pt.y = lpRect->bottom-1;
459
460 return pt;
461}
462
463/***********************************************************************
464 * SCROLL_GetThumbVal
465 *
466 * Compute the current scroll position based on the thumb position in pixels
467 * from the top of the scroll-bar.
468 */
469static UINT SCROLL_GetThumbVal( SCROLLBAR_INFO *infoPtr, RECT *rect,
470 BOOL vertical, INT pos )
471{
472 INT thumbSize;
473 INT pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
474
475 if ((pixels -= 2*(GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP)) <= 0)
476 return infoPtr->MinVal;
477
478 if (infoPtr->Page)
479 {
480 thumbSize = pixels * infoPtr->Page/(infoPtr->MaxVal-infoPtr->MinVal+1);
481 if (thumbSize < SCROLL_MIN_THUMB) thumbSize = SCROLL_MIN_THUMB;
482 }
483 else thumbSize = GetSystemMetrics(SM_CXVSCROLL);
484
485 if ((pixels -= thumbSize) <= 0) return infoPtr->MinVal;
486
487 pos = MAX( 0, pos - (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP) );
488 if (pos > pixels) pos = pixels;
489
490 if (!infoPtr->Page) pos *= infoPtr->MaxVal - infoPtr->MinVal;
491 else pos *= infoPtr->MaxVal - infoPtr->MinVal - infoPtr->Page + 1;
492 return infoPtr->MinVal + ((pos + pixels / 2) / pixels);
493}
494
495void SCROLL_GetSizeBox(HWND hwnd,DWORD dwStyle,PRECT rect)
496{
497 RECT clientRect;
498 INT cx = GetSystemMetrics(SM_CXVSCROLL);
499 INT cy = GetSystemMetrics(SM_CYHSCROLL);
500
501 GetClientRect(hwnd,&clientRect);
502
503 if (dwStyle & SBS_SIZEBOXTOPLEFTALIGN)
504 {
505 rect->left = 0;
506 rect->right = cx;
507 rect->bottom = cy;
508 rect->top = 0;
509 } else
510 {
511 rect->left = clientRect.right-cx;
512 rect->right = clientRect.right;
513 rect->bottom = clientRect.bottom;
514 rect->top = clientRect.bottom-cy;
515 }
516}
517
518void SCROLL_DrawSizeBox(HDC hdc,RECT rect)
519{
520 POINT p1,p2;
521 HPEN penDark = GetSysColorPen(COLOR_3DSHADOW);
522 HPEN penWhite = GetSysColorPen(COLOR_3DHILIGHT);
523 HPEN oldPen = SelectObject(hdc,penDark);
524 INT x;
525
526 p1.x = rect.right-2;
527 p1.y = rect.bottom;
528 p2.x = rect.right-1;
529 p2.y = rect.bottom-1;
530 for (x = 0;x < 3;x++)
531 {
532 SelectObject(hdc,penDark);
533 MoveToEx(hdc,p1.x,p1.y,NULL);
534 LineTo(hdc,p2.x,p2.y);
535 p1.x--;
536 p2.y--;
537 MoveToEx(hdc,p1.x,p1.y,NULL);
538 LineTo(hdc,p2.x,p2.y);
539 SelectObject(hdc,penWhite);
540 p1.x--;
541 p2.y--;
542 MoveToEx(hdc,p1.x,p1.y,NULL);
543 LineTo(hdc,p2.x,p2.y);
544 p1.x -= 2;
545 p2.y -= 2;
546 }
547
548 SelectObject(hdc,oldPen);
549}
550
551/***********************************************************************
552 * SCROLL_DrawScrollBar
553 *
554 * Redraw the whole scrollbar.
555 */
556void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar,
557 BOOL arrows, BOOL interior )
558{
559 INT arrowSize, thumbSize, thumbPos;
560 RECT rect;
561 BOOL vertical;
562 SCROLLBAR_INFO *infoPtr = SCROLL_GetInfoPtr( hwnd, nBar );
563
564 if (!infoPtr) return;
565 if (nBar == SB_CTL)
566 {
567 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
568
569 if (dwStyle & (SBS_SIZEBOX | SBS_SIZEGRIP))
570 {
571 RECT rect;
572 HBRUSH hBrush;
573
574 hdc = GetDC(hwnd);
575 hBrush = GetSysColorBrush(COLOR_3DFACE);
576 GetClientRect(hwnd,&rect);
577 FillRect(hdc,&rect,hBrush);
578
579 if (dwStyle & SBS_SIZEGRIP)
580 {
581 SCROLL_GetSizeBox(hwnd,dwStyle,&rect);
582 SCROLL_DrawSizeBox(hdc,rect);
583 }
584
585 ReleaseDC(hwnd,hdc);
586
587 return;
588 }
589 }
590
591 vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
592 &arrowSize, &thumbSize, &thumbPos );
593
594 /* Draw the arrows */
595
596 if (arrows && arrowSize)
597 {
598 if( vertical == SCROLL_trackVertical && GetCapture() == hwnd )
599 SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize, vertical,
600 (SCROLL_trackHitTest == SCROLL_TOP_ARROW),
601 (SCROLL_trackHitTest == SCROLL_BOTTOM_ARROW) );
602 else
603 SCROLL_DrawArrows( hdc, infoPtr, &rect, arrowSize, vertical,
604 FALSE, FALSE );
605 }
606
607 if (SCROLL_MovingThumb &&
608 (SCROLL_TrackingWin == hwnd) &&
609 (SCROLL_TrackingBar == nBar))
610 SCROLL_DrawMovingThumb( hdc, &rect, vertical, arrowSize, thumbSize );
611 else if( interior )
612 SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
613 thumbPos, infoPtr->flags, vertical, SCROLL_trackHitTest == SCROLL_TOP_RECT && SCROLL_lastHitTest == SCROLL_TOP_RECT,SCROLL_trackHitTest == SCROLL_BOTTOM_RECT && SCROLL_lastHitTest == SCROLL_BOTTOM_RECT);
614}
615
616/***********************************************************************
617 * SCROLL_RefreshScrollBar
618 *
619 * Repaint the scroll bar interior after a SetScrollRange() or
620 * SetScrollPos() call.
621 */
622static void SCROLL_RefreshScrollBar( HWND hwnd, INT nBar,
623 BOOL arrows, BOOL interior )
624{
625 Win32BaseWindow *window;
626 HDC hdc;
627
628 hdc = GetDCEx( hwnd, 0, DCX_CACHE | ((nBar == SB_CTL) ? 0 : DCX_WINDOW));
629
630 if (!hdc) return;
631
632 SCROLL_DrawScrollBar( hwnd, hdc, nBar, arrows, interior );
633 ReleaseDC( hwnd, hdc );
634}
635
636/* Message Handler */
637
638LRESULT SCROLL_NCCreate(HWND hwnd,WPARAM wParam,LPARAM lParam)
639{
640 SCROLLBAR_INFO *infoPtr = (SCROLLBAR_INFO*)malloc(sizeof(SCROLLBAR_INFO));
641
642 infoPtr->MinVal = infoPtr->CurVal = infoPtr->Page = 0;
643 infoPtr->MaxVal = 100;
644 infoPtr->flags = ESB_ENABLE_BOTH;
645
646 SetInfoPtr(hwnd,(DWORD)infoPtr);
647
648 return TRUE;
649}
650
651LRESULT SCROLL_Create(HWND hwnd,WPARAM wParam,LPARAM lParam)
652{
653 CREATESTRUCTA *lpCreat = (CREATESTRUCTA *)lParam;
654
655 if (!(lpCreat->style & (SBS_SIZEBOX | SBS_SIZEGRIP)) && lpCreat->style & (SBS_LEFTALIGN | SBS_RIGHTALIGN))
656 {
657 if (lpCreat->style & SBS_VERT)
658 {
659 INT w,h;
660
661 w = GetSystemMetrics(SM_CXVSCROLL);
662 h = lpCreat->cy;
663
664 if (lpCreat->style & SBS_LEFTALIGN)
665 MoveWindow(hwnd,lpCreat->x,lpCreat->y,w,h,FALSE);
666 else if (lpCreat->style & SBS_RIGHTALIGN)
667 MoveWindow(hwnd,lpCreat->x+lpCreat->cx-w,lpCreat->y,w,h,FALSE);
668 } else /* SBS_HORZ */
669 {
670 INT w,h;
671
672 w = lpCreat->cx;
673 h = GetSystemMetrics(SM_CYHSCROLL);
674
675 if (lpCreat->style & SBS_TOPALIGN)
676 MoveWindow(hwnd,lpCreat->x,lpCreat->y,w,h,FALSE);
677 else if (lpCreat->style & SBS_BOTTOMALIGN)
678 MoveWindow(hwnd,lpCreat->x,lpCreat->y+lpCreat->cy-h,w,h,FALSE);
679 }
680 }
681
682 return 0;
683}
684
685/***********************************************************************
686 * SCROLL_HandleScrollEvent
687 *
688 * Handle a mouse or timer event for the scrollbar.
689 * 'pt' is the location of the mouse event in client (for SB_CTL) or
690 * windows coordinates.
691 */
692LRESULT SCROLL_HandleScrollEvent(HWND hwnd,WPARAM wParam,LPARAM lParam,INT nBar,UINT msg)
693{
694 static POINT prevPt; /* Previous mouse position for timer events */
695 static UINT trackThumbPos; /* Thumb position when tracking started. */
696 static INT lastClickPos; /* Position in the scroll-bar of the last button-down event. */
697 static INT lastMousePos; /* Position in the scroll-bar of the last mouse event. */
698 static BOOL timerRunning;
699
700 enum SCROLL_HITTEST hittest;
701 HWND hwndOwner, hwndCtl;
702 BOOL vertical;
703 INT arrowSize, thumbSize, thumbPos;
704 RECT rect;
705 HDC hdc;
706 POINT pt;
707 LRESULT res = (msg == WM_MOUSEMOVE) ? 1:0;
708
709 SCROLLBAR_INFO *infoPtr = SCROLL_GetInfoPtr( hwnd, nBar );
710 if (!infoPtr) return res;
711
712 if (nBar == SB_CTL)
713 {
714 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
715
716 if ((dwStyle & (SBS_SIZEBOX | SBS_SIZEGRIP)))
717 {
718 if (!(dwStyle & SBS_SIZEGRIP)) return res;
719
720 if (msg == WM_MOUSEMOVE)
721 {
722 RECT rect;
723
724 SCROLL_GetSizeBox(hwnd,dwStyle,&rect);
725 pt.x = (SHORT)LOWORD(lParam);
726 pt.y = (SHORT)HIWORD(lParam);
727
728 if (PtInRect(&rect,pt))
729 {
730 SetCursor(LoadCursorA(0,IDC_SIZENWSEA));
731 return 0;
732 }
733 } else if (msg == WM_LBUTTONDOWN)
734 {
735 if (dwStyle & SBS_SIZEGRIP)
736 {
737 RECT rect;
738
739 pt.x = (SHORT)LOWORD(lParam);
740 pt.y = (SHORT)HIWORD(lParam);
741 SCROLL_GetSizeBox(hwnd,dwStyle,&rect);
742 if (PtInRect(&rect,pt))
743 {
744 HWND hwndFrame;
745
746 Win32BaseWindow *win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
747 if (!win32wnd) return res;
748 hwndFrame = OSLibWinQueryWindow(win32wnd->getOS2WindowHandle(),QWOS_OWNER);
749 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwndFrame);
750 if (!win32wnd) return res;
751 FrameTrackFrame(win32wnd,dwStyle & SBS_SIZEBOXTOPLEFTALIGN);
752 }
753 }
754 }
755
756 return res;
757 }
758 }
759
760 if ((SCROLL_trackHitTest == SCROLL_NOWHERE) && (msg == WM_MOUSEMOVE || msg == WM_LBUTTONUP || msg == WM_CAPTURECHANGED))
761 return res;
762
763 vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
764 &arrowSize, &thumbSize, &thumbPos );
765 if (nBar == SB_CTL) hwndOwner = GetParent(hwnd); else
766 {
767 Win32BaseWindow *win32wnd;
768 HWND hwndFrame;
769
770 win32wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
771 if (!win32wnd) return res;
772 hwndFrame = OSLibWinQueryWindow(win32wnd->getOS2WindowHandle(),QWOS_OWNER);
773 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwndFrame);
774 if (!win32wnd) return res;
775 hwndOwner = win32wnd->getWindowHandle();
776 }
777
778 hwndCtl = (nBar == SB_CTL) ? hwnd : 0;
779
780 switch (msg)
781 {
782 case WM_LBUTTONDOWN: /* Initialise mouse tracking */
783 pt.x = (SHORT)LOWORD(lParam);
784 pt.y = (SHORT)HIWORD(lParam);
785 SCROLL_trackVertical = vertical;
786 SCROLL_trackHitTest = hittest = SCROLL_HitTest( hwnd, nBar, pt, FALSE );
787 SCROLL_Scrolling = TRUE;
788 timerRunning = FALSE;
789 if (SCROLL_FocusWin == hwnd && SCROLL_Highlighted)
790 {
791 hdc = GetDCEx(hwnd,0,DCX_CACHE);
792 SCROLL_DrawScrollBar(hwnd,hdc,nBar,FALSE,TRUE);
793 ReleaseDC(hwnd,hdc);
794 }
795 lastClickPos = vertical ? pt.y:pt.x;
796 lastMousePos = lastClickPos;
797 trackThumbPos = thumbPos;
798 prevPt = pt;
799 SetCapture( hwnd );
800 if (nBar == SB_CTL) SetFocus( hwnd );
801 break;
802
803 case WM_MOUSEMOVE:
804 pt.x = (SHORT)LOWORD(lParam);
805 pt.y = (SHORT)HIWORD(lParam);
806 hittest = SCROLL_HitTest( hwnd, nBar, pt, TRUE );
807 prevPt = pt;
808 break;
809
810 case WM_LBUTTONUP:
811 pt.x = (SHORT)LOWORD(lParam);
812 pt.y = (SHORT)HIWORD(lParam);
813 hittest = SCROLL_NOWHERE;
814 ReleaseCapture();
815 SCROLL_Scrolling = FALSE;
816 break;
817
818 case WM_CAPTURECHANGED:
819 hittest = SCROLL_NOWHERE;
820 SCROLL_Scrolling = FALSE;
821 break;
822
823 case WM_SETFOCUS:
824 if (nBar == SB_CTL)
825 {
826 SCROLL_FocusWin = hwnd;
827 SCROLL_HasFocus = TRUE;
828 SCROLL_Highlighted = FALSE;
829 SetSystemTimer(hwnd,BLINK_TIMER,SCROLL_BLINK_DELAY,(TIMERPROC)0);
830 }
831 return res;
832
833 case WM_KILLFOCUS:
834 if (SCROLL_FocusWin == hwnd)
835 {
836 SCROLL_FocusWin = 0;
837 SCROLL_HasFocus = FALSE;
838 if (SCROLL_Highlighted)
839 {
840 SCROLL_Highlighted = FALSE;
841 hdc = GetDCEx(hwnd,0,DCX_CACHE);
842 SCROLL_DrawScrollBar(hwnd,hdc,nBar,FALSE,TRUE);
843 ReleaseDC(hwnd,hdc);
844 }
845 KillSystemTimer(hwnd,BLINK_TIMER);
846 }
847 return res;
848
849 case WM_SYSTIMER:
850 if (wParam == SCROLL_TIMER)
851 {
852 pt = prevPt;
853 hittest = SCROLL_HitTest( hwnd, nBar, pt, FALSE );
854 break;
855 } else if (wParam == BLINK_TIMER)
856 {
857 SCROLL_Highlighted = ~SCROLL_Highlighted;
858 if (!SCROLL_Scrolling)
859 {
860 hdc = GetDCEx(hwnd,0,DCX_CACHE);
861 SCROLL_DrawScrollBar(hwnd,hdc,nBar,FALSE,TRUE);
862 ReleaseDC(hwnd,hdc);
863 }
864 return res;
865 } else return res;
866
867 default:
868 return res; /* Should never happen */
869 }
870
871 hdc = GetDCEx(hwnd,0,DCX_CACHE | ((nBar == SB_CTL) ? 0:DCX_WINDOW));
872
873 //TRACE("Event: hwnd=%04x bar=%d msg=%x pt=%ld,%ld hit=%d\n",
874 // hwnd, nBar, msg, pt.x, pt.y, hittest );
875
876 switch(SCROLL_trackHitTest)
877 {
878 case SCROLL_NOWHERE: /* No tracking in progress */
879 break;
880
881 case SCROLL_TOP_ARROW:
882 if (msg == WM_LBUTTONUP)
883 KillSystemTimer(hwnd,SCROLL_TIMER);
884 else if (msg == WM_LBUTTONDOWN || (!timerRunning && msg == WM_SYSTIMER))
885 {
886 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
887 SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
888 (TIMERPROC)0 );
889 if (msg != WM_LBUTTONDOWN) timerRunning = TRUE;
890 }
891
892 if (msg == WM_LBUTTONDOWN || SCROLL_lastHitTest != hittest)
893 {
894 SCROLL_DrawTopArrow(hdc,infoPtr,&rect,arrowSize,vertical,(hittest == SCROLL_trackHitTest));
895 SCROLL_lastHitTest = hittest;
896 }
897 if (hittest == SCROLL_trackHitTest && (msg == WM_LBUTTONDOWN || msg == WM_SYSTIMER))
898 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_LINEUP,hwndCtl);
899
900 break;
901
902 case SCROLL_TOP_RECT:
903 if (msg == WM_LBUTTONUP)
904 KillSystemTimer(hwnd,SCROLL_TIMER);
905 else if (msg == WM_LBUTTONDOWN || (!timerRunning && msg == WM_SYSTIMER))
906 {
907 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
908 SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
909 (TIMERPROC)0 );
910 if (msg != WM_LBUTTONDOWN) timerRunning = TRUE;
911 }
912
913 if (msg == WM_LBUTTONDOWN || SCROLL_lastHitTest != hittest)
914 {
915 SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
916 thumbPos, infoPtr->flags, vertical,
917 (hittest == SCROLL_trackHitTest), FALSE );
918 SCROLL_lastHitTest = hittest;
919 }
920
921 if (hittest == SCROLL_trackHitTest && (msg == WM_LBUTTONDOWN || msg == WM_SYSTIMER))
922 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_PAGEUP,hwndCtl);
923
924 break;
925
926 case SCROLL_THUMB:
927 if (msg == WM_LBUTTONDOWN)
928 {
929 SCROLL_TrackingWin = hwnd;
930 SCROLL_TrackingBar = nBar;
931 SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
932 SCROLL_MovingThumb = TRUE;
933 SCROLL_DrawMovingThumb(hdc, &rect, vertical, arrowSize, thumbSize);
934 } else if (msg == WM_LBUTTONUP || msg == WM_CAPTURECHANGED)
935 {
936 UINT val;
937 INT oldPos = infoPtr->CurVal;
938
939 SCROLL_MovingThumb = FALSE;
940 SCROLL_TrackingWin = 0;
941 val = SCROLL_GetThumbVal( infoPtr, &rect, vertical,
942 trackThumbPos + lastMousePos - lastClickPos );
943 SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
944 MAKEWPARAM( SB_THUMBPOSITION, val ), hwndCtl );
945
946 if (oldPos == infoPtr->CurVal)
947 SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
948 thumbPos, infoPtr->flags, vertical,
949 FALSE, FALSE );
950 } else if (msg == WM_MOUSEMOVE)
951 {
952 UINT pos;
953
954 if (!SCROLL_PtInRectEx( &rect, pt, vertical )) pos = lastClickPos;
955 else
956 {
957 pt = SCROLL_ClipPos( &rect, pt );
958 pos = vertical ? pt.y:pt.x;
959 }
960 if (pos != lastMousePos)
961 {
962 lastMousePos = pos;
963 SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
964 SCROLL_TrackingVal = SCROLL_GetThumbVal( infoPtr, &rect,
965 vertical,
966 SCROLL_TrackingPos );
967 SCROLL_DrawMovingThumb( hdc, &rect, vertical,
968 arrowSize, thumbSize );
969 SendMessageA( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
970 MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
971 hwndCtl );
972 }
973 }
974 break;
975
976 case SCROLL_BOTTOM_RECT:
977 if (msg == WM_LBUTTONUP)
978 KillSystemTimer(hwnd,SCROLL_TIMER);
979 else if (msg == WM_LBUTTONDOWN || (!timerRunning && msg == WM_SYSTIMER))
980 {
981 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
982 SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
983 (TIMERPROC)0 );
984 if (msg != WM_LBUTTONDOWN) timerRunning = TRUE;
985 }
986
987 if (msg == WM_LBUTTONDOWN || SCROLL_lastHitTest != hittest)
988 {
989 SCROLL_DrawInterior( hwnd, hdc, nBar, &rect, arrowSize, thumbSize,
990 thumbPos, infoPtr->flags, vertical,
991 FALSE, (hittest == SCROLL_trackHitTest) );
992 SCROLL_lastHitTest = hittest;
993 }
994
995 if (hittest == SCROLL_trackHitTest && (msg == WM_LBUTTONDOWN || msg == WM_SYSTIMER))
996 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_PAGEDOWN,hwndCtl);
997
998 break;
999
1000 case SCROLL_BOTTOM_ARROW:
1001 if (msg == WM_LBUTTONUP)
1002 KillSystemTimer(hwnd,SCROLL_TIMER);
1003 else if (msg == WM_LBUTTONDOWN || (!timerRunning && msg == WM_SYSTIMER))
1004 {
1005 SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
1006 SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY,
1007 (TIMERPROC)0 );
1008 if (msg != WM_LBUTTONDOWN) timerRunning = TRUE;
1009 }
1010
1011 if (msg == WM_LBUTTONDOWN || SCROLL_lastHitTest != hittest)
1012 {
1013 SCROLL_DrawBottomArrow(hdc,infoPtr,&rect,arrowSize,vertical,(hittest == SCROLL_trackHitTest));
1014 SCROLL_lastHitTest = hittest;
1015 }
1016 if (hittest == SCROLL_trackHitTest && (msg == WM_LBUTTONDOWN || msg == WM_SYSTIMER))
1017 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_LINEDOWN,hwndCtl);
1018
1019 break;
1020 }
1021
1022 if (msg == WM_LBUTTONUP || msg == WM_CAPTURECHANGED)
1023 {
1024 hittest = SCROLL_trackHitTest;
1025 SCROLL_trackHitTest = SCROLL_NOWHERE; /* Terminate tracking */
1026
1027 if (hittest != SCROLL_THUMB)
1028 SendMessageA(hwndOwner,vertical ? WM_VSCROLL:WM_HSCROLL,SB_ENDSCROLL,hwndCtl);
1029 }
1030
1031 ReleaseDC( hwnd, hdc );
1032
1033 return res;
1034}
1035
1036/***********************************************************************
1037 * SCROLL_HandleKbdEvent
1038 *
1039 * Handle a keyboard event (only for SB_CTL scrollbars).
1040 */
1041LRESULT SCROLL_KeyDown(HWND hwnd,WPARAM wParam,LPARAM lParam)
1042{
1043 DWORD dwStyle = GetWindowLongA(hwnd,GWL_STYLE);
1044 UINT msg;
1045
1046 if (dwStyle & (SBS_SIZEBOX | SBS_SIZEGRIP)) return 0;
1047
1048 switch(wParam)
1049 {
1050 case VK_PRIOR: msg = SB_PAGEUP; break;
1051 case VK_NEXT: msg = SB_PAGEDOWN; break;
1052 case VK_HOME: msg = SB_TOP; break;
1053 case VK_END: msg = SB_BOTTOM; break;
1054 case VK_UP: msg = SB_LINEUP; break;
1055 case VK_DOWN: msg = SB_LINEDOWN; break;
1056 default:
1057 return 0;
1058 }
1059 SendMessageA( GetParent(hwnd),
1060 (dwStyle & SBS_VERT) ? WM_VSCROLL : WM_HSCROLL,
1061 msg, hwnd );
1062
1063 return 0;
1064}
1065
1066LRESULT SCROLL_Paint(HWND hwnd,WPARAM wParam,LPARAM lParam,INT nBar)
1067{
1068 PAINTSTRUCT ps;
1069 HDC hdc = wParam ? (HDC)wParam:BeginPaint( hwnd, &ps );
1070
1071 SCROLL_DrawScrollBar( hwnd, hdc, nBar, TRUE, TRUE );
1072 if (!wParam) EndPaint( hwnd, &ps );
1073
1074 return 0;
1075}
1076
1077LRESULT SCROLL_SetRange(HWND hwnd,WPARAM wParam,LPARAM lParam,INT nBar,BOOL redraw)
1078{
1079 SCROLLBAR_INFO *infoPtr = SCROLL_GetInfoPtr(hwnd,nBar);
1080 INT oldPos = infoPtr->CurVal;
1081
1082 SetScrollRange((nBar == SB_CTL) ? hwnd:SCROLL_GetFrameHandle(hwnd),nBar,wParam,lParam,redraw);
1083 return (oldPos != infoPtr->CurVal) ? infoPtr->CurVal:0;
1084}
1085
1086/* Window Procedures */
1087
1088/***********************************************************************
1089 * ScrollBarWndProc
1090 */
1091LRESULT WINAPI ScrollBarWndProc( HWND hwnd, UINT message, WPARAM wParam,
1092 LPARAM lParam )
1093{
1094 switch(message)
1095 {
1096 case WM_NCCREATE:
1097 return SCROLL_NCCreate(hwnd,wParam,lParam);
1098
1099 case WM_CREATE:
1100 return SCROLL_Create(hwnd,wParam,lParam);
1101
1102 case WM_LBUTTONDOWN:
1103 case WM_LBUTTONUP:
1104 case WM_CAPTURECHANGED:
1105 case WM_MOUSEMOVE:
1106 case WM_SYSTIMER:
1107 case WM_SETFOCUS:
1108 case WM_KILLFOCUS:
1109 return SCROLL_HandleScrollEvent(hwnd,wParam,lParam,SB_CTL,message);
1110
1111 case WM_KEYDOWN:
1112 return SCROLL_KeyDown(hwnd,wParam,lParam);
1113
1114 case WM_ERASEBKGND:
1115 return 1;
1116
1117 case WM_GETDLGCODE:
1118 return DLGC_WANTARROWS; /* Windows returns this value */
1119
1120 case WM_PAINT:
1121 return SCROLL_Paint(hwnd,wParam,lParam,SB_CTL);
1122
1123 case SBM_SETPOS:
1124 return SetScrollPos( hwnd, SB_CTL, wParam, (BOOL)lParam );
1125
1126 case SBM_GETPOS:
1127 return GetScrollPos( hwnd, SB_CTL );
1128
1129 case SBM_SETRANGE:
1130 return SCROLL_SetRange(hwnd,wParam,lParam,SB_CTL,FALSE);
1131
1132 case SBM_GETRANGE:
1133 GetScrollRange( hwnd, SB_CTL, (LPINT)wParam, (LPINT)lParam );
1134 return 0;
1135
1136 case SBM_ENABLE_ARROWS:
1137 return EnableScrollBar( hwnd, SB_CTL, wParam );
1138
1139 case SBM_SETRANGEREDRAW:
1140 return SCROLL_SetRange(hwnd,wParam,lParam,SB_CTL,TRUE);
1141
1142 case SBM_SETSCROLLINFO:
1143 return SetScrollInfo(hwnd,SB_CTL,(SCROLLINFO*)lParam,wParam);
1144
1145 case SBM_GETSCROLLINFO:
1146 return GetScrollInfo( hwnd, SB_CTL, (SCROLLINFO *)lParam );
1147
1148 case 0x00e5:
1149 case 0x00e7:
1150 case 0x00e8:
1151 case 0x00eb:
1152 case 0x00ec:
1153 case 0x00ed:
1154 case 0x00ee:
1155 case 0x00ef:
1156 //ERR("unknown Win32 msg %04x wp=%08x lp=%08lx\n",
1157 // message, wParam, lParam );
1158 break;
1159
1160 default:
1161 return DefWindowProcA( hwnd, message, wParam, lParam );
1162 }
1163
1164 return 0;
1165}
1166
1167/* frame handlers */
1168
1169VOID SCROLL_SubclassScrollBars(HWND hwndHorz,HWND hwndVert)
1170{
1171 if (hwndHorz) SetWindowLongA(hwndHorz,GWL_WNDPROC,(ULONG)HorzScrollBarWndProc);
1172 if (hwndVert) SetWindowLongA(hwndVert,GWL_WNDPROC,(ULONG)VertScrollBarWndProc);
1173}
1174
1175LRESULT WINAPI HorzScrollBarWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
1176{
1177 switch (message)
1178 {
1179 case WM_LBUTTONDOWN:
1180 case WM_LBUTTONUP:
1181 case WM_CAPTURECHANGED:
1182 case WM_MOUSEMOVE:
1183 case WM_SYSTIMER:
1184 case WM_SETFOCUS:
1185 case WM_KILLFOCUS:
1186 return SCROLL_HandleScrollEvent(hwnd,wParam,lParam,SB_HORZ,message);
1187
1188 case WM_ERASEBKGND:
1189 return 1;
1190
1191 case WM_GETDLGCODE:
1192 return DLGC_WANTARROWS; /* Windows returns this value */
1193
1194 case WM_PAINT:
1195 return SCROLL_Paint(hwnd,wParam,lParam,SB_HORZ);
1196
1197 case SBM_SETPOS:
1198 return SetScrollPos(SCROLL_GetFrameHandle(hwnd),SB_HORZ,wParam,(BOOL)lParam);
1199
1200 case SBM_GETPOS:
1201 return GetScrollPos(SCROLL_GetFrameHandle(hwnd),SB_HORZ);
1202
1203 case SBM_SETRANGE:
1204 return SCROLL_SetRange(hwnd,wParam,lParam,SB_HORZ,FALSE);
1205
1206 case SBM_GETRANGE:
1207 GetScrollRange(SCROLL_GetFrameHandle(hwnd),SB_HORZ,(LPINT)wParam,(LPINT)lParam);
1208 return 0;
1209
1210 case SBM_ENABLE_ARROWS:
1211 return EnableScrollBar(SCROLL_GetFrameHandle(hwnd),SB_HORZ,wParam);
1212
1213 case SBM_SETRANGEREDRAW:
1214 return SCROLL_SetRange(hwnd,wParam,lParam,SB_HORZ,TRUE);
1215
1216 case SBM_SETSCROLLINFO:
1217 return SetScrollInfo(SCROLL_GetFrameHandle(hwnd),SB_HORZ,(SCROLLINFO*)lParam,wParam);
1218
1219 case SBM_GETSCROLLINFO:
1220 return GetScrollInfo(SCROLL_GetFrameHandle(hwnd),SB_HORZ,(SCROLLINFO*)lParam);
1221
1222 default:
1223 return DefWindowProcA(hwnd,message,wParam,lParam);
1224 }
1225
1226 return 0;
1227}
1228
1229LRESULT WINAPI VertScrollBarWndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam )
1230{
1231 switch (message)
1232 {
1233 case WM_LBUTTONDOWN:
1234 case WM_LBUTTONUP:
1235 case WM_CAPTURECHANGED:
1236 case WM_MOUSEMOVE:
1237 case WM_SYSTIMER:
1238 case WM_SETFOCUS:
1239 case WM_KILLFOCUS:
1240 return SCROLL_HandleScrollEvent(hwnd,wParam,lParam,SB_VERT,message);
1241
1242 case WM_ERASEBKGND:
1243 return 1;
1244
1245 case WM_GETDLGCODE:
1246 return DLGC_WANTARROWS; /* Windows returns this value */
1247
1248 case WM_PAINT:
1249 return SCROLL_Paint(hwnd,wParam,lParam,SB_VERT);
1250
1251 case SBM_SETPOS:
1252 return SetScrollPos(SCROLL_GetFrameHandle(hwnd),SB_VERT,wParam,(BOOL)lParam);
1253
1254 case SBM_GETPOS:
1255 return GetScrollPos(SCROLL_GetFrameHandle(hwnd),SB_VERT);
1256
1257 case SBM_SETRANGE:
1258 return SCROLL_SetRange(hwnd,wParam,lParam,SB_VERT,FALSE);
1259
1260 case SBM_GETRANGE:
1261 GetScrollRange(SCROLL_GetFrameHandle(hwnd),SB_VERT,(LPINT)wParam,(LPINT)lParam);
1262 return 0;
1263
1264 case SBM_ENABLE_ARROWS:
1265 return EnableScrollBar(SCROLL_GetFrameHandle(hwnd),SB_VERT,wParam);
1266
1267 case SBM_SETRANGEREDRAW:
1268 return SCROLL_SetRange(hwnd,wParam,lParam,SB_VERT,TRUE);
1269
1270 case SBM_SETSCROLLINFO:
1271 return SetScrollInfo(SCROLL_GetFrameHandle(hwnd),SB_VERT,(SCROLLINFO*)lParam,wParam);
1272
1273 case SBM_GETSCROLLINFO:
1274 return GetScrollInfo(SCROLL_GetFrameHandle(hwnd),SB_VERT,(SCROLLINFO*)lParam);
1275
1276 default:
1277 return DefWindowProcA(hwnd,message,wParam,lParam);
1278 }
1279
1280 return 0;
1281}
1282
1283/* Scrollbar API */
1284
1285/*************************************************************************
1286 * SetScrollInfo (USER32.501)
1287 * SetScrollInfo32 can be used to set the position, upper bound,
1288 * lower bound, and page size of a scrollbar control.
1289 *
1290 * RETURNS
1291 * Scrollbar position
1292 *
1293 * NOTE
1294 * For 100 lines of text to be displayed in a window of 25 lines,
1295 * one would for instance use info->nMin=0, info->nMax=75
1296 * (corresponding to the 76 different positions of the window on
1297 * the text), and info->nPage=25.
1298 */
1299INT WINAPI SetScrollInfo(HWND hwnd,INT nBar,const SCROLLINFO *info,BOOL bRedraw)
1300{
1301 /* Update the scrollbar state and set action flags according to
1302 * what has to be done graphics wise. */
1303
1304 SCROLLBAR_INFO *infoPtr;
1305 UINT new_flags;
1306 INT action = 0;
1307 HWND hwndScroll = SCROLL_GetScrollHandle(hwnd,nBar);
1308
1309 if (!hwndScroll) return 0;
1310 if (!(infoPtr = SCROLL_GetInfoPtr(hwndScroll,nBar))) return 0;
1311 if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return 0;
1312 if ((info->cbSize != sizeof(*info)) &&
1313 (info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return 0;
1314
1315 /* Set the page size */
1316 if (info->fMask & SIF_PAGE)
1317 {
1318 if( infoPtr->Page != info->nPage )
1319 {
1320 infoPtr->Page = info->nPage;
1321 action |= SA_SSI_REPAINT_INTERIOR;
1322 }
1323 }
1324
1325 /* Set the scroll pos */
1326 if (info->fMask & SIF_POS)
1327 {
1328 //dsprintf(scroll, " pos=%d", info->nPos );
1329 if( infoPtr->CurVal != info->nPos )
1330 {
1331 infoPtr->CurVal = info->nPos;
1332 action |= SA_SSI_MOVE_THUMB;
1333 }
1334 }
1335
1336 /* Set the scroll range */
1337 if (info->fMask & SIF_RANGE)
1338 {
1339 /* Invalid range -> range is set to (0,0) */
1340 if ((info->nMin > info->nMax) ||
1341 ((UINT)(info->nMax - info->nMin) >= 0x80000000))
1342 {
1343 infoPtr->MinVal = 0;
1344 infoPtr->MaxVal = 0;
1345 }
1346 else
1347 {
1348 if( infoPtr->MinVal != info->nMin ||
1349 infoPtr->MaxVal != info->nMax )
1350 {
1351 action |= SA_SSI_REPAINT_INTERIOR;
1352 infoPtr->MinVal = info->nMin;
1353 infoPtr->MaxVal = info->nMax;
1354 }
1355 }
1356 }
1357
1358 /* Make sure the page size is valid */
1359
1360 if (infoPtr->Page < 0) infoPtr->Page = 0;
1361 else if (infoPtr->Page > infoPtr->MaxVal - infoPtr->MinVal + 1 )
1362 infoPtr->Page = infoPtr->MaxVal - infoPtr->MinVal + 1;
1363
1364 /* Make sure the pos is inside the range */
1365
1366 if (infoPtr->CurVal < infoPtr->MinVal)
1367 infoPtr->CurVal = infoPtr->MinVal;
1368 else if (infoPtr->CurVal > infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
1369 infoPtr->CurVal = infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 );
1370
1371 //TRACE(" new values: page=%d pos=%d min=%d max=%d\n",
1372 // infoPtr->Page, infoPtr->CurVal,
1373 // infoPtr->MinVal, infoPtr->MaxVal );
1374
1375 /* Check if the scrollbar should be hidden or disabled */
1376 if (info->fMask & (SIF_RANGE | SIF_PAGE | SIF_DISABLENOSCROLL))
1377 {
1378 new_flags = infoPtr->flags;
1379 if (infoPtr->MinVal >= infoPtr->MaxVal - MAX( infoPtr->Page-1, 0 ))
1380 {
1381 /* Hide or disable scroll-bar */
1382 if (info->fMask & SIF_DISABLENOSCROLL)
1383 {
1384 new_flags = ESB_DISABLE_BOTH;
1385 action |= SA_SSI_REFRESH;
1386 }
1387 else if (nBar != SB_CTL)
1388 {
1389 action = SA_SSI_HIDE;
1390 goto done;
1391 }
1392 }
1393 else /* Show and enable scroll-bar */
1394 {
1395 new_flags = 0;
1396 if (nBar != SB_CTL)
1397 action |= SA_SSI_SHOW;
1398 }
1399
1400 if (infoPtr->flags != new_flags) /* check arrow flags */
1401 {
1402 infoPtr->flags = new_flags;
1403 action |= SA_SSI_REPAINT_ARROWS;
1404 }
1405 }
1406
1407done:
1408 /* Update scrollbar */
1409
1410 if( action & SA_SSI_HIDE )
1411 ShowScrollBar(hwnd,nBar,FALSE);
1412 else
1413 {
1414 if(action & SA_SSI_SHOW)
1415 ShowScrollBar(hwnd,nBar,TRUE);
1416
1417 if(bRedraw && (action & SA_SSI_REFRESH))
1418 SCROLL_RefreshScrollBar(hwndScroll,nBar,TRUE,TRUE);
1419 else
1420 {
1421 if (action & SA_SSI_REPAINT_INTERIOR || action & SA_SSI_MOVE_THUMB)
1422 SCROLL_RefreshScrollBar(hwndScroll,nBar,FALSE,TRUE);
1423 if (action & SA_SSI_REPAINT_ARROWS )
1424 SCROLL_RefreshScrollBar(hwndScroll,nBar,TRUE,FALSE);
1425 }
1426 }
1427
1428 /* Return current position */
1429
1430 return infoPtr->CurVal;
1431}
1432/*************************************************************************
1433 * GetScrollInfo (USER32.284)
1434 * GetScrollInfo32 can be used to retrieve the position, upper bound,
1435 * lower bound, and page size of a scrollbar control.
1436 *
1437 * RETURNS STD
1438 */
1439BOOL WINAPI GetScrollInfo(
1440 HWND hwnd /* [I] Handle of window */ ,
1441 INT nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */,
1442 LPSCROLLINFO info /* [IO] (info.fMask [I] specifies which values are to retrieve) */)
1443{
1444 SCROLLBAR_INFO *infoPtr;
1445
1446 if (!(infoPtr = SCROLL_GetInfoPtr(SCROLL_GetScrollHandle(hwnd,nBar),nBar))) return FALSE;
1447 if (info->fMask & ~(SIF_ALL | SIF_DISABLENOSCROLL)) return FALSE;
1448 if ((info->cbSize != sizeof(*info)) &&
1449 (info->cbSize != sizeof(*info)-sizeof(info->nTrackPos))) return FALSE;
1450
1451 if (info->fMask & SIF_PAGE) info->nPage = infoPtr->Page;
1452 if (info->fMask & SIF_POS) info->nPos = infoPtr->CurVal;
1453 if ((info->fMask & SIF_TRACKPOS) && (info->cbSize == sizeof(*info)))
1454 info->nTrackPos = (SCROLL_TrackingWin==hwnd) ? SCROLL_TrackingVal : infoPtr->CurVal;
1455 if (info->fMask & SIF_RANGE)
1456 {
1457 info->nMin = infoPtr->MinVal;
1458 info->nMax = infoPtr->MaxVal;
1459 }
1460 return (info->fMask & SIF_ALL) != 0;
1461}
1462/*************************************************************************
1463 * SetScrollPos (USER32.502)
1464 *
1465 * RETURNS
1466 * Success: Scrollbar position
1467 * Failure: 0
1468 *
1469 * REMARKS
1470 * Note the ambiguity when 0 is returned. Use GetLastError
1471 * to make sure there was an error (and to know which one).
1472 */
1473INT WINAPI SetScrollPos(
1474 HWND hwnd /* [I] Handle of window whose scrollbar will be affected */,
1475 INT nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */,
1476 INT nPos /* [I] New value */,
1477 BOOL bRedraw /* [I] Should scrollbar be redrawn afterwards ? */ )
1478{
1479 SCROLLINFO info;
1480 SCROLLBAR_INFO *infoPtr;
1481 INT oldPos;
1482
1483 dprintf(("SetScrollPos %x %d %d %d", hwnd, nBar, nPos, bRedraw));
1484 if (!(infoPtr = SCROLL_GetInfoPtr(SCROLL_GetScrollHandle(hwnd,nBar),nBar))) return 0;
1485 oldPos = infoPtr->CurVal;
1486 info.cbSize = sizeof(info);
1487 info.nPos = nPos;
1488 info.fMask = SIF_POS;
1489 SetScrollInfo( hwnd, nBar, &info, bRedraw );
1490 return oldPos;
1491}
1492/*************************************************************************
1493 * GetScrollPos (USER32.285)
1494 *
1495 * RETURNS
1496 * Success: Current position
1497 * Failure: 0
1498 *
1499 * REMARKS
1500 * Note the ambiguity when 0 is returned. Use GetLastError
1501 * to make sure there was an error (and to know which one).
1502 */
1503INT WINAPI GetScrollPos(
1504 HWND hwnd, /* [I] Handle of window */
1505 INT nBar /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */)
1506{
1507 SCROLLBAR_INFO *infoPtr;
1508
1509 dprintf(("GetScrollPos %x %d", hwnd, nBar));
1510
1511 infoPtr = SCROLL_GetInfoPtr(SCROLL_GetScrollHandle(hwnd,nBar),nBar);
1512 if (!infoPtr) return 0;
1513
1514 return infoPtr->CurVal;
1515}
1516/*************************************************************************
1517 * SetScrollRange (USER32.503)
1518 *
1519 * RETURNS STD
1520 */
1521BOOL WINAPI SetScrollRange(
1522 HWND hwnd, /* [I] Handle of window whose scrollbar will be affected */
1523 INT nBar, /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */
1524 INT MinVal, /* [I] New minimum value */
1525 INT MaxVal, /* [I] New maximum value */
1526 BOOL bRedraw /* [I] Should scrollbar be redrawn afterwards ? */)
1527{
1528 SCROLLINFO info;
1529
1530 dprintf(("SetScrollRange %x %x %d %d %d", hwnd, nBar, MinVal, MaxVal, bRedraw));
1531 info.cbSize = sizeof(info);
1532 info.nMin = MinVal;
1533 info.nMax = MaxVal;
1534 info.fMask = SIF_RANGE;
1535 SetScrollInfo( hwnd, nBar, &info, bRedraw );
1536 return TRUE;
1537}
1538
1539/*************************************************************************
1540 * GetScrollRange (USER32.286)
1541 *
1542 * RETURNS STD
1543 */
1544BOOL WINAPI GetScrollRange(
1545 HWND hwnd, /* [I] Handle of window */
1546 INT nBar, /* [I] One of SB_HORZ, SB_VERT, or SB_CTL */
1547 LPINT lpMin, /* [O] Where to store minimum value */
1548 LPINT lpMax /* [O] Where to store maximum value */)
1549{
1550 SCROLLBAR_INFO *infoPtr;
1551
1552 infoPtr = SCROLL_GetInfoPtr(SCROLL_GetScrollHandle(hwnd,nBar),nBar);
1553 if (!infoPtr)
1554 {
1555 if (lpMin) lpMin = 0;
1556 if (lpMax) lpMax = 0;
1557 return FALSE;
1558 }
1559 if (lpMin) *lpMin = infoPtr->MinVal;
1560 if (lpMax) *lpMax = infoPtr->MaxVal;
1561 return TRUE;
1562}
1563
1564/*************************************************************************
1565 * ShowScrollBar (USER32.532)
1566 *
1567 * RETURNS STD
1568 */
1569BOOL WINAPI ShowScrollBar(
1570 HWND hwnd, /* [I] Handle of window whose scrollbar(s) will be affected */
1571 INT nBar, /* [I] One of SB_HORZ, SB_VERT, SB_BOTH or SB_CTL */
1572 BOOL fShow /* [I] TRUE = show, FALSE = hide */)
1573{
1574 dprintf(("ShowScrollBar %04x %d %d\n", hwnd, nBar, fShow));
1575
1576 if (nBar == SB_CTL)
1577 {
1578 ShowWindow(hwnd,fShow ? SW_SHOW:SW_HIDE);
1579
1580 return TRUE;
1581 } else
1582 {
1583 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1584
1585 if (!window)
1586 {
1587 dprintf(("ShowScrollBar window not found!"));
1588 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1589 return 0;
1590 }
1591
1592 if (window->getStyle() & (WS_HSCROLL | WS_VSCROLL))
1593 {
1594 BOOL rc;
1595
1596 if (nBar == SB_HORZ || nBar == SB_BOTH)
1597 rc = OSLibWinShowScrollBar(window->getOS2FrameWindowHandle(),
1598 window->getHorzScrollHandle(),
1599 OSLIB_HSCROLL, fShow);
1600
1601 if (nBar == SB_VERT || (rc == TRUE && nBar == SB_BOTH))
1602 rc = OSLibWinShowScrollBar(window->getOS2FrameWindowHandle(),
1603 window->getVertScrollHandle(),
1604 OSLIB_VSCROLL, fShow);
1605 return rc;
1606 }
1607 }
1608
1609 return TRUE;
1610}
1611
1612/*************************************************************************
1613 * EnableScrollBar (USER32.171)
1614 */
1615BOOL WINAPI EnableScrollBar( HWND hwnd, INT nBar, UINT flags)
1616{
1617 Win32BaseWindow *window;
1618 SCROLLBAR_INFO *infoPtr;
1619
1620 dprintf(("EnableScrollBar %04x %d %d\n", hwnd, nBar, flags));
1621
1622 if (nBar == SB_CTL)
1623 {
1624 if (!(infoPtr = SCROLL_GetInfoPtr(hwnd,nBar))) return FALSE;
1625
1626 if (infoPtr->flags != flags)
1627 {
1628 infoPtr->flags = flags;
1629 SCROLL_RefreshScrollBar(hwnd,nBar,TRUE,TRUE);
1630 }
1631
1632 return TRUE;
1633 } else
1634 {
1635 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromHandle(hwnd);
1636 if(!window)
1637 {
1638 dprintf(("EnableScrollBar window not found!"));
1639 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
1640 return FALSE;
1641 }
1642
1643 if(window->getStyle() & (WS_HSCROLL | WS_VSCROLL))
1644 {
1645 BOOL rc = FALSE;
1646
1647 if (nBar == SB_VERT || nBar == SB_BOTH)
1648 {
1649 HWND hwndScroll = Win32BaseWindow::OS2ToWin32Handle(window->getVertScrollHandle());
1650
1651 infoPtr = SCROLL_GetInfoPtr(hwndScroll,SB_VERT);
1652 if (infoPtr)
1653 {
1654 if (infoPtr->flags != flags)
1655 {
1656 infoPtr->flags = flags;
1657 SCROLL_RefreshScrollBar(hwndScroll,nBar,TRUE,TRUE);
1658 }
1659
1660 rc = TRUE;
1661 }
1662 }
1663 if (nBar == SB_HORZ || (rc && nBar == SB_BOTH))
1664 {
1665 HWND hwndScroll = Win32BaseWindow::OS2ToWin32Handle(window->getVertScrollHandle());
1666
1667 infoPtr = SCROLL_GetInfoPtr(hwndScroll,SB_VERT);
1668 if (infoPtr)
1669 {
1670 if (infoPtr->flags != flags)
1671 {
1672 infoPtr->flags = flags;
1673 SCROLL_RefreshScrollBar(hwndScroll,nBar,TRUE,TRUE);
1674 }
1675
1676 rc = TRUE;
1677 }
1678 }
1679
1680 return rc;
1681 }
1682 }
1683
1684 return TRUE;
1685}
1686
1687//CB: not listed in user32.exp -> don't know the id!
1688
1689BOOL WINAPI GetScrollBarInfo(HWND hwnd,LONG idObject,PSCROLLBARINFO psbi)
1690{
1691 if (!psbi || psbi->cbSize != sizeof(SCROLLBARINFO))
1692 {
1693 SetLastError(ERROR_INVALID_PARAMETER);
1694
1695 return FALSE;
1696 }
1697
1698 HWND hwndScroll;
1699 INT nBar,arrowSize;
1700
1701 switch (idObject)
1702 {
1703 case OBJID_CLIENT:
1704 nBar = SB_CTL;
1705 hwndScroll = hwnd;
1706 break;
1707
1708 case OBJID_HSCROLL:
1709 nBar = SB_HORZ;
1710 hwndScroll = SCROLL_GetScrollHandle(hwnd,SB_HORZ);
1711 break;
1712
1713 case OBJID_VSCROLL:
1714 nBar = SB_VERT;
1715 hwndScroll = SCROLL_GetScrollHandle(hwnd,SB_VERT);
1716 break;
1717
1718 default:
1719 return FALSE;
1720 }
1721
1722 if (!hwndScroll) return FALSE;
1723
1724 SCROLL_GetScrollBarRect(hwndScroll,nBar,&psbi->rcScrollBar,&arrowSize,&psbi->dxyLineButton,&psbi->xyThumbTop);
1725 psbi->xyThumbBottom = psbi->xyThumbTop+psbi->dxyLineButton;
1726 psbi->bogus = 0; //CB: undocumented!
1727 psbi->rgstate[0] = IsWindowVisible(hwndScroll) ? STATE_SYSTEM_INVISIBLE:0;
1728 psbi->rgstate[1] = psbi->rgstate[2] = psbi->rgstate[3] = psbi->rgstate[4] = psbi->rgstate[5] = psbi->rgstate[0]; //CB: todo
1729
1730 return TRUE;
1731}
1732//******************************************************************************
1733//******************************************************************************
1734BOOL SCROLLBAR_Register()
1735{
1736 WNDCLASSA wndClass;
1737
1738//SvL: Don't check this now
1739// if (GlobalFindAtomA(SCROLLBARCLASSNAME)) return FALSE;
1740
1741 ZeroMemory(&wndClass,sizeof(WNDCLASSA));
1742 wndClass.style = CS_GLOBALCLASS | CS_HREDRAW | CS_VREDRAW | CS_PARENTDC;
1743 wndClass.lpfnWndProc = (WNDPROC)ScrollBarWndProc;
1744 wndClass.cbClsExtra = 0;
1745 wndClass.cbWndExtra = sizeof(SCROLLBAR_INFO);
1746 wndClass.hCursor = LoadCursorA(0,IDC_ARROWA);
1747 wndClass.hbrBackground = (HBRUSH)0;
1748 wndClass.lpszClassName = SCROLLBARCLASSNAME;
1749
1750 return RegisterClassA(&wndClass);
1751}
1752//******************************************************************************
1753//******************************************************************************
1754BOOL SCROLLBAR_Unregister()
1755{
1756 if (GlobalFindAtomA(SCROLLBARCLASSNAME))
1757 return UnregisterClassA(SCROLLBARCLASSNAME,(HINSTANCE)NULL);
1758 else return FALSE;
1759}
1760//******************************************************************************
1761//******************************************************************************
1762
Note: See TracBrowser for help on using the repository browser.