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

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

cursor handling fixed

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