source: trunk/src/comctl32/pager.c@ 6705

Last change on this file since 6705 was 6705, checked in by sandervl, 24 years ago

update

File size: 37.6 KB
Line 
1/*
2 * Pager control
3 *
4 * Copyright 1998, 1999 Eric Kohl
5 *
6 * NOTES
7 * Tested primarily with the controlspy Pager application.
8 * Susan Farley (susan@codeweavers.com)
9 *
10 * TODO:
11 * Implement repetitive button press.
12 * Adjust arrow size relative to size of button.
13 * Allow border size changes.
14 * Implement drag and drop style.
15 */
16
17#include <string.h>
18#include "winbase.h"
19#include "commctrl.h"
20#include "debugtools.h"
21
22DEFAULT_DEBUG_CHANNEL(pager);
23
24#ifdef __WIN32OS2__
25#include "ccbase.h"
26#undef inline
27#define inline
28#endif
29
30typedef struct
31{
32#ifdef __WIN32OS2__
33 COMCTL32_HEADER header;
34#endif
35 HWND hwndChild; /* handle of the contained wnd */
36 BOOL bNoResize; /* set when created with CCS_NORESIZE */
37 COLORREF clrBk; /* background color */
38 INT nBorder; /* border size for the control */
39 INT nButtonSize;/* size of the pager btns */
40 INT nPos; /* scroll position */
41 INT nWidth; /* from child wnd's response to PGN_CALCSIZE */
42 INT nHeight; /* from child wnd's response to PGN_CALCSIZE */
43 BOOL bForward; /* forward WM_MOUSEMOVE msgs to the contained wnd */
44 INT TLbtnState; /* state of top or left btn */
45 INT BRbtnState; /* state of bottom or right btn */
46 INT direction; /* direction of the scroll, (e.g. PGF_SCROLLUP) */
47} PAGER_INFO;
48
49#define PAGER_GetInfoPtr(hwnd) ((PAGER_INFO *)GetWindowLongA(hwnd, 0))
50#define PAGER_IsHorizontal(hwnd) ((GetWindowLongA (hwnd, GWL_STYLE) & PGS_HORZ))
51
52#define MIN_ARROW_WIDTH 8
53#define MIN_ARROW_HEIGHT 5
54
55#define TIMERID1 1
56#define TIMERID2 2
57#define INITIAL_DELAY 500
58#define REPEAT_DELAY 50
59
60/* the horizontal arrows are:
61 *
62 * 01234 01234
63 * 1 * *
64 * 2 ** **
65 * 3*** ***
66 * 4*** ***
67 * 5 ** **
68 * 6 * *
69 * 7
70 *
71 */
72static void
73PAGER_DrawHorzArrow (HDC hdc, RECT r, INT colorRef, BOOL left)
74{
75 INT x, y, w, h;
76 HPEN hOldPen;
77
78 w = r.right - r.left + 1;
79 h = r.bottom - r.top + 1;
80 if ((h < MIN_ARROW_WIDTH) || (w < MIN_ARROW_HEIGHT))
81 return; /* refuse to draw partial arrow */
82
83 hOldPen = SelectObject ( hdc, GetSysColorPen (colorRef));
84 if (left)
85 {
86 x = r.left + ((w - MIN_ARROW_HEIGHT) / 2) + 3;
87 y = r.top + ((h - MIN_ARROW_WIDTH) / 2) + 1;
88 MoveToEx (hdc, x, y, NULL);
89 LineTo (hdc, x--, y+5); y++;
90 MoveToEx (hdc, x, y, NULL);
91 LineTo (hdc, x--, y+3); y++;
92 MoveToEx (hdc, x, y, NULL);
93 LineTo (hdc, x, y+1);
94 }
95 else
96 {
97 x = r.left + ((w - MIN_ARROW_HEIGHT) / 2) + 1;
98 y = r.top + ((h - MIN_ARROW_WIDTH) / 2) + 1;
99 MoveToEx (hdc, x, y, NULL);
100 LineTo (hdc, x++, y+5); y++;
101 MoveToEx (hdc, x, y, NULL);
102 LineTo (hdc, x++, y+3); y++;
103 MoveToEx (hdc, x, y, NULL);
104 LineTo (hdc, x, y+1);
105 }
106
107 SelectObject( hdc, hOldPen );
108}
109
110/* the vertical arrows are:
111 *
112 * 01234567 01234567
113 * 1****** **
114 * 2 **** ****
115 * 3 ** ******
116 * 4
117 *
118 */
119static void
120PAGER_DrawVertArrow (HDC hdc, RECT r, INT colorRef, BOOL up)
121{
122 INT x, y, w, h;
123 HPEN hOldPen;
124
125 w = r.right - r.left + 1;
126 h = r.bottom - r.top + 1;
127 if ((h < MIN_ARROW_WIDTH) || (w < MIN_ARROW_HEIGHT))
128 return; /* refuse to draw partial arrow */
129
130 hOldPen = SelectObject ( hdc, GetSysColorPen (colorRef));
131 if (up)
132 {
133 x = r.left + ((w - MIN_ARROW_HEIGHT) / 2) + 1;
134 y = r.top + ((h - MIN_ARROW_WIDTH) / 2) + 3;
135 MoveToEx (hdc, x, y, NULL);
136 LineTo (hdc, x+5, y--); x++;
137 MoveToEx (hdc, x, y, NULL);
138 LineTo (hdc, x+3, y--); x++;
139 MoveToEx (hdc, x, y, NULL);
140 LineTo (hdc, x+1, y);
141 }
142 else
143 {
144 x = r.left + ((w - MIN_ARROW_HEIGHT) / 2) + 1;
145 y = r.top + ((h - MIN_ARROW_WIDTH) / 2) + 1;
146 MoveToEx (hdc, x, y, NULL);
147 LineTo (hdc, x+5, y++); x++;
148 MoveToEx (hdc, x, y, NULL);
149 LineTo (hdc, x+3, y++); x++;
150 MoveToEx (hdc, x, y, NULL);
151 LineTo (hdc, x+1, y);
152 }
153
154 SelectObject( hdc, hOldPen );
155}
156
157static void
158PAGER_DrawButton(HDC hdc, COLORREF clrBk, RECT arrowRect,
159 BOOL horz, BOOL topLeft, INT btnState)
160{
161 HBRUSH hBrush, hOldBrush;
162 RECT rc = arrowRect;
163
164 if (!btnState) /* PGF_INVISIBLE */
165 return;
166
167 if ((rc.right - rc.left <= 0) || (rc.bottom - rc.top <= 0))
168 return;
169
170 hBrush = CreateSolidBrush(clrBk);
171 hOldBrush = (HBRUSH)SelectObject(hdc, hBrush);
172
173 FillRect(hdc, &rc, hBrush);
174
175 if (btnState == PGF_HOT)
176 {
177 DrawEdge( hdc, &rc, BDR_RAISEDINNER, BF_RECT);
178 if (horz)
179 PAGER_DrawHorzArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft);
180 else
181 PAGER_DrawVertArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft);
182 }
183 else if (btnState == PGF_NORMAL)
184 {
185 DrawEdge (hdc, &rc, BDR_OUTER, BF_FLAT);
186 if (horz)
187 PAGER_DrawHorzArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft);
188 else
189 PAGER_DrawVertArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft);
190 }
191 else if (btnState == PGF_DEPRESSED)
192 {
193 DrawEdge( hdc, &rc, BDR_SUNKENOUTER, BF_RECT);
194 if (horz)
195 PAGER_DrawHorzArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft);
196 else
197 PAGER_DrawVertArrow(hdc, rc, COLOR_WINDOWFRAME, topLeft);
198 }
199 else if (btnState == PGF_GRAYED)
200 {
201 DrawEdge (hdc, &rc, BDR_OUTER, BF_FLAT);
202 if (horz)
203 {
204 PAGER_DrawHorzArrow(hdc, rc, COLOR_3DHIGHLIGHT, topLeft);
205 rc.left++, rc.top++; rc.right++, rc.bottom++;
206 PAGER_DrawHorzArrow(hdc, rc, COLOR_3DSHADOW, topLeft);
207 }
208 else
209 {
210 PAGER_DrawVertArrow(hdc, rc, COLOR_3DHIGHLIGHT, topLeft);
211 rc.left++, rc.top++; rc.right++, rc.bottom++;
212 PAGER_DrawVertArrow(hdc, rc, COLOR_3DSHADOW, topLeft);
213 }
214 }
215
216 SelectObject( hdc, hOldBrush );
217 DeleteObject(hBrush);
218}
219
220/* << PAGER_GetDropTarget >> */
221
222static inline LRESULT
223PAGER_ForwardMouse (HWND hwnd, WPARAM wParam)
224{
225 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
226 TRACE("[%04x]\n", hwnd);
227
228 infoPtr->bForward = (BOOL)wParam;
229
230 return 0;
231}
232
233static inline LRESULT
234PAGER_GetButtonState (HWND hwnd, WPARAM wParam, LPARAM lParam)
235{
236 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
237 LRESULT btnState = PGF_INVISIBLE;
238 INT btn = (INT)lParam;
239 TRACE("[%04x]\n", hwnd);
240
241 if (btn == PGB_TOPORLEFT)
242 btnState = infoPtr->TLbtnState;
243 else if (btn == PGB_BOTTOMORRIGHT)
244 btnState = infoPtr->BRbtnState;
245
246 return btnState;
247}
248
249
250static inline LRESULT
251PAGER_GetPos(HWND hwnd)
252{
253 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
254 TRACE("[%04x] returns %d\n", hwnd, infoPtr->nPos);
255 return (LRESULT)infoPtr->nPos;
256}
257
258static inline LRESULT
259PAGER_GetButtonSize(HWND hwnd)
260{
261 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
262 TRACE("[%04x] returns %d\n", hwnd, infoPtr->nButtonSize);
263 return (LRESULT)infoPtr->nButtonSize;
264}
265
266static inline LRESULT
267PAGER_GetBorder(HWND hwnd)
268{
269 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
270 TRACE("[%04x] returns %d\n", hwnd, infoPtr->nBorder);
271 return (LRESULT)infoPtr->nBorder;
272}
273
274static inline LRESULT
275PAGER_GetBkColor(HWND hwnd)
276{
277 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
278 TRACE("[%04x] returns %06lx\n", hwnd, infoPtr->clrBk);
279 return (LRESULT)infoPtr->clrBk;
280}
281
282static void
283PAGER_CalcSize (HWND hwnd, INT* size, BOOL getWidth)
284{
285 NMPGCALCSIZE nmpgcs;
286 ZeroMemory (&nmpgcs, sizeof (NMPGCALCSIZE));
287 nmpgcs.hdr.hwndFrom = hwnd;
288 nmpgcs.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
289 nmpgcs.hdr.code = PGN_CALCSIZE;
290 nmpgcs.dwFlag = getWidth ? PGF_CALCWIDTH : PGF_CALCHEIGHT;
291 nmpgcs.iWidth = getWidth ? *size : 0;
292 nmpgcs.iHeight = getWidth ? 0 : *size;
293 SendMessageA (GetParent (hwnd), WM_NOTIFY,
294 (WPARAM)nmpgcs.hdr.idFrom, (LPARAM)&nmpgcs);
295
296 *size = getWidth ? nmpgcs.iWidth : nmpgcs.iHeight;
297
298 TRACE("[%04x] PGN_CALCSIZE returns %s=%d\n", hwnd,
299 getWidth ? "width" : "height", *size);
300}
301
302static void
303PAGER_PositionChildWnd(HWND hwnd, PAGER_INFO* infoPtr)
304{
305 if (infoPtr->hwndChild)
306 {
307 RECT rcClient;
308 int nPos = infoPtr->nPos;
309
310 /* compensate for a grayed btn, which will soon become invisible */
311 if (infoPtr->TLbtnState == PGF_GRAYED)
312 nPos += infoPtr->nButtonSize;
313
314 GetClientRect(hwnd, &rcClient);
315
316 if (PAGER_IsHorizontal(hwnd))
317 {
318 int wndSize = max(0, rcClient.right - rcClient.left);
319 if (infoPtr->nWidth < wndSize)
320 infoPtr->nWidth = wndSize;
321
322 TRACE("[%04x] SWP %dx%d at (%d,%d)\n", hwnd,
323 infoPtr->nWidth, infoPtr->nHeight,
324 -nPos, 0);
325 SetWindowPos(infoPtr->hwndChild, 0,
326 -nPos, 0,
327 infoPtr->nWidth, infoPtr->nHeight,
328 SWP_NOZORDER);
329 }
330 else
331 {
332 int wndSize = max(0, rcClient.bottom - rcClient.top);
333 if (infoPtr->nHeight < wndSize)
334 infoPtr->nHeight = wndSize;
335
336 TRACE("[%04x] SWP %dx%d at (%d,%d)\n", hwnd,
337 infoPtr->nWidth, infoPtr->nHeight,
338 0, -nPos);
339 SetWindowPos(infoPtr->hwndChild, 0,
340 0, -nPos,
341 infoPtr->nWidth, infoPtr->nHeight,
342 SWP_NOZORDER);
343 }
344
345 InvalidateRect(infoPtr->hwndChild, NULL, TRUE);
346 }
347}
348
349static INT
350PAGER_GetScrollRange(HWND hwnd, PAGER_INFO* infoPtr)
351{
352 INT scrollRange = 0;
353
354 if (infoPtr->hwndChild)
355 {
356 INT wndSize, childSize;
357 RECT wndRect;
358 GetWindowRect(hwnd, &wndRect);
359
360 if (PAGER_IsHorizontal(hwnd))
361 {
362 wndSize = wndRect.right - wndRect.left;
363 PAGER_CalcSize(hwnd, &infoPtr->nWidth, TRUE);
364 childSize = infoPtr->nWidth;
365 }
366 else
367 {
368 wndSize = wndRect.bottom - wndRect.top;
369 PAGER_CalcSize(hwnd, &infoPtr->nHeight, FALSE);
370 childSize = infoPtr->nHeight;
371 }
372
373 TRACE("childSize = %d, wndSize = %d\n", childSize, wndSize);
374 if (childSize > wndSize)
375 scrollRange = childSize - wndSize + infoPtr->nButtonSize;
376 }
377
378 TRACE("[%04x] returns %d\n", hwnd, scrollRange);
379 return scrollRange;
380}
381
382static void
383PAGER_GrayAndRestoreBtns(PAGER_INFO* infoPtr, INT scrollRange,
384 BOOL* needsResize, BOOL* needsRepaint)
385{
386 if (infoPtr->nPos > 0)
387 {
388 *needsResize |= !infoPtr->TLbtnState; /* PGF_INVISIBLE */
389 if (infoPtr->TLbtnState != PGF_DEPRESSED)
390 infoPtr->TLbtnState = PGF_NORMAL;
391 }
392 else
393 {
394 *needsRepaint |= (infoPtr->TLbtnState != PGF_GRAYED);
395 infoPtr->TLbtnState = PGF_GRAYED;
396 }
397
398 if (scrollRange <= 0)
399 {
400 *needsRepaint |= (infoPtr->TLbtnState != PGF_GRAYED);
401 infoPtr->TLbtnState = PGF_GRAYED;
402 *needsRepaint |= (infoPtr->BRbtnState != PGF_GRAYED);
403 infoPtr->BRbtnState = PGF_GRAYED;
404 }
405 else if (infoPtr->nPos < scrollRange)
406 {
407 *needsResize |= !infoPtr->BRbtnState; /* PGF_INVISIBLE */
408 if (infoPtr->BRbtnState != PGF_DEPRESSED)
409 infoPtr->BRbtnState = PGF_NORMAL;
410 }
411 else
412 {
413 *needsRepaint |= (infoPtr->BRbtnState != PGF_GRAYED);
414 infoPtr->BRbtnState = PGF_GRAYED;
415 }
416}
417
418
419static void
420PAGER_NormalizeBtns(PAGER_INFO* infoPtr, BOOL* needsRepaint)
421{
422 if (infoPtr->TLbtnState & (PGF_HOT | PGF_DEPRESSED))
423 {
424 infoPtr->TLbtnState = PGF_NORMAL;
425 *needsRepaint = TRUE;
426 }
427
428 if (infoPtr->BRbtnState & (PGF_HOT | PGF_DEPRESSED))
429 {
430 infoPtr->BRbtnState = PGF_NORMAL;
431 *needsRepaint = TRUE;
432 }
433}
434
435static void
436PAGER_HideGrayBtns(PAGER_INFO* infoPtr, BOOL* needsResize)
437{
438 if (infoPtr->TLbtnState == PGF_GRAYED)
439 {
440 infoPtr->TLbtnState = PGF_INVISIBLE;
441 *needsResize = TRUE;
442 }
443
444 if (infoPtr->BRbtnState == PGF_GRAYED)
445 {
446 infoPtr->BRbtnState = PGF_INVISIBLE;
447 *needsResize = TRUE;
448 }
449}
450
451static void
452PAGER_UpdateBtns(HWND hwnd, PAGER_INFO *infoPtr,
453 INT scrollRange, BOOL hideGrayBtns)
454{
455 BOOL resizeClient = FALSE;
456 BOOL repaintBtns = FALSE;
457
458 if (scrollRange < 0)
459 PAGER_NormalizeBtns(infoPtr, &repaintBtns);
460 else
461 PAGER_GrayAndRestoreBtns(infoPtr, scrollRange, &resizeClient, &repaintBtns);
462
463 if (hideGrayBtns)
464 PAGER_HideGrayBtns(infoPtr, &resizeClient);
465
466 if (resizeClient) /* initiate NCCalcSize to resize client wnd */ {
467 SetWindowPos(hwnd, 0,0,0,0,0,
468 SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
469 SWP_NOZORDER | SWP_NOACTIVATE);
470 }
471
472 if (repaintBtns)
473 SendMessageA(hwnd, WM_NCPAINT, 0, 0);
474}
475
476static LRESULT
477PAGER_SetPos(HWND hwnd, INT newPos, BOOL fromBtnPress)
478{
479 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
480 INT scrollRange = PAGER_GetScrollRange(hwnd, infoPtr);
481 INT oldPos = infoPtr->nPos;
482
483 if ((scrollRange <= 0) || (newPos < 0))
484 infoPtr->nPos = 0;
485 else if (newPos > scrollRange)
486 infoPtr->nPos = scrollRange;
487 else
488 infoPtr->nPos = newPos;
489
490 TRACE("[%04x] pos=%d\n", hwnd, infoPtr->nPos);
491
492 if (infoPtr->nPos != oldPos)
493 {
494 /* gray and restore btns, and if from WM_SETPOS, hide the gray btns */
495 PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, !fromBtnPress);
496 PAGER_PositionChildWnd(hwnd, infoPtr);
497 }
498
499 return 0;
500}
501
502static LRESULT
503PAGER_HandleWindowPosChanging(HWND hwnd, WPARAM wParam, WINDOWPOS *winpos)
504{
505 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
506
507 if (infoPtr->bNoResize && !(winpos->flags & SWP_NOSIZE))
508 {
509 /* don't let the app resize the nonscrollable dimension of a control
510 * that was created with CCS_NORESIZE style
511 * (i.e. height for a horizontal pager, or width for a vertical one) */
512
513 /* except if the current dimension is 0 and app is setting for
514 * first time, then save amount as dimension. - GA 8/01 */
515
516 if (PAGER_IsHorizontal(hwnd))
517 if (!infoPtr->nHeight && winpos->cy)
518 infoPtr->nHeight = winpos->cy;
519 else
520 winpos->cy = infoPtr->nHeight;
521 else
522 if (!infoPtr->nWidth && winpos->cx)
523 infoPtr->nWidth = winpos->cx;
524 else
525 winpos->cx = infoPtr->nWidth;
526 return 0;
527 }
528
529 DefWindowProcA (hwnd, WM_WINDOWPOSCHANGING, wParam, (LPARAM)winpos);
530
531 return 1;
532}
533
534static INT
535PAGER_SetFixedWidth(HWND hwnd, PAGER_INFO* infoPtr)
536{
537 /* Must set the non-scrollable dimension to be less than the full height/width
538 * so that NCCalcSize is called. The Msoft docs mention 3/4 factor for button
539 * size, and experimentation shows that affect is almost right. */
540
541 RECT wndRect;
542 INT delta, h;
543 GetWindowRect(hwnd, &wndRect);
544
545 /* see what the app says for btn width */
546 PAGER_CalcSize(hwnd, &infoPtr->nWidth, TRUE);
547
548 if (infoPtr->bNoResize)
549 {
550 delta = wndRect.right - wndRect.left - infoPtr->nWidth;
551 if (delta > infoPtr->nButtonSize)
552 infoPtr->nWidth += 4 * infoPtr->nButtonSize / 3;
553 else if (delta > 0)
554 infoPtr->nWidth += infoPtr->nButtonSize / 3;
555 }
556
557 h = wndRect.bottom - wndRect.top + infoPtr->nButtonSize;
558
559 TRACE("[%04x] infoPtr->nWidth set to %d\n",
560 hwnd, infoPtr->nWidth);
561
562 return h;
563}
564
565static INT
566PAGER_SetFixedHeight(HWND hwnd, PAGER_INFO* infoPtr)
567{
568 /* Must set the non-scrollable dimension to be less than the full height/width
569 * so that NCCalcSize is called. The Msoft docs mention 3/4 factor for button
570 * size, and experimentation shows that affect is almost right. */
571
572 RECT wndRect;
573 INT delta, w;
574 GetWindowRect(hwnd, &wndRect);
575
576 /* see what the app says for btn height */
577 PAGER_CalcSize(hwnd, &infoPtr->nHeight, FALSE);
578
579 if (infoPtr->bNoResize)
580 {
581 delta = wndRect.bottom - wndRect.top - infoPtr->nHeight;
582 if (delta > infoPtr->nButtonSize)
583 infoPtr->nHeight += infoPtr->nButtonSize;
584 else if (delta > 0)
585 infoPtr->nHeight += infoPtr->nButtonSize / 3;
586 }
587
588 w = wndRect.right - wndRect.left + infoPtr->nButtonSize;
589
590 TRACE("[%04x] infoPtr->nHeight set to %d\n",
591 hwnd, infoPtr->nHeight);
592
593 return w;
594}
595
596static LRESULT
597PAGER_RecalcSize(HWND hwnd)
598{
599 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
600
601 TRACE("[%04x]\n", hwnd);
602
603 if (infoPtr->hwndChild)
604 {
605 INT scrollRange = PAGER_GetScrollRange(hwnd, infoPtr);
606
607 if (scrollRange <= 0)
608 {
609 infoPtr->nPos = -1;
610 PAGER_SetPos(hwnd, 0, FALSE);
611 }
612 else
613 {
614 PAGER_UpdateBtns(hwnd, infoPtr, scrollRange, TRUE);
615 PAGER_PositionChildWnd(hwnd, infoPtr);
616 }
617 }
618
619 return 1;
620}
621
622
623static LRESULT
624PAGER_SetBkColor (HWND hwnd, WPARAM wParam, LPARAM lParam)
625{
626 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
627 COLORREF clrTemp = infoPtr->clrBk;
628
629 infoPtr->clrBk = (COLORREF)lParam;
630 TRACE("[%04x] %06lx\n", hwnd, infoPtr->clrBk);
631
632 PAGER_RecalcSize(hwnd);
633 SendMessageA(hwnd, WM_NCPAINT, (WPARAM)0, (LPARAM)0);
634
635 return (LRESULT)clrTemp;
636}
637
638
639static LRESULT
640PAGER_SetBorder (HWND hwnd, WPARAM wParam, LPARAM lParam)
641{
642 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
643 INT nTemp = infoPtr->nBorder;
644
645 infoPtr->nBorder = (INT)lParam;
646 TRACE("[%04x] %d\n", hwnd, infoPtr->nBorder);
647
648 PAGER_RecalcSize(hwnd);
649
650 return (LRESULT)nTemp;
651}
652
653
654static LRESULT
655PAGER_SetButtonSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
656{
657 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
658 INT nTemp = infoPtr->nButtonSize;
659
660 infoPtr->nButtonSize = (INT)lParam;
661 TRACE("[%04x] %d\n", hwnd, infoPtr->nButtonSize);
662
663 PAGER_RecalcSize(hwnd);
664
665 return (LRESULT)nTemp;
666}
667
668
669static LRESULT
670PAGER_SetChild (HWND hwnd, WPARAM wParam, LPARAM lParam)
671{
672 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
673 INT hw;
674
675 infoPtr->hwndChild = IsWindow ((HWND)lParam) ? (HWND)lParam : 0;
676
677 if (infoPtr->hwndChild)
678 {
679 TRACE("[%04x] hwndChild=%04x\n", hwnd, infoPtr->hwndChild);
680
681 if (PAGER_IsHorizontal(hwnd)) {
682 hw = PAGER_SetFixedHeight(hwnd, infoPtr);
683 /* adjust non-scrollable dimension to fit the child */
684 SetWindowPos(hwnd, 0, 0,0, hw, infoPtr->nHeight,
685 SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER |
686 SWP_NOSIZE | SWP_NOACTIVATE);
687 }
688 else {
689 hw = PAGER_SetFixedWidth(hwnd, infoPtr);
690 /* adjust non-scrollable dimension to fit the child */
691 SetWindowPos(hwnd, 0, 0,0, infoPtr->nWidth, hw,
692 SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER |
693 SWP_NOSIZE | SWP_NOACTIVATE);
694 }
695
696 /* position child within the page scroller */
697 SetWindowPos(infoPtr->hwndChild, HWND_TOP,
698 0,0,0,0,
699 SWP_SHOWWINDOW | SWP_NOSIZE); /* native is 0 */
700
701 infoPtr->nPos = -1;
702 PAGER_SetPos(hwnd, 0, FALSE);
703 }
704
705 return 0;
706}
707
708static void
709PAGER_Scroll(HWND hwnd, INT dir)
710{
711 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
712 NMPGSCROLL nmpgScroll;
713 RECT rcWnd;
714
715 if (infoPtr->hwndChild)
716 {
717 ZeroMemory (&nmpgScroll, sizeof (NMPGSCROLL));
718 nmpgScroll.hdr.hwndFrom = hwnd;
719 nmpgScroll.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
720 nmpgScroll.hdr.code = PGN_SCROLL;
721
722 GetWindowRect(hwnd, &rcWnd);
723 GetClientRect(hwnd, &nmpgScroll.rcParent);
724 nmpgScroll.iXpos = nmpgScroll.iYpos = 0;
725 nmpgScroll.iDir = dir;
726
727 if (PAGER_IsHorizontal(hwnd))
728 {
729 nmpgScroll.iScroll = rcWnd.right - rcWnd.left;
730 nmpgScroll.iXpos = infoPtr->nPos;
731 }
732 else
733 {
734 nmpgScroll.iScroll = rcWnd.bottom - rcWnd.top;
735 nmpgScroll.iYpos = infoPtr->nPos;
736 }
737 nmpgScroll.iScroll -= 2*infoPtr->nButtonSize;
738
739 SendMessageA (hwnd, WM_NOTIFY,
740 (WPARAM)nmpgScroll.hdr.idFrom, (LPARAM)&nmpgScroll);
741
742 TRACE("[%04x] PGN_SCROLL returns iScroll=%d\n", hwnd, nmpgScroll.iScroll);
743
744 if (nmpgScroll.iScroll > 0)
745 {
746 infoPtr->direction = dir;
747
748 if (dir == PGF_SCROLLLEFT || dir == PGF_SCROLLUP)
749 PAGER_SetPos(hwnd, infoPtr->nPos - nmpgScroll.iScroll, TRUE);
750 else
751 PAGER_SetPos(hwnd, infoPtr->nPos + nmpgScroll.iScroll, TRUE);
752 }
753 else
754 infoPtr->direction = -1;
755 }
756}
757
758static LRESULT
759PAGER_Create (HWND hwnd, WPARAM wParam, LPARAM lParam)
760{
761 PAGER_INFO *infoPtr;
762 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
763
764 /* allocate memory for info structure */
765#ifdef __WIN32OS2__
766 infoPtr =(PAGER_INFO*)initControl(hwnd,sizeof(PAGER_INFO));
767#else
768 infoPtr = (PAGER_INFO *)COMCTL32_Alloc (sizeof(PAGER_INFO));
769#endif
770 SetWindowLongA (hwnd, 0, (DWORD)infoPtr);
771
772 /* set default settings */
773 infoPtr->hwndChild = (HWND)NULL;
774 infoPtr->bNoResize = dwStyle & CCS_NORESIZE;
775 infoPtr->clrBk = GetSysColor(COLOR_BTNFACE);
776 infoPtr->nBorder = 0;
777 infoPtr->nButtonSize = 12;
778 infoPtr->nPos = 0;
779 infoPtr->nWidth = 0;
780 infoPtr->nHeight = 0;
781 infoPtr->bForward = FALSE;
782 infoPtr->TLbtnState = PGF_INVISIBLE;
783 infoPtr->BRbtnState = PGF_INVISIBLE;
784 infoPtr->direction = -1;
785
786 if (dwStyle & PGS_AUTOSCROLL)
787 FIXME("[%04x] Autoscroll style is not implemented yet.\n", hwnd);
788 if (dwStyle & PGS_DRAGNDROP)
789 FIXME("[%04x] Drag and Drop style is not implemented yet.\n", hwnd);
790 /*
791 * If neither horizontal nor vertical style specified, default to vertical.
792 * This is probably not necessary, since the style may be set later on as
793 * the control is initialized, but just in case it isn't, set it here.
794 */
795 if (!(dwStyle & PGS_HORZ) && !(dwStyle & PGS_VERT))
796 {
797 dwStyle |= PGS_VERT;
798 SetWindowLongA(hwnd, GWL_STYLE, dwStyle);
799 }
800
801 return 0;
802}
803
804
805static LRESULT
806PAGER_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam)
807{
808 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
809 /* free pager info data */
810 COMCTL32_Free (infoPtr);
811 SetWindowLongA (hwnd, 0, 0);
812 return 0;
813}
814
815static LRESULT
816PAGER_NCCalcSize(HWND hwnd, WPARAM wParam, LPARAM lParam)
817{
818 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
819 LPRECT lpRect = (LPRECT)lParam;
820 RECT rcChildw, rcmyw, wnrc, lbrc, rbrc;
821 POINT cursor;
822
823 /*
824 * lParam points to a RECT struct. On entry, the struct
825 * contains the proposed wnd rectangle for the window.
826 * On exit, the struct should contain the screen
827 * coordinates of the corresponding window's client area.
828 */
829
830 DefWindowProcA (hwnd, WM_NCCALCSIZE, wParam, lParam);
831
832 if (PAGER_IsHorizontal(hwnd))
833 {
834 infoPtr->nWidth = lpRect->right - lpRect->left;
835 PAGER_CalcSize (hwnd, &infoPtr->nWidth, TRUE);
836 GetWindowRect (infoPtr->hwndChild, &rcChildw);
837 MapWindowPoints (0, hwnd, (LPPOINT)&rcChildw, 2);
838 GetCursorPos (&cursor);
839 GetWindowRect (hwnd, &rcmyw);
840 if (PtInRect (&rcmyw, cursor)) {
841 GetWindowRect (hwnd, &wnrc);
842 lbrc = wnrc;
843 lbrc.right = lbrc.left + infoPtr->nButtonSize;
844 rbrc = wnrc;
845 rbrc.left = rbrc.right - infoPtr->nButtonSize;
846 TRACE("horz lb rect=(%d,%d)-(%d,%d), rb rect=(%d,%d)-(%d,%d)\n",
847 lbrc.left, lbrc.top, lbrc.right, lbrc.bottom,
848 rbrc.left, rbrc.top, rbrc.right, rbrc.bottom);
849 if (PtInRect (&lbrc, cursor) && infoPtr->TLbtnState)
850 RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE);
851 if (PtInRect (&rbrc, cursor) && infoPtr->BRbtnState)
852 RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE);
853 }
854 if (infoPtr->TLbtnState) /* != PGF_INVISIBLE */
855 lpRect->left += infoPtr->nButtonSize;
856 if (infoPtr->BRbtnState)
857 lpRect->right -= infoPtr->nButtonSize;
858 }
859 else
860 {
861 /* native does: (from trace of IE4 opening "Favorites" frame)
862 * DefWindowProc
863 * WM_NOITFY PGN_CALCSIZE w/ dwFlag=2
864 * GetWindowRect (child, &rc)
865 * MapWindowPoints (0, syspager, &rc, 2)
866 * GetCursorPos( &cur )
867 * GetWindowRect (syspager, &rc2)
868 * PtInRect (&rc2, cur.x, cur.y) rtns 0
869 * returns with rect empty
870 */
871 infoPtr->nHeight = lpRect->bottom - lpRect->top;
872 PAGER_CalcSize (hwnd, &infoPtr->nHeight, FALSE);
873 GetWindowRect (infoPtr->hwndChild, &rcChildw);
874 MapWindowPoints (0, hwnd, (LPPOINT)&rcChildw, 2);
875 GetCursorPos (&cursor);
876 GetWindowRect (hwnd, &rcmyw);
877 if (PtInRect (&rcmyw, cursor)) {
878
879 /* native does:
880 * GetWindowRect(pager, &rc)
881 * PtInRect(btn-left????, cur.x, cur.y)
882 * if true -> ???
883 * PtInRect(btn-right????, cur.x, cur.y)
884 * if true
885 * RedrawWindow(pager, 0, 0, 5)
886 * return TRUE
887 */
888
889 GetWindowRect (hwnd, &wnrc);
890 lbrc = wnrc;
891 lbrc.right = lbrc.left + infoPtr->nButtonSize;
892 rbrc = wnrc;
893 rbrc.left = rbrc.right - infoPtr->nButtonSize;
894 TRACE("vert lb rect=(%d,%d)-(%d,%d), rb rect=(%d,%d)-(%d,%d)\n",
895 lbrc.left, lbrc.top, lbrc.right, lbrc.bottom,
896 rbrc.left, rbrc.top, rbrc.right, rbrc.bottom);
897 if (PtInRect (&lbrc, cursor) && infoPtr->TLbtnState)
898 RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE);
899 if (PtInRect (&rbrc, cursor) && infoPtr->BRbtnState)
900 RedrawWindow (hwnd, 0, 0, RDW_INVALIDATE | RDW_ERASE);
901 }
902 if (infoPtr->TLbtnState)
903 lpRect->top += infoPtr->nButtonSize;
904 if (infoPtr->BRbtnState)
905 lpRect->bottom -= infoPtr->nButtonSize;
906 /* ???? */
907 if ((lpRect->bottom < 0) || (lpRect->bottom > infoPtr->nHeight))
908 lpRect->bottom = infoPtr->nHeight;
909 }
910
911 TRACE("[%04x] client rect set to %dx%d at (%d,%d)\n", hwnd,
912 lpRect->right-lpRect->left,
913 lpRect->bottom-lpRect->top,
914 lpRect->left, lpRect->top);
915
916 return 0;
917}
918
919static LRESULT
920PAGER_NCPaint (HWND hwnd, WPARAM wParam, LPARAM lParam)
921{
922 PAGER_INFO* infoPtr = PAGER_GetInfoPtr(hwnd);
923 DWORD dwStyle = GetWindowLongA (hwnd, GWL_STYLE);
924 RECT rcWindow, rcBottomRight, rcTopLeft;
925 HDC hdc;
926 BOOL bHorizontal = PAGER_IsHorizontal(hwnd);
927
928 if (dwStyle & WS_MINIMIZE)
929 return 0;
930
931 DefWindowProcA (hwnd, WM_NCPAINT, wParam, lParam);
932
933 if (!(hdc = GetDCEx (hwnd, 0, DCX_USESTYLE | DCX_WINDOW)))
934 return 0;
935
936 GetWindowRect (hwnd, &rcWindow);
937 OffsetRect (&rcWindow, -rcWindow.left, -rcWindow.top);
938
939 rcTopLeft = rcBottomRight = rcWindow;
940 if (bHorizontal)
941 {
942 rcTopLeft.right = rcTopLeft.left + infoPtr->nButtonSize;
943 rcBottomRight.left = rcBottomRight.right - infoPtr->nButtonSize;
944 }
945 else
946 {
947 rcTopLeft.bottom = rcTopLeft.top + infoPtr->nButtonSize;
948 rcBottomRight.top = rcBottomRight.bottom - infoPtr->nButtonSize;
949 }
950
951 PAGER_DrawButton(hdc, infoPtr->clrBk, rcTopLeft,
952 bHorizontal, TRUE, infoPtr->TLbtnState);
953 PAGER_DrawButton(hdc, infoPtr->clrBk, rcBottomRight,
954 bHorizontal, FALSE, infoPtr->BRbtnState);
955
956 ReleaseDC( hwnd, hdc );
957 return 0;
958}
959
960static INT
961PAGER_HitTest (HWND hwnd, LPPOINT pt)
962{
963 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
964 RECT clientRect;
965 BOOL bHorizontal = PAGER_IsHorizontal(hwnd);
966
967 GetClientRect (hwnd, &clientRect);
968
969 if (PtInRect(&clientRect, *pt))
970 {
971 /* TRACE("HTCLIENT\n"); */
972 return HTCLIENT;
973 }
974
975 if (infoPtr->TLbtnState && infoPtr->TLbtnState != PGF_GRAYED)
976 {
977 if (bHorizontal)
978 {
979 if (pt->x < clientRect.left)
980 {
981 /* TRACE("HTLEFT\n"); */
982 return HTLEFT;
983 }
984 }
985 else
986 {
987 if (pt->y < clientRect.top)
988 {
989 /* TRACE("HTTOP\n"); */
990 return HTTOP;
991 }
992 }
993 }
994
995 if (infoPtr->BRbtnState && infoPtr->BRbtnState != PGF_GRAYED)
996 {
997 if (bHorizontal)
998 {
999 if (pt->x > clientRect.right)
1000 {
1001 /* TRACE("HTRIGHT\n"); */
1002 return HTRIGHT;
1003 }
1004 }
1005 else
1006 {
1007 if (pt->y > clientRect.bottom)
1008 {
1009 /* TRACE("HTBOTTOM\n"); */
1010 return HTBOTTOM;
1011 }
1012 }
1013 }
1014
1015 /* TRACE("HTNOWHERE\n"); */
1016 return HTNOWHERE;
1017}
1018
1019static LRESULT
1020PAGER_NCHitTest (HWND hwnd, WPARAM wParam, LPARAM lParam)
1021{
1022 POINT pt = { SLOWORD(lParam), SHIWORD(lParam) };
1023 ScreenToClient (hwnd, &pt);
1024 return PAGER_HitTest(hwnd, &pt);
1025}
1026
1027static LRESULT
1028PAGER_SetCursor( HWND hwnd, WPARAM wParam, LPARAM lParam )
1029{
1030 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
1031 BOOL notCaptured = FALSE;
1032
1033 switch(LOWORD(lParam))
1034 {
1035 case HTLEFT:
1036 case HTTOP:
1037 if ((notCaptured = infoPtr->TLbtnState != PGF_HOT))
1038 infoPtr->TLbtnState = PGF_HOT;
1039 break;
1040 case HTRIGHT:
1041 case HTBOTTOM:
1042 if ((notCaptured = infoPtr->BRbtnState != PGF_HOT))
1043 infoPtr->BRbtnState = PGF_HOT;
1044 break;
1045 default:
1046 return FALSE;
1047 }
1048
1049 if (notCaptured)
1050 {
1051 TRACKMOUSEEVENT trackinfo;
1052
1053 TRACE("[%04x] SetCapture\n", hwnd);
1054 SetCapture(hwnd);
1055
1056 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
1057 trackinfo.dwFlags = TME_QUERY;
1058 trackinfo.hwndTrack = hwnd;
1059 trackinfo.dwHoverTime = HOVER_DEFAULT;
1060
1061 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
1062 _TrackMouseEvent(&trackinfo);
1063
1064 /* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
1065 if(!(trackinfo.dwFlags & TME_LEAVE)) {
1066 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
1067
1068 /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
1069 /* and can properly deactivate the hot button */
1070 _TrackMouseEvent(&trackinfo);
1071 }
1072
1073 SendMessageA(hwnd, WM_NCPAINT, 0, 0);
1074 }
1075
1076 return TRUE;
1077}
1078
1079static LRESULT
1080PAGER_MouseLeave (HWND hwnd, WPARAM wParam, LPARAM lParam)
1081{
1082 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
1083
1084 KillTimer (hwnd, TIMERID1);
1085 KillTimer (hwnd, TIMERID2);
1086
1087 TRACE("[%04x] ReleaseCapture\n", hwnd);
1088 ReleaseCapture();
1089
1090 /* Notify parent of released mouse capture */
1091 {
1092 NMHDR nmhdr;
1093 ZeroMemory (&nmhdr, sizeof (NMHDR));
1094 nmhdr.hwndFrom = hwnd;
1095 nmhdr.idFrom = GetWindowLongA (hwnd, GWL_ID);
1096 nmhdr.code = NM_RELEASEDCAPTURE;
1097 SendMessageA (GetParent(hwnd), WM_NOTIFY,
1098 (WPARAM)nmhdr.idFrom, (LPARAM)&nmhdr);
1099 }
1100
1101 /* make HOT btns NORMAL and hide gray btns */
1102 PAGER_UpdateBtns(hwnd, infoPtr, -1, TRUE);
1103
1104 return TRUE;
1105}
1106
1107static LRESULT
1108PAGER_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam)
1109{
1110 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
1111 BOOL repaintBtns = FALSE;
1112 POINT pt = { SLOWORD(lParam), SHIWORD(lParam) };
1113 INT hit;
1114
1115 TRACE("[%04x]\n", hwnd);
1116
1117 hit = PAGER_HitTest(hwnd, &pt);
1118
1119 /* put btn in DEPRESSED state */
1120 if (hit == HTLEFT || hit == HTTOP)
1121 {
1122 repaintBtns = infoPtr->TLbtnState != PGF_DEPRESSED;
1123 infoPtr->TLbtnState = PGF_DEPRESSED;
1124 SetTimer(hwnd, TIMERID1, INITIAL_DELAY, 0);
1125 }
1126 else if (hit == HTRIGHT || hit == HTBOTTOM)
1127 {
1128 repaintBtns = infoPtr->BRbtnState != PGF_DEPRESSED;
1129 infoPtr->BRbtnState = PGF_DEPRESSED;
1130 SetTimer(hwnd, TIMERID1, INITIAL_DELAY, 0);
1131 }
1132
1133 if (repaintBtns)
1134 SendMessageA(hwnd, WM_NCPAINT, 0, 0);
1135
1136 switch(hit)
1137 {
1138 case HTLEFT:
1139 TRACE("[%04x] PGF_SCROLLLEFT\n", hwnd);
1140 PAGER_Scroll(hwnd, PGF_SCROLLLEFT);
1141 break;
1142 case HTTOP:
1143 TRACE("[%04x] PGF_SCROLLUP\n", hwnd);
1144 PAGER_Scroll(hwnd, PGF_SCROLLUP);
1145 break;
1146 case HTRIGHT:
1147 TRACE("[%04x] PGF_SCROLLRIGHT\n", hwnd);
1148 PAGER_Scroll(hwnd, PGF_SCROLLRIGHT);
1149 break;
1150 case HTBOTTOM:
1151 TRACE("[%04x] PGF_SCROLLDOWN\n", hwnd);
1152 PAGER_Scroll(hwnd, PGF_SCROLLDOWN);
1153 break;
1154 default:
1155 break;
1156 }
1157
1158 return TRUE;
1159}
1160
1161static LRESULT
1162PAGER_LButtonUp (HWND hwnd, WPARAM wParam, LPARAM lParam)
1163{
1164 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
1165 TRACE("[%04x]\n", hwnd);
1166
1167 KillTimer (hwnd, TIMERID1);
1168 KillTimer (hwnd, TIMERID2);
1169
1170 /* make PRESSED btns NORMAL but don't hide gray btns */
1171 PAGER_UpdateBtns(hwnd, infoPtr, -1, FALSE);
1172
1173 return 0;
1174}
1175
1176static LRESULT
1177PAGER_EraseBackground (HWND hwnd, WPARAM wParam, LPARAM lParam)
1178{
1179 POINT pt, ptorig;
1180 HDC hdc = (HDC)wParam;
1181 HWND parent;
1182
1183 /* native does:
1184 * parent = GetParent(pager)
1185 * pt.x=0; pt.y=0; ?????
1186 * MapWindowPoints(pager, parent, &pt, 1)
1187 * OffsetWindowOrgEx(hdc, pt.x, pt.y, &ptorg)
1188 * SendMessageA(parent, WM_ERASEBKGND, hdc, 0)
1189 * SetWindowOrgEx(hdc, 0, 0, 0)
1190 */
1191
1192 pt.x = 0;
1193 pt.y = 0;
1194 parent = GetParent(hwnd);
1195 MapWindowPoints(hwnd, parent, &pt, 1);
1196 OffsetWindowOrgEx (hdc, pt.x, pt.y, &ptorig);
1197 SendMessageA (parent, WM_ERASEBKGND, wParam, lParam);
1198 SetWindowOrgEx (hdc, ptorig.x, ptorig.y, 0);
1199
1200
1201#if 0
1202 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
1203 HBRUSH hBrush = CreateSolidBrush(infoPtr->clrBk);
1204 RECT rect;
1205
1206 GetClientRect (hwnd, &rect);
1207 FillRect ((HDC)wParam, &rect, hBrush);
1208
1209 /* background color of the child should be the same as the pager */
1210 if (infoPtr->hwndChild)
1211 {
1212 GetClientRect (infoPtr->hwndChild, &rect);
1213 FillRect ((HDC)wParam, &rect, hBrush);
1214 }
1215
1216 DeleteObject (hBrush);
1217#endif
1218
1219 return TRUE;
1220}
1221
1222
1223static LRESULT
1224PAGER_Size (HWND hwnd, WPARAM wParam, LPARAM lParam)
1225{
1226 /* note that WM_SIZE is sent whenever NCCalcSize resizes the client wnd */
1227
1228 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
1229 TRACE("[%04x] %dx%d\n", hwnd, LOWORD(lParam), HIWORD(lParam));
1230
1231 if (PAGER_IsHorizontal(hwnd))
1232 infoPtr->nHeight = HIWORD(lParam);
1233 else
1234 infoPtr->nWidth = LOWORD(lParam);
1235
1236 return PAGER_RecalcSize(hwnd);
1237}
1238
1239
1240static LRESULT WINAPI
1241PAGER_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1242{
1243 PAGER_INFO *infoPtr = PAGER_GetInfoPtr (hwnd);
1244
1245 if (!infoPtr && (uMsg != WM_CREATE))
1246 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1247
1248 switch (uMsg)
1249 {
1250 case PGM_FORWARDMOUSE:
1251 return PAGER_ForwardMouse (hwnd, wParam);
1252
1253 case PGM_GETBKCOLOR:
1254 return PAGER_GetBkColor(hwnd);
1255
1256 case PGM_GETBORDER:
1257 return PAGER_GetBorder(hwnd);
1258
1259 case PGM_GETBUTTONSIZE:
1260 return PAGER_GetButtonSize(hwnd);
1261
1262 case PGM_GETPOS:
1263 return PAGER_GetPos(hwnd);
1264
1265 case PGM_GETBUTTONSTATE:
1266 return PAGER_GetButtonState (hwnd, wParam, lParam);
1267
1268/* case PGM_GETDROPTARGET: */
1269
1270 case PGM_RECALCSIZE:
1271 return PAGER_RecalcSize(hwnd);
1272
1273 case PGM_SETBKCOLOR:
1274 return PAGER_SetBkColor (hwnd, wParam, lParam);
1275
1276 case PGM_SETBORDER:
1277 return PAGER_SetBorder (hwnd, wParam, lParam);
1278
1279 case PGM_SETBUTTONSIZE:
1280 return PAGER_SetButtonSize (hwnd, wParam, lParam);
1281
1282 case PGM_SETCHILD:
1283 return PAGER_SetChild (hwnd, wParam, lParam);
1284
1285 case PGM_SETPOS:
1286 return PAGER_SetPos(hwnd, (INT)lParam, FALSE);
1287
1288 case WM_CREATE:
1289 return PAGER_Create (hwnd, wParam, lParam);
1290
1291 case WM_DESTROY:
1292 return PAGER_Destroy (hwnd, wParam, lParam);
1293
1294 case WM_SIZE:
1295 return PAGER_Size (hwnd, wParam, lParam);
1296
1297 case WM_NCPAINT:
1298 return PAGER_NCPaint (hwnd, wParam, lParam);
1299
1300 case WM_WINDOWPOSCHANGING:
1301 return PAGER_HandleWindowPosChanging (hwnd, wParam, (WINDOWPOS*)lParam);
1302
1303 case WM_NCCALCSIZE:
1304 return PAGER_NCCalcSize (hwnd, wParam, lParam);
1305
1306 case WM_NCHITTEST:
1307 return PAGER_NCHitTest (hwnd, wParam, lParam);
1308
1309 case WM_SETCURSOR:
1310 {
1311 if (hwnd == (HWND)wParam)
1312 return PAGER_SetCursor(hwnd, wParam, lParam);
1313 else /* its for the child */
1314 return 0;
1315 }
1316
1317 case WM_MOUSEMOVE:
1318 if (infoPtr->bForward && infoPtr->hwndChild)
1319 PostMessageA(infoPtr->hwndChild, WM_MOUSEMOVE, wParam, lParam);
1320 return TRUE;
1321
1322 case WM_MOUSELEAVE:
1323 return PAGER_MouseLeave (hwnd, wParam, lParam);
1324
1325 case WM_LBUTTONDOWN:
1326 return PAGER_LButtonDown (hwnd, wParam, lParam);
1327
1328 case WM_LBUTTONUP:
1329 return PAGER_LButtonUp (hwnd, wParam, lParam);
1330
1331 case WM_ERASEBKGND:
1332 return PAGER_EraseBackground (hwnd, wParam, lParam);
1333/*
1334 case WM_PAINT:
1335 return PAGER_Paint (hwnd, wParam);
1336*/
1337 case WM_TIMER:
1338 /* if initial timer, kill it and start the repeat timer */
1339 if (wParam == TIMERID1)
1340 {
1341 KillTimer(hwnd, TIMERID1);
1342 SetTimer(hwnd, TIMERID2, REPEAT_DELAY, 0);
1343 }
1344
1345 KillTimer(hwnd, TIMERID2);
1346 if (infoPtr->direction > 0)
1347 {
1348 PAGER_Scroll(hwnd, infoPtr->direction);
1349 SetTimer(hwnd, TIMERID2, REPEAT_DELAY, 0);
1350 }
1351 break;
1352
1353 case WM_NOTIFY:
1354 case WM_COMMAND:
1355 return SendMessageA (GetParent (hwnd), uMsg, wParam, lParam);
1356
1357 default:
1358#ifdef __WIN32OS2__
1359 return defComCtl32ProcA(hwnd, uMsg, wParam, lParam);
1360#else
1361 return DefWindowProcA (hwnd, uMsg, wParam, lParam);
1362#endif
1363 }
1364
1365 return 0;
1366}
1367
1368
1369VOID
1370PAGER_Register (void)
1371{
1372 WNDCLASSA wndClass;
1373
1374 ZeroMemory (&wndClass, sizeof(WNDCLASSA));
1375 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS;
1376 wndClass.lpfnWndProc = (WNDPROC)PAGER_WindowProc;
1377 wndClass.cbClsExtra = 0;
1378 wndClass.cbWndExtra = sizeof(PAGER_INFO *);
1379 wndClass.hCursor = LoadCursorA (0, IDC_ARROWA);
1380 wndClass.hbrBackground = 0;
1381 wndClass.lpszClassName = WC_PAGESCROLLERA;
1382
1383 RegisterClassA (&wndClass);
1384}
1385
1386
1387VOID
1388PAGER_Unregister (void)
1389{
1390 UnregisterClassA (WC_PAGESCROLLERA, (HINSTANCE)NULL);
1391}
1392
Note: See TracBrowser for help on using the repository browser.