Release 940510
[wine/multimedia.git] / controls / scroll.c
blobaf1d12db40e77bf6bc3e25b5ee3da156b3ec3885
1 /*
2 * Interface code to SCROLLBAR widget
4 * Copyright Martin Ayotte, 1993
6 */
8 /*
9 #define DEBUG_SCROLL
11 static char Copyright[] = "Copyright Martin Ayotte, 1993";
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include "windows.h"
18 #include "sysmetrics.h"
19 #include "scroll.h"
20 #include "heap.h"
21 #include "win.h"
22 #include "prototypes.h"
24 HBITMAP hUpArrow = 0;
25 HBITMAP hDnArrow = 0;
26 HBITMAP hLfArrow = 0;
27 HBITMAP hRgArrow = 0;
28 HBITMAP hUpArrowD = 0;
29 HBITMAP hDnArrowD = 0;
30 HBITMAP hLfArrowD = 0;
31 HBITMAP hRgArrowD = 0;
33 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hWnd, WND **wndPtr);
34 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd);
35 LPHEADSCROLL GetScrollObjectStruct(HWND hWnd, int nBar);
36 void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y);
37 void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y);
38 void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y);
39 void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs);
40 int CreateScrollBarStruct(HWND hWnd);
41 void NC_CreateScrollBars(HWND hWnd);
42 LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height);
45 /***********************************************************************
46 * WIDGETS_ScrollBarWndProc
48 LONG ScrollBarWndProc( HWND hWnd, WORD message, WORD wParam, LONG lParam )
50 WORD wRet;
51 short x, y;
52 short width, height;
53 WND *wndPtr;
54 LPHEADSCROLL lphs;
55 PAINTSTRUCT ps;
56 HDC hDC;
57 BITMAP bm;
58 RECT rect, rect2;
59 LPCREATESTRUCT lpCreat;
60 static RECT rectsel;
61 switch(message) {
62 case WM_CREATE:
63 lpCreat = (LPCREATESTRUCT)lParam;
64 if (lpCreat->style & SBS_VERT) {
65 if (lpCreat->style & SBS_LEFTALIGN)
66 SetWindowPos(hWnd, 0, 0, 0, 16, lpCreat->cy,
67 SWP_NOZORDER | SWP_NOMOVE);
68 if (lpCreat->style & SBS_RIGHTALIGN)
69 SetWindowPos(hWnd, 0, lpCreat->x + lpCreat->cx - 16,
70 lpCreat->y, 16, lpCreat->cy, SWP_NOZORDER);
72 if (lpCreat->style & SBS_HORZ) {
73 if (lpCreat->style & SBS_TOPALIGN)
74 SetWindowPos(hWnd, 0, 0, 0, lpCreat->cx, 16,
75 SWP_NOZORDER | SWP_NOMOVE);
76 if (lpCreat->style & SBS_BOTTOMALIGN)
77 SetWindowPos(hWnd, 0, lpCreat->x,
78 lpCreat->y + lpCreat->cy - 16,
79 lpCreat->cx, 16, SWP_NOZORDER);
81 CreateScrollBarStruct(hWnd);
82 #ifdef DEBUG_SCROLL
83 printf("ScrollBar Creation !\n");
84 #endif
85 return 0;
86 case WM_DESTROY:
87 lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
88 if (lphs == 0) return 0;
89 #ifdef DEBUG_SCROLL
90 printf("ScrollBar WM_DESTROY %lX !\n", lphs);
91 #endif
92 free(lphs);
93 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0;
94 return 0;
96 case WM_LBUTTONDOWN:
97 SetCapture(hWnd);
98 ScrollBarButtonDown(hWnd, SB_CTL, LOWORD(lParam), HIWORD(lParam));
99 break;
100 case WM_LBUTTONUP:
101 ReleaseCapture();
102 ScrollBarButtonUp(hWnd, SB_CTL, LOWORD(lParam), HIWORD(lParam));
103 break;
105 case WM_MOUSEMOVE:
106 ScrollBarMouseMove(hWnd, SB_CTL, wParam, LOWORD(lParam), HIWORD(lParam));
107 break;
108 case WM_KEYDOWN:
109 case WM_KEYUP:
110 case WM_CHAR:
111 lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
112 return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
114 case WM_TIMER:
115 #ifdef DEBUG_SCROLL
116 printf("ScrollBar WM_TIMER wParam=%X lParam=%lX !\n", wParam, lParam);
117 #endif
118 lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
119 KillTimer(hWnd, wParam);
120 switch(lphs->ButtonDown) {
121 case 0:
122 lphs->TimerPending = FALSE;
123 return 0;
124 case 1:
125 case 3:
126 SendMessage(wndPtr->hwndParent, lphs->Direction,
127 SB_LINEUP, MAKELONG(0, hWnd));
128 break;
129 case 2:
130 case 4:
131 SendMessage(wndPtr->hwndParent, lphs->Direction,
132 SB_LINEDOWN, MAKELONG(0, hWnd));
133 break;
134 case 5:
135 SendMessage(wndPtr->hwndParent, lphs->Direction,
136 SB_PAGEUP, MAKELONG(0, hWnd));
137 break;
138 case 6:
139 SendMessage(wndPtr->hwndParent, lphs->Direction,
140 SB_PAGEDOWN, MAKELONG(0, hWnd));
141 break;
143 SetTimer(hWnd, 1, 100, NULL);
144 return 0;
146 case WM_PAINT:
147 hDC = BeginPaint(hWnd, &ps);
148 lphs = ScrollBarGetStorageHeader(hWnd);
149 if (lphs != NULL) {
150 GetClientRect(hWnd, &rect);
151 StdDrawScrollBar(hWnd, hDC, SB_CTL, &rect, lphs);
153 EndPaint(hWnd, &ps);
154 break;
155 default:
156 return DefWindowProc( hWnd, message, wParam, lParam );
158 return(0);
163 void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y)
165 LPHEADSCROLL lphs;
166 HWND hWndParent;
167 RECT rect, rect2;
168 int width, height;
169 LONG dwOwner;
170 lphs = GetScrollObjectStruct(hWnd, nBar);
171 if (nBar == SB_CTL) {
172 hWndParent = GetParent(hWnd);
173 dwOwner = MAKELONG(0, lphs->hWndOwner);
174 #ifdef DEBUG_SCROLL
175 printf("ScrollBarButtonDown SB_CTL // x=%d y=%d\n", x, y);
176 #endif
178 else {
179 hWndParent = hWnd;
180 dwOwner = 0L;
181 #ifdef DEBUG_SCROLL
182 printf("ScrollBarButtonDown SB_?SCROLL // x=%d y=%d\n", x, y);
183 #endif
186 SetFocus(lphs->hWndOwner);
188 CopyRect(&rect, &lphs->rect);
189 #ifdef DEBUG_SCROLL
190 printf("ScrollDown / x=%d y=%d left=%d top=%d right=%d bottom=%d \n",
191 x, y, rect.left, rect.top, rect.right, rect.bottom);
192 #endif
193 if (lphs->Direction == WM_VSCROLL) {
194 width = rect.right - rect.left;
195 if (y <= lphs->rectUp.bottom) {
196 lphs->ButtonDown = 1;
197 InvalidateRect(lphs->hWndOwner, &lphs->rectUp, TRUE);
198 #ifdef DEBUG_SCROLL
199 printf("ScrollBarButtonDown send SB_LINEUP\n");
200 #endif
201 SendMessage(hWndParent, lphs->Direction,
202 SB_LINEUP, dwOwner);
204 if (y >= lphs->rectDown.top) {
205 lphs->ButtonDown = 2;
206 InvalidateRect(lphs->hWndOwner, &lphs->rectDown, TRUE);
207 #ifdef DEBUG_SCROLL
208 printf("ScrollBarButtonDown send SB_LINEDOWN\n");
209 #endif
210 SendMessage(hWndParent, lphs->Direction,
211 SB_LINEDOWN, dwOwner);
213 if (y > lphs->rectUp.bottom && y < (lphs->CurPix + width)) {
214 lphs->ButtonDown = 5;
215 #ifdef DEBUG_SCROLL
216 printf("ScrollBarButtonDown send SB_PAGEUP\n");
217 #endif
218 SendMessage(hWndParent, lphs->Direction,
219 SB_PAGEUP, dwOwner);
221 if (y < lphs->rectDown.top && y > (lphs->CurPix + (width << 1))) {
222 lphs->ButtonDown = 6;
223 #ifdef DEBUG_SCROLL
224 printf("ScrollBarButtonDown send SB_PAGEDOWN\n");
225 #endif
226 SendMessage(hWndParent, lphs->Direction,
227 SB_PAGEDOWN, dwOwner);
229 if (lphs->MaxPix > 0 && y > (lphs->CurPix + width) &&
230 y < (lphs->CurPix + (width << 1))) {
231 lphs->ThumbActive = TRUE;
232 #ifdef DEBUG_SCROLL
233 printf("THUMB DOWN !\n");
234 #endif
237 else {
238 height = rect.bottom - rect.top;
239 if (x <= lphs->rectUp.right) {
240 lphs->ButtonDown = 3;
241 InvalidateRect(lphs->hWndOwner, &lphs->rectUp, TRUE);
242 #ifdef DEBUG_SCROLL
243 printf("ScrollBarButtonDown send SB_LINEUP\n");
244 #endif
245 SendMessage(hWndParent, lphs->Direction,
246 SB_LINEUP, dwOwner);
248 if (x >= lphs->rectDown.left) {
249 lphs->ButtonDown = 4;
250 InvalidateRect(lphs->hWndOwner, &lphs->rectDown, TRUE);
251 #ifdef DEBUG_SCROLL
252 printf("ScrollBarButtonDown send SB_LINEDOWN\n");
253 #endif
254 SendMessage(hWndParent, lphs->Direction,
255 SB_LINEDOWN, dwOwner);
257 if (x > lphs->rectUp.right && x < (lphs->CurPix + height)) {
258 lphs->ButtonDown = 5;
259 #ifdef DEBUG_SCROLL
260 printf("ScrollBarButtonDown send SB_PAGEUP\n");
261 #endif
262 SendMessage(hWndParent, lphs->Direction,
263 SB_PAGEUP, dwOwner);
265 if (x < lphs->rectDown.left && x > (lphs->CurPix + (height << 1))) {
266 lphs->ButtonDown = 6;
267 #ifdef DEBUG_SCROLL
268 printf("ScrollBarButtonDown send SB_PAGEDOWN\n");
269 #endif
270 SendMessage(hWndParent, lphs->Direction,
271 SB_PAGEDOWN, dwOwner);
273 if (lphs->MaxPix > 0 && x > (lphs->CurPix + height) &&
274 x < (lphs->CurPix + (height << 1))) {
275 lphs->ThumbActive = TRUE;
276 #ifdef DEBUG_SCROLL
277 printf("THUMB DOWN !\n");
278 #endif
281 if (lphs->ButtonDown != 0) {
282 UpdateWindow(lphs->hWndOwner);
283 if (!lphs->TimerPending && nBar == SB_CTL) {
284 lphs->TimerPending = TRUE;
285 SetTimer(lphs->hWndOwner, 1, 500, NULL);
291 void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y)
293 LPHEADSCROLL lphs;
294 RECT rect, rect2;
295 HDC hDC;
296 #ifdef DEBUG_SCROLL
297 printf("ScrollBarButtonUp // x=%d y=%d\n", x, y);
298 #endif
299 lphs = GetScrollObjectStruct(hWnd, nBar);
300 lphs->ThumbActive = FALSE;
301 if (lphs->ButtonDown != 0) {
302 lphs->ButtonDown = 0;
303 if (nBar == SB_CTL) {
304 GetClientRect(lphs->hWndOwner, &rect);
305 InvalidateRect(lphs->hWndOwner, &rect, TRUE);
306 UpdateWindow(lphs->hWndOwner);
308 else {
309 hDC = GetWindowDC(lphs->hWndOwner);
310 StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs);
311 ReleaseDC(lphs->hWndOwner, hDC);
317 void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y)
319 LPHEADSCROLL lphs;
320 HWND hWndParent;
321 HWND hWndOwner;
322 LONG dwOwner;
323 if ((wParam & MK_LBUTTON) == 0) return;
324 lphs = GetScrollObjectStruct(hWnd, nBar);
325 if (lphs->ThumbActive == 0) return;
326 if (nBar == SB_CTL) {
327 hWndParent = GetParent(hWnd);
328 hWndOwner = lphs->hWndOwner;
329 #ifdef DEBUG_SCROLL
330 printf("ScrollBarButtonMove SB_CTL // x=%d y=%d\n", x, y);
331 #endif
333 else {
334 hWndParent = hWnd;
335 hWndOwner = 0;
336 #ifdef DEBUG_SCROLL
337 printf("ScrollBarButtonMove SB_?SCROLL // x=%d y=%d\n", x, y);
338 #endif
340 if (lphs->Direction == WM_VSCROLL) {
341 int butsiz = lphs->rect.right - lphs->rect.left;
342 y = y - butsiz - (butsiz >> 1);
344 else {
345 int butsiz = lphs->rect.bottom - lphs->rect.top;
346 y = x - butsiz - (butsiz >> 1);
348 x = (y * (lphs->MaxVal - lphs->MinVal) /
349 lphs->MaxPix) + lphs->MinVal;
350 #ifdef DEBUG_SCROLL
351 printf("Scroll WM_MOUSEMOVE val=%d pix=%d\n", x, y);
352 #endif
353 SendMessage(hWndParent, lphs->Direction,
354 SB_THUMBTRACK, MAKELONG(x, hWndOwner));
358 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hWnd, WND **wndPtr)
360 WND *Ptr;
361 LPHEADSCROLL lphs;
362 *(wndPtr) = Ptr = WIN_FindWndPtr(hWnd);
363 if (Ptr == 0) {
364 printf("Bad Window handle on ScrollBar !\n");
365 return 0;
367 lphs = *((LPHEADSCROLL *)&Ptr->wExtra[1]);
368 return lphs;
372 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd)
374 WND *wndPtr;
375 LPHEADSCROLL lphs;
376 wndPtr = WIN_FindWndPtr(hWnd);
377 if (wndPtr == 0) {
378 printf("Bad Window handle on ScrollBar !\n");
379 return 0;
381 lphs = *((LPHEADSCROLL *)&wndPtr->wExtra[1]);
382 return lphs;
387 void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs)
389 HWND hWndParent;
390 HBRUSH hBrush;
391 HDC hMemDC;
392 BITMAP bm;
393 RECT rect;
394 UINT i, w, w2, h, h2, siz;
395 char C[128];
396 if (lphs == NULL) return;
397 #ifdef DEBUG_SCROLL
398 printf("StdDrawScrollBar nBar=%04X !\n", nBar);
399 if (lphs->Direction == WM_VSCROLL)
400 printf("StdDrawScrollBar Vertical left=%d top=%d right=%d bottom=%d !\n",
401 lprect->left, lprect->top, lprect->right, lprect->bottom);
402 else
403 printf("StdDrawScrollBar Horizontal left=%d top=%d right=%d bottom=%d !\n",
404 lprect->left, lprect->top, lprect->right, lprect->bottom);
405 #endif
406 if (nBar == SB_CTL)
407 hWndParent = GetParent(hWnd);
408 else
409 hWndParent = lphs->hWndOwner;
410 hBrush = SendMessage(hWndParent, WM_CTLCOLOR, (WORD)hDC,
411 MAKELONG(hWnd, CTLCOLOR_SCROLLBAR));
412 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(LTGRAY_BRUSH);
413 CopyRect(&lphs->rect, lprect);
414 CopyRect(&lphs->rectUp, lprect);
415 CopyRect(&lphs->rectDown, lprect);
416 CopyRect(&rect, lprect);
417 w = rect.right - rect.left;
418 h = rect.bottom - rect.top;
419 if (w == 0 || h == 0) return;
420 if (lphs->Direction == WM_VSCROLL) {
421 if (h > 3 * w)
422 lphs->MaxPix = h - 3 * w;
423 else
424 lphs->MaxPix = 0;
425 if (h > 2 * w)
426 h2 = w;
427 else
428 h2 = (h - 4) / 2;
429 lphs->rectUp.bottom = h2;
430 lphs->rectDown.top = rect.bottom - h2;
432 else {
433 if (w > 3 * h)
434 lphs->MaxPix = w - 3 * h;
435 else
436 lphs->MaxPix = 0;
437 if (w > 2 * h)
438 w2 = h;
439 else
440 w2 = (w - 4) / 2;
441 lphs->rectUp.right = w2;
442 lphs->rectDown.left = rect.right - w2;
444 if (lphs->MaxVal != lphs->MinVal)
445 lphs->CurPix = lphs->MaxPix * (abs((short)lphs->CurVal) - abs(lphs->MinVal)) /
446 (abs(lphs->MaxVal) - abs(lphs->MinVal));
447 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
448 hMemDC = CreateCompatibleDC(hDC);
449 if (lphs->Direction == WM_VSCROLL) {
450 GetObject(hUpArrow, sizeof(BITMAP), (LPSTR)&bm);
451 if (lphs->ButtonDown == 1)
452 SelectObject(hMemDC, hUpArrowD);
453 else
454 SelectObject(hMemDC, hUpArrow);
455 StretchBlt(hDC, rect.left, rect.top, w, h2, hMemDC,
456 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
457 GetObject(hDnArrow, sizeof(BITMAP), (LPSTR)&bm);
458 if (lphs->ButtonDown == 2)
459 SelectObject(hMemDC, hDnArrowD);
460 else
461 SelectObject(hMemDC, hDnArrow);
462 StretchBlt(hDC, rect.left, rect.bottom - h2, w, h2, hMemDC,
463 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
464 rect.top += h2;
465 rect.bottom -= h2;
467 else {
468 GetObject(hLfArrow, sizeof(BITMAP), (LPSTR)&bm);
469 if (lphs->ButtonDown == 3)
470 SelectObject(hMemDC, hLfArrowD);
471 else
472 SelectObject(hMemDC, hLfArrow);
473 StretchBlt(hDC, rect.left, rect.top, w2, h, hMemDC,
474 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
475 GetObject(hRgArrow, sizeof(BITMAP), (LPSTR)&bm);
476 if (lphs->ButtonDown == 4)
477 SelectObject(hMemDC, hRgArrowD);
478 else
479 SelectObject(hMemDC, hRgArrow);
480 StretchBlt(hDC, rect.right - w2, rect.top, w2, h, hMemDC,
481 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
482 rect.left += w2;
483 rect.right -= w2;
485 DeleteDC(hMemDC);
486 FillRect(hDC, &rect, hBrush);
487 if (lphs->MaxPix != 0) {
488 if (lphs->Direction == WM_VSCROLL)
489 SetRect(&rect, rect.left, rect.top + lphs->CurPix,
490 rect.left + w, rect.top + lphs->CurPix + h2);
491 else
492 SetRect(&rect, rect.left + lphs->CurPix, rect.top,
493 rect.left + lphs->CurPix + w2, rect.top + h);
494 FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
495 InflateRect(&rect, -1, -1);
496 FillRect(hDC, &rect, GetStockObject(LTGRAY_BRUSH));
497 DrawReliefRect(hDC, rect, 2, 0);
498 InflateRect(&rect, -3, -3);
499 DrawReliefRect(hDC, rect, 1, 1);
505 int CreateScrollBarStruct(HWND hWnd)
507 RECT rect;
508 int width, height;
509 WND *wndPtr;
510 LPHEADSCROLL lphs;
511 wndPtr = WIN_FindWndPtr(hWnd);
512 width = wndPtr->rectClient.right - wndPtr->rectClient.left;
513 height = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
514 if (width <= height)
515 lphs = AllocScrollBar(WS_VSCROLL, width, height);
516 else
517 lphs = AllocScrollBar(WS_HSCROLL, width, height);
518 #ifdef DEBUG_SCROLL
519 printf("CreateScrollBarStruct %lX !\n", lphs);
520 #endif
521 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = lphs;
522 lphs->hWndOwner = hWnd;
523 CopyRect(&lphs->rect, &wndPtr->rectClient);
524 return TRUE;
529 LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height)
531 LPHEADSCROLL lphs;
532 if (hUpArrow == (HBITMAP)NULL)
533 hUpArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWI));
534 if (hDnArrow == (HBITMAP)NULL)
535 hDnArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWI));
536 if (hLfArrow == (HBITMAP)NULL)
537 hLfArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWI));
538 if (hRgArrow == (HBITMAP)NULL)
539 hRgArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWI));
540 if (hUpArrowD == (HBITMAP)NULL)
541 hUpArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWD));
542 if (hDnArrowD == (HBITMAP)NULL)
543 hDnArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWD));
544 if (hLfArrowD == (HBITMAP)NULL)
545 hLfArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWD));
546 if (hRgArrowD == (HBITMAP)NULL)
547 hRgArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWD));
548 lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL));
549 if (lphs == 0) {
550 printf("Bad Memory Alloc on ScrollBar !\n");
551 return NULL;
553 lphs->ThumbActive = FALSE;
554 lphs->TimerPending = FALSE;
555 lphs->ButtonDown = 0;
556 lphs->MinVal = 0;
557 lphs->MaxVal = 100;
558 lphs->CurVal = 0;
559 lphs->CurPix = 0;
560 SetRect(&lphs->rect, 0, 0, width, height);
561 if (dwStyle & WS_VSCROLL) {
562 if (height > 3 * width)
563 lphs->MaxPix = height - 3 * width;
564 else
565 lphs->MaxPix = 0;
566 lphs->Direction = WM_VSCROLL;
568 else {
569 if (width > 3 * height)
570 lphs->MaxPix = width - 3 * height;
571 else
572 lphs->MaxPix = 0;
573 lphs->Direction = WM_HSCROLL;
575 if (lphs->MaxPix < 1) lphs->MaxPix = 1;
576 return lphs;
580 void NC_CreateScrollBars(HWND hWnd)
582 RECT rect;
583 int width, height;
584 WND *wndPtr;
585 LPHEADSCROLL lphs;
586 wndPtr = WIN_FindWndPtr(hWnd);
587 GetWindowRect(hWnd, &rect);
588 width = rect.right - rect.left;
589 height = rect.bottom - rect.top;
590 if (wndPtr->dwStyle & WS_VSCROLL) {
591 if (wndPtr->dwStyle & WS_HSCROLL) height -= SYSMETRICS_CYHSCROLL;
592 lphs = AllocScrollBar(WS_VSCROLL, SYSMETRICS_CXVSCROLL, height);
593 #ifdef DEBUG_SCROLL
594 printf("NC_CreateScrollBars Vertical %lX !\n", lphs);
595 #endif
596 lphs->rect.left = width - SYSMETRICS_CYVSCROLL;
597 lphs->rect.right = width;
598 lphs->hWndOwner = hWnd;
599 wndPtr->VScroll = lphs;
600 if (wndPtr->dwStyle & WS_HSCROLL) height += SYSMETRICS_CYHSCROLL;
602 if (wndPtr->dwStyle & WS_HSCROLL) {
603 if (wndPtr->dwStyle & WS_VSCROLL) width -= SYSMETRICS_CYVSCROLL;
604 lphs = AllocScrollBar(WS_HSCROLL, width, SYSMETRICS_CYHSCROLL);
605 #ifdef DEBUG_SCROLL
606 printf("NC_CreateScrollBars Horizontal %lX !\n", lphs);
607 #endif
608 lphs->rect.top = height - SYSMETRICS_CYHSCROLL;
609 lphs->rect.bottom = height;
610 lphs->hWndOwner = hWnd;
611 wndPtr->HScroll = lphs;
616 /*************************************************************************
617 * GetScrollObjectStruct [internal]
619 LPHEADSCROLL GetScrollObjectStruct(HWND hWnd, int nBar)
621 WND *wndPtr;
622 if (nBar != SB_CTL) {
623 wndPtr = WIN_FindWndPtr(hWnd);
624 if (nBar == SB_VERT) return (LPHEADSCROLL)wndPtr->VScroll;
625 if (nBar == SB_HORZ) return (LPHEADSCROLL)wndPtr->HScroll;
626 return NULL;
628 return ScrollBarGetStorageHeader(hWnd);
632 /*************************************************************************
633 * SetScrollPos [USER.62]
635 int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw)
637 LPHEADSCROLL lphs;
638 HDC hDC;
639 int nRet;
640 lphs = GetScrollObjectStruct(hWnd, nBar);
641 if (lphs == NULL) return 0;
642 nRet = lphs->CurVal;
643 lphs->CurVal = (short)nPos;
644 if (lphs->MaxVal != lphs->MinVal)
645 lphs->CurPix = lphs->MaxPix * (abs((short)nPos) - abs(lphs->MinVal)) /
646 (abs(lphs->MaxVal) - abs(lphs->MinVal));
647 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
648 #ifdef DEBUG_SCROLL
649 printf("SetScrollPos val=%d pixval=%d pixmax%d\n",
650 (short)nPos, lphs->CurPix, lphs->MaxPix);
651 printf("SetScrollPos min=%d max=%d\n",
652 lphs->MinVal, lphs->MaxVal);
653 #endif
654 if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) {
655 if (nBar == SB_CTL) {
656 InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE);
657 UpdateWindow(lphs->hWndOwner);
659 else {
660 if (lphs->rect.right != 0 && lphs->rect.bottom != 0) {
661 hDC = GetWindowDC(lphs->hWndOwner);
662 StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs);
663 ReleaseDC(lphs->hWndOwner, hDC);
667 return nRet;
672 /*************************************************************************
673 * GetScrollPos [USER.63]
675 int GetScrollPos(HWND hWnd, int nBar)
677 LPHEADSCROLL lphs;
678 lphs = GetScrollObjectStruct(hWnd, nBar);
679 if (lphs == NULL) return 0;
680 return lphs->CurVal;
685 /*************************************************************************
686 * SetScrollRange [USER.64]
688 void SetScrollRange(HWND hWnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw)
690 LPHEADSCROLL lphs;
691 HDC hDC;
692 lphs = GetScrollObjectStruct(hWnd, nBar);
693 if (lphs == NULL) return;
694 lphs->MinVal = (short)MinPos;
695 lphs->MaxVal = (short)MaxPos;
696 if (lphs->MaxVal != lphs->MinVal)
697 lphs->CurPix = abs(lphs->MaxVal) *
698 (abs(lphs->CurVal) - abs(lphs->MinVal)) /
699 (abs(lphs->MaxVal) - abs(lphs->MinVal));
700 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
701 #ifdef DEBUG_SCROLL
702 printf("SetScrollRange min=%d max=%d\n", lphs->MinVal, lphs->MaxVal);
703 #endif
704 if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) {
705 if (nBar == SB_CTL) {
706 InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE);
707 UpdateWindow(lphs->hWndOwner);
709 else {
710 if (lphs->rect.right != 0 && lphs->rect.bottom != 0) {
711 hDC = GetWindowDC(lphs->hWndOwner);
712 StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs);
713 ReleaseDC(lphs->hWndOwner, hDC);
721 /*************************************************************************
722 * GetScrollRange [USER.65]
724 void GetScrollRange(HWND hWnd, int nBar, LPINT lpMin, LPINT lpMax)
726 LPHEADSCROLL lphs;
727 lphs = GetScrollObjectStruct(hWnd, nBar);
728 if (lphs == NULL) return;
729 *lpMin = lphs->MinVal;
730 *lpMax = lphs->MaxVal;
735 /*************************************************************************
736 * ShowScrollBar [USER.267]
738 void ShowScrollBar(HWND hWnd, WORD wBar, BOOL bFlag)
740 WND *wndPtr;
741 #ifdef DEBUG_SCROLL
742 printf("ShowScrollBar hWnd=%04X wBar=%d bFlag=%d\n", hWnd, wBar, bFlag);
743 #endif
744 if (wBar == SB_CTL) {
745 if (bFlag)
746 ShowWindow(hWnd, SW_SHOW);
747 else
748 ShowWindow(hWnd, SW_HIDE);
749 return;
751 wndPtr = WIN_FindWndPtr(hWnd);
753 if ((wBar == SB_VERT) || (wBar == SB_BOTH)) {
754 if (bFlag)
755 wndPtr->dwStyle |= WS_VSCROLL;
756 else
757 wndPtr->dwStyle &= 0xFFFFFFFFL ^ WS_VSCROLL;
759 if ((wBar == SB_HORZ) || (wBar == SB_BOTH)) {
760 if (bFlag)
761 wndPtr->dwStyle |= WS_HSCROLL;
762 else
763 wndPtr->dwStyle &= 0xFFFFFFFFL ^ WS_HSCROLL;