Release 940815
[wine/gsoc-2012-control.git] / controls / scroll.c
blobe962e8c50d6b6ec01091f7c69af8148365a70bd9
1 /*
2 * Interface code to SCROLLBAR widget
4 * Copyright Martin Ayotte, 1993
6 * Small fixes and implemented SB_THUMBPOSITION
7 * by Peter Broadhurst, 940611
8 */
11 #define DEBUG_SCROLL
13 static char Copyright[] = "Copyright Martin Ayotte, 1993";
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include "windows.h"
20 #include "sysmetrics.h"
21 #include "scroll.h"
22 #include "heap.h"
23 #include "win.h"
24 #include "prototypes.h"
26 HBITMAP hUpArrow = 0;
27 HBITMAP hDnArrow = 0;
28 HBITMAP hLfArrow = 0;
29 HBITMAP hRgArrow = 0;
30 HBITMAP hUpArrowD = 0;
31 HBITMAP hDnArrowD = 0;
32 HBITMAP hLfArrowD = 0;
33 HBITMAP hRgArrowD = 0;
35 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hWnd, WND **wndPtr);
36 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd);
37 LPHEADSCROLL GetScrollObjectStruct(HWND hWnd, int nBar);
38 void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y);
39 void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y);
40 void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y);
41 void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs);
42 int CreateScrollBarStruct(HWND hWnd);
43 void NC_CreateScrollBars(HWND hWnd);
44 LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height);
47 /***********************************************************************
48 * WIDGETS_ScrollBarWndProc
50 LONG ScrollBarWndProc( HWND hWnd, WORD message, WORD wParam, LONG lParam )
52 WORD wRet;
53 short x, y;
54 short width, height;
55 WND *wndPtr;
56 LPHEADSCROLL lphs;
57 PAINTSTRUCT ps;
58 HDC hDC;
59 BITMAP bm;
60 RECT rect, rect2;
61 LPCREATESTRUCT lpCreat;
62 static RECT rectsel;
63 POINT *pt;
64 pt=(POINT*)&lParam;
65 switch(message) {
66 case WM_CREATE:
67 lpCreat = (LPCREATESTRUCT)lParam;
68 if (lpCreat->style & SBS_VERT) {
69 if (lpCreat->style & SBS_LEFTALIGN)
70 SetWindowPos(hWnd, 0, 0, 0, 16, lpCreat->cy,
71 SWP_NOZORDER | SWP_NOMOVE);
72 if (lpCreat->style & SBS_RIGHTALIGN)
73 SetWindowPos(hWnd, 0, lpCreat->x + lpCreat->cx - 16,
74 lpCreat->y, 16, lpCreat->cy, SWP_NOZORDER);
76 if (lpCreat->style & SBS_HORZ) {
77 if (lpCreat->style & SBS_TOPALIGN)
78 SetWindowPos(hWnd, 0, 0, 0, lpCreat->cx, 16,
79 SWP_NOZORDER | SWP_NOMOVE);
80 if (lpCreat->style & SBS_BOTTOMALIGN)
81 SetWindowPos(hWnd, 0, lpCreat->x,
82 lpCreat->y + lpCreat->cy - 16,
83 lpCreat->cx, 16, SWP_NOZORDER);
85 CreateScrollBarStruct(hWnd);
86 #ifdef DEBUG_SCROLL
87 printf("ScrollBar Creation !\n");
88 #endif
89 return 0;
90 case WM_DESTROY:
91 lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
92 if (lphs == 0) return 0;
93 #ifdef DEBUG_SCROLL
94 printf("ScrollBar WM_DESTROY %lX !\n", lphs);
95 #endif
96 free(lphs);
97 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0;
98 return 0;
100 case WM_LBUTTONDOWN:
101 SetCapture(hWnd);
102 ScrollBarButtonDown(hWnd, SB_CTL, pt->x,pt->y);
103 break;
104 case WM_LBUTTONUP:
105 ReleaseCapture();
106 ScrollBarButtonUp(hWnd, SB_CTL, pt->x,pt->y);
107 break;
109 case WM_MOUSEMOVE:
110 ScrollBarMouseMove(hWnd, SB_CTL, wParam, pt->x,pt->y);
111 break;
112 case WM_KEYDOWN:
113 case WM_KEYUP:
114 case WM_CHAR:
115 lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
116 return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
118 case WM_TIMER:
119 #ifdef DEBUG_SCROLL
120 printf("ScrollBar WM_TIMER wParam=%X lParam=%lX !\n", wParam, lParam);
121 #endif
122 lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
123 KillTimer(hWnd, wParam);
124 switch(lphs->ButtonDown) {
125 case 0:
126 lphs->TimerPending = FALSE;
127 return 0;
128 case 1:
129 case 3:
130 SendMessage(wndPtr->hwndParent, lphs->Direction,
131 SB_LINEUP, MAKELONG(0, hWnd));
132 break;
133 case 2:
134 case 4:
135 SendMessage(wndPtr->hwndParent, lphs->Direction,
136 SB_LINEDOWN, MAKELONG(0, hWnd));
137 break;
138 case 5:
139 SendMessage(wndPtr->hwndParent, lphs->Direction,
140 SB_PAGEUP, MAKELONG(0, hWnd));
141 break;
142 case 6:
143 SendMessage(wndPtr->hwndParent, lphs->Direction,
144 SB_PAGEDOWN, MAKELONG(0, hWnd));
145 break;
147 SetTimer(hWnd, 1, 100, NULL);
148 return 0;
150 case WM_PAINT:
151 hDC = BeginPaint(hWnd, &ps);
152 lphs = ScrollBarGetStorageHeader(hWnd);
153 if (lphs != NULL) {
154 GetClientRect(hWnd, &rect);
155 StdDrawScrollBar(hWnd, hDC, SB_CTL, &rect, lphs);
157 EndPaint(hWnd, &ps);
158 break;
159 default:
160 return DefWindowProc( hWnd, message, wParam, lParam );
162 return(0);
167 void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y)
169 LPHEADSCROLL lphs;
170 HWND hWndParent;
171 RECT rect, rect2;
172 int width, height;
173 LONG dwOwner;
174 lphs = GetScrollObjectStruct(hWnd, nBar);
175 if (nBar == SB_CTL) {
176 hWndParent = GetParent(hWnd);
177 dwOwner = MAKELONG(0, lphs->hWndOwner);
178 #ifdef DEBUG_SCROLL
179 printf("ScrollBarButtonDown SB_CTL // x=%d y=%d\n", x, y);
180 #endif
182 else {
183 hWndParent = hWnd;
184 dwOwner = 0L;
185 #ifdef DEBUG_SCROLL
186 printf("ScrollBarButtonDown SB_?SCROLL // x=%d y=%d\n", x, y);
187 #endif
190 SetFocus(lphs->hWndOwner);
192 CopyRect(&rect, &lphs->rect);
193 #ifdef DEBUG_SCROLL
194 printf("ScrollDown / x=%d y=%d left=%d top=%d right=%d bottom=%d \n",
195 x, y, rect.left, rect.top, rect.right, rect.bottom);
196 #endif
197 if (lphs->Direction == WM_VSCROLL) {
198 width = rect.right - rect.left;
199 if (y <= lphs->rectUp.bottom) {
200 lphs->ButtonDown = 1;
201 InvalidateRect(lphs->hWndOwner, &lphs->rectUp, TRUE);
202 #ifdef DEBUG_SCROLL
203 printf("ScrollBarButtonDown send SB_LINEUP\n");
204 #endif
205 SendMessage(hWndParent, lphs->Direction,
206 SB_LINEUP, dwOwner);
208 if (y >= lphs->rectDown.top) {
209 lphs->ButtonDown = 2;
210 InvalidateRect(lphs->hWndOwner, &lphs->rectDown, TRUE);
211 #ifdef DEBUG_SCROLL
212 printf("ScrollBarButtonDown send SB_LINEDOWN\n");
213 #endif
214 SendMessage(hWndParent, lphs->Direction,
215 SB_LINEDOWN, dwOwner);
217 if (y > lphs->rectUp.bottom && y < (lphs->CurPix + width)) {
218 lphs->ButtonDown = 5;
219 #ifdef DEBUG_SCROLL
220 printf("ScrollBarButtonDown send SB_PAGEUP\n");
221 #endif
222 SendMessage(hWndParent, lphs->Direction,
223 SB_PAGEUP, dwOwner);
225 if (y < lphs->rectDown.top && y > (lphs->CurPix + (width << 1))) {
226 lphs->ButtonDown = 6;
227 #ifdef DEBUG_SCROLL
228 printf("ScrollBarButtonDown send SB_PAGEDOWN\n");
229 #endif
230 SendMessage(hWndParent, lphs->Direction,
231 SB_PAGEDOWN, dwOwner);
233 if (lphs->MaxPix > 0 && y > (lphs->CurPix + width) &&
234 y < (lphs->CurPix + (width << 1))) {
235 lphs->ThumbActive = TRUE;
236 #ifdef DEBUG_SCROLL
237 printf("THUMB DOWN !\n");
238 #endif
241 else {
242 height = rect.bottom - rect.top;
243 if (x <= lphs->rectUp.right) {
244 lphs->ButtonDown = 3;
245 InvalidateRect(lphs->hWndOwner, &lphs->rectUp, TRUE);
246 #ifdef DEBUG_SCROLL
247 printf("ScrollBarButtonDown send SB_LINEUP\n");
248 #endif
249 SendMessage(hWndParent, lphs->Direction,
250 SB_LINEUP, dwOwner);
252 if (x >= lphs->rectDown.left) {
253 lphs->ButtonDown = 4;
254 InvalidateRect(lphs->hWndOwner, &lphs->rectDown, TRUE);
255 #ifdef DEBUG_SCROLL
256 printf("ScrollBarButtonDown send SB_LINEDOWN\n");
257 #endif
258 SendMessage(hWndParent, lphs->Direction,
259 SB_LINEDOWN, dwOwner);
261 if (x > lphs->rectUp.right && x < (lphs->CurPix + height)) {
262 lphs->ButtonDown = 5;
263 #ifdef DEBUG_SCROLL
264 printf("ScrollBarButtonDown send SB_PAGEUP\n");
265 #endif
266 SendMessage(hWndParent, lphs->Direction,
267 SB_PAGEUP, dwOwner);
269 if (x < lphs->rectDown.left && x > (lphs->CurPix + (height << 1))) {
270 lphs->ButtonDown = 6;
271 #ifdef DEBUG_SCROLL
272 printf("ScrollBarButtonDown send SB_PAGEDOWN\n");
273 #endif
274 SendMessage(hWndParent, lphs->Direction,
275 SB_PAGEDOWN, dwOwner);
277 if (lphs->MaxPix > 0 && x > (lphs->CurPix + height) &&
278 x < (lphs->CurPix + (height << 1))) {
279 lphs->ThumbActive = TRUE;
280 #ifdef DEBUG_SCROLL
281 printf("THUMB DOWN !\n");
282 #endif
285 if (lphs->ButtonDown != 0) {
286 UpdateWindow(lphs->hWndOwner);
287 if (!lphs->TimerPending && nBar == SB_CTL) {
288 lphs->TimerPending = TRUE;
289 SetTimer(lphs->hWndOwner, 1, 500, NULL);
295 void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y)
297 LPHEADSCROLL lphs;
298 RECT rect, rect2;
299 HDC hDC;
300 #ifdef DEBUG_SCROLL
301 printf("ScrollBarButtonUp // x=%d y=%d\n", x, y);
302 #endif
303 lphs = GetScrollObjectStruct(hWnd, nBar);
304 if(lphs->ThumbActive)
306 HWND hWndOwner,hWndParent;
307 if (nBar == SB_CTL) {
308 hWndParent = GetParent(hWnd);
309 hWndOwner = lphs->hWndOwner;
311 else {
312 hWndParent = hWnd;
313 hWndOwner = 0;
317 SendMessage(hWndParent, lphs->Direction,
318 SB_THUMBPOSITION, MAKELONG(lphs->ThumbVal, hWndOwner));
319 lphs->ThumbActive = FALSE;
322 if (lphs->ButtonDown != 0) {
323 lphs->ButtonDown = 0;
324 if (nBar == SB_CTL) {
325 GetClientRect(lphs->hWndOwner, &rect);
326 InvalidateRect(lphs->hWndOwner, &rect, TRUE);
327 UpdateWindow(lphs->hWndOwner);
329 else {
330 hDC = GetWindowDC(lphs->hWndOwner);
331 StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs);
332 ReleaseDC(lphs->hWndOwner, hDC);
338 void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y)
340 LPHEADSCROLL lphs;
341 HWND hWndParent;
342 HWND hWndOwner;
343 LONG dwOwner;
344 if ((wParam & MK_LBUTTON) == 0) return;
345 lphs = GetScrollObjectStruct(hWnd, nBar);
346 if (lphs->ThumbActive == 0) return;
347 if (nBar == SB_CTL) {
348 hWndParent = GetParent(hWnd);
349 hWndOwner = lphs->hWndOwner;
350 #ifdef DEBUG_SCROLL
351 printf("ScrollBarButtonMove SB_CTL // x=%d y=%d\n", x, y);
352 #endif
354 else {
355 hWndParent = hWnd;
356 hWndOwner = 0;
357 #ifdef DEBUG_SCROLL
358 printf("ScrollBarButtonMove SB_?SCROLL // x=%d y=%d\n", x, y);
359 #endif
362 if(x<lphs->rect.left||x>lphs->rect.right||
363 y<lphs->rect.top||y>lphs->rect.bottom)
366 #ifdef DEBUG_SCROLL
367 printf("Rejecting thumb position !\n");
368 #endif
369 lphs->ThumbVal=lphs->CurVal;/*revert to last set position*/
371 else
374 if (lphs->Direction == WM_VSCROLL) {
375 int butsiz = lphs->rect.right - lphs->rect.left;
376 y = y - butsiz - (butsiz >> 1);
378 else {
379 int butsiz = lphs->rect.bottom - lphs->rect.top;
380 y = x - butsiz - (butsiz >> 1);
382 if(y<0)y=0;
383 if(y>lphs->MaxPix)y=lphs->MaxPix;
384 lphs->ThumbVal = (y * (lphs->MaxVal - lphs->MinVal) /
385 lphs->MaxPix) + lphs->MinVal;
388 #ifdef DEBUG_SCROLL
389 printf("Scroll WM_MOUSEMOVE val=%d pix=%d\n", lphs->ThumbVal, y);
390 #endif
391 SendMessage(hWndParent, lphs->Direction,
392 SB_THUMBTRACK, MAKELONG(lphs->ThumbVal, hWndOwner));
396 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hWnd, WND **wndPtr)
398 WND *Ptr;
399 LPHEADSCROLL lphs;
400 *(wndPtr) = Ptr = WIN_FindWndPtr(hWnd);
401 if (Ptr == 0) {
402 printf("Bad Window handle on ScrollBar !\n");
403 return 0;
405 lphs = *((LPHEADSCROLL *)&Ptr->wExtra[1]);
406 return lphs;
410 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd)
412 WND *wndPtr;
413 LPHEADSCROLL lphs;
414 wndPtr = WIN_FindWndPtr(hWnd);
415 if (wndPtr == 0) {
416 printf("Bad Window handle on ScrollBar !\n");
417 return 0;
419 lphs = *((LPHEADSCROLL *)&wndPtr->wExtra[1]);
420 return lphs;
425 void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs)
427 HWND hWndParent;
428 HBRUSH hBrush;
429 HDC hMemDC;
430 BITMAP bm;
431 RECT rect;
432 UINT i, w, w2, h, h2, siz;
433 char C[128];
434 if (lphs == NULL) return;
435 #ifdef DEBUG_SCROLL
436 printf("StdDrawScrollBar nBar=%04X !\n", nBar);
437 if (lphs->Direction == WM_VSCROLL)
438 printf("StdDrawScrollBar Vertical left=%d top=%d right=%d bottom=%d !\n",
439 lprect->left, lprect->top, lprect->right, lprect->bottom);
440 else
441 printf("StdDrawScrollBar Horizontal left=%d top=%d right=%d bottom=%d !\n",
442 lprect->left, lprect->top, lprect->right, lprect->bottom);
443 #endif
444 if (nBar == SB_CTL)
445 hWndParent = GetParent(hWnd);
446 else
447 hWndParent = lphs->hWndOwner;
448 hBrush = SendMessage(hWndParent, WM_CTLCOLOR, (WORD)hDC,
449 MAKELONG(hWnd, CTLCOLOR_SCROLLBAR));
450 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(LTGRAY_BRUSH);
451 CopyRect(&lphs->rect, lprect);
452 CopyRect(&lphs->rectUp, lprect);
453 CopyRect(&lphs->rectDown, lprect);
454 CopyRect(&rect, lprect);
455 w = rect.right - rect.left;
456 h = rect.bottom - rect.top;
457 if (w == 0 || h == 0) return;
458 if (lphs->Direction == WM_VSCROLL) {
459 if (h > 3 * w)
460 lphs->MaxPix = h - 3 * w;
461 else
462 lphs->MaxPix = 0;
463 if (h > 2 * w)
464 h2 = w;
465 else
466 h2 = (h - 4) / 2;
467 lphs->rectUp.bottom = h2;
468 lphs->rectDown.top = rect.bottom - h2;
470 else {
471 if (w > 3 * h)
472 lphs->MaxPix = w - 3 * h;
473 else
474 lphs->MaxPix = 0;
475 if (w > 2 * h)
476 w2 = h;
477 else
478 w2 = (w - 4) / 2;
479 lphs->rectUp.right = w2;
480 lphs->rectDown.left = rect.right - w2;
482 if (lphs->MaxVal != lphs->MinVal)
483 lphs->CurPix = lphs->MaxPix * (lphs->CurVal - lphs->MinVal) /
484 (lphs->MaxVal - lphs->MinVal);
485 if(lphs->CurPix <0)lphs->CurPix=0;
486 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
488 hMemDC = CreateCompatibleDC(hDC);
489 if (lphs->Direction == WM_VSCROLL) {
490 GetObject(hUpArrow, sizeof(BITMAP), (LPSTR)&bm);
491 if (lphs->ButtonDown == 1)
492 SelectObject(hMemDC, hUpArrowD);
493 else
494 SelectObject(hMemDC, hUpArrow);
495 StretchBlt(hDC, rect.left, rect.top, w, h2, hMemDC,
496 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
497 GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm);
498 if (lphs->ButtonDown == 2)
499 SelectObject(hMemDC, hDnArrowD);
500 else
501 SelectObject(hMemDC, hDnArrow);
502 StretchBlt(hDC, rect.left, rect.bottom - h2, w, h2, hMemDC,
503 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
504 rect.top += h2;
505 rect.bottom -= h2;
507 else {
508 GetObject(hLfArrow, sizeof(BITMAP), (LPSTR)&bm);
509 if (lphs->ButtonDown == 3)
510 SelectObject(hMemDC, hLfArrowD);
511 else
512 SelectObject(hMemDC, hLfArrow);
513 StretchBlt(hDC, rect.left, rect.top, w2, h, hMemDC,
514 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
515 GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm);
516 if (lphs->ButtonDown == 4)
517 SelectObject(hMemDC, hRgArrowD);
518 else
519 SelectObject(hMemDC, hRgArrow);
520 StretchBlt(hDC, rect.right - w2, rect.top, w2, h, hMemDC,
521 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
522 rect.left += w2;
523 rect.right -= w2;
525 DeleteDC(hMemDC);
526 FillRect(hDC, &rect, hBrush);
527 if (lphs->MaxPix != 0) {
528 if (lphs->Direction == WM_VSCROLL)
529 SetRect(&rect, rect.left, rect.top + lphs->CurPix,
530 rect.left + w, rect.top + lphs->CurPix + h2);
531 else
532 SetRect(&rect, rect.left + lphs->CurPix, rect.top,
533 rect.left + lphs->CurPix + w2, rect.top + h);
534 FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
535 InflateRect(&rect, -1, -1);
536 FillRect(hDC, &rect, GetStockObject(LTGRAY_BRUSH));
537 DrawReliefRect(hDC, rect, 2, 0);
538 InflateRect(&rect, -3, -3);
539 DrawReliefRect(hDC, rect, 1, 1);
545 int CreateScrollBarStruct(HWND hWnd)
547 RECT rect;
548 int width, height;
549 WND *wndPtr;
550 LPHEADSCROLL lphs;
551 wndPtr = WIN_FindWndPtr(hWnd);
552 width = wndPtr->rectClient.right - wndPtr->rectClient.left;
553 height = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
554 if (width <= height)
555 lphs = AllocScrollBar(WS_VSCROLL, width, height);
556 else
557 lphs = AllocScrollBar(WS_HSCROLL, width, height);
558 #ifdef DEBUG_SCROLL
559 printf("CreateScrollBarStruct %lX !\n", lphs);
560 #endif
561 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = lphs;
562 lphs->hWndOwner = hWnd;
563 CopyRect(&lphs->rect, &wndPtr->rectClient);
564 return TRUE;
569 LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height)
571 LPHEADSCROLL lphs;
572 if (hUpArrow == (HBITMAP)NULL)
573 hUpArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWI));
574 if (hDnArrow == (HBITMAP)NULL)
575 hDnArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWI));
576 if (hLfArrow == (HBITMAP)NULL)
577 hLfArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWI));
578 if (hRgArrow == (HBITMAP)NULL)
579 hRgArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWI));
580 if (hUpArrowD == (HBITMAP)NULL)
581 hUpArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWD));
582 if (hDnArrowD == (HBITMAP)NULL)
583 hDnArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWD));
584 if (hLfArrowD == (HBITMAP)NULL)
585 hLfArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWD));
586 if (hRgArrowD == (HBITMAP)NULL)
587 hRgArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWD));
588 lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL));
589 if (lphs == 0) {
590 printf("Bad Memory Alloc on ScrollBar !\n");
591 return NULL;
593 lphs->ThumbActive = FALSE;
594 lphs->TimerPending = FALSE;
595 lphs->ButtonDown = 0;
596 lphs->MinVal = 0;
597 lphs->MaxVal = 100;
598 lphs->CurVal = 0;
599 lphs->CurPix = 0;
600 SetRect(&lphs->rect, 0, 0, width, height);
601 if (dwStyle & WS_VSCROLL) {
602 if (height > 3 * width)
603 lphs->MaxPix = height - 3 * width;
604 else
605 lphs->MaxPix = 0;
606 lphs->Direction = WM_VSCROLL;
608 else {
609 if (width > 3 * height)
610 lphs->MaxPix = width - 3 * height;
611 else
612 lphs->MaxPix = 0;
613 lphs->Direction = WM_HSCROLL;
615 if (lphs->MaxPix < 1) lphs->MaxPix = 1;
616 return lphs;
620 void NC_CreateScrollBars(HWND hWnd)
622 RECT rect;
623 int width, height;
624 WND *wndPtr;
625 LPHEADSCROLL lphs;
626 wndPtr = WIN_FindWndPtr(hWnd);
627 GetWindowRect(hWnd, &rect);
628 width = rect.right - rect.left;
629 height = rect.bottom - rect.top;
630 if (wndPtr->dwStyle & WS_VSCROLL) {
631 if (wndPtr->dwStyle & WS_HSCROLL) height -= SYSMETRICS_CYHSCROLL;
632 lphs = AllocScrollBar(WS_VSCROLL, SYSMETRICS_CXVSCROLL, height);
633 #ifdef DEBUG_SCROLL
634 printf("NC_CreateScrollBars Vertical %lX !\n", lphs);
635 #endif
636 lphs->rect.left = width - SYSMETRICS_CYVSCROLL;
637 lphs->rect.right = width;
638 lphs->hWndOwner = hWnd;
639 wndPtr->VScroll = lphs;
640 wndPtr->scroll_flags |= 0x0001;
641 if (wndPtr->dwStyle & WS_HSCROLL) height += SYSMETRICS_CYHSCROLL;
643 if (wndPtr->dwStyle & WS_HSCROLL) {
644 if (wndPtr->dwStyle & WS_VSCROLL) width -= SYSMETRICS_CYVSCROLL;
645 lphs = AllocScrollBar(WS_HSCROLL, width, SYSMETRICS_CYHSCROLL);
646 #ifdef DEBUG_SCROLL
647 printf("NC_CreateScrollBars Horizontal %lX !\n", lphs);
648 #endif
649 lphs->rect.top = height - SYSMETRICS_CYHSCROLL;
650 lphs->rect.bottom = height;
651 lphs->hWndOwner = hWnd;
652 wndPtr->HScroll = lphs;
653 wndPtr->scroll_flags |= 0x0002;
658 /*************************************************************************
659 * GetScrollObjectStruct [internal]
661 LPHEADSCROLL GetScrollObjectStruct(HWND hWnd, int nBar)
663 WND *wndPtr;
664 if (nBar != SB_CTL) {
665 wndPtr = WIN_FindWndPtr(hWnd);
666 if (nBar == SB_VERT) return (LPHEADSCROLL)wndPtr->VScroll;
667 if (nBar == SB_HORZ) return (LPHEADSCROLL)wndPtr->HScroll;
668 return NULL;
670 return ScrollBarGetStorageHeader(hWnd);
674 /*************************************************************************
675 * SetScrollPos [USER.62]
677 int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw)
679 LPHEADSCROLL lphs;
680 HDC hDC;
681 int nRet;
682 lphs = GetScrollObjectStruct(hWnd, nBar);
683 if (lphs == NULL) return 0;
684 nRet = lphs->CurVal;
685 lphs->CurVal = (short)nPos;
686 if (lphs->MaxVal != lphs->MinVal)
687 lphs->CurPix = lphs->MaxPix * (lphs->CurVal - lphs->MinVal) /
688 (lphs->MaxVal - lphs->MinVal);
689 if(lphs->CurPix <0)lphs->CurPix=0;
691 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
692 #ifdef DEBUG_SCROLL
693 printf("SetScrollPos val=%d pixval=%d pixmax%d\n",
694 (short)nPos, lphs->CurPix, lphs->MaxPix);
695 printf("SetScrollPos min=%d max=%d\n",
696 lphs->MinVal, lphs->MaxVal);
697 #endif
698 if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) {
699 if (nBar == SB_CTL) {
700 InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE);
701 UpdateWindow(lphs->hWndOwner);
703 else {
704 if (lphs->rect.right != 0 && lphs->rect.bottom != 0) {
705 hDC = GetWindowDC(lphs->hWndOwner);
706 StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs);
707 ReleaseDC(lphs->hWndOwner, hDC);
711 return nRet;
716 /*************************************************************************
717 * GetScrollPos [USER.63]
719 int GetScrollPos(HWND hWnd, int nBar)
721 LPHEADSCROLL lphs;
722 lphs = GetScrollObjectStruct(hWnd, nBar);
723 if (lphs == NULL) return 0;
724 return lphs->CurVal;
729 /*************************************************************************
730 * SetScrollRange [USER.64]
732 void SetScrollRange(HWND hWnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw)
734 LPHEADSCROLL lphs;
735 HDC hDC;
736 lphs = GetScrollObjectStruct(hWnd, nBar);
737 if (lphs == NULL) return;
739 /* should a bad range be rejected here?
741 lphs->MinVal = (short)MinPos;
742 lphs->MaxVal = (short)MaxPos;
743 if (lphs->MaxVal != lphs->MinVal)
744 lphs->CurPix = lphs->MaxPix * (lphs->CurVal - lphs->MinVal) /
745 (lphs->MaxVal - lphs->MinVal);
746 if(lphs->CurPix <0)lphs->CurPix=0;
747 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
748 #ifdef DEBUG_SCROLL
749 printf("SetScrollRange min=%d max=%d\n", lphs->MinVal, lphs->MaxVal);
750 #endif
751 if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) {
752 if (nBar == SB_CTL) {
753 InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE);
754 UpdateWindow(lphs->hWndOwner);
756 else {
757 if (lphs->rect.right != 0 && lphs->rect.bottom != 0) {
758 hDC = GetWindowDC(lphs->hWndOwner);
759 StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs);
760 ReleaseDC(lphs->hWndOwner, hDC);
768 /*************************************************************************
769 * GetScrollRange [USER.65]
771 void GetScrollRange(HWND hWnd, int nBar, LPINT lpMin, LPINT lpMax)
773 LPHEADSCROLL lphs;
774 lphs = GetScrollObjectStruct(hWnd, nBar);
775 if (lphs == NULL) return;
776 *lpMin = lphs->MinVal;
777 *lpMax = lphs->MaxVal;
782 /*************************************************************************
783 * ShowScrollBar [USER.267]
785 void ShowScrollBar(HWND hWnd, WORD wBar, BOOL bFlag)
787 WND *wndPtr;
788 printf("ShowScrollBar hWnd=%04X wBar=%d bFlag=%d\n", hWnd, wBar, bFlag);
789 #ifdef DEBUG_SCROLL
790 printf("ShowScrollBar hWnd=%04X wBar=%d bFlag=%d\n", hWnd, wBar, bFlag);
791 #endif
792 if (wBar == SB_CTL) {
793 if (bFlag)
794 ShowWindow(hWnd, SW_SHOW);
795 else
796 ShowWindow(hWnd, SW_HIDE);
797 return;
799 wndPtr = WIN_FindWndPtr(hWnd);
800 if ((wBar == SB_VERT) || (wBar == SB_BOTH)) {
801 if (bFlag)
802 wndPtr->scroll_flags != 0x0001;
803 else
804 wndPtr->scroll_flags &= 0xFFFE;
806 if ((wBar == SB_HORZ) || (wBar == SB_BOTH)) {
807 if (bFlag)
808 wndPtr->scroll_flags != 0x0002;
809 else
810 wndPtr->scroll_flags &= 0xFFFD;
812 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
813 SWP_NOZORDER | SWP_NOMOVE |
814 SWP_NOSIZE | SWP_FRAMECHANGED);