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

Last change on this file since 10367 was 10119, checked in by sandervl, 22 years ago

Do not send WM_STYLECHANGING/ED messages when the scrollbar control is shown or hidden.

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