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

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

enhanced edit control

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