4 * Copyright 1998, 1999 Eric Kohl
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * Tested primarily with the controlspy Pager application.
22 * Susan Farley (susan@codeweavers.com)
24 * This code was audited for completeness against the documented features
25 * of Comctl32.dll version 6.0 on Sep. 18, 2004, by Robert Shearman.
27 * Unless otherwise noted, we believe this code to be complete, as per
28 * the specification mentioned above.
29 * If you discover missing features or bugs please note them below.
32 * Implement repetitive button press.
33 * Adjust arrow size relative to size of button.
34 * Allow border size changes.
50 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(pager
);
56 HWND hwndChild
; /* handle of the contained wnd */
57 HWND hwndNotify
; /* handle of the parent wnd */
58 BOOL bNoResize
; /* set when created with CCS_NORESIZE */
59 COLORREF clrBk
; /* background color */
60 INT nBorder
; /* border size for the control */
61 INT nButtonSize
;/* size of the pager btns */
62 INT nPos
; /* scroll position */
63 INT nWidth
; /* from child wnd's response to PGN_CALCSIZE */
64 INT nHeight
; /* from child wnd's response to PGN_CALCSIZE */
65 BOOL bForward
; /* forward WM_MOUSEMOVE msgs to the contained wnd */
66 BOOL bCapture
; /* we have captured the mouse */
67 INT TLbtnState
; /* state of top or left btn */
68 INT BRbtnState
; /* state of bottom or right btn */
69 INT direction
; /* direction of the scroll, (e.g. PGF_SCROLLUP) */
72 #define PAGER_GetInfoPtr(hwnd) ((PAGER_INFO *)GetWindowLongPtrW(hwnd, 0))
73 #define PAGER_IsHorizontal(hwnd) ((GetWindowLongA (hwnd, GWL_STYLE) & PGS_HORZ))
75 #define MIN_ARROW_WIDTH 8
76 #define MIN_ARROW_HEIGHT 5
80 #define INITIAL_DELAY 500
81 #define REPEAT_DELAY 50
84 PAGER_GetButtonRects(HWND hwnd
, PAGER_INFO
* infoPtr
, RECT
* prcTopLeft
, RECT
* prcBottomRight
, BOOL bClientCoords
)
87 GetWindowRect (hwnd
, &rcWindow
);
91 POINT pt
= {rcWindow
.left
, rcWindow
.top
};
92 ScreenToClient(hwnd
, &pt
);
93 OffsetRect(&rcWindow
, -(rcWindow
.left
-pt
.x
), -(rcWindow
.top
-pt
.y
));
96 OffsetRect(&rcWindow
, -rcWindow
.left
, -rcWindow
.top
);
98 *prcTopLeft
= *prcBottomRight
= rcWindow
;
99 if (PAGER_IsHorizontal(hwnd
))
101 prcTopLeft
->right
= prcTopLeft
->left
+ infoPtr
->nButtonSize
;
102 prcBottomRight
->left
= prcBottomRight
->right
- infoPtr
->nButtonSize
;
106 prcTopLeft
->bottom
= prcTopLeft
->top
+ infoPtr
->nButtonSize
;
107 prcBottomRight
->top
= prcBottomRight
->bottom
- infoPtr
->nButtonSize
;
111 /* the horizontal arrows are:
124 PAGER_DrawHorzArrow (HDC hdc
, RECT r
, INT colorRef
, BOOL left
)
129 w
= r
.right
- r
.left
+ 1;
130 h
= r
.bottom
- r
.top
+ 1;
131 if ((h
< MIN_ARROW_WIDTH
) || (w
< MIN_ARROW_HEIGHT
))
132 return; /* refuse to draw partial arrow */
134 if (!(hPen
= CreatePen( PS_SOLID
, 1, GetSysColor( colorRef
)))) return;
135 hOldPen
= SelectObject ( hdc
, hPen
);
138 x
= r
.left
+ ((w
- MIN_ARROW_HEIGHT
) / 2) + 3;
139 y
= r
.top
+ ((h
- MIN_ARROW_WIDTH
) / 2) + 1;
140 MoveToEx (hdc
, x
, y
, NULL
);
141 LineTo (hdc
, x
--, y
+5); y
++;
142 MoveToEx (hdc
, x
, y
, NULL
);
143 LineTo (hdc
, x
--, y
+3); y
++;
144 MoveToEx (hdc
, x
, y
, NULL
);
145 LineTo (hdc
, x
, y
+1);
149 x
= r
.left
+ ((w
- MIN_ARROW_HEIGHT
) / 2) + 1;
150 y
= r
.top
+ ((h
- MIN_ARROW_WIDTH
) / 2) + 1;
151 MoveToEx (hdc
, x
, y
, NULL
);
152 LineTo (hdc
, x
++, y
+5); y
++;
153 MoveToEx (hdc
, x
, y
, NULL
);
154 LineTo (hdc
, x
++, y
+3); y
++;
155 MoveToEx (hdc
, x
, y
, NULL
);
156 LineTo (hdc
, x
, y
+1);
159 SelectObject( hdc
, hOldPen
);
160 DeleteObject( hPen
);
163 /* the vertical arrows are:
173 PAGER_DrawVertArrow (HDC hdc
, RECT r
, INT colorRef
, BOOL up
)
178 w
= r
.right
- r
.left
+ 1;
179 h
= r
.bottom
- r
.top
+ 1;
180 if ((h
< MIN_ARROW_WIDTH
) || (w
< MIN_ARROW_HEIGHT
))
181 return; /* refuse to draw partial arrow */
183 if (!(hPen
= CreatePen( PS_SOLID
, 1, GetSysColor( colorRef
)))) return;
184 hOldPen
= SelectObject ( hdc
, hPen
);
187 x
= r
.left
+ ((w
- MIN_ARROW_HEIGHT
) / 2) + 1;
188 y
= r
.top
+ ((h
- MIN_ARROW_WIDTH
) / 2) + 3;
189 MoveToEx (hdc
, x
, y
, NULL
);
190 LineTo (hdc
, x
+5, y
--); x
++;
191 MoveToEx (hdc
, x
, y
, NULL
);
192 LineTo (hdc
, x
+3, y
--); x
++;
193 MoveToEx (hdc
, x
, y
, NULL
);
194 LineTo (hdc
, x
+1, y
);
198 x
= r
.left
+ ((w
- MIN_ARROW_HEIGHT
) / 2) + 1;
199 y
= r
.top
+ ((h
- MIN_ARROW_WIDTH
) / 2) + 1;
200 MoveToEx (hdc
, x
, y
, NULL
);
201 LineTo (hdc
, x
+5, y
++); x
++;
202 MoveToEx (hdc
, x
, y
, NULL
);
203 LineTo (hdc
, x
+3, y
++); x
++;
204 MoveToEx (hdc
, x
, y
, NULL
);
205 LineTo (hdc
, x
+1, y
);
208 SelectObject( hdc
, hOldPen
);
209 DeleteObject( hPen
);
213 PAGER_DrawButton(HDC hdc
, COLORREF clrBk
, RECT arrowRect
,
214 BOOL horz
, BOOL topLeft
, INT btnState
)
216 HBRUSH hBrush
, hOldBrush
;
219 TRACE("arrowRect = %s, btnState = %d\n", wine_dbgstr_rect(&arrowRect
), btnState
);
221 if (btnState
== PGF_INVISIBLE
)
224 if ((rc
.right
- rc
.left
<= 0) || (rc
.bottom
- rc
.top
<= 0))
227 hBrush
= CreateSolidBrush(clrBk
);
228 hOldBrush
= (HBRUSH
)SelectObject(hdc
, hBrush
);
230 FillRect(hdc
, &rc
, hBrush
);
232 if (btnState
== PGF_HOT
)
234 DrawEdge( hdc
, &rc
, BDR_RAISEDINNER
, BF_RECT
);
236 PAGER_DrawHorzArrow(hdc
, rc
, COLOR_WINDOWFRAME
, topLeft
);
238 PAGER_DrawVertArrow(hdc
, rc
, COLOR_WINDOWFRAME
, topLeft
);
240 else if (btnState
== PGF_NORMAL
)
242 DrawEdge (hdc
, &rc
, BDR_OUTER
, BF_FLAT
);
244 PAGER_DrawHorzArrow(hdc
, rc
, COLOR_WINDOWFRAME
, topLeft
);
246 PAGER_DrawVertArrow(hdc
, rc
, COLOR_WINDOWFRAME
, topLeft
);
248 else if (btnState
== PGF_DEPRESSED
)
250 DrawEdge( hdc
, &rc
, BDR_SUNKENOUTER
, BF_RECT
);
252 PAGER_DrawHorzArrow(hdc
, rc
, COLOR_WINDOWFRAME
, topLeft
);
254 PAGER_DrawVertArrow(hdc
, rc
, COLOR_WINDOWFRAME
, topLeft
);
256 else if (btnState
== PGF_GRAYED
)
258 DrawEdge (hdc
, &rc
, BDR_OUTER
, BF_FLAT
);
261 PAGER_DrawHorzArrow(hdc
, rc
, COLOR_3DHIGHLIGHT
, topLeft
);
262 rc
.left
++, rc
.top
++; rc
.right
++, rc
.bottom
++;
263 PAGER_DrawHorzArrow(hdc
, rc
, COLOR_3DSHADOW
, topLeft
);
267 PAGER_DrawVertArrow(hdc
, rc
, COLOR_3DHIGHLIGHT
, topLeft
);
268 rc
.left
++, rc
.top
++; rc
.right
++, rc
.bottom
++;
269 PAGER_DrawVertArrow(hdc
, rc
, COLOR_3DSHADOW
, topLeft
);
273 SelectObject( hdc
, hOldBrush
);
274 DeleteObject(hBrush
);
277 /* << PAGER_GetDropTarget >> */
279 static inline LRESULT
280 PAGER_ForwardMouse (HWND hwnd
, WPARAM wParam
)
282 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
283 TRACE("[%p]\n", hwnd
);
285 infoPtr
->bForward
= (BOOL
)wParam
;
290 static inline LRESULT
291 PAGER_GetButtonState (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
293 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
294 LRESULT btnState
= PGF_INVISIBLE
;
295 INT btn
= (INT
)lParam
;
296 TRACE("[%p]\n", hwnd
);
298 if (btn
== PGB_TOPORLEFT
)
299 btnState
= infoPtr
->TLbtnState
;
300 else if (btn
== PGB_BOTTOMORRIGHT
)
301 btnState
= infoPtr
->BRbtnState
;
307 static inline LRESULT
308 PAGER_GetPos(HWND hwnd
)
310 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
311 TRACE("[%p] returns %d\n", hwnd
, infoPtr
->nPos
);
312 return (LRESULT
)infoPtr
->nPos
;
315 static inline LRESULT
316 PAGER_GetButtonSize(HWND hwnd
)
318 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
319 TRACE("[%p] returns %d\n", hwnd
, infoPtr
->nButtonSize
);
320 return (LRESULT
)infoPtr
->nButtonSize
;
323 static inline LRESULT
324 PAGER_GetBorder(HWND hwnd
)
326 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
327 TRACE("[%p] returns %d\n", hwnd
, infoPtr
->nBorder
);
328 return (LRESULT
)infoPtr
->nBorder
;
331 static inline LRESULT
332 PAGER_GetBkColor(HWND hwnd
)
334 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
335 TRACE("[%p] returns %06lx\n", hwnd
, infoPtr
->clrBk
);
336 return (LRESULT
)infoPtr
->clrBk
;
340 PAGER_CalcSize (HWND hwnd
, INT
* size
, BOOL getWidth
)
342 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
344 ZeroMemory (&nmpgcs
, sizeof (NMPGCALCSIZE
));
345 nmpgcs
.hdr
.hwndFrom
= hwnd
;
346 nmpgcs
.hdr
.idFrom
= GetWindowLongPtrW (hwnd
, GWLP_ID
);
347 nmpgcs
.hdr
.code
= PGN_CALCSIZE
;
348 nmpgcs
.dwFlag
= getWidth
? PGF_CALCWIDTH
: PGF_CALCHEIGHT
;
349 nmpgcs
.iWidth
= getWidth
? *size
: 0;
350 nmpgcs
.iHeight
= getWidth
? 0 : *size
;
351 SendMessageW (infoPtr
->hwndNotify
, WM_NOTIFY
,
352 (WPARAM
)nmpgcs
.hdr
.idFrom
, (LPARAM
)&nmpgcs
);
354 *size
= getWidth
? nmpgcs
.iWidth
: nmpgcs
.iHeight
;
356 TRACE("[%p] PGN_CALCSIZE returns %s=%d\n", hwnd
,
357 getWidth
? "width" : "height", *size
);
361 PAGER_PositionChildWnd(HWND hwnd
, PAGER_INFO
* infoPtr
)
363 if (infoPtr
->hwndChild
)
366 int nPos
= infoPtr
->nPos
;
368 /* compensate for a grayed btn, which will soon become invisible */
369 if (infoPtr
->TLbtnState
== PGF_GRAYED
)
370 nPos
+= infoPtr
->nButtonSize
;
372 GetClientRect(hwnd
, &rcClient
);
374 if (PAGER_IsHorizontal(hwnd
))
376 int wndSize
= max(0, rcClient
.right
- rcClient
.left
);
377 if (infoPtr
->nWidth
< wndSize
)
378 infoPtr
->nWidth
= wndSize
;
380 TRACE("[%p] SWP %dx%d at (%d,%d)\n", hwnd
,
381 infoPtr
->nWidth
, infoPtr
->nHeight
,
383 SetWindowPos(infoPtr
->hwndChild
, 0,
385 infoPtr
->nWidth
, infoPtr
->nHeight
,
390 int wndSize
= max(0, rcClient
.bottom
- rcClient
.top
);
391 if (infoPtr
->nHeight
< wndSize
)
392 infoPtr
->nHeight
= wndSize
;
394 TRACE("[%p] SWP %dx%d at (%d,%d)\n", hwnd
,
395 infoPtr
->nWidth
, infoPtr
->nHeight
,
397 SetWindowPos(infoPtr
->hwndChild
, 0,
399 infoPtr
->nWidth
, infoPtr
->nHeight
,
403 InvalidateRect(infoPtr
->hwndChild
, NULL
, TRUE
);
408 PAGER_GetScrollRange(HWND hwnd
, PAGER_INFO
* infoPtr
)
412 if (infoPtr
->hwndChild
)
414 INT wndSize
, childSize
;
416 GetWindowRect(hwnd
, &wndRect
);
418 if (PAGER_IsHorizontal(hwnd
))
420 wndSize
= wndRect
.right
- wndRect
.left
;
421 PAGER_CalcSize(hwnd
, &infoPtr
->nWidth
, TRUE
);
422 childSize
= infoPtr
->nWidth
;
426 wndSize
= wndRect
.bottom
- wndRect
.top
;
427 PAGER_CalcSize(hwnd
, &infoPtr
->nHeight
, FALSE
);
428 childSize
= infoPtr
->nHeight
;
431 TRACE("childSize = %d, wndSize = %d\n", childSize
, wndSize
);
432 if (childSize
> wndSize
)
433 scrollRange
= childSize
- wndSize
+ infoPtr
->nButtonSize
;
436 TRACE("[%p] returns %d\n", hwnd
, scrollRange
);
441 PAGER_UpdateBtns(HWND hwnd
, PAGER_INFO
*infoPtr
,
442 INT scrollRange
, BOOL hideGrayBtns
)
446 INT oldTLbtnState
= infoPtr
->TLbtnState
;
447 INT oldBRbtnState
= infoPtr
->BRbtnState
;
449 RECT rcTopLeft
, rcBottomRight
;
451 /* get button rects */
452 PAGER_GetButtonRects(hwnd
, infoPtr
, &rcTopLeft
, &rcBottomRight
, FALSE
);
456 /* update states based on scroll position */
457 if (infoPtr
->nPos
> 0)
459 if (infoPtr
->TLbtnState
== PGF_INVISIBLE
|| infoPtr
->TLbtnState
== PGF_GRAYED
)
460 infoPtr
->TLbtnState
= PGF_NORMAL
;
462 else if (PtInRect(&rcTopLeft
, pt
))
463 infoPtr
->TLbtnState
= PGF_GRAYED
;
465 infoPtr
->TLbtnState
= PGF_INVISIBLE
;
467 if (scrollRange
<= 0)
469 infoPtr
->TLbtnState
= PGF_INVISIBLE
;
470 infoPtr
->BRbtnState
= PGF_INVISIBLE
;
472 else if (infoPtr
->nPos
< scrollRange
)
474 if (infoPtr
->BRbtnState
== PGF_INVISIBLE
|| infoPtr
->BRbtnState
== PGF_GRAYED
)
475 infoPtr
->BRbtnState
= PGF_NORMAL
;
477 else if (PtInRect(&rcBottomRight
, pt
))
478 infoPtr
->BRbtnState
= PGF_GRAYED
;
480 infoPtr
->BRbtnState
= PGF_INVISIBLE
;
482 /* only need to resize when entering or leaving PGF_INVISIBLE state */
484 ((oldTLbtnState
== PGF_INVISIBLE
) != (infoPtr
->TLbtnState
== PGF_INVISIBLE
)) ||
485 ((oldBRbtnState
== PGF_INVISIBLE
) != (infoPtr
->BRbtnState
== PGF_INVISIBLE
));
486 /* initiate NCCalcSize to resize client wnd if necessary */
488 SetWindowPos(hwnd
, 0,0,0,0,0,
489 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
490 SWP_NOZORDER
| SWP_NOACTIVATE
);
492 /* repaint when changing any state */
493 repaintBtns
= (oldTLbtnState
!= infoPtr
->TLbtnState
) ||
494 (oldBRbtnState
!= infoPtr
->BRbtnState
);
496 SendMessageW(hwnd
, WM_NCPAINT
, 0, 0);
500 PAGER_SetPos(HWND hwnd
, INT newPos
, BOOL fromBtnPress
)
502 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
503 INT scrollRange
= PAGER_GetScrollRange(hwnd
, infoPtr
);
504 INT oldPos
= infoPtr
->nPos
;
506 if ((scrollRange
<= 0) || (newPos
< 0))
508 else if (newPos
> scrollRange
)
509 infoPtr
->nPos
= scrollRange
;
511 infoPtr
->nPos
= newPos
;
513 TRACE("[%p] pos=%d, oldpos=%d\n", hwnd
, infoPtr
->nPos
, oldPos
);
515 if (infoPtr
->nPos
!= oldPos
)
517 /* gray and restore btns, and if from WM_SETPOS, hide the gray btns */
518 PAGER_UpdateBtns(hwnd
, infoPtr
, scrollRange
, !fromBtnPress
);
519 PAGER_PositionChildWnd(hwnd
, infoPtr
);
526 PAGER_HandleWindowPosChanging(HWND hwnd
, WPARAM wParam
, WINDOWPOS
*winpos
)
528 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
530 if (infoPtr
->bNoResize
&& !(winpos
->flags
& SWP_NOSIZE
))
532 /* don't let the app resize the nonscrollable dimension of a control
533 * that was created with CCS_NORESIZE style
534 * (i.e. height for a horizontal pager, or width for a vertical one) */
536 /* except if the current dimension is 0 and app is setting for
537 * first time, then save amount as dimension. - GA 8/01 */
539 if (PAGER_IsHorizontal(hwnd
))
540 if (!infoPtr
->nHeight
&& winpos
->cy
)
541 infoPtr
->nHeight
= winpos
->cy
;
543 winpos
->cy
= infoPtr
->nHeight
;
545 if (!infoPtr
->nWidth
&& winpos
->cx
)
546 infoPtr
->nWidth
= winpos
->cx
;
548 winpos
->cx
= infoPtr
->nWidth
;
552 DefWindowProcW (hwnd
, WM_WINDOWPOSCHANGING
, wParam
, (LPARAM
)winpos
);
558 PAGER_SetFixedWidth(HWND hwnd
, PAGER_INFO
* infoPtr
)
560 /* Must set the non-scrollable dimension to be less than the full height/width
561 * so that NCCalcSize is called. The Msoft docs mention 3/4 factor for button
562 * size, and experimentation shows that affect is almost right. */
566 GetWindowRect(hwnd
, &wndRect
);
568 /* see what the app says for btn width */
569 PAGER_CalcSize(hwnd
, &infoPtr
->nWidth
, TRUE
);
571 if (infoPtr
->bNoResize
)
573 delta
= wndRect
.right
- wndRect
.left
- infoPtr
->nWidth
;
574 if (delta
> infoPtr
->nButtonSize
)
575 infoPtr
->nWidth
+= 4 * infoPtr
->nButtonSize
/ 3;
577 infoPtr
->nWidth
+= infoPtr
->nButtonSize
/ 3;
580 h
= wndRect
.bottom
- wndRect
.top
+ infoPtr
->nButtonSize
;
582 TRACE("[%p] infoPtr->nWidth set to %d\n",
583 hwnd
, infoPtr
->nWidth
);
589 PAGER_SetFixedHeight(HWND hwnd
, PAGER_INFO
* infoPtr
)
591 /* Must set the non-scrollable dimension to be less than the full height/width
592 * so that NCCalcSize is called. The Msoft docs mention 3/4 factor for button
593 * size, and experimentation shows that affect is almost right. */
597 GetWindowRect(hwnd
, &wndRect
);
599 /* see what the app says for btn height */
600 PAGER_CalcSize(hwnd
, &infoPtr
->nHeight
, FALSE
);
602 if (infoPtr
->bNoResize
)
604 delta
= wndRect
.bottom
- wndRect
.top
- infoPtr
->nHeight
;
605 if (delta
> infoPtr
->nButtonSize
)
606 infoPtr
->nHeight
+= infoPtr
->nButtonSize
;
608 infoPtr
->nHeight
+= infoPtr
->nButtonSize
/ 3;
611 w
= wndRect
.right
- wndRect
.left
+ infoPtr
->nButtonSize
;
613 TRACE("[%p] infoPtr->nHeight set to %d\n",
614 hwnd
, infoPtr
->nHeight
);
619 /******************************************************************
620 * For the PGM_RECALCSIZE message (but not the other uses in *
621 * this module), the native control does only the following: *
623 * if (some condition) *
624 * PostMessageW(hwnd, EM_FMTLINES, 0, 0); *
625 * return DefWindowProcW(hwnd, PGM_RECALCSIZE, 0, 0); *
627 * When we figure out what the "some condition" is we will *
628 * implement that for the message processing. *
629 ******************************************************************/
632 PAGER_RecalcSize(HWND hwnd
)
634 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
636 TRACE("[%p]\n", hwnd
);
638 if (infoPtr
->hwndChild
)
640 INT scrollRange
= PAGER_GetScrollRange(hwnd
, infoPtr
);
642 if (scrollRange
<= 0)
645 PAGER_SetPos(hwnd
, 0, FALSE
);
648 PAGER_PositionChildWnd(hwnd
, infoPtr
);
656 PAGER_SetBkColor (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
658 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
659 COLORREF clrTemp
= infoPtr
->clrBk
;
661 infoPtr
->clrBk
= (COLORREF
)lParam
;
662 TRACE("[%p] %06lx\n", hwnd
, infoPtr
->clrBk
);
664 /* the native control seems to do things this way */
665 SetWindowPos(hwnd
, 0,0,0,0,0,
666 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
667 SWP_NOZORDER
| SWP_NOACTIVATE
);
669 RedrawWindow(hwnd
, 0, 0, RDW_ERASE
| RDW_INVALIDATE
);
671 return (LRESULT
)clrTemp
;
676 PAGER_SetBorder (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
678 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
679 INT nTemp
= infoPtr
->nBorder
;
681 infoPtr
->nBorder
= (INT
)lParam
;
682 TRACE("[%p] %d\n", hwnd
, infoPtr
->nBorder
);
684 PAGER_RecalcSize(hwnd
);
686 return (LRESULT
)nTemp
;
691 PAGER_SetButtonSize (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
693 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
694 INT nTemp
= infoPtr
->nButtonSize
;
696 infoPtr
->nButtonSize
= (INT
)lParam
;
697 TRACE("[%p] %d\n", hwnd
, infoPtr
->nButtonSize
);
699 PAGER_RecalcSize(hwnd
);
701 return (LRESULT
)nTemp
;
706 PAGER_SetChild (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
708 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
711 infoPtr
->hwndChild
= IsWindow ((HWND
)lParam
) ? (HWND
)lParam
: 0;
713 if (infoPtr
->hwndChild
)
715 TRACE("[%p] hwndChild=%p\n", hwnd
, infoPtr
->hwndChild
);
717 if (PAGER_IsHorizontal(hwnd
)) {
718 hw
= PAGER_SetFixedHeight(hwnd
, infoPtr
);
719 /* adjust non-scrollable dimension to fit the child */
720 SetWindowPos(hwnd
, 0, 0,0, hw
, infoPtr
->nHeight
,
721 SWP_FRAMECHANGED
| SWP_NOMOVE
| SWP_NOZORDER
|
722 SWP_NOSIZE
| SWP_NOACTIVATE
);
725 hw
= PAGER_SetFixedWidth(hwnd
, infoPtr
);
726 /* adjust non-scrollable dimension to fit the child */
727 SetWindowPos(hwnd
, 0, 0,0, infoPtr
->nWidth
, hw
,
728 SWP_FRAMECHANGED
| SWP_NOMOVE
| SWP_NOZORDER
|
729 SWP_NOSIZE
| SWP_NOACTIVATE
);
732 /* position child within the page scroller */
733 SetWindowPos(infoPtr
->hwndChild
, HWND_TOP
,
735 SWP_SHOWWINDOW
| SWP_NOSIZE
); /* native is 0 */
738 PAGER_SetPos(hwnd
, 0, FALSE
);
745 PAGER_Scroll(HWND hwnd
, INT dir
)
747 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
748 NMPGSCROLL nmpgScroll
;
751 if (infoPtr
->hwndChild
)
753 ZeroMemory (&nmpgScroll
, sizeof (NMPGSCROLL
));
754 nmpgScroll
.hdr
.hwndFrom
= hwnd
;
755 nmpgScroll
.hdr
.idFrom
= GetWindowLongPtrW (hwnd
, GWLP_ID
);
756 nmpgScroll
.hdr
.code
= PGN_SCROLL
;
758 GetWindowRect(hwnd
, &rcWnd
);
759 GetClientRect(hwnd
, &nmpgScroll
.rcParent
);
760 nmpgScroll
.iXpos
= nmpgScroll
.iYpos
= 0;
761 nmpgScroll
.iDir
= dir
;
763 if (PAGER_IsHorizontal(hwnd
))
765 nmpgScroll
.iScroll
= rcWnd
.right
- rcWnd
.left
;
766 nmpgScroll
.iXpos
= infoPtr
->nPos
;
770 nmpgScroll
.iScroll
= rcWnd
.bottom
- rcWnd
.top
;
771 nmpgScroll
.iYpos
= infoPtr
->nPos
;
773 nmpgScroll
.iScroll
-= 2*infoPtr
->nButtonSize
;
775 SendMessageW (infoPtr
->hwndNotify
, WM_NOTIFY
,
776 (WPARAM
)nmpgScroll
.hdr
.idFrom
, (LPARAM
)&nmpgScroll
);
778 TRACE("[%p] PGN_SCROLL returns iScroll=%d\n", hwnd
, nmpgScroll
.iScroll
);
780 if (nmpgScroll
.iScroll
> 0)
782 infoPtr
->direction
= dir
;
784 if (dir
== PGF_SCROLLLEFT
|| dir
== PGF_SCROLLUP
)
785 PAGER_SetPos(hwnd
, infoPtr
->nPos
- nmpgScroll
.iScroll
, TRUE
);
787 PAGER_SetPos(hwnd
, infoPtr
->nPos
+ nmpgScroll
.iScroll
, TRUE
);
790 infoPtr
->direction
= -1;
795 PAGER_FmtLines(HWND hwnd
)
797 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
799 /* initiate NCCalcSize to resize client wnd and get size */
800 SetWindowPos(hwnd
, 0, 0,0,0,0,
801 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
802 SWP_NOZORDER
| SWP_NOACTIVATE
);
804 SetWindowPos(infoPtr
->hwndChild
, 0,
805 0,0,infoPtr
->nWidth
,infoPtr
->nHeight
,
808 return DefWindowProcW (hwnd
, EM_FMTLINES
, 0, 0);
812 PAGER_Create (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
815 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
817 /* allocate memory for info structure */
818 infoPtr
= (PAGER_INFO
*)Alloc (sizeof(PAGER_INFO
));
819 SetWindowLongPtrW (hwnd
, 0, (DWORD_PTR
)infoPtr
);
821 /* set default settings */
822 infoPtr
->hwndChild
= NULL
;
823 infoPtr
->hwndNotify
= ((LPCREATESTRUCTW
)lParam
)->hwndParent
;
824 infoPtr
->bNoResize
= dwStyle
& CCS_NORESIZE
;
825 infoPtr
->clrBk
= GetSysColor(COLOR_BTNFACE
);
826 infoPtr
->nBorder
= 0;
827 infoPtr
->nButtonSize
= 12;
830 infoPtr
->nHeight
= 0;
831 infoPtr
->bForward
= FALSE
;
832 infoPtr
->bCapture
= FALSE
;
833 infoPtr
->TLbtnState
= PGF_INVISIBLE
;
834 infoPtr
->BRbtnState
= PGF_INVISIBLE
;
835 infoPtr
->direction
= -1;
837 if (dwStyle
& PGS_DRAGNDROP
)
838 FIXME("[%p] Drag and Drop style is not implemented yet.\n", hwnd
);
845 PAGER_Destroy (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
847 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
848 /* free pager info data */
850 SetWindowLongPtrW (hwnd
, 0, 0);
855 PAGER_NCCalcSize(HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
857 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
858 LPRECT lpRect
= (LPRECT
)lParam
;
859 RECT rcChild
, rcWindow
;
863 * lParam points to a RECT struct. On entry, the struct
864 * contains the proposed wnd rectangle for the window.
865 * On exit, the struct should contain the screen
866 * coordinates of the corresponding window's client area.
869 DefWindowProcW (hwnd
, WM_NCCALCSIZE
, wParam
, lParam
);
871 TRACE("orig rect=%s\n", wine_dbgstr_rect(lpRect
));
873 GetWindowRect (infoPtr
->hwndChild
, &rcChild
);
874 MapWindowPoints (0, hwnd
, (LPPOINT
)&rcChild
, 2); /* FIXME: RECT != 2 POINTS */
875 GetWindowRect (hwnd
, &rcWindow
);
877 if (PAGER_IsHorizontal(hwnd
))
879 infoPtr
->nWidth
= lpRect
->right
- lpRect
->left
;
880 PAGER_CalcSize (hwnd
, &infoPtr
->nWidth
, TRUE
);
882 scrollRange
= infoPtr
->nWidth
- (rcWindow
.right
- rcWindow
.left
);
884 if (infoPtr
->TLbtnState
&& (lpRect
->left
+ infoPtr
->nButtonSize
< lpRect
->right
))
885 lpRect
->left
+= infoPtr
->nButtonSize
;
886 if (infoPtr
->BRbtnState
&& (lpRect
->right
- infoPtr
->nButtonSize
> lpRect
->left
))
887 lpRect
->right
-= infoPtr
->nButtonSize
;
891 infoPtr
->nHeight
= lpRect
->bottom
- lpRect
->top
;
892 PAGER_CalcSize (hwnd
, &infoPtr
->nHeight
, FALSE
);
894 scrollRange
= infoPtr
->nHeight
- (rcWindow
.bottom
- rcWindow
.top
);
896 if (infoPtr
->TLbtnState
&& (lpRect
->top
+ infoPtr
->nButtonSize
< lpRect
->bottom
))
897 lpRect
->top
+= infoPtr
->nButtonSize
;
898 if (infoPtr
->BRbtnState
&& (lpRect
->bottom
- infoPtr
->nButtonSize
> lpRect
->top
))
899 lpRect
->bottom
-= infoPtr
->nButtonSize
;
902 TRACE("nPos=%d, nHeigth=%d, window=%s\n",
903 infoPtr
->nPos
, infoPtr
->nHeight
,
904 wine_dbgstr_rect(&rcWindow
));
906 TRACE("[%p] client rect set to %ldx%ld at (%ld,%ld) BtnState[%d,%d]\n",
907 hwnd
, lpRect
->right
-lpRect
->left
, lpRect
->bottom
-lpRect
->top
,
908 lpRect
->left
, lpRect
->top
,
909 infoPtr
->TLbtnState
, infoPtr
->BRbtnState
);
915 PAGER_NCPaint (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
917 PAGER_INFO
* infoPtr
= PAGER_GetInfoPtr(hwnd
);
918 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
919 RECT rcBottomRight
, rcTopLeft
;
921 BOOL bHorizontal
= PAGER_IsHorizontal(hwnd
);
923 if (dwStyle
& WS_MINIMIZE
)
926 DefWindowProcW (hwnd
, WM_NCPAINT
, wParam
, lParam
);
928 if (!(hdc
= GetDCEx (hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
)))
931 PAGER_GetButtonRects(hwnd
, infoPtr
, &rcTopLeft
, &rcBottomRight
, FALSE
);
933 PAGER_DrawButton(hdc
, infoPtr
->clrBk
, rcTopLeft
,
934 bHorizontal
, TRUE
, infoPtr
->TLbtnState
);
935 PAGER_DrawButton(hdc
, infoPtr
->clrBk
, rcBottomRight
,
936 bHorizontal
, FALSE
, infoPtr
->BRbtnState
);
938 ReleaseDC( hwnd
, hdc
);
943 PAGER_HitTest (HWND hwnd
, const POINT
* pt
)
945 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
946 RECT clientRect
, rcTopLeft
, rcBottomRight
;
949 GetClientRect (hwnd
, &clientRect
);
951 if (PtInRect(&clientRect
, *pt
))
958 PAGER_GetButtonRects(hwnd
, infoPtr
, &rcTopLeft
, &rcBottomRight
, TRUE
);
960 if ((infoPtr
->TLbtnState
!= PGF_INVISIBLE
) && PtInRect(&rcTopLeft
, ptWindow
))
962 TRACE("PGB_TOPORLEFT\n");
963 return PGB_TOPORLEFT
;
965 else if ((infoPtr
->BRbtnState
!= PGF_INVISIBLE
) && PtInRect(&rcBottomRight
, ptWindow
))
967 TRACE("PGB_BOTTOMORRIGHT\n");
968 return PGB_BOTTOMORRIGHT
;
976 PAGER_NCHitTest (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
981 pt
.x
= (short)LOWORD(lParam
);
982 pt
.y
= (short)HIWORD(lParam
);
984 ScreenToClient (hwnd
, &pt
);
985 nHit
= PAGER_HitTest(hwnd
, &pt
);
987 return HTTRANSPARENT
;
992 PAGER_MouseMove (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
994 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
996 RECT wnrect
, *btnrect
= NULL
;
997 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
998 BOOL topLeft
= FALSE
;
1003 pt
.x
= (short)LOWORD(lParam
);
1004 pt
.y
= (short)HIWORD(lParam
);
1006 TRACE("[%p] to (%ld,%ld)\n", hwnd
, pt
.x
, pt
.y
);
1007 ClientToScreen(hwnd
, &pt
);
1008 GetWindowRect(hwnd
, &wnrect
);
1009 if (PtInRect(&wnrect
, pt
)) {
1010 RECT TLbtnrect
, BRbtnrect
;
1011 PAGER_GetButtonRects(hwnd
, infoPtr
, &TLbtnrect
, &BRbtnrect
, FALSE
);
1014 MapWindowPoints(0, hwnd
, &clpt
, 1);
1015 hit
= PAGER_HitTest(hwnd
, &clpt
);
1016 if ((hit
== PGB_TOPORLEFT
) && (infoPtr
->TLbtnState
== PGF_NORMAL
))
1019 btnrect
= &TLbtnrect
;
1020 infoPtr
->TLbtnState
= PGF_HOT
;
1021 btnstate
= infoPtr
->TLbtnState
;
1023 else if ((hit
== PGB_BOTTOMORRIGHT
) && (infoPtr
->BRbtnState
== PGF_NORMAL
))
1026 btnrect
= &BRbtnrect
;
1027 infoPtr
->BRbtnState
= PGF_HOT
;
1028 btnstate
= infoPtr
->BRbtnState
;
1031 /* If in one of the buttons the capture and draw buttons */
1034 TRACE("[%p] draw btn (%ld,%ld)-(%ld,%ld), Capture %s, style %08lx\n",
1035 hwnd
, btnrect
->left
, btnrect
->top
,
1036 btnrect
->right
, btnrect
->bottom
,
1037 (infoPtr
->bCapture
) ? "TRUE" : "FALSE",
1039 if (!infoPtr
->bCapture
)
1041 TRACE("[%p] SetCapture\n", hwnd
);
1043 infoPtr
->bCapture
= TRUE
;
1045 if (dwStyle
& PGS_AUTOSCROLL
)
1046 SetTimer(hwnd
, TIMERID1
, 0x3e, 0);
1047 hdc
= GetWindowDC(hwnd
);
1048 /* OffsetRect(wnrect, 0 | 1, 0 | 1) */
1049 PAGER_DrawButton(hdc
, infoPtr
->clrBk
, *btnrect
,
1050 PAGER_IsHorizontal(hwnd
), topLeft
, btnstate
);
1051 ReleaseDC(hwnd
, hdc
);
1056 /* If we think we are captured, then do release */
1057 if (infoPtr
->bCapture
&& (WindowFromPoint(pt
) != hwnd
))
1061 infoPtr
->bCapture
= FALSE
;
1063 if (GetCapture() == hwnd
)
1067 if (infoPtr
->TLbtnState
== PGF_GRAYED
)
1069 infoPtr
->TLbtnState
= PGF_INVISIBLE
;
1070 SetWindowPos(hwnd
, 0,0,0,0,0,
1071 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1072 SWP_NOZORDER
| SWP_NOACTIVATE
);
1074 else if (infoPtr
->TLbtnState
== PGF_HOT
)
1076 infoPtr
->TLbtnState
= PGF_NORMAL
;
1077 /* FIXME: just invalidate button rect */
1078 RedrawWindow(hwnd
, NULL
, NULL
, RDW_FRAME
| RDW_INVALIDATE
);
1081 if (infoPtr
->BRbtnState
== PGF_GRAYED
)
1083 infoPtr
->BRbtnState
= PGF_INVISIBLE
;
1084 SetWindowPos(hwnd
, 0,0,0,0,0,
1085 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1086 SWP_NOZORDER
| SWP_NOACTIVATE
);
1088 else if (infoPtr
->BRbtnState
== PGF_HOT
)
1090 infoPtr
->BRbtnState
= PGF_NORMAL
;
1091 /* FIXME: just invalidate button rect */
1092 RedrawWindow(hwnd
, NULL
, NULL
, RDW_FRAME
| RDW_INVALIDATE
);
1095 /* Notify parent of released mouse capture */
1096 memset(&nmhdr
, 0, sizeof(NMHDR
));
1097 nmhdr
.hwndFrom
= hwnd
;
1098 nmhdr
.idFrom
= GetWindowLongPtrW(hwnd
, GWLP_ID
);
1099 nmhdr
.code
= NM_RELEASEDCAPTURE
;
1100 SendMessageW(infoPtr
->hwndNotify
, WM_NOTIFY
,
1101 (WPARAM
)nmhdr
.idFrom
, (LPARAM
)&nmhdr
);
1104 KillTimer(hwnd
, TIMERID1
);
1110 PAGER_LButtonDown (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1112 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
1113 BOOL repaintBtns
= FALSE
;
1117 pt
.x
= (short)LOWORD(lParam
);
1118 pt
.y
= (short)HIWORD(lParam
);
1120 TRACE("[%p] at (%d,%d)\n", hwnd
, (short)LOWORD(lParam
), (short)HIWORD(lParam
));
1122 hit
= PAGER_HitTest(hwnd
, &pt
);
1124 /* put btn in DEPRESSED state */
1125 if (hit
== PGB_TOPORLEFT
)
1127 repaintBtns
= infoPtr
->TLbtnState
!= PGF_DEPRESSED
;
1128 infoPtr
->TLbtnState
= PGF_DEPRESSED
;
1129 SetTimer(hwnd
, TIMERID1
, INITIAL_DELAY
, 0);
1131 else if (hit
== PGB_BOTTOMORRIGHT
)
1133 repaintBtns
= infoPtr
->BRbtnState
!= PGF_DEPRESSED
;
1134 infoPtr
->BRbtnState
= PGF_DEPRESSED
;
1135 SetTimer(hwnd
, TIMERID1
, INITIAL_DELAY
, 0);
1139 SendMessageW(hwnd
, WM_NCPAINT
, 0, 0);
1144 if (PAGER_IsHorizontal(hwnd
))
1146 TRACE("[%p] PGF_SCROLLLEFT\n", hwnd
);
1147 PAGER_Scroll(hwnd
, PGF_SCROLLLEFT
);
1151 TRACE("[%p] PGF_SCROLLUP\n", hwnd
);
1152 PAGER_Scroll(hwnd
, PGF_SCROLLUP
);
1155 case PGB_BOTTOMORRIGHT
:
1156 if (PAGER_IsHorizontal(hwnd
))
1158 TRACE("[%p] PGF_SCROLLRIGHT\n", hwnd
);
1159 PAGER_Scroll(hwnd
, PGF_SCROLLRIGHT
);
1163 TRACE("[%p] PGF_SCROLLDOWN\n", hwnd
);
1164 PAGER_Scroll(hwnd
, PGF_SCROLLDOWN
);
1175 PAGER_LButtonUp (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1177 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
1178 TRACE("[%p]\n", hwnd
);
1180 KillTimer (hwnd
, TIMERID1
);
1181 KillTimer (hwnd
, TIMERID2
);
1183 /* make PRESSED btns NORMAL but don't hide gray btns */
1184 if (infoPtr
->TLbtnState
& (PGF_HOT
| PGF_DEPRESSED
))
1185 infoPtr
->TLbtnState
= PGF_NORMAL
;
1186 if (infoPtr
->BRbtnState
& (PGF_HOT
| PGF_DEPRESSED
))
1187 infoPtr
->BRbtnState
= PGF_NORMAL
;
1193 PAGER_Timer (HWND hwnd
, WPARAM wParam
)
1195 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
1196 DWORD dwStyle
= GetWindowLongA (hwnd
, GWL_STYLE
);
1199 /* if initial timer, kill it and start the repeat timer */
1200 if (wParam
== TIMERID1
) {
1201 if (infoPtr
->TLbtnState
== PGF_HOT
)
1202 dir
= PAGER_IsHorizontal(hwnd
) ?
1203 PGF_SCROLLLEFT
: PGF_SCROLLUP
;
1205 dir
= PAGER_IsHorizontal(hwnd
) ?
1206 PGF_SCROLLRIGHT
: PGF_SCROLLDOWN
;
1207 TRACE("[%p] TIMERID1: style=%08lx, dir=%d\n", hwnd
, dwStyle
, dir
);
1208 KillTimer(hwnd
, TIMERID1
);
1209 SetTimer(hwnd
, TIMERID1
, REPEAT_DELAY
, 0);
1210 if (dwStyle
& PGS_AUTOSCROLL
) {
1211 PAGER_Scroll(hwnd
, dir
);
1212 SetWindowPos(hwnd
, 0,0,0,0,0,
1213 SWP_FRAMECHANGED
| SWP_NOSIZE
| SWP_NOMOVE
|
1214 SWP_NOZORDER
| SWP_NOACTIVATE
);
1220 TRACE("[%p] TIMERID2: dir=%d\n", hwnd
, infoPtr
->direction
);
1221 KillTimer(hwnd
, TIMERID2
);
1222 if (infoPtr
->direction
> 0) {
1223 PAGER_Scroll(hwnd
, infoPtr
->direction
);
1224 SetTimer(hwnd
, TIMERID2
, REPEAT_DELAY
, 0);
1230 PAGER_EraseBackground (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1233 HDC hdc
= (HDC
)wParam
;
1238 parent
= GetParent(hwnd
);
1239 MapWindowPoints(hwnd
, parent
, &pt
, 1);
1240 OffsetWindowOrgEx (hdc
, pt
.x
, pt
.y
, &ptorig
);
1241 SendMessageW (parent
, WM_ERASEBKGND
, wParam
, lParam
);
1242 SetWindowOrgEx (hdc
, ptorig
.x
, ptorig
.y
, 0);
1249 PAGER_Size (HWND hwnd
, WPARAM wParam
, LPARAM lParam
)
1251 /* note that WM_SIZE is sent whenever NCCalcSize resizes the client wnd */
1253 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
1254 TRACE("[%p] %dx%d\n", hwnd
, (short)LOWORD(lParam
), (short)HIWORD(lParam
));
1256 if (PAGER_IsHorizontal(hwnd
))
1257 infoPtr
->nHeight
= (short)HIWORD(lParam
);
1259 infoPtr
->nWidth
= (short)LOWORD(lParam
);
1261 return PAGER_RecalcSize(hwnd
);
1265 static LRESULT WINAPI
1266 PAGER_WindowProc (HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1268 PAGER_INFO
*infoPtr
= PAGER_GetInfoPtr (hwnd
);
1270 if (!infoPtr
&& (uMsg
!= WM_CREATE
))
1271 return DefWindowProcW (hwnd
, uMsg
, wParam
, lParam
);
1276 return PAGER_FmtLines(hwnd
);
1278 case PGM_FORWARDMOUSE
:
1279 return PAGER_ForwardMouse (hwnd
, wParam
);
1281 case PGM_GETBKCOLOR
:
1282 return PAGER_GetBkColor(hwnd
);
1285 return PAGER_GetBorder(hwnd
);
1287 case PGM_GETBUTTONSIZE
:
1288 return PAGER_GetButtonSize(hwnd
);
1291 return PAGER_GetPos(hwnd
);
1293 case PGM_GETBUTTONSTATE
:
1294 return PAGER_GetButtonState (hwnd
, wParam
, lParam
);
1296 /* case PGM_GETDROPTARGET: */
1298 case PGM_RECALCSIZE
:
1299 return PAGER_RecalcSize(hwnd
);
1301 case PGM_SETBKCOLOR
:
1302 return PAGER_SetBkColor (hwnd
, wParam
, lParam
);
1305 return PAGER_SetBorder (hwnd
, wParam
, lParam
);
1307 case PGM_SETBUTTONSIZE
:
1308 return PAGER_SetButtonSize (hwnd
, wParam
, lParam
);
1311 return PAGER_SetChild (hwnd
, wParam
, lParam
);
1314 return PAGER_SetPos(hwnd
, (INT
)lParam
, FALSE
);
1317 return PAGER_Create (hwnd
, wParam
, lParam
);
1320 return PAGER_Destroy (hwnd
, wParam
, lParam
);
1323 return PAGER_Size (hwnd
, wParam
, lParam
);
1326 return PAGER_NCPaint (hwnd
, wParam
, lParam
);
1328 case WM_WINDOWPOSCHANGING
:
1329 return PAGER_HandleWindowPosChanging (hwnd
, wParam
, (WINDOWPOS
*)lParam
);
1332 return PAGER_NCCalcSize (hwnd
, wParam
, lParam
);
1335 return PAGER_NCHitTest (hwnd
, wParam
, lParam
);
1338 if (infoPtr
->bForward
&& infoPtr
->hwndChild
)
1339 PostMessageW(infoPtr
->hwndChild
, WM_MOUSEMOVE
, wParam
, lParam
);
1340 return PAGER_MouseMove (hwnd
, wParam
, lParam
);
1342 case WM_LBUTTONDOWN
:
1343 return PAGER_LButtonDown (hwnd
, wParam
, lParam
);
1346 return PAGER_LButtonUp (hwnd
, wParam
, lParam
);
1349 return PAGER_EraseBackground (hwnd
, wParam
, lParam
);
1352 return PAGER_Timer (hwnd
, wParam
);
1356 return SendMessageW (infoPtr
->hwndNotify
, uMsg
, wParam
, lParam
);
1359 return DefWindowProcW (hwnd
, uMsg
, wParam
, lParam
);
1365 PAGER_Register (void)
1369 ZeroMemory (&wndClass
, sizeof(WNDCLASSW
));
1370 wndClass
.style
= CS_GLOBALCLASS
;
1371 wndClass
.lpfnWndProc
= PAGER_WindowProc
;
1372 wndClass
.cbClsExtra
= 0;
1373 wndClass
.cbWndExtra
= sizeof(PAGER_INFO
*);
1374 wndClass
.hCursor
= LoadCursorW (0, (LPWSTR
)IDC_ARROW
);
1375 wndClass
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+1);
1376 wndClass
.lpszClassName
= WC_PAGESCROLLERW
;
1378 RegisterClassW (&wndClass
);
1383 PAGER_Unregister (void)
1385 UnregisterClassW (WC_PAGESCROLLERW
, NULL
);