ReactOS  0.4.13-dev-482-ge57f103
pager.c
Go to the documentation of this file.
1 /*
2  * Pager control
3  *
4  * Copyright 1998, 1999 Eric Kohl
5  *
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.
10  *
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.
15  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  * NOTES
21  *
22  * This code was audited for completeness against the documented features
23  * of Comctl32.dll version 6.0 on Sep. 18, 2004, by Robert Shearman.
24  *
25  * Unless otherwise noted, we believe this code to be complete, as per
26  * the specification mentioned above.
27  * If you discover missing features or bugs please note them below.
28  *
29  * TODO:
30  * Implement repetitive button press.
31  * Adjust arrow size relative to size of button.
32  * Allow border size changes.
33  * Styles:
34  * PGS_DRAGNDROP
35  * Notifications:
36  * PGN_HOTITEMCHANGE
37  * Messages:
38  * WM_PRINT and/or WM_PRINTCLIENT
39  *
40  * TESTING:
41  * Tested primarily with the controlspy Pager application.
42  * Susan Farley (susan@codeweavers.com)
43  *
44  * IMPLEMENTATION NOTES:
45  * This control uses WM_NCPAINT instead of WM_PAINT to paint itself
46  * as we need to scroll a child window. In order to do this we move
47  * the child window in the control's client area, using the clipping
48  * region that is automatically set around the client area. As the
49  * entire client area now consists of the child window, we must
50  * allocate space (WM_NCCALCSIZE) for the buttons and draw them as
51  * a non-client area (WM_NCPAINT).
52  * Robert Shearman <rob@codeweavers.com>
53  */
54 
55 #include <stdarg.h>
56 #include <string.h>
57 #include "windef.h"
58 #include "winbase.h"
59 #include "wingdi.h"
60 #include "winuser.h"
61 #include "winnls.h"
62 #include "commctrl.h"
63 #include "comctl32.h"
64 #include "wine/debug.h"
65 #include "wine/heap.h"
66 
68 
69 typedef struct
70 {
71  HWND hwndSelf; /* handle of the control wnd */
72  HWND hwndChild; /* handle of the contained wnd */
73  HWND hwndNotify; /* handle of the parent wnd */
74  DWORD dwStyle; /* styles for this control */
75  COLORREF clrBk; /* background color */
76  INT nBorder; /* border size for the control */
77  INT nButtonSize;/* size of the pager btns */
78  INT nPos; /* scroll position */
79  INT nWidth; /* from child wnd's response to PGN_CALCSIZE */
80  INT nHeight; /* from child wnd's response to PGN_CALCSIZE */
81  BOOL bForward; /* forward WM_MOUSEMOVE msgs to the contained wnd */
82  BOOL bCapture; /* we have captured the mouse */
83  INT TLbtnState; /* state of top or left btn */
84  INT BRbtnState; /* state of bottom or right btn */
85  INT direction; /* direction of the scroll, (e.g. PGF_SCROLLUP) */
86 } PAGER_INFO;
87 
88 #define TIMERID1 1
89 #define TIMERID2 2
90 #define INITIAL_DELAY 500
91 #define REPEAT_DELAY 50
92 
93 static void
94 PAGER_GetButtonRects(const PAGER_INFO* infoPtr, RECT* prcTopLeft, RECT* prcBottomRight, BOOL bClientCoords)
95 {
96  RECT rcWindow;
97  GetWindowRect (infoPtr->hwndSelf, &rcWindow);
98 
99  if (bClientCoords)
100  MapWindowPoints( 0, infoPtr->hwndSelf, (POINT *)&rcWindow, 2 );
101  else
102  OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
103 
104  *prcTopLeft = *prcBottomRight = rcWindow;
105  if (infoPtr->dwStyle & PGS_HORZ)
106  {
107  prcTopLeft->right = prcTopLeft->left + infoPtr->nButtonSize;
108  prcBottomRight->left = prcBottomRight->right - infoPtr->nButtonSize;
109  }
110  else
111  {
112  prcTopLeft->bottom = prcTopLeft->top + infoPtr->nButtonSize;
113  prcBottomRight->top = prcBottomRight->bottom - infoPtr->nButtonSize;
114  }
115 }
116 
117 static void
119  BOOL horz, BOOL topLeft, INT btnState)
120 {
121  UINT flags;
122 
123  TRACE("rc = %s, btnState = %d\n", wine_dbgstr_rect(&rc), btnState);
124 
125  if (btnState == PGF_INVISIBLE)
126  return;
127 
128  if ((rc.right - rc.left <= 0) || (rc.bottom - rc.top <= 0))
129  return;
130 
131  if (horz)
132  flags = topLeft ? DFCS_SCROLLLEFT : DFCS_SCROLLRIGHT;
133  else
134  flags = topLeft ? DFCS_SCROLLUP : DFCS_SCROLLDOWN;
135 
136  switch (btnState)
137  {
138  case PGF_HOT:
139  break;
140  case PGF_NORMAL:
141  flags |= DFCS_FLAT;
142  break;
143  case PGF_DEPRESSED:
144  flags |= DFCS_PUSHED;
145  break;
146  case PGF_GRAYED:
148  break;
149  }
151 }
152 
153 /* << PAGER_GetDropTarget >> */
154 
155 static inline LRESULT
157 {
158  TRACE("[%p]\n", infoPtr->hwndSelf);
159 
160  infoPtr->bForward = bFwd;
161 
162  return 0;
163 }
164 
165 static inline LRESULT
166 PAGER_GetButtonState (const PAGER_INFO* infoPtr, INT btn)
167 {
168  LRESULT btnState = PGF_INVISIBLE;
169  TRACE("[%p]\n", infoPtr->hwndSelf);
170 
171  if (btn == PGB_TOPORLEFT)
172  btnState = infoPtr->TLbtnState;
173  else if (btn == PGB_BOTTOMORRIGHT)
174  btnState = infoPtr->BRbtnState;
175 
176  return btnState;
177 }
178 
179 
180 static inline INT
181 PAGER_GetPos(const PAGER_INFO *infoPtr)
182 {
183  TRACE("[%p] returns %d\n", infoPtr->hwndSelf, infoPtr->nPos);
184  return infoPtr->nPos;
185 }
186 
187 static inline INT
189 {
190  TRACE("[%p] returns %d\n", infoPtr->hwndSelf, infoPtr->nButtonSize);
191  return infoPtr->nButtonSize;
192 }
193 
194 static inline INT
196 {
197  TRACE("[%p] returns %d\n", infoPtr->hwndSelf, infoPtr->nBorder);
198  return infoPtr->nBorder;
199 }
200 
201 static inline COLORREF
203 {
204  TRACE("[%p] returns %06x\n", infoPtr->hwndSelf, infoPtr->clrBk);
205  return infoPtr->clrBk;
206 }
207 
208 static void
210 {
211  NMPGCALCSIZE nmpgcs;
212  ZeroMemory (&nmpgcs, sizeof (NMPGCALCSIZE));
213  nmpgcs.hdr.hwndFrom = infoPtr->hwndSelf;
214  nmpgcs.hdr.idFrom = GetWindowLongPtrW (infoPtr->hwndSelf, GWLP_ID);
215  nmpgcs.hdr.code = PGN_CALCSIZE;
216  nmpgcs.dwFlag = (infoPtr->dwStyle & PGS_HORZ) ? PGF_CALCWIDTH : PGF_CALCHEIGHT;
217  nmpgcs.iWidth = infoPtr->nWidth;
218  nmpgcs.iHeight = infoPtr->nHeight;
219  SendMessageW (infoPtr->hwndNotify, WM_NOTIFY, nmpgcs.hdr.idFrom, (LPARAM)&nmpgcs);
220 
221  if (infoPtr->dwStyle & PGS_HORZ)
222  infoPtr->nWidth = nmpgcs.iWidth;
223  else
224  infoPtr->nHeight = nmpgcs.iHeight;
225 
226  TRACE("[%p] PGN_CALCSIZE returns %dx%d\n", infoPtr->hwndSelf, nmpgcs.iWidth, nmpgcs.iHeight );
227 }
228 
229 static void
231 {
232  if (infoPtr->hwndChild)
233  {
234  RECT rcClient;
235  int nPos = infoPtr->nPos;
236 
237  /* compensate for a grayed btn, which will soon become invisible */
238  if (infoPtr->TLbtnState == PGF_GRAYED)
239  nPos += infoPtr->nButtonSize;
240 
241  GetClientRect(infoPtr->hwndSelf, &rcClient);
242 
243  if (infoPtr->dwStyle & PGS_HORZ)
244  {
245  int wndSize = max(0, rcClient.right - rcClient.left);
246  if (infoPtr->nWidth < wndSize)
247  infoPtr->nWidth = wndSize;
248 
249  TRACE("[%p] SWP %dx%d at (%d,%d)\n", infoPtr->hwndSelf,
250  infoPtr->nWidth, infoPtr->nHeight,
251  -nPos, 0);
252  SetWindowPos(infoPtr->hwndChild, HWND_TOP,
253  -nPos, 0,
254  infoPtr->nWidth, infoPtr->nHeight, 0);
255  }
256  else
257  {
258  int wndSize = max(0, rcClient.bottom - rcClient.top);
259  if (infoPtr->nHeight < wndSize)
260  infoPtr->nHeight = wndSize;
261 
262  TRACE("[%p] SWP %dx%d at (%d,%d)\n", infoPtr->hwndSelf,
263  infoPtr->nWidth, infoPtr->nHeight,
264  0, -nPos);
265  SetWindowPos(infoPtr->hwndChild, HWND_TOP,
266  0, -nPos,
267  infoPtr->nWidth, infoPtr->nHeight, 0);
268  }
269 
270  InvalidateRect(infoPtr->hwndChild, NULL, TRUE);
271  }
272 }
273 
274 static INT
276 {
277  INT scrollRange = 0;
278 
279  if (infoPtr->hwndChild)
280  {
281  INT wndSize, childSize;
282  RECT wndRect;
283  GetWindowRect(infoPtr->hwndSelf, &wndRect);
284 
285  if (calc_size)
286  PAGER_CalcSize(infoPtr);
287  if (infoPtr->dwStyle & PGS_HORZ)
288  {
289  wndSize = wndRect.right - wndRect.left;
290  childSize = infoPtr->nWidth;
291  }
292  else
293  {
294  wndSize = wndRect.bottom - wndRect.top;
295  childSize = infoPtr->nHeight;
296  }
297 
298  TRACE("childSize = %d, wndSize = %d\n", childSize, wndSize);
299  if (childSize > wndSize)
300  scrollRange = childSize - wndSize + infoPtr->nButtonSize;
301  }
302 
303  TRACE("[%p] returns %d\n", infoPtr->hwndSelf, scrollRange);
304  return scrollRange;
305 }
306 
307 static void
308 PAGER_UpdateBtns(PAGER_INFO *infoPtr, INT scrollRange, BOOL hideGrayBtns)
309 {
310  BOOL resizeClient;
311  BOOL repaintBtns;
312  INT oldTLbtnState = infoPtr->TLbtnState;
313  INT oldBRbtnState = infoPtr->BRbtnState;
314  POINT pt;
315  RECT rcTopLeft, rcBottomRight;
316 
317  /* get button rects */
318  PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, TRUE);
319 
320  GetCursorPos(&pt);
321  ScreenToClient( infoPtr->hwndSelf, &pt );
322 
323  /* update states based on scroll position */
324  if (infoPtr->nPos > 0)
325  {
326  if (infoPtr->TLbtnState == PGF_INVISIBLE || infoPtr->TLbtnState == PGF_GRAYED)
327  infoPtr->TLbtnState = PGF_NORMAL;
328  }
329  else if (!hideGrayBtns && PtInRect(&rcTopLeft, pt))
330  infoPtr->TLbtnState = PGF_GRAYED;
331  else
332  infoPtr->TLbtnState = PGF_INVISIBLE;
333 
334  if (scrollRange <= 0)
335  {
336  infoPtr->TLbtnState = PGF_INVISIBLE;
337  infoPtr->BRbtnState = PGF_INVISIBLE;
338  }
339  else if (infoPtr->nPos < scrollRange)
340  {
341  if (infoPtr->BRbtnState == PGF_INVISIBLE || infoPtr->BRbtnState == PGF_GRAYED)
342  infoPtr->BRbtnState = PGF_NORMAL;
343  }
344  else if (!hideGrayBtns && PtInRect(&rcBottomRight, pt))
345  infoPtr->BRbtnState = PGF_GRAYED;
346  else
347  infoPtr->BRbtnState = PGF_INVISIBLE;
348 
349  /* only need to resize when entering or leaving PGF_INVISIBLE state */
350  resizeClient =
351  ((oldTLbtnState == PGF_INVISIBLE) != (infoPtr->TLbtnState == PGF_INVISIBLE)) ||
352  ((oldBRbtnState == PGF_INVISIBLE) != (infoPtr->BRbtnState == PGF_INVISIBLE));
353  /* initiate NCCalcSize to resize client wnd if necessary */
354  if (resizeClient)
355  SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
358 
359  /* repaint when changing any state */
360  repaintBtns = (oldTLbtnState != infoPtr->TLbtnState) ||
361  (oldBRbtnState != infoPtr->BRbtnState);
362  if (repaintBtns)
363  SendMessageW(infoPtr->hwndSelf, WM_NCPAINT, 0, 0);
364 }
365 
366 static LRESULT
367 PAGER_SetPos(PAGER_INFO* infoPtr, INT newPos, BOOL fromBtnPress, BOOL calc_size)
368 {
369  INT scrollRange = PAGER_GetScrollRange(infoPtr, calc_size);
370  INT oldPos = infoPtr->nPos;
371 
372  if ((scrollRange <= 0) || (newPos < 0))
373  infoPtr->nPos = 0;
374  else if (newPos > scrollRange)
375  infoPtr->nPos = scrollRange;
376  else
377  infoPtr->nPos = newPos;
378 
379  TRACE("[%p] pos=%d, oldpos=%d\n", infoPtr->hwndSelf, infoPtr->nPos, oldPos);
380 
381  if (infoPtr->nPos != oldPos)
382  {
383  /* gray and restore btns, and if from WM_SETPOS, hide the gray btns */
384  PAGER_UpdateBtns(infoPtr, scrollRange, !fromBtnPress);
385  PAGER_PositionChildWnd(infoPtr);
386  }
387 
388  return 0;
389 }
390 
391 /******************************************************************
392  * For the PGM_RECALCSIZE message (but not the other uses in *
393  * this module), the native control does only the following: *
394  * *
395  * if (some condition) *
396  * PostMessageW(hwnd, EM_FMTLINES, 0, 0); *
397  * return DefWindowProcW(hwnd, PGM_RECALCSIZE, 0, 0); *
398  * *
399  * When we figure out what the "some condition" is we will *
400  * implement that for the message processing. *
401  ******************************************************************/
402 
403 static LRESULT
405 {
406  TRACE("[%p]\n", infoPtr->hwndSelf);
407 
408  if (infoPtr->hwndChild)
409  {
410  INT scrollRange = PAGER_GetScrollRange(infoPtr, TRUE);
411 
412  if (scrollRange <= 0)
413  {
414  infoPtr->nPos = -1;
415  PAGER_SetPos(infoPtr, 0, FALSE, TRUE);
416  }
417  else
418  PAGER_PositionChildWnd(infoPtr);
419  }
420 
421  return 1;
422 }
423 
424 
425 static COLORREF
427 {
428  COLORREF clrTemp = infoPtr->clrBk;
429 
430  infoPtr->clrBk = clrBk;
431  TRACE("[%p] %06x\n", infoPtr->hwndSelf, infoPtr->clrBk);
432 
433  /* the native control seems to do things this way */
434  SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
437 
438  RedrawWindow(infoPtr->hwndSelf, 0, 0, RDW_ERASE | RDW_INVALIDATE);
439 
440  return clrTemp;
441 }
442 
443 
444 static INT
445 PAGER_SetBorder (PAGER_INFO* infoPtr, INT iBorder)
446 {
447  INT nTemp = infoPtr->nBorder;
448 
449  infoPtr->nBorder = iBorder;
450  TRACE("[%p] %d\n", infoPtr->hwndSelf, infoPtr->nBorder);
451 
452  PAGER_RecalcSize(infoPtr);
453 
454  return nTemp;
455 }
456 
457 
458 static INT
459 PAGER_SetButtonSize (PAGER_INFO* infoPtr, INT iButtonSize)
460 {
461  INT nTemp = infoPtr->nButtonSize;
462 
463  infoPtr->nButtonSize = iButtonSize;
464  TRACE("[%p] %d\n", infoPtr->hwndSelf, infoPtr->nButtonSize);
465 
466  PAGER_RecalcSize(infoPtr);
467 
468  return nTemp;
469 }
470 
471 
472 static LRESULT
473 PAGER_SetChild (PAGER_INFO* infoPtr, HWND hwndChild)
474 {
475  infoPtr->hwndChild = IsWindow (hwndChild) ? hwndChild : 0;
476 
477  if (infoPtr->hwndChild)
478  {
479  TRACE("[%p] hwndChild=%p\n", infoPtr->hwndSelf, infoPtr->hwndChild);
480 
481  SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
483 
484  infoPtr->nPos = -1;
485  PAGER_SetPos(infoPtr, 0, FALSE, FALSE);
486  }
487 
488  return 0;
489 }
490 
491 static void
493 {
494  NMPGSCROLL nmpgScroll;
495  RECT rcWnd;
496 
497  if (infoPtr->hwndChild)
498  {
499  ZeroMemory (&nmpgScroll, sizeof (NMPGSCROLL));
500  nmpgScroll.hdr.hwndFrom = infoPtr->hwndSelf;
501  nmpgScroll.hdr.idFrom = GetWindowLongPtrW (infoPtr->hwndSelf, GWLP_ID);
502  nmpgScroll.hdr.code = PGN_SCROLL;
503 
504  GetWindowRect(infoPtr->hwndSelf, &rcWnd);
505  GetClientRect(infoPtr->hwndSelf, &nmpgScroll.rcParent);
506  nmpgScroll.iXpos = nmpgScroll.iYpos = 0;
507  nmpgScroll.iDir = dir;
508 
509  if (infoPtr->dwStyle & PGS_HORZ)
510  {
511  nmpgScroll.iScroll = rcWnd.right - rcWnd.left;
512  nmpgScroll.iXpos = infoPtr->nPos;
513  }
514  else
515  {
516  nmpgScroll.iScroll = rcWnd.bottom - rcWnd.top;
517  nmpgScroll.iYpos = infoPtr->nPos;
518  }
519  nmpgScroll.iScroll -= 2*infoPtr->nButtonSize;
520 
521  SendMessageW (infoPtr->hwndNotify, WM_NOTIFY, nmpgScroll.hdr.idFrom, (LPARAM)&nmpgScroll);
522 
523  TRACE("[%p] PGN_SCROLL returns iScroll=%d\n", infoPtr->hwndSelf, nmpgScroll.iScroll);
524 
525  if (nmpgScroll.iScroll > 0)
526  {
527  infoPtr->direction = dir;
528 
529  if (dir == PGF_SCROLLLEFT || dir == PGF_SCROLLUP)
530  PAGER_SetPos(infoPtr, infoPtr->nPos - nmpgScroll.iScroll, TRUE, TRUE);
531  else
532  PAGER_SetPos(infoPtr, infoPtr->nPos + nmpgScroll.iScroll, TRUE, TRUE);
533  }
534  else
535  infoPtr->direction = -1;
536  }
537 }
538 
539 static LRESULT
540 PAGER_FmtLines(const PAGER_INFO *infoPtr)
541 {
542  /* initiate NCCalcSize to resize client wnd and get size */
543  SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
546 
547  SetWindowPos(infoPtr->hwndChild, 0,
548  0,0,infoPtr->nWidth,infoPtr->nHeight,
549  0);
550 
551  return DefWindowProcW (infoPtr->hwndSelf, EM_FMTLINES, 0, 0);
552 }
553 
554 static LRESULT
556 {
557  PAGER_INFO *infoPtr;
558 
559  /* allocate memory for info structure */
560  infoPtr = heap_alloc_zero (sizeof(*infoPtr));
561  if (!infoPtr) return -1;
562  SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
563 
564  /* set default settings */
565  infoPtr->hwndSelf = hwnd;
566  infoPtr->hwndChild = NULL;
567  infoPtr->hwndNotify = lpcs->hwndParent;
568  infoPtr->dwStyle = lpcs->style;
569  infoPtr->clrBk = GetSysColor(COLOR_BTNFACE);
570  infoPtr->nBorder = 0;
571  infoPtr->nButtonSize = 12;
572  infoPtr->nPos = 0;
573  infoPtr->nWidth = 0;
574  infoPtr->nHeight = 0;
575  infoPtr->bForward = FALSE;
576  infoPtr->bCapture = FALSE;
577  infoPtr->TLbtnState = PGF_INVISIBLE;
578  infoPtr->BRbtnState = PGF_INVISIBLE;
579  infoPtr->direction = -1;
580 
581  if (infoPtr->dwStyle & PGS_DRAGNDROP)
582  FIXME("[%p] Drag and Drop style is not implemented yet.\n", infoPtr->hwndSelf);
583 
584  return 0;
585 }
586 
587 
588 static LRESULT
590 {
591  SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0);
592  heap_free (infoPtr);
593  return 0;
594 }
595 
596 static LRESULT
598 {
599  RECT rcChild, rcWindow;
600 
601  /*
602  * lpRect points to a RECT struct. On entry, the struct
603  * contains the proposed wnd rectangle for the window.
604  * On exit, the struct should contain the screen
605  * coordinates of the corresponding window's client area.
606  */
607 
608  DefWindowProcW (infoPtr->hwndSelf, WM_NCCALCSIZE, wParam, (LPARAM)lpRect);
609 
610  TRACE("orig rect=%s\n", wine_dbgstr_rect(lpRect));
611 
612  GetWindowRect (infoPtr->hwndChild, &rcChild);
613  MapWindowPoints (0, infoPtr->hwndSelf, (LPPOINT)&rcChild, 2); /* FIXME: RECT != 2 POINTS */
614  GetWindowRect (infoPtr->hwndSelf, &rcWindow);
615 
616  infoPtr->nWidth = lpRect->right - lpRect->left;
617  infoPtr->nHeight = lpRect->bottom - lpRect->top;
618  PAGER_CalcSize( infoPtr );
619 
620  if (infoPtr->dwStyle & PGS_HORZ)
621  {
622  if (infoPtr->TLbtnState && (lpRect->left + infoPtr->nButtonSize < lpRect->right))
623  lpRect->left += infoPtr->nButtonSize;
624  if (infoPtr->BRbtnState && (lpRect->right - infoPtr->nButtonSize > lpRect->left))
625  lpRect->right -= infoPtr->nButtonSize;
626  }
627  else
628  {
629  if (infoPtr->TLbtnState && (lpRect->top + infoPtr->nButtonSize < lpRect->bottom))
630  lpRect->top += infoPtr->nButtonSize;
631  if (infoPtr->BRbtnState && (lpRect->bottom - infoPtr->nButtonSize > lpRect->top))
632  lpRect->bottom -= infoPtr->nButtonSize;
633  }
634 
635  TRACE("nPos=%d, nHeight=%d, window=%s\n", infoPtr->nPos, infoPtr->nHeight, wine_dbgstr_rect(&rcWindow));
636  TRACE("[%p] client rect set to %s BtnState[%d,%d]\n", infoPtr->hwndSelf, wine_dbgstr_rect(lpRect),
637  infoPtr->TLbtnState, infoPtr->BRbtnState);
638 
639  return 0;
640 }
641 
642 static LRESULT
643 PAGER_NCPaint (const PAGER_INFO* infoPtr, HRGN hRgn)
644 {
645  RECT rcBottomRight, rcTopLeft;
646  HDC hdc;
647 
648  if (infoPtr->dwStyle & WS_MINIMIZE)
649  return 0;
650 
651  DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)hRgn, 0);
652 
653  if (!(hdc = GetDCEx (infoPtr->hwndSelf, 0, DCX_USESTYLE | DCX_WINDOW)))
654  return 0;
655 
656  PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, FALSE);
657 
658  PAGER_DrawButton(hdc, infoPtr->clrBk, rcTopLeft,
659  infoPtr->dwStyle & PGS_HORZ, TRUE, infoPtr->TLbtnState);
660  PAGER_DrawButton(hdc, infoPtr->clrBk, rcBottomRight,
661  infoPtr->dwStyle & PGS_HORZ, FALSE, infoPtr->BRbtnState);
662 
663  ReleaseDC( infoPtr->hwndSelf, hdc );
664  return 0;
665 }
666 
667 static INT
668 PAGER_HitTest (const PAGER_INFO* infoPtr, const POINT * pt)
669 {
670  RECT clientRect, rcTopLeft, rcBottomRight;
671  POINT ptWindow;
672 
673  GetClientRect (infoPtr->hwndSelf, &clientRect);
674 
675  if (PtInRect(&clientRect, *pt))
676  {
677  TRACE("child\n");
678  return -1;
679  }
680 
681  ptWindow = *pt;
682  PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, TRUE);
683 
684  if ((infoPtr->TLbtnState != PGF_INVISIBLE) && PtInRect(&rcTopLeft, ptWindow))
685  {
686  TRACE("PGB_TOPORLEFT\n");
687  return PGB_TOPORLEFT;
688  }
689  else if ((infoPtr->BRbtnState != PGF_INVISIBLE) && PtInRect(&rcBottomRight, ptWindow))
690  {
691  TRACE("PGB_BOTTOMORRIGHT\n");
692  return PGB_BOTTOMORRIGHT;
693  }
694 
695  TRACE("nowhere\n");
696  return -1;
697 }
698 
699 static LRESULT
700 PAGER_NCHitTest (const PAGER_INFO* infoPtr, INT x, INT y)
701 {
702  POINT pt;
703  INT nHit;
704 
705  pt.x = x;
706  pt.y = y;
707 
708  ScreenToClient (infoPtr->hwndSelf, &pt);
709  nHit = PAGER_HitTest(infoPtr, &pt);
710 
711  return (nHit < 0) ? HTTRANSPARENT : HTCLIENT;
712 }
713 
714 static LRESULT
715 PAGER_MouseMove (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
716 {
717  POINT clpt, pt;
718  RECT wnrect;
719  BOOL topLeft = FALSE;
720  INT btnstate = 0;
721  INT hit;
722  HDC hdc;
723 
724  pt.x = x;
725  pt.y = y;
726 
727  TRACE("[%p] to (%d,%d)\n", infoPtr->hwndSelf, x, y);
728  ClientToScreen(infoPtr->hwndSelf, &pt);
729  GetWindowRect(infoPtr->hwndSelf, &wnrect);
730  if (PtInRect(&wnrect, pt)) {
731  RECT topleft, bottomright, *rect = NULL;
732 
733  PAGER_GetButtonRects(infoPtr, &topleft, &bottomright, FALSE);
734 
735  clpt = pt;
736  MapWindowPoints(0, infoPtr->hwndSelf, &clpt, 1);
737  hit = PAGER_HitTest(infoPtr, &clpt);
738  if ((hit == PGB_TOPORLEFT) && (infoPtr->TLbtnState == PGF_NORMAL))
739  {
740  topLeft = TRUE;
741  rect = &topleft;
742  infoPtr->TLbtnState = PGF_HOT;
743  btnstate = infoPtr->TLbtnState;
744  }
745  else if ((hit == PGB_BOTTOMORRIGHT) && (infoPtr->BRbtnState == PGF_NORMAL))
746  {
747  topLeft = FALSE;
748  rect = &bottomright;
749  infoPtr->BRbtnState = PGF_HOT;
750  btnstate = infoPtr->BRbtnState;
751  }
752 
753  /* If in one of the buttons the capture and draw buttons */
754  if (rect)
755  {
756  TRACE("[%p] draw btn (%s), Capture %s, style %08x\n",
757  infoPtr->hwndSelf, wine_dbgstr_rect(rect),
758  (infoPtr->bCapture) ? "TRUE" : "FALSE",
759  infoPtr->dwStyle);
760  if (!infoPtr->bCapture)
761  {
762  TRACE("[%p] SetCapture\n", infoPtr->hwndSelf);
763  SetCapture(infoPtr->hwndSelf);
764  infoPtr->bCapture = TRUE;
765  }
766  if (infoPtr->dwStyle & PGS_AUTOSCROLL)
767  SetTimer(infoPtr->hwndSelf, TIMERID1, 0x3e, 0);
768  hdc = GetWindowDC(infoPtr->hwndSelf);
769  /* OffsetRect(wnrect, 0 | 1, 0 | 1) */
770  PAGER_DrawButton(hdc, infoPtr->clrBk, *rect,
771  infoPtr->dwStyle & PGS_HORZ, topLeft, btnstate);
772  ReleaseDC(infoPtr->hwndSelf, hdc);
773  return 0;
774  }
775  }
776 
777  /* If we think we are captured, then do release */
778  if (infoPtr->bCapture && (WindowFromPoint(pt) != infoPtr->hwndSelf))
779  {
780  NMHDR nmhdr;
781 
782  infoPtr->bCapture = FALSE;
783 
784  if (GetCapture() == infoPtr->hwndSelf)
785  {
786  ReleaseCapture();
787 
788  if (infoPtr->TLbtnState == PGF_GRAYED)
789  {
790  infoPtr->TLbtnState = PGF_INVISIBLE;
791  SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
794  }
795  else if (infoPtr->TLbtnState == PGF_HOT)
796  {
797  infoPtr->TLbtnState = PGF_NORMAL;
798  /* FIXME: just invalidate button rect */
800  }
801 
802  if (infoPtr->BRbtnState == PGF_GRAYED)
803  {
804  infoPtr->BRbtnState = PGF_INVISIBLE;
805  SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
808  }
809  else if (infoPtr->BRbtnState == PGF_HOT)
810  {
811  infoPtr->BRbtnState = PGF_NORMAL;
812  /* FIXME: just invalidate button rect */
814  }
815 
816  /* Notify parent of released mouse capture */
817  memset(&nmhdr, 0, sizeof(NMHDR));
818  nmhdr.hwndFrom = infoPtr->hwndSelf;
819  nmhdr.idFrom = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
820  nmhdr.code = NM_RELEASEDCAPTURE;
821  SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmhdr.idFrom, (LPARAM)&nmhdr);
822  }
823  if (IsWindow(infoPtr->hwndSelf))
824  KillTimer(infoPtr->hwndSelf, TIMERID1);
825  }
826  return 0;
827 }
828 
829 static LRESULT
831 {
832  BOOL repaintBtns = FALSE;
833  POINT pt;
834  INT hit;
835 
836  pt.x = x;
837  pt.y = y;
838 
839  TRACE("[%p] at (%d,%d)\n", infoPtr->hwndSelf, x, y);
840 
841  hit = PAGER_HitTest(infoPtr, &pt);
842 
843  /* put btn in DEPRESSED state */
844  if (hit == PGB_TOPORLEFT)
845  {
846  repaintBtns = infoPtr->TLbtnState != PGF_DEPRESSED;
847  infoPtr->TLbtnState = PGF_DEPRESSED;
848  SetTimer(infoPtr->hwndSelf, TIMERID1, INITIAL_DELAY, 0);
849  }
850  else if (hit == PGB_BOTTOMORRIGHT)
851  {
852  repaintBtns = infoPtr->BRbtnState != PGF_DEPRESSED;
853  infoPtr->BRbtnState = PGF_DEPRESSED;
854  SetTimer(infoPtr->hwndSelf, TIMERID1, INITIAL_DELAY, 0);
855  }
856 
857  if (repaintBtns)
858  SendMessageW(infoPtr->hwndSelf, WM_NCPAINT, 0, 0);
859 
860  switch(hit)
861  {
862  case PGB_TOPORLEFT:
863  if (infoPtr->dwStyle & PGS_HORZ)
864  {
865  TRACE("[%p] PGF_SCROLLLEFT\n", infoPtr->hwndSelf);
866  PAGER_Scroll(infoPtr, PGF_SCROLLLEFT);
867  }
868  else
869  {
870  TRACE("[%p] PGF_SCROLLUP\n", infoPtr->hwndSelf);
871  PAGER_Scroll(infoPtr, PGF_SCROLLUP);
872  }
873  break;
874  case PGB_BOTTOMORRIGHT:
875  if (infoPtr->dwStyle & PGS_HORZ)
876  {
877  TRACE("[%p] PGF_SCROLLRIGHT\n", infoPtr->hwndSelf);
878  PAGER_Scroll(infoPtr, PGF_SCROLLRIGHT);
879  }
880  else
881  {
882  TRACE("[%p] PGF_SCROLLDOWN\n", infoPtr->hwndSelf);
883  PAGER_Scroll(infoPtr, PGF_SCROLLDOWN);
884  }
885  break;
886  default:
887  break;
888  }
889 
890  return 0;
891 }
892 
893 static LRESULT
894 PAGER_LButtonUp (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
895 {
896  TRACE("[%p]\n", infoPtr->hwndSelf);
897 
898  KillTimer (infoPtr->hwndSelf, TIMERID1);
899  KillTimer (infoPtr->hwndSelf, TIMERID2);
900 
901  /* make PRESSED btns NORMAL but don't hide gray btns */
902  if (infoPtr->TLbtnState & (PGF_HOT | PGF_DEPRESSED))
903  infoPtr->TLbtnState = PGF_NORMAL;
904  if (infoPtr->BRbtnState & (PGF_HOT | PGF_DEPRESSED))
905  infoPtr->BRbtnState = PGF_NORMAL;
906 
907  return 0;
908 }
909 
910 static LRESULT
911 PAGER_Timer (PAGER_INFO* infoPtr, INT nTimerId)
912 {
913  INT dir;
914 
915  /* if initial timer, kill it and start the repeat timer */
916  if (nTimerId == TIMERID1) {
917  if (infoPtr->TLbtnState == PGF_HOT)
918  dir = (infoPtr->dwStyle & PGS_HORZ) ?
920  else
921  dir = (infoPtr->dwStyle & PGS_HORZ) ?
923  TRACE("[%p] TIMERID1: style=%08x, dir=%d\n",
924  infoPtr->hwndSelf, infoPtr->dwStyle, dir);
925  KillTimer(infoPtr->hwndSelf, TIMERID1);
926  SetTimer(infoPtr->hwndSelf, TIMERID1, REPEAT_DELAY, 0);
927  if (infoPtr->dwStyle & PGS_AUTOSCROLL) {
928  PAGER_Scroll(infoPtr, dir);
929  SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
932  }
933  return 0;
934 
935  }
936 
937  TRACE("[%p] TIMERID2: dir=%d\n", infoPtr->hwndSelf, infoPtr->direction);
938  KillTimer(infoPtr->hwndSelf, TIMERID2);
939  if (infoPtr->direction > 0) {
940  PAGER_Scroll(infoPtr, infoPtr->direction);
941  SetTimer(infoPtr->hwndSelf, TIMERID2, REPEAT_DELAY, 0);
942  }
943  return 0;
944 }
945 
946 static LRESULT
948 {
949  POINT pt, ptorig;
950  HWND parent;
951  LRESULT ret;
952 
953  pt.x = 0;
954  pt.y = 0;
955  parent = GetParent(infoPtr->hwndSelf);
956  MapWindowPoints(infoPtr->hwndSelf, parent, &pt, 1);
957  OffsetWindowOrgEx (hdc, pt.x, pt.y, &ptorig);
959  SetWindowOrgEx (hdc, ptorig.x, ptorig.y, 0);
960 
961  return ret;
962 }
963 
964 
965 static LRESULT
967 {
968  /* note that WM_SIZE is sent whenever NCCalcSize resizes the client wnd */
969 
970  TRACE("[%p] %d,%d\n", infoPtr->hwndSelf, x, y);
971 
972  if (infoPtr->dwStyle & PGS_HORZ)
973  infoPtr->nHeight = y;
974  else
975  infoPtr->nWidth = x;
976 
977  return PAGER_RecalcSize(infoPtr);
978 }
979 
980 
981 static LRESULT
982 PAGER_StyleChanged(PAGER_INFO *infoPtr, WPARAM wStyleType, const STYLESTRUCT *lpss)
983 {
984  DWORD oldStyle = infoPtr->dwStyle;
985 
986  TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
987  wStyleType, lpss->styleOld, lpss->styleNew);
988 
989  if (wStyleType != GWL_STYLE) return 0;
990 
991  infoPtr->dwStyle = lpss->styleNew;
992 
993  if ((oldStyle ^ lpss->styleNew) & (PGS_HORZ | PGS_VERT))
994  {
995  PAGER_RecalcSize(infoPtr);
996  }
997 
998  return 0;
999 }
1000 
1001 static LRESULT WINAPI
1003 {
1004  PAGER_INFO *infoPtr = (PAGER_INFO *)GetWindowLongPtrW(hwnd, 0);
1005 
1006  TRACE("(%p, %#x, %#lx, %#lx)\n", hwnd, uMsg, wParam, lParam);
1007 
1008  if (!infoPtr && (uMsg != WM_CREATE))
1009  return DefWindowProcW (hwnd, uMsg, wParam, lParam);
1010 
1011  switch (uMsg)
1012  {
1013  case EM_FMTLINES:
1014  return PAGER_FmtLines(infoPtr);
1015 
1016  case PGM_FORWARDMOUSE:
1017  return PAGER_ForwardMouse (infoPtr, (BOOL)wParam);
1018 
1019  case PGM_GETBKCOLOR:
1020  return PAGER_GetBkColor(infoPtr);
1021 
1022  case PGM_GETBORDER:
1023  return PAGER_GetBorder(infoPtr);
1024 
1025  case PGM_GETBUTTONSIZE:
1026  return PAGER_GetButtonSize(infoPtr);
1027 
1028  case PGM_GETPOS:
1029  return PAGER_GetPos(infoPtr);
1030 
1031  case PGM_GETBUTTONSTATE:
1032  return PAGER_GetButtonState (infoPtr, (INT)lParam);
1033 
1034 /* case PGM_GETDROPTARGET: */
1035 
1036  case PGM_RECALCSIZE:
1037  return PAGER_RecalcSize(infoPtr);
1038 
1039  case PGM_SETBKCOLOR:
1040  return PAGER_SetBkColor (infoPtr, (COLORREF)lParam);
1041 
1042  case PGM_SETBORDER:
1043  return PAGER_SetBorder (infoPtr, (INT)lParam);
1044 
1045  case PGM_SETBUTTONSIZE:
1046  return PAGER_SetButtonSize (infoPtr, (INT)lParam);
1047 
1048  case PGM_SETCHILD:
1049  return PAGER_SetChild (infoPtr, (HWND)lParam);
1050 
1051  case PGM_SETPOS:
1052  return PAGER_SetPos(infoPtr, (INT)lParam, FALSE, TRUE);
1053 
1054  case WM_CREATE:
1056 
1057  case WM_DESTROY:
1058  return PAGER_Destroy (infoPtr);
1059 
1060  case WM_SIZE:
1061  return PAGER_Size (infoPtr, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
1062 
1063  case WM_NCPAINT:
1064  return PAGER_NCPaint (infoPtr, (HRGN)wParam);
1065 
1066  case WM_STYLECHANGED:
1067  return PAGER_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);
1068 
1069  case WM_NCCALCSIZE:
1070  return PAGER_NCCalcSize (infoPtr, wParam, (LPRECT)lParam);
1071 
1072  case WM_NCHITTEST:
1073  return PAGER_NCHitTest (infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam));
1074 
1075  case WM_MOUSEMOVE:
1076  if (infoPtr->bForward && infoPtr->hwndChild)
1078  return PAGER_MouseMove (infoPtr, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
1079 
1080  case WM_LBUTTONDOWN:
1081  return PAGER_LButtonDown (infoPtr, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
1082 
1083  case WM_LBUTTONUP:
1084  return PAGER_LButtonUp (infoPtr, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
1085 
1086  case WM_ERASEBKGND:
1087  return PAGER_EraseBackground (infoPtr, (HDC)wParam);
1088 
1089  case WM_TIMER:
1090  return PAGER_Timer (infoPtr, (INT)wParam);
1091 
1092  case WM_NOTIFY:
1093  case WM_COMMAND:
1094  return SendMessageW (infoPtr->hwndNotify, uMsg, wParam, lParam);
1095 
1096  default:
1097  return DefWindowProcW (hwnd, uMsg, wParam, lParam);
1098  }
1099 }
1100 
1101 
1102 VOID
1104 {
1105  WNDCLASSW wndClass;
1106 
1107  ZeroMemory (&wndClass, sizeof(WNDCLASSW));
1108  wndClass.style = CS_GLOBALCLASS;
1109  wndClass.lpfnWndProc = PAGER_WindowProc;
1110  wndClass.cbClsExtra = 0;
1111  wndClass.cbWndExtra = sizeof(PAGER_INFO *);
1112  wndClass.hCursor = LoadCursorW (0, (LPWSTR)IDC_ARROW);
1113  wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
1114  wndClass.lpszClassName = WC_PAGESCROLLERW;
1115 
1116  RegisterClassW (&wndClass);
1117 }
1118 
1119 
1120 VOID
1122 {
1124 }
static LRESULT PAGER_NCCalcSize(PAGER_INFO *infoPtr, WPARAM wParam, LPRECT lpRect)
Definition: pager.c:597
BOOL WINAPI OffsetWindowOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:900
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define DFCS_FLAT
Definition: winuser.h:510
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
static INT PAGER_GetScrollRange(PAGER_INFO *infoPtr, BOOL calc_size)
Definition: pager.c:275
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
#define max(a, b)
Definition: svc.c:63
#define HTTRANSPARENT
Definition: winuser.h:2427
#define TRUE
Definition: types.h:120
#define PGB_BOTTOMORRIGHT
Definition: commctrl.h:4486
static INT PAGER_SetBorder(PAGER_INFO *infoPtr, INT iBorder)
Definition: pager.c:445
INT nButtonSize
Definition: pager.c:77
INT nBorder
Definition: pager.c:76
static INT PAGER_SetButtonSize(PAGER_INFO *infoPtr, INT iButtonSize)
Definition: pager.c:459
long y
Definition: polytest.cpp:48
UINT style
Definition: winuser.h:3129
static INT PAGER_GetPos(const PAGER_INFO *infoPtr)
Definition: pager.c:181
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
BOOL WINAPI ClientToScreen(_In_ HWND, _Inout_ LPPOINT)
#define WM_LBUTTONDOWN
Definition: winuser.h:1752
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define PGF_SCROLLLEFT
Definition: commctrl.h:4531
BOOL WINAPI IsWindow(_In_opt_ HWND)
long x
Definition: polytest.cpp:48
static LRESULT PAGER_LButtonDown(PAGER_INFO *infoPtr, INT keys, INT x, INT y)
Definition: pager.c:830
#define pt(x, y)
Definition: drawing.c:79
#define WM_NCCALCSIZE
Definition: winuser.h:1667
static LRESULT PAGER_EraseBackground(const PAGER_INFO *infoPtr, HDC hdc)
Definition: pager.c:947
COLORREF clrBk
Definition: pager.c:75
#define TIMERID1
Definition: pager.c:88
#define NM_RELEASEDCAPTURE
Definition: commctrl.h:141
BOOL bForward
Definition: pager.c:81
HWND hwndNotify
Definition: pager.c:73
static HDC
Definition: imagelist.c:92
#define DFCS_INACTIVE
Definition: winuser.h:502
#define REPEAT_DELAY
Definition: pager.c:91
static void PAGER_UpdateBtns(PAGER_INFO *infoPtr, INT scrollRange, BOOL hideGrayBtns)
Definition: pager.c:308
LONG top
Definition: windef.h:292
HWND hwndSelf
Definition: pager.c:71
VOID PAGER_Register(void)
Definition: pager.c:1103
static LRESULT PAGER_FmtLines(const PAGER_INFO *infoPtr)
Definition: pager.c:540
static HRGN hRgn
Definition: mapping.c:33
#define DCX_USESTYLE
Definition: GetDCEx.c:10
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define ZeroMemory
Definition: winbase.h:1635
#define HWND_TOP
Definition: winuser.h:1193
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define PGB_TOPORLEFT
Definition: commctrl.h:4485
int cbClsExtra
Definition: winuser.h:3131
#define PGF_CALCHEIGHT
Definition: commctrl.h:4555
#define WM_NCHITTEST
Definition: winuser.h:1668
BOOL WINAPI DrawFrameControl(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
UINT_PTR WPARAM
Definition: windef.h:207
VOID PAGER_Unregister(void)
Definition: pager.c:1121
#define GetWindowLongPtrW
Definition: winuser.h:4698
#define RDW_FRAME
Definition: winuser.h:1198
LONG left
Definition: windef.h:291
#define SWP_NOZORDER
Definition: winuser.h:1232
INT nHeight
Definition: pager.c:80
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2635
LONG right
Definition: windef.h:293
#define PGM_SETCHILD
Definition: commctrl.h:4488
#define PGF_SCROLLUP
Definition: commctrl.h:4529
static LRESULT PAGER_Timer(PAGER_INFO *infoPtr, INT nTimerId)
Definition: pager.c:911
int32_t INT
Definition: typedefs.h:56
DWORD WINAPI GetSysColor(_In_ int)
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define PGF_DEPRESSED
Definition: commctrl.h:4482
#define DCX_WINDOW
Definition: winuser.h:2074
static COLORREF PAGER_GetBkColor(const PAGER_INFO *infoPtr)
Definition: pager.c:202
UINT code
Definition: winuser.h:3112
#define WM_NCPAINT
Definition: winuser.h:1669
#define PGN_CALCSIZE
Definition: commctrl.h:4552
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define DFCS_PUSHED
Definition: winuser.h:503
INT nPos
Definition: pager.c:78
static void PAGER_Scroll(PAGER_INFO *infoPtr, INT dir)
Definition: pager.c:492
#define PGM_SETPOS
Definition: commctrl.h:4509
#define WS_MINIMIZE
Definition: pedump.c:622
unsigned int BOOL
Definition: ntddk_ex.h:94
UINT_PTR idFrom
Definition: winuser.h:3111
static INT PAGER_GetButtonSize(const PAGER_INFO *infoPtr)
Definition: pager.c:188
int iScroll
Definition: commctrl.h:4547
WNDPROC lpfnWndProc
Definition: winuser.h:3130
HWND WINAPI GetCapture(void)
Definition: message.c:2879
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define FIXME(fmt,...)
Definition: debug.h:110
#define PGF_GRAYED
Definition: commctrl.h:4481
smooth NULL
Definition: ftsmooth.c:416
#define PGF_CALCWIDTH
Definition: commctrl.h:4554
LPCWSTR lpszClassName
Definition: winuser.h:3138
LONG_PTR LPARAM
Definition: windef.h:208
DWORD dwStyle
Definition: pager.c:74
INT nWidth
Definition: pager.c:79
static LRESULT PAGER_NCHitTest(const PAGER_INFO *infoPtr, INT x, INT y)
Definition: pager.c:700
#define PGS_HORZ
Definition: commctrl.h:4475
DWORD dwFlag
Definition: commctrl.h:4559
static void PAGER_GetButtonRects(const PAGER_INFO *infoPtr, RECT *prcTopLeft, RECT *prcBottomRight, BOOL bClientCoords)
Definition: pager.c:94
unsigned int dir
Definition: maze.c:112
static void PAGER_PositionChildWnd(PAGER_INFO *infoPtr)
Definition: pager.c:230
#define PGF_INVISIBLE
Definition: commctrl.h:4479
static LRESULT PAGER_SetChild(PAGER_INFO *infoPtr, HWND hwndChild)
Definition: pager.c:473
HWND hwndChild
Definition: pager.c:72
#define WC_PAGESCROLLERW
Definition: commctrl.h:4469
#define DFCS_SCROLLDOWN
Definition: winuser.h:490
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define PGM_GETBORDER
Definition: commctrl.h:4506
#define WM_DESTROY
Definition: winuser.h:1591
#define PGM_SETBUTTONSIZE
Definition: commctrl.h:4515
static LRESULT PAGER_SetPos(PAGER_INFO *infoPtr, INT newPos, BOOL fromBtnPress, BOOL calc_size)
Definition: pager.c:367
#define PGF_NORMAL
Definition: commctrl.h:4480
#define PGM_GETBKCOLOR
Definition: commctrl.h:4500
#define TRACE(s)
Definition: solgame.cpp:4
#define PGM_SETBORDER
Definition: commctrl.h:4503
#define PGN_SCROLL
Definition: commctrl.h:4527
r parent
Definition: btrfs.c:2708
int cbWndExtra
Definition: winuser.h:3132
#define PGM_FORWARDMOUSE
Definition: commctrl.h:4494
#define PGM_GETPOS
Definition: commctrl.h:4512
static INT PAGER_HitTest(const PAGER_INFO *infoPtr, const POINT *pt)
Definition: pager.c:668
static INT PAGER_GetBorder(const PAGER_INFO *infoPtr)
Definition: pager.c:195
#define WM_SIZE
Definition: winuser.h:1593
#define SWP_NOACTIVATE
Definition: winuser.h:1227
DWORD COLORREF
Definition: windef.h:285
#define RDW_ERASE
Definition: winuser.h:1197
#define WM_TIMER
Definition: winuser.h:1718
#define CS_GLOBALCLASS
Definition: winuser.h:647
#define WINAPI
Definition: msvc.h:8
const char * wine_dbgstr_rect(const RECT *rect)
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
#define PGF_SCROLLDOWN
Definition: commctrl.h:4530
unsigned long DWORD
Definition: ntddk_ex.h:95
#define DFCS_SCROLLRIGHT
Definition: winuser.h:492
#define DFCS_SCROLLUP
Definition: winuser.h:489
static LRESULT PAGER_NCPaint(const PAGER_INFO *infoPtr, HRGN hRgn)
Definition: pager.c:643
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2074
static LRESULT PAGER_ForwardMouse(PAGER_INFO *infoPtr, BOOL bFwd)
Definition: pager.c:156
GLbitfield flags
Definition: glext.h:7161
WINE_DEFAULT_DEBUG_CHANNEL(pager)
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
int ret
static LRESULT PAGER_StyleChanged(PAGER_INFO *infoPtr, WPARAM wStyleType, const STYLESTRUCT *lpss)
Definition: pager.c:982
static COLORREF PAGER_SetBkColor(PAGER_INFO *infoPtr, COLORREF clrBk)
Definition: pager.c:426
HDC hdc
Definition: main.c:9
#define COLOR_BTNFACE
Definition: winuser.h:918
#define EM_FMTLINES
Definition: winuser.h:1947
#define SWP_FRAMECHANGED
Definition: winuser.h:1225
BOOL bCapture
Definition: pager.c:82
#define PGF_HOT
Definition: commctrl.h:4483
static LRESULT PAGER_RecalcSize(PAGER_INFO *infoPtr)
Definition: pager.c:404
#define WM_COMMAND
Definition: winuser.h:1716
HWND hwndFrom
Definition: winuser.h:3110
uint32_t DWORD_PTR
Definition: typedefs.h:63
static LRESULT PAGER_GetButtonState(const PAGER_INFO *infoPtr, INT btn)
Definition: pager.c:166
static void PAGER_CalcSize(PAGER_INFO *infoPtr)
Definition: pager.c:209
#define PGS_DRAGNDROP
Definition: commctrl.h:4477
#define SWP_NOSIZE
Definition: winuser.h:1230
HCURSOR hCursor
Definition: winuser.h:3135
#define PGM_GETBUTTONSIZE
Definition: commctrl.h:4518
#define GWL_STYLE
Definition: winuser.h:846
static LRESULT PAGER_LButtonUp(PAGER_INFO *infoPtr, INT keys, INT x, INT y)
Definition: pager.c:894
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
HWND WINAPI GetParent(_In_ HWND)
#define TIMERID2
Definition: pager.c:89
#define PGF_SCROLLRIGHT
Definition: commctrl.h:4532
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define PGM_RECALCSIZE
Definition: commctrl.h:4491
HBRUSH hbrBackground
Definition: winuser.h:3136
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_LBUTTONUP
Definition: winuser.h:1753
static LRESULT PAGER_Destroy(PAGER_INFO *infoPtr)
Definition: pager.c:589
DWORD styleNew
Definition: winuser.h:3635
HDC WINAPI GetWindowDC(_In_opt_ HWND)
#define PGM_SETBKCOLOR
Definition: commctrl.h:4497
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1751
#define PGS_VERT
Definition: commctrl.h:4474
static LRESULT PAGER_Size(PAGER_INFO *infoPtr, INT type, INT x, INT y)
Definition: pager.c:966
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
HWND WINAPI WindowFromPoint(_In_ POINT)
#define DFC_SCROLL
Definition: winuser.h:475
static LRESULT PAGER_MouseMove(PAGER_INFO *infoPtr, INT keys, INT x, INT y)
Definition: pager.c:715
DWORD styleOld
Definition: winuser.h:3634
NMHDR hdr
Definition: commctrl.h:4541
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define IDC_ARROW
Definition: winuser.h:682
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2888
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
RECT rcParent
Definition: commctrl.h:4543
#define WM_CREATE
Definition: winuser.h:1590
#define PGS_AUTOSCROLL
Definition: commctrl.h:4476
#define HIWORD(l)
Definition: typedefs.h:246
INT BRbtnState
Definition: pager.c:84
BOOL WINAPI SetWindowOrgEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
Definition: coord.c:532
LONG bottom
Definition: windef.h:294
#define SWP_NOMOVE
Definition: winuser.h:1229
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define SetWindowLongPtrW
Definition: winuser.h:5215
#define INITIAL_DELAY
Definition: pager.c:90
static LRESULT WINAPI PAGER_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: pager.c:1002
INT direction
Definition: pager.c:85
#define WM_ERASEBKGND
Definition: winuser.h:1607
#define HTCLIENT
Definition: winuser.h:2429
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define DFCS_SCROLLLEFT
Definition: winuser.h:491
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
LONG_PTR LRESULT
Definition: windef.h:209
#define memset(x, y, z)
Definition: compat.h:39
static void PAGER_DrawButton(HDC hdc, COLORREF clrBk, RECT rc, BOOL horz, BOOL topLeft, INT btnState)
Definition: pager.c:118
static LRESULT PAGER_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
Definition: pager.c:555
LPARAM lParam
Definition: combotst.c:139
INT TLbtnState
Definition: pager.c:83
#define LOWORD(l)
Definition: pedump.c:82
#define GWLP_ID
Definition: winuser.h:854
#define WM_NOTIFY
Definition: richedit.h:61
#define RDW_INVALIDATE
Definition: winuser.h:1200
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#define PGM_GETBUTTONSTATE
Definition: commctrl.h:4521