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

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

scroll: removed WS_* check

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