Release 941017
[wine/gsoc-2012-control.git] / controls / scroll.c
blob36c7ef80b0dc0b089280f9a103d0e800694129ea
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 */
10 static char Copyright[] = "Copyright Martin Ayotte, 1993";
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include "windows.h"
17 #include "sysmetrics.h"
18 #include "scroll.h"
19 #include "heap.h"
20 #include "win.h"
21 #include "prototypes.h"
22 #include "stddebug.h"
23 /* #define DEBUG_SCROLL /* */
24 /* #undef DEBUG_SCROLL /* */
25 #include "debug.h"
28 HBITMAP hUpArrow = 0;
29 HBITMAP hDnArrow = 0;
30 HBITMAP hLfArrow = 0;
31 HBITMAP hRgArrow = 0;
32 HBITMAP hUpArrowD = 0;
33 HBITMAP hDnArrowD = 0;
34 HBITMAP hLfArrowD = 0;
35 HBITMAP hRgArrowD = 0;
37 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hWnd, WND **wndPtr);
38 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd);
39 LPHEADSCROLL GetScrollObjectStruct(HWND hWnd, int nBar);
40 void ScrollBarButtonDown(HWND hWnd, int nBar, int x, int y);
41 void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y);
42 void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y);
43 void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs);
44 int CreateScrollBarStruct(HWND hWnd);
45 void NC_CreateScrollBars(HWND hWnd);
46 LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height);
49 /***********************************************************************
50 * WIDGETS_ScrollBarWndProc
52 LONG ScrollBarWndProc( HWND hWnd, WORD message, WORD wParam, LONG lParam )
54 WORD wRet;
55 short x, y;
56 short width, height;
57 WND *wndPtr;
58 LPHEADSCROLL lphs;
59 PAINTSTRUCT ps;
60 HDC hDC;
61 BITMAP bm;
62 RECT rect, rect2;
63 LPCREATESTRUCT lpCreat;
64 static RECT rectsel;
65 POINT *pt;
66 pt=(POINT*)&lParam;
67 switch(message) {
68 case WM_CREATE:
69 lpCreat = (LPCREATESTRUCT)lParam;
70 if (lpCreat->style & SBS_VERT) {
71 if (lpCreat->style & SBS_LEFTALIGN)
72 SetWindowPos(hWnd, 0, 0, 0, 16, lpCreat->cy,
73 SWP_NOZORDER | SWP_NOMOVE);
74 if (lpCreat->style & SBS_RIGHTALIGN)
75 SetWindowPos(hWnd, 0, lpCreat->x + lpCreat->cx - 16,
76 lpCreat->y, 16, lpCreat->cy, SWP_NOZORDER);
78 if (lpCreat->style & SBS_HORZ) {
79 if (lpCreat->style & SBS_TOPALIGN)
80 SetWindowPos(hWnd, 0, 0, 0, lpCreat->cx, 16,
81 SWP_NOZORDER | SWP_NOMOVE);
82 if (lpCreat->style & SBS_BOTTOMALIGN)
83 SetWindowPos(hWnd, 0, lpCreat->x,
84 lpCreat->y + lpCreat->cy - 16,
85 lpCreat->cx, 16, SWP_NOZORDER);
87 CreateScrollBarStruct(hWnd);
88 dprintf_scroll(stddeb,"ScrollBar Creation !\n");
89 return 0;
90 case WM_DESTROY:
91 lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
92 if (lphs == 0) return 0;
93 dprintf_scroll(stddeb,"ScrollBar WM_DESTROY %lX !\n", lphs);
94 free(lphs);
95 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = 0;
96 return 0;
98 case WM_LBUTTONDOWN:
99 SetCapture(hWnd);
100 ScrollBarButtonDown(hWnd, SB_CTL, pt->x,pt->y);
101 break;
102 case WM_LBUTTONUP:
103 ReleaseCapture();
104 ScrollBarButtonUp(hWnd, SB_CTL, pt->x,pt->y);
105 break;
107 case WM_MOUSEMOVE:
108 ScrollBarMouseMove(hWnd, SB_CTL, wParam, pt->x,pt->y);
109 break;
110 case WM_KEYDOWN:
111 case WM_KEYUP:
112 case WM_CHAR:
113 lphs = ScrollBarGetWindowAndStorage(hWnd, &wndPtr);
114 return(SendMessage(wndPtr->hwndParent, message, wParam, lParam));
116 case WM_TIMER:
117 dprintf_scroll(stddeb,"ScrollBar WM_TIMER wParam=%X lParam=%lX !\n", wParam, lParam);
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 dprintf_scroll(stddeb,"ScrollBarButtonDown SB_CTL // x=%d y=%d\n", x, y);
176 else {
177 hWndParent = hWnd;
178 dwOwner = 0L;
179 dprintf_scroll(stddeb,"ScrollBarButtonDown SB_?SCROLL // x=%d y=%d\n", x, y);
182 SetFocus(lphs->hWndOwner);
184 CopyRect(&rect, &lphs->rect);
185 dprintf_scroll(stddeb,"ScrollDown / x=%d y=%d left=%d top=%d right=%d bottom=%d \n",
186 x, y, rect.left, rect.top, rect.right, rect.bottom);
187 if (lphs->Direction == WM_VSCROLL) {
188 width = rect.right - rect.left;
189 if (y <= lphs->rectUp.bottom) {
190 lphs->ButtonDown = 1;
191 InvalidateRect(lphs->hWndOwner, &lphs->rectUp, TRUE);
192 dprintf_scroll(stddeb,"ScrollBarButtonDown send SB_LINEUP\n");
193 SendMessage(hWndParent, lphs->Direction,
194 SB_LINEUP, dwOwner);
196 if (y >= lphs->rectDown.top) {
197 lphs->ButtonDown = 2;
198 InvalidateRect(lphs->hWndOwner, &lphs->rectDown, TRUE);
199 dprintf_scroll(stddeb,"ScrollBarButtonDown send SB_LINEDOWN\n");
200 SendMessage(hWndParent, lphs->Direction,
201 SB_LINEDOWN, dwOwner);
203 if (y > lphs->rectUp.bottom && y < (lphs->CurPix + width)) {
204 lphs->ButtonDown = 5;
205 dprintf_scroll(stddeb,"ScrollBarButtonDown send SB_PAGEUP\n");
206 SendMessage(hWndParent, lphs->Direction,
207 SB_PAGEUP, dwOwner);
209 if (y < lphs->rectDown.top && y > (lphs->CurPix + (width << 1))) {
210 lphs->ButtonDown = 6;
211 dprintf_scroll(stddeb,"ScrollBarButtonDown send SB_PAGEDOWN\n");
212 SendMessage(hWndParent, lphs->Direction,
213 SB_PAGEDOWN, dwOwner);
215 if (lphs->MaxPix > 0 && y > (lphs->CurPix + width) &&
216 y < (lphs->CurPix + (width << 1))) {
217 lphs->ThumbActive = TRUE;
218 dprintf_scroll(stddeb,"THUMB DOWN !\n");
221 else {
222 height = rect.bottom - rect.top;
223 if (x <= lphs->rectUp.right) {
224 lphs->ButtonDown = 3;
225 InvalidateRect(lphs->hWndOwner, &lphs->rectUp, TRUE);
226 dprintf_scroll(stddeb,"ScrollBarButtonDown send SB_LINEUP\n");
227 SendMessage(hWndParent, lphs->Direction,
228 SB_LINEUP, dwOwner);
230 if (x >= lphs->rectDown.left) {
231 lphs->ButtonDown = 4;
232 InvalidateRect(lphs->hWndOwner, &lphs->rectDown, TRUE);
233 dprintf_scroll(stddeb,"ScrollBarButtonDown send SB_LINEDOWN\n");
234 SendMessage(hWndParent, lphs->Direction,
235 SB_LINEDOWN, dwOwner);
237 if (x > lphs->rectUp.right && x < (lphs->CurPix + height)) {
238 lphs->ButtonDown = 5;
239 dprintf_scroll(stddeb,"ScrollBarButtonDown send SB_PAGEUP\n");
240 SendMessage(hWndParent, lphs->Direction,
241 SB_PAGEUP, dwOwner);
243 if (x < lphs->rectDown.left && x > (lphs->CurPix + (height << 1))) {
244 lphs->ButtonDown = 6;
245 dprintf_scroll(stddeb,"ScrollBarButtonDown send SB_PAGEDOWN\n");
246 SendMessage(hWndParent, lphs->Direction,
247 SB_PAGEDOWN, dwOwner);
249 if (lphs->MaxPix > 0 && x > (lphs->CurPix + height) &&
250 x < (lphs->CurPix + (height << 1))) {
251 lphs->ThumbActive = TRUE;
252 dprintf_scroll(stddeb,"THUMB DOWN !\n");
255 if (lphs->ButtonDown != 0) {
256 UpdateWindow(lphs->hWndOwner);
257 if (!lphs->TimerPending && nBar == SB_CTL) {
258 lphs->TimerPending = TRUE;
259 SetTimer(lphs->hWndOwner, 1, 500, NULL);
265 void ScrollBarButtonUp(HWND hWnd, int nBar, int x, int y)
267 LPHEADSCROLL lphs;
268 RECT rect, rect2;
269 HDC hDC;
270 dprintf_scroll(stddeb,"ScrollBarButtonUp // x=%d y=%d\n", x, y);
271 lphs = GetScrollObjectStruct(hWnd, nBar);
272 if(lphs->ThumbActive)
274 HWND hWndOwner,hWndParent;
275 if (nBar == SB_CTL) {
276 hWndParent = GetParent(hWnd);
277 hWndOwner = lphs->hWndOwner;
279 else {
280 hWndParent = hWnd;
281 hWndOwner = 0;
285 SendMessage(hWndParent, lphs->Direction,
286 SB_THUMBPOSITION, MAKELONG(lphs->ThumbVal, hWndOwner));
287 lphs->ThumbActive = FALSE;
290 if (lphs->ButtonDown != 0) {
291 lphs->ButtonDown = 0;
292 if (nBar == SB_CTL) {
293 GetClientRect(lphs->hWndOwner, &rect);
294 InvalidateRect(lphs->hWndOwner, &rect, TRUE);
295 UpdateWindow(lphs->hWndOwner);
297 else {
298 hDC = GetWindowDC(lphs->hWndOwner);
299 StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs);
300 ReleaseDC(lphs->hWndOwner, hDC);
306 void ScrollBarMouseMove(HWND hWnd, int nBar, WORD wParam, int x, int y)
308 LPHEADSCROLL lphs;
309 HWND hWndParent;
310 HWND hWndOwner;
311 LONG dwOwner;
312 if ((wParam & MK_LBUTTON) == 0) return;
313 lphs = GetScrollObjectStruct(hWnd, nBar);
314 if (lphs->ThumbActive == 0) return;
315 if (nBar == SB_CTL) {
316 hWndParent = GetParent(hWnd);
317 hWndOwner = lphs->hWndOwner;
318 dprintf_scroll(stddeb,"ScrollBarButtonMove SB_CTL // x=%d y=%d\n", x, y);
320 else {
321 hWndParent = hWnd;
322 hWndOwner = 0;
323 dprintf_scroll(stddeb,"ScrollBarButtonMove SB_?SCROLL // x=%d y=%d\n", x, y);
326 if(x<lphs->rect.left||x>lphs->rect.right||
327 y<lphs->rect.top||y>lphs->rect.bottom)
330 dprintf_scroll(stddeb,"Rejecting thumb position !\n");
331 lphs->ThumbVal=lphs->CurVal;/*revert to last set position*/
333 else
336 if (lphs->Direction == WM_VSCROLL) {
337 int butsiz = lphs->rect.right - lphs->rect.left;
338 y = y - butsiz - (butsiz >> 1);
340 else {
341 int butsiz = lphs->rect.bottom - lphs->rect.top;
342 y = x - butsiz - (butsiz >> 1);
344 if(y<0)y=0;
345 if(y>lphs->MaxPix)y=lphs->MaxPix;
346 lphs->ThumbVal = (y * (lphs->MaxVal - lphs->MinVal) /
347 lphs->MaxPix) + lphs->MinVal;
350 dprintf_scroll(stddeb,"Scroll WM_MOUSEMOVE val=%d pix=%d\n",
351 lphs->ThumbVal, y);
352 SendMessage(hWndParent, lphs->Direction,
353 SB_THUMBTRACK, MAKELONG(lphs->ThumbVal, hWndOwner));
357 LPHEADSCROLL ScrollBarGetWindowAndStorage(HWND hWnd, WND **wndPtr)
359 WND *Ptr;
360 LPHEADSCROLL lphs;
361 *(wndPtr) = Ptr = WIN_FindWndPtr(hWnd);
362 if (Ptr == 0) {
363 fprintf(stderr,"Bad Window handle on ScrollBar !\n");
364 return 0;
366 lphs = *((LPHEADSCROLL *)&Ptr->wExtra[1]);
367 return lphs;
371 LPHEADSCROLL ScrollBarGetStorageHeader(HWND hWnd)
373 WND *wndPtr;
374 LPHEADSCROLL lphs;
375 wndPtr = WIN_FindWndPtr(hWnd);
376 if (wndPtr == 0) {
377 fprintf(stderr,"Bad Window handle on ScrollBar !\n");
378 return 0;
380 lphs = *((LPHEADSCROLL *)&wndPtr->wExtra[1]);
381 return lphs;
386 void StdDrawScrollBar(HWND hWnd, HDC hDC, int nBar, LPRECT lprect, LPHEADSCROLL lphs)
388 HWND hWndParent;
389 HBRUSH hBrush;
390 HDC hMemDC;
391 HBITMAP hOldBmp;
392 BITMAP bm;
393 RECT rect;
394 UINT i, w, w2, h, h2, siz;
395 char C[128];
396 if (lphs == NULL) return;
397 dprintf_scroll(stddeb,"StdDrawScrollBar nBar=%04X !\n", nBar);
398 if (lphs->Direction == WM_VSCROLL)
399 dprintf_scroll(stddeb,"StdDrawScrollBar Vertical left=%d top=%d right=%d bottom=%d !\n",
400 lprect->left, lprect->top, lprect->right, lprect->bottom);
401 else
402 dprintf_scroll(stddeb,"StdDrawScrollBar Horizontal left=%d top=%d right=%d bottom=%d !\n",
403 lprect->left, lprect->top, lprect->right, lprect->bottom);
404 if (nBar == SB_CTL)
405 hWndParent = GetParent(hWnd);
406 else
407 hWndParent = lphs->hWndOwner;
408 hBrush = SendMessage(hWndParent, WM_CTLCOLOR, (WORD)hDC,
409 MAKELONG(hWnd, CTLCOLOR_SCROLLBAR));
410 if (hBrush == (HBRUSH)NULL) hBrush = GetStockObject(LTGRAY_BRUSH);
411 CopyRect(&lphs->rect, lprect);
412 CopyRect(&lphs->rectUp, lprect);
413 CopyRect(&lphs->rectDown, lprect);
414 CopyRect(&rect, lprect);
415 w = rect.right - rect.left;
416 h = rect.bottom - rect.top;
417 if (w == 0 || h == 0) return;
418 if (lphs->Direction == WM_VSCROLL) {
419 if (h > 3 * w)
420 lphs->MaxPix = h - 3 * w;
421 else
422 lphs->MaxPix = 0;
423 if (h > 2 * w)
424 h2 = w;
425 else
426 h2 = (h - 4) / 2;
427 lphs->rectUp.bottom = h2;
428 lphs->rectDown.top = rect.bottom - h2;
430 else {
431 if (w > 3 * h)
432 lphs->MaxPix = w - 3 * h;
433 else
434 lphs->MaxPix = 0;
435 if (w > 2 * h)
436 w2 = h;
437 else
438 w2 = (w - 4) / 2;
439 lphs->rectUp.right = w2;
440 lphs->rectDown.left = rect.right - w2;
442 if (lphs->MaxVal != lphs->MinVal)
443 lphs->CurPix = lphs->MaxPix * (lphs->CurVal - lphs->MinVal) /
444 (lphs->MaxVal - lphs->MinVal);
445 if(lphs->CurPix <0)lphs->CurPix=0;
446 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 hOldBmp = SelectObject(hMemDC, hUpArrowD);
453 else
454 hOldBmp = 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 hOldBmp = SelectObject(hMemDC, hLfArrowD);
471 else
472 hOldBmp = 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 SelectObject( hMemDC, hOldBmp );
486 DeleteDC(hMemDC);
487 FillRect(hDC, &rect, hBrush);
488 if (lphs->MaxPix != 0) {
489 if (lphs->Direction == WM_VSCROLL)
490 SetRect(&rect, rect.left, rect.top + lphs->CurPix,
491 rect.left + w, rect.top + lphs->CurPix + h2);
492 else
493 SetRect(&rect, rect.left + lphs->CurPix, rect.top,
494 rect.left + lphs->CurPix + w2, rect.top + h);
495 FrameRect(hDC, &rect, GetStockObject(BLACK_BRUSH));
496 InflateRect(&rect, -1, -1);
497 FillRect(hDC, &rect, GetStockObject(LTGRAY_BRUSH));
498 GRAPH_DrawReliefRect(hDC, &rect, 2, 0);
499 InflateRect(&rect, -3, -3);
500 GRAPH_DrawReliefRect(hDC, &rect, 1, 1);
506 int CreateScrollBarStruct(HWND hWnd)
508 RECT rect;
509 int width, height;
510 WND *wndPtr;
511 LPHEADSCROLL lphs;
512 wndPtr = WIN_FindWndPtr(hWnd);
513 width = wndPtr->rectClient.right - wndPtr->rectClient.left;
514 height = wndPtr->rectClient.bottom - wndPtr->rectClient.top;
515 if (width <= height)
516 lphs = AllocScrollBar(WS_VSCROLL, width, height);
517 else
518 lphs = AllocScrollBar(WS_HSCROLL, width, height);
519 dprintf_scroll(stddeb,"CreateScrollBarStruct %lX !\n", lphs);
520 *((LPHEADSCROLL *)&wndPtr->wExtra[1]) = lphs;
521 lphs->hWndOwner = hWnd;
522 CopyRect(&lphs->rect, &wndPtr->rectClient);
523 return TRUE;
528 LPHEADSCROLL AllocScrollBar(DWORD dwStyle, int width, int height)
530 LPHEADSCROLL lphs;
531 if (hUpArrow == (HBITMAP)NULL)
532 hUpArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWI));
533 if (hDnArrow == (HBITMAP)NULL)
534 hDnArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWI));
535 if (hLfArrow == (HBITMAP)NULL)
536 hLfArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWI));
537 if (hRgArrow == (HBITMAP)NULL)
538 hRgArrow = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWI));
539 if (hUpArrowD == (HBITMAP)NULL)
540 hUpArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_UPARROWD));
541 if (hDnArrowD == (HBITMAP)NULL)
542 hDnArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_DNARROWD));
543 if (hLfArrowD == (HBITMAP)NULL)
544 hLfArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_LFARROWD));
545 if (hRgArrowD == (HBITMAP)NULL)
546 hRgArrowD = LoadBitmap((HINSTANCE)NULL, MAKEINTRESOURCE(OBM_RGARROWD));
547 lphs = (LPHEADSCROLL)malloc(sizeof(HEADSCROLL));
548 if (lphs == 0) {
549 fprintf(stderr,"Bad Memory Alloc on ScrollBar !\n");
550 return NULL;
552 lphs->ThumbActive = FALSE;
553 lphs->TimerPending = FALSE;
554 lphs->ButtonDown = 0;
555 lphs->MinVal = 0;
556 lphs->MaxVal = 100;
557 lphs->CurVal = 0;
558 lphs->CurPix = 0;
559 SetRect(&lphs->rect, 0, 0, width, height);
560 if (dwStyle & WS_VSCROLL) {
561 if (height > 3 * width)
562 lphs->MaxPix = height - 3 * width;
563 else
564 lphs->MaxPix = 0;
565 lphs->Direction = WM_VSCROLL;
567 else {
568 if (width > 3 * height)
569 lphs->MaxPix = width - 3 * height;
570 else
571 lphs->MaxPix = 0;
572 lphs->Direction = WM_HSCROLL;
574 if (lphs->MaxPix < 1) lphs->MaxPix = 1;
575 return lphs;
579 void NC_CreateScrollBars(HWND hWnd)
581 RECT rect;
582 int width, height;
583 WND *wndPtr;
584 LPHEADSCROLL lphs;
585 wndPtr = WIN_FindWndPtr(hWnd);
586 GetWindowRect(hWnd, &rect);
587 width = rect.right - rect.left;
588 height = rect.bottom - rect.top;
589 if (wndPtr->dwStyle & WS_VSCROLL) {
590 if (wndPtr->dwStyle & WS_HSCROLL) height -= SYSMETRICS_CYHSCROLL;
591 lphs = AllocScrollBar(WS_VSCROLL, SYSMETRICS_CXVSCROLL, height);
592 dprintf_scroll(stddeb,"NC_CreateScrollBars Vertical %lX !\n",
593 lphs);
594 lphs->rect.left = width - SYSMETRICS_CYVSCROLL;
595 lphs->rect.right = width;
596 lphs->hWndOwner = hWnd;
597 wndPtr->VScroll = lphs;
598 wndPtr->scroll_flags |= 0x0001;
599 if (wndPtr->dwStyle & WS_HSCROLL) height += SYSMETRICS_CYHSCROLL;
601 if (wndPtr->dwStyle & WS_HSCROLL) {
602 if (wndPtr->dwStyle & WS_VSCROLL) width -= SYSMETRICS_CYVSCROLL;
603 lphs = AllocScrollBar(WS_HSCROLL, width, SYSMETRICS_CYHSCROLL);
604 dprintf_scroll(stddeb,"NC_CreateScrollBars Horizontal %lX !\n", lphs);
605 lphs->rect.top = height - SYSMETRICS_CYHSCROLL;
606 lphs->rect.bottom = height;
607 lphs->hWndOwner = hWnd;
608 wndPtr->HScroll = lphs;
609 wndPtr->scroll_flags |= 0x0002;
614 /*************************************************************************
615 * GetScrollObjectStruct [internal]
617 LPHEADSCROLL GetScrollObjectStruct(HWND hWnd, int nBar)
619 WND *wndPtr;
620 if (nBar != SB_CTL) {
621 wndPtr = WIN_FindWndPtr(hWnd);
622 if (nBar == SB_VERT) return (LPHEADSCROLL)wndPtr->VScroll;
623 if (nBar == SB_HORZ) return (LPHEADSCROLL)wndPtr->HScroll;
624 return NULL;
626 return ScrollBarGetStorageHeader(hWnd);
630 /*************************************************************************
631 * SetScrollPos [USER.62]
633 int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw)
635 LPHEADSCROLL lphs;
636 HDC hDC;
637 int nRet;
638 lphs = GetScrollObjectStruct(hWnd, nBar);
639 if (lphs == NULL) return 0;
640 nRet = lphs->CurVal;
641 lphs->CurVal = (short)nPos;
642 if (lphs->MaxVal != lphs->MinVal)
643 lphs->CurPix = lphs->MaxPix * (lphs->CurVal - lphs->MinVal) /
644 (lphs->MaxVal - lphs->MinVal);
645 if(lphs->CurPix <0)lphs->CurPix=0;
647 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
648 dprintf_scroll(stddeb,"SetScrollPos val=%d pixval=%d pixmax%d\n",
649 (short)nPos, lphs->CurPix, lphs->MaxPix);
650 dprintf_scroll(stddeb,"SetScrollPos min=%d max=%d\n",
651 lphs->MinVal, lphs->MaxVal);
652 if ((bRedraw) && (IsWindowVisible(lphs->hWndOwner))) {
653 if (nBar == SB_CTL) {
654 InvalidateRect(lphs->hWndOwner, &lphs->rect, TRUE);
655 UpdateWindow(lphs->hWndOwner);
657 else {
658 if (lphs->rect.right != 0 && lphs->rect.bottom != 0) {
659 hDC = GetWindowDC(lphs->hWndOwner);
660 StdDrawScrollBar(lphs->hWndOwner, hDC, nBar, &lphs->rect, lphs);
661 ReleaseDC(lphs->hWndOwner, hDC);
665 return nRet;
670 /*************************************************************************
671 * GetScrollPos [USER.63]
673 int GetScrollPos(HWND hWnd, int nBar)
675 LPHEADSCROLL lphs;
676 lphs = GetScrollObjectStruct(hWnd, nBar);
677 if (lphs == NULL) return 0;
678 return lphs->CurVal;
683 /*************************************************************************
684 * SetScrollRange [USER.64]
686 void SetScrollRange(HWND hWnd, int nBar, int MinPos, int MaxPos, BOOL bRedraw)
688 LPHEADSCROLL lphs;
689 HDC hDC;
690 lphs = GetScrollObjectStruct(hWnd, nBar);
691 if (lphs == NULL) return;
693 /* should a bad range be rejected here?
695 lphs->MinVal = (short)MinPos;
696 lphs->MaxVal = (short)MaxPos;
697 if (lphs->MaxVal != lphs->MinVal)
698 lphs->CurPix = lphs->MaxPix * (lphs->CurVal - lphs->MinVal) /
699 (lphs->MaxVal - lphs->MinVal);
700 if(lphs->CurPix <0)lphs->CurPix=0;
701 if (lphs->CurPix > lphs->MaxPix) lphs->CurPix = lphs->MaxPix;
702 dprintf_scroll(stddeb,"SetScrollRange min=%d max=%d\n",
703 lphs->MinVal, lphs->MaxVal);
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 dprintf_scroll(stddeb,"ShowScrollBar hWnd=%04X wBar=%d bFlag=%d\n",
742 hWnd, wBar, bFlag);
743 if (wBar == SB_CTL) {
744 if (bFlag)
745 ShowWindow(hWnd, SW_SHOW);
746 else
747 ShowWindow(hWnd, SW_HIDE);
748 return;
750 wndPtr = WIN_FindWndPtr(hWnd);
751 if ((wBar == SB_VERT) || (wBar == SB_BOTH)) {
752 if (bFlag)
753 wndPtr->scroll_flags != 0x0001;
754 else
755 wndPtr->scroll_flags &= 0xFFFE;
757 if ((wBar == SB_HORZ) || (wBar == SB_BOTH)) {
758 if (bFlag)
759 wndPtr->scroll_flags != 0x0002;
760 else
761 wndPtr->scroll_flags &= 0xFFFD;
763 SetWindowPos(hWnd, 0, 0, 0, 0, 0,
764 SWP_NOZORDER | SWP_NOMOVE |
765 SWP_NOSIZE | SWP_FRAMECHANGED);