~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/comctl32/pager.c

Version: ~ [ wine-1.5.30 ] ~ [ wine-1.5.29 ] ~ [ wine-1.5.28 ] ~ [ wine-1.5.27 ] ~ [ wine-1.5.26 ] ~ [ wine-1.5.25 ] ~ [ wine-1.5.24 ] ~ [ wine-1.5.23 ] ~ [ wine-1.5.22 ] ~ [ wine-1.5.21 ] ~ [ wine-1.5.20 ] ~ [ wine-1.5.19 ] ~ [ wine-1.5.18 ] ~ [ wine-1.5.17 ] ~ [ wine-1.5.16 ] ~ [ wine-1.5.15 ] ~ [ wine-1.5.14 ] ~ [ wine-1.5.13 ] ~ [ wine-1.5.12 ] ~ [ wine-1.5.11 ] ~ [ wine-1.5.10 ] ~ [ wine-1.5.9 ] ~ [ wine-1.5.8 ] ~ [ wine-1.5.7 ] ~ [ wine-1.4.1 ] ~ [ wine-1.5.6 ] ~ [ wine-1.5.5 ] ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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 
 66 WINE_DEFAULT_DEBUG_CHANNEL(pager);
 67 
 68 typedef struct
 69 {
 70     HWND   hwndSelf;   /* handle of the control wnd */
 71     HWND   hwndChild;  /* handle of the contained wnd */
 72     HWND   hwndNotify; /* handle of the parent wnd */
 73     DWORD  dwStyle;    /* styles for this control */
 74     COLORREF clrBk;    /* background color */
 75     INT    nBorder;    /* border size for the control */
 76     INT    nButtonSize;/* size of the pager btns */
 77     INT    nPos;       /* scroll position */
 78     INT    nWidth;     /* from child wnd's response to PGN_CALCSIZE */
 79     INT    nHeight;    /* from child wnd's response to PGN_CALCSIZE */
 80     BOOL   bForward;   /* forward WM_MOUSEMOVE msgs to the contained wnd */
 81     BOOL   bCapture;   /* we have captured the mouse  */
 82     INT    TLbtnState; /* state of top or left btn */
 83     INT    BRbtnState; /* state of bottom or right btn */
 84     INT    direction;  /* direction of the scroll, (e.g. PGF_SCROLLUP) */
 85 } PAGER_INFO;
 86 
 87 #define TIMERID1         1
 88 #define TIMERID2         2
 89 #define INITIAL_DELAY    500
 90 #define REPEAT_DELAY     50
 91 
 92 static void
 93 PAGER_GetButtonRects(const PAGER_INFO* infoPtr, RECT* prcTopLeft, RECT* prcBottomRight, BOOL bClientCoords)
 94 {
 95     RECT rcWindow;
 96     GetWindowRect (infoPtr->hwndSelf, &rcWindow);
 97 
 98     if (bClientCoords)
 99         MapWindowPoints( 0, infoPtr->hwndSelf, (POINT *)&rcWindow, 2 );
100     else
101         OffsetRect(&rcWindow, -rcWindow.left, -rcWindow.top);
102 
103     *prcTopLeft = *prcBottomRight = rcWindow;
104     if (infoPtr->dwStyle & PGS_HORZ)
105     {
106         prcTopLeft->right = prcTopLeft->left + infoPtr->nButtonSize;
107         prcBottomRight->left = prcBottomRight->right - infoPtr->nButtonSize;
108     }
109     else
110     {
111         prcTopLeft->bottom = prcTopLeft->top + infoPtr->nButtonSize;
112         prcBottomRight->top = prcBottomRight->bottom - infoPtr->nButtonSize;
113     }
114 }
115 
116 static void
117 PAGER_DrawButton(HDC hdc, COLORREF clrBk, RECT rc,
118                  BOOL horz, BOOL topLeft, INT btnState)
119 {
120     UINT flags;
121 
122     TRACE("rc = %s, btnState = %d\n", wine_dbgstr_rect(&rc), btnState);
123 
124     if (btnState == PGF_INVISIBLE)
125         return;
126 
127     if ((rc.right - rc.left <= 0) || (rc.bottom - rc.top <= 0))
128         return;
129 
130     if (horz)
131         flags = topLeft ? DFCS_SCROLLLEFT : DFCS_SCROLLRIGHT;
132     else
133         flags = topLeft ? DFCS_SCROLLUP : DFCS_SCROLLDOWN;
134 
135     switch (btnState)
136     {
137     case PGF_HOT:
138         break;
139     case PGF_NORMAL:
140         flags |= DFCS_FLAT;
141         break;
142     case PGF_DEPRESSED:
143         flags |= DFCS_PUSHED;
144         break;
145     case PGF_GRAYED:
146         flags |= DFCS_INACTIVE | DFCS_FLAT;
147         break;
148     }
149     DrawFrameControl( hdc, &rc, DFC_SCROLL, flags );
150 }
151 
152 /* << PAGER_GetDropTarget >> */
153 
154 static inline LRESULT
155 PAGER_ForwardMouse (PAGER_INFO* infoPtr, BOOL bFwd)
156 {
157     TRACE("[%p]\n", infoPtr->hwndSelf);
158 
159     infoPtr->bForward = bFwd;
160 
161     return 0;
162 }
163 
164 static inline LRESULT
165 PAGER_GetButtonState (const PAGER_INFO* infoPtr, INT btn)
166 {
167     LRESULT btnState = PGF_INVISIBLE;
168     TRACE("[%p]\n", infoPtr->hwndSelf);
169 
170     if (btn == PGB_TOPORLEFT)
171         btnState = infoPtr->TLbtnState;
172     else if (btn == PGB_BOTTOMORRIGHT)
173         btnState = infoPtr->BRbtnState;
174 
175     return btnState;
176 }
177 
178 
179 static inline INT
180 PAGER_GetPos(const PAGER_INFO *infoPtr)
181 {
182     TRACE("[%p] returns %d\n", infoPtr->hwndSelf, infoPtr->nPos);
183     return infoPtr->nPos;
184 }
185 
186 static inline INT
187 PAGER_GetButtonSize(const PAGER_INFO *infoPtr)
188 {
189     TRACE("[%p] returns %d\n", infoPtr->hwndSelf, infoPtr->nButtonSize);
190     return infoPtr->nButtonSize;
191 }
192 
193 static inline INT
194 PAGER_GetBorder(const PAGER_INFO *infoPtr)
195 {
196     TRACE("[%p] returns %d\n", infoPtr->hwndSelf, infoPtr->nBorder);
197     return infoPtr->nBorder;
198 }
199 
200 static inline COLORREF
201 PAGER_GetBkColor(const PAGER_INFO *infoPtr)
202 {
203     TRACE("[%p] returns %06x\n", infoPtr->hwndSelf, infoPtr->clrBk);
204     return infoPtr->clrBk;
205 }
206 
207 static void
208 PAGER_CalcSize( PAGER_INFO *infoPtr )
209 {
210     NMPGCALCSIZE nmpgcs;
211     ZeroMemory (&nmpgcs, sizeof (NMPGCALCSIZE));
212     nmpgcs.hdr.hwndFrom = infoPtr->hwndSelf;
213     nmpgcs.hdr.idFrom   = GetWindowLongPtrW (infoPtr->hwndSelf, GWLP_ID);
214     nmpgcs.hdr.code = PGN_CALCSIZE;
215     nmpgcs.dwFlag = (infoPtr->dwStyle & PGS_HORZ) ? PGF_CALCWIDTH : PGF_CALCHEIGHT;
216     nmpgcs.iWidth = infoPtr->nWidth;
217     nmpgcs.iHeight = infoPtr->nHeight;
218     SendMessageW (infoPtr->hwndNotify, WM_NOTIFY, nmpgcs.hdr.idFrom, (LPARAM)&nmpgcs);
219 
220     if (infoPtr->dwStyle & PGS_HORZ)
221         infoPtr->nWidth = nmpgcs.iWidth;
222     else
223         infoPtr->nHeight = nmpgcs.iHeight;
224 
225     TRACE("[%p] PGN_CALCSIZE returns %dx%d\n", infoPtr->hwndSelf, nmpgcs.iWidth, nmpgcs.iHeight );
226 }
227 
228 static void
229 PAGER_PositionChildWnd(PAGER_INFO* infoPtr)
230 {
231     if (infoPtr->hwndChild)
232     {
233         RECT rcClient;
234         int nPos = infoPtr->nPos;
235 
236         /* compensate for a grayed btn, which will soon become invisible */
237         if (infoPtr->TLbtnState == PGF_GRAYED)
238             nPos += infoPtr->nButtonSize;
239 
240         GetClientRect(infoPtr->hwndSelf, &rcClient);
241 
242         if (infoPtr->dwStyle & PGS_HORZ)
243         {
244             int wndSize = max(0, rcClient.right - rcClient.left);
245             if (infoPtr->nWidth < wndSize)
246                 infoPtr->nWidth = wndSize;
247 
248             TRACE("[%p] SWP %dx%d at (%d,%d)\n", infoPtr->hwndSelf,
249                          infoPtr->nWidth, infoPtr->nHeight,
250                          -nPos, 0);
251             SetWindowPos(infoPtr->hwndChild, 0,
252                          -nPos, 0,
253                          infoPtr->nWidth, infoPtr->nHeight,
254                          SWP_NOZORDER);
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, 0,
266                          0, -nPos,
267                          infoPtr->nWidth, infoPtr->nHeight,
268                          SWP_NOZORDER);
269         }
270 
271         InvalidateRect(infoPtr->hwndChild, NULL, TRUE);
272     }
273 }
274 
275 static INT
276 PAGER_GetScrollRange(PAGER_INFO* infoPtr)
277 {
278     INT scrollRange = 0;
279 
280     if (infoPtr->hwndChild)
281     {
282         INT wndSize, childSize;
283         RECT wndRect;
284         GetWindowRect(infoPtr->hwndSelf, &wndRect);
285 
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,
356                      SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
357                      SWP_NOZORDER | SWP_NOACTIVATE);
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)
368 {
369     INT scrollRange = PAGER_GetScrollRange(infoPtr);
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 static LRESULT
392 PAGER_WindowPosChanging(PAGER_INFO* infoPtr, WINDOWPOS *winpos)
393 {
394     if ((infoPtr->dwStyle & CCS_NORESIZE) && !(winpos->flags & SWP_NOSIZE))
395     {
396         /* don't let the app resize the nonscrollable dimension of a control
397          * that was created with CCS_NORESIZE style
398          * (i.e. height for a horizontal pager, or width for a vertical one) */
399 
400         /* except if the current dimension is 0 and app is setting for
401          * first time, then save amount as dimension. - GA 8/01 */
402 
403         if (infoPtr->dwStyle & PGS_HORZ)
404             if (!infoPtr->nHeight && winpos->cy)
405                 infoPtr->nHeight = winpos->cy;
406             else
407                 winpos->cy = infoPtr->nHeight;
408         else
409             if (!infoPtr->nWidth && winpos->cx)
410                 infoPtr->nWidth = winpos->cx;
411             else
412                 winpos->cx = infoPtr->nWidth;
413         return 0;
414     }
415 
416     return DefWindowProcW (infoPtr->hwndSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM)winpos);
417 }
418 
419 /******************************************************************
420  * For the PGM_RECALCSIZE message (but not the other uses in      *
421  * this module), the native control does only the following:      *
422  *                                                                *
423  *    if (some condition)                                         *
424  *          PostMessageW(hwnd, EM_FMTLINES, 0, 0);                *
425  *    return DefWindowProcW(hwnd, PGM_RECALCSIZE, 0, 0);          *
426  *                                                                *
427  * When we figure out what the "some condition" is we will        *
428  * implement that for the message processing.                     *
429  ******************************************************************/
430 
431 static LRESULT
432 PAGER_RecalcSize(PAGER_INFO *infoPtr)
433 {
434     TRACE("[%p]\n", infoPtr->hwndSelf);
435 
436     if (infoPtr->hwndChild)
437     {
438         INT scrollRange = PAGER_GetScrollRange(infoPtr);
439 
440         if (scrollRange <= 0)
441         {
442             infoPtr->nPos = -1;
443             PAGER_SetPos(infoPtr, 0, FALSE);
444         }
445         else
446             PAGER_PositionChildWnd(infoPtr);
447     }
448 
449     return 1;
450 }
451 
452 
453 static COLORREF
454 PAGER_SetBkColor (PAGER_INFO* infoPtr, COLORREF clrBk)
455 {
456     COLORREF clrTemp = infoPtr->clrBk;
457 
458     infoPtr->clrBk = clrBk;
459     TRACE("[%p] %06x\n", infoPtr->hwndSelf, infoPtr->clrBk);
460 
461     /* the native control seems to do things this way */
462     SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
463                  SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
464                  SWP_NOZORDER | SWP_NOACTIVATE);
465 
466     RedrawWindow(infoPtr->hwndSelf, 0, 0, RDW_ERASE | RDW_INVALIDATE);
467 
468     return clrTemp;
469 }
470 
471 
472 static INT
473 PAGER_SetBorder (PAGER_INFO* infoPtr, INT iBorder)
474 {
475     INT nTemp = infoPtr->nBorder;
476 
477     infoPtr->nBorder = iBorder;
478     TRACE("[%p] %d\n", infoPtr->hwndSelf, infoPtr->nBorder);
479 
480     PAGER_RecalcSize(infoPtr);
481 
482     return nTemp;
483 }
484 
485 
486 static INT
487 PAGER_SetButtonSize (PAGER_INFO* infoPtr, INT iButtonSize)
488 {
489     INT nTemp = infoPtr->nButtonSize;
490 
491     infoPtr->nButtonSize = iButtonSize;
492     TRACE("[%p] %d\n", infoPtr->hwndSelf, infoPtr->nButtonSize);
493 
494     PAGER_RecalcSize(infoPtr);
495 
496     return nTemp;
497 }
498 
499 
500 static LRESULT
501 PAGER_SetChild (PAGER_INFO* infoPtr, HWND hwndChild)
502 {
503     infoPtr->hwndChild = IsWindow (hwndChild) ? hwndChild : 0;
504 
505     if (infoPtr->hwndChild)
506     {
507         TRACE("[%p] hwndChild=%p\n", infoPtr->hwndSelf, infoPtr->hwndChild);
508 
509         SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
510                      SWP_FRAMECHANGED | SWP_NOMOVE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
511 
512         /* position child within the page scroller */
513         SetWindowPos(infoPtr->hwndChild, HWND_TOP,
514                      0,0,0,0,
515                      SWP_SHOWWINDOW | SWP_NOSIZE);  /* native is 0 */
516 
517         infoPtr->nPos = -1;
518         PAGER_SetPos(infoPtr, 0, FALSE);
519     }
520 
521     return 0;
522 }
523 
524 static void
525 PAGER_Scroll(PAGER_INFO* infoPtr, INT dir)
526 {
527     NMPGSCROLL nmpgScroll;
528     RECT rcWnd;
529 
530     if (infoPtr->hwndChild)
531     {
532         ZeroMemory (&nmpgScroll, sizeof (NMPGSCROLL));
533         nmpgScroll.hdr.hwndFrom = infoPtr->hwndSelf;
534         nmpgScroll.hdr.idFrom   = GetWindowLongPtrW (infoPtr->hwndSelf, GWLP_ID);
535         nmpgScroll.hdr.code = PGN_SCROLL;
536 
537         GetWindowRect(infoPtr->hwndSelf, &rcWnd);
538         GetClientRect(infoPtr->hwndSelf, &nmpgScroll.rcParent);
539         nmpgScroll.iXpos = nmpgScroll.iYpos = 0;
540         nmpgScroll.iDir = dir;
541 
542         if (infoPtr->dwStyle & PGS_HORZ)
543         {
544             nmpgScroll.iScroll = rcWnd.right - rcWnd.left;
545             nmpgScroll.iXpos = infoPtr->nPos;
546         }
547         else
548         {
549             nmpgScroll.iScroll = rcWnd.bottom - rcWnd.top;
550             nmpgScroll.iYpos = infoPtr->nPos;
551         }
552         nmpgScroll.iScroll -= 2*infoPtr->nButtonSize;
553 
554         SendMessageW (infoPtr->hwndNotify, WM_NOTIFY, nmpgScroll.hdr.idFrom, (LPARAM)&nmpgScroll);
555 
556         TRACE("[%p] PGN_SCROLL returns iScroll=%d\n", infoPtr->hwndSelf, nmpgScroll.iScroll);
557 
558         if (nmpgScroll.iScroll > 0)
559         {
560             infoPtr->direction = dir;
561 
562             if (dir == PGF_SCROLLLEFT || dir == PGF_SCROLLUP)
563                 PAGER_SetPos(infoPtr, infoPtr->nPos - nmpgScroll.iScroll, TRUE);
564             else
565                 PAGER_SetPos(infoPtr, infoPtr->nPos + nmpgScroll.iScroll, TRUE);
566         }
567         else
568             infoPtr->direction = -1;
569     }
570 }
571 
572 static LRESULT
573 PAGER_FmtLines(const PAGER_INFO *infoPtr)
574 {
575     /* initiate NCCalcSize to resize client wnd and get size */
576     SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
577                  SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
578                  SWP_NOZORDER | SWP_NOACTIVATE);
579 
580     SetWindowPos(infoPtr->hwndChild, 0,
581                  0,0,infoPtr->nWidth,infoPtr->nHeight,
582                  0);
583 
584     return DefWindowProcW (infoPtr->hwndSelf, EM_FMTLINES, 0, 0);
585 }
586 
587 static LRESULT
588 PAGER_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
589 {
590     PAGER_INFO *infoPtr;
591 
592     /* allocate memory for info structure */
593     infoPtr = Alloc (sizeof(PAGER_INFO));
594     if (!infoPtr) return -1;
595     SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
596 
597     /* set default settings */
598     infoPtr->hwndSelf = hwnd;
599     infoPtr->hwndChild = NULL;
600     infoPtr->hwndNotify = lpcs->hwndParent;
601     infoPtr->dwStyle = lpcs->style;
602     infoPtr->clrBk = GetSysColor(COLOR_BTNFACE);
603     infoPtr->nBorder = 0;
604     infoPtr->nButtonSize = 12;
605     infoPtr->nPos = 0;
606     infoPtr->nWidth = 0;
607     infoPtr->nHeight = 0;
608     infoPtr->bForward = FALSE;
609     infoPtr->bCapture = FALSE;
610     infoPtr->TLbtnState = PGF_INVISIBLE;
611     infoPtr->BRbtnState = PGF_INVISIBLE;
612     infoPtr->direction = -1;
613 
614     if (infoPtr->dwStyle & PGS_DRAGNDROP)
615         FIXME("[%p] Drag and Drop style is not implemented yet.\n", infoPtr->hwndSelf);
616 
617     return 0;
618 }
619 
620 
621 static LRESULT
622 PAGER_Destroy (PAGER_INFO *infoPtr)
623 {
624     SetWindowLongPtrW (infoPtr->hwndSelf, 0, 0);
625     Free (infoPtr);  /* free pager info data */
626     return 0;
627 }
628 
629 static LRESULT
630 PAGER_NCCalcSize(PAGER_INFO* infoPtr, WPARAM wParam, LPRECT lpRect)
631 {
632     RECT rcChild, rcWindow;
633 
634     /*
635      * lpRect points to a RECT struct.  On entry, the struct
636      * contains the proposed wnd rectangle for the window.
637      * On exit, the struct should contain the screen
638      * coordinates of the corresponding window's client area.
639      */
640 
641     DefWindowProcW (infoPtr->hwndSelf, WM_NCCALCSIZE, wParam, (LPARAM)lpRect);
642 
643     TRACE("orig rect=%s\n", wine_dbgstr_rect(lpRect));
644 
645     GetWindowRect (infoPtr->hwndChild, &rcChild);
646     MapWindowPoints (0, infoPtr->hwndSelf, (LPPOINT)&rcChild, 2); /* FIXME: RECT != 2 POINTS */
647     GetWindowRect (infoPtr->hwndSelf, &rcWindow);
648 
649     infoPtr->nWidth = lpRect->right - lpRect->left;
650     infoPtr->nHeight = lpRect->bottom - lpRect->top;
651     PAGER_CalcSize( infoPtr );
652 
653     if (infoPtr->dwStyle & PGS_HORZ)
654     {
655         if (infoPtr->TLbtnState && (lpRect->left + infoPtr->nButtonSize < lpRect->right))
656             lpRect->left += infoPtr->nButtonSize;
657         if (infoPtr->BRbtnState && (lpRect->right - infoPtr->nButtonSize > lpRect->left))
658             lpRect->right -= infoPtr->nButtonSize;
659     }
660     else
661     {
662         if (infoPtr->TLbtnState && (lpRect->top + infoPtr->nButtonSize < lpRect->bottom))
663             lpRect->top += infoPtr->nButtonSize;
664         if (infoPtr->BRbtnState && (lpRect->bottom - infoPtr->nButtonSize > lpRect->top))
665             lpRect->bottom -= infoPtr->nButtonSize;
666     }
667 
668     TRACE("nPos=%d, nHeight=%d, window=%s\n",
669           infoPtr->nPos, infoPtr->nHeight,
670           wine_dbgstr_rect(&rcWindow));
671 
672     TRACE("[%p] client rect set to %dx%d at (%d,%d) BtnState[%d,%d]\n",
673           infoPtr->hwndSelf, lpRect->right-lpRect->left, lpRect->bottom-lpRect->top,
674           lpRect->left, lpRect->top,
675           infoPtr->TLbtnState, infoPtr->BRbtnState);
676 
677     return 0;
678 }
679 
680 static LRESULT
681 PAGER_NCPaint (const PAGER_INFO* infoPtr, HRGN hRgn)
682 {
683     RECT rcBottomRight, rcTopLeft;
684     HDC hdc;
685 
686     if (infoPtr->dwStyle & WS_MINIMIZE)
687         return 0;
688 
689     DefWindowProcW (infoPtr->hwndSelf, WM_NCPAINT, (WPARAM)hRgn, 0);
690 
691     if (!(hdc = GetDCEx (infoPtr->hwndSelf, 0, DCX_USESTYLE | DCX_WINDOW)))
692         return 0;
693 
694     PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, FALSE);
695 
696     PAGER_DrawButton(hdc, infoPtr->clrBk, rcTopLeft,
697                      infoPtr->dwStyle & PGS_HORZ, TRUE, infoPtr->TLbtnState);
698     PAGER_DrawButton(hdc, infoPtr->clrBk, rcBottomRight,
699                      infoPtr->dwStyle & PGS_HORZ, FALSE, infoPtr->BRbtnState);
700 
701     ReleaseDC( infoPtr->hwndSelf, hdc );
702     return 0;
703 }
704 
705 static INT
706 PAGER_HitTest (const PAGER_INFO* infoPtr, const POINT * pt)
707 {
708     RECT clientRect, rcTopLeft, rcBottomRight;
709     POINT ptWindow;
710 
711     GetClientRect (infoPtr->hwndSelf, &clientRect);
712 
713     if (PtInRect(&clientRect, *pt))
714     {
715         TRACE("child\n");
716         return -1;
717     }
718 
719     ptWindow = *pt;
720     PAGER_GetButtonRects(infoPtr, &rcTopLeft, &rcBottomRight, TRUE);
721 
722     if ((infoPtr->TLbtnState != PGF_INVISIBLE) && PtInRect(&rcTopLeft, ptWindow))
723     {
724         TRACE("PGB_TOPORLEFT\n");
725         return PGB_TOPORLEFT;
726     }
727     else if ((infoPtr->BRbtnState != PGF_INVISIBLE) && PtInRect(&rcBottomRight, ptWindow))
728     {
729         TRACE("PGB_BOTTOMORRIGHT\n");
730         return PGB_BOTTOMORRIGHT;
731     }
732 
733     TRACE("nowhere\n");
734     return -1;
735 }
736 
737 static LRESULT
738 PAGER_NCHitTest (const PAGER_INFO* infoPtr, INT x, INT y)
739 {
740     POINT pt;
741     INT nHit;
742 
743     pt.x = x;
744     pt.y = y;
745 
746     ScreenToClient (infoPtr->hwndSelf, &pt);
747     nHit = PAGER_HitTest(infoPtr, &pt);
748 
749     return (nHit < 0) ? HTTRANSPARENT : HTCLIENT;
750 }
751 
752 static LRESULT
753 PAGER_MouseMove (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
754 {
755     POINT clpt, pt;
756     RECT wnrect, *btnrect = NULL;
757     BOOL topLeft = FALSE;
758     INT btnstate = 0;
759     INT hit;
760     HDC hdc;
761 
762     pt.x = x;
763     pt.y = y;
764 
765     TRACE("[%p] to (%d,%d)\n", infoPtr->hwndSelf, x, y);
766     ClientToScreen(infoPtr->hwndSelf, &pt);
767     GetWindowRect(infoPtr->hwndSelf, &wnrect);
768     if (PtInRect(&wnrect, pt)) {
769         RECT TLbtnrect, BRbtnrect;
770         PAGER_GetButtonRects(infoPtr, &TLbtnrect, &BRbtnrect, FALSE);
771 
772         clpt = pt;
773         MapWindowPoints(0, infoPtr->hwndSelf, &clpt, 1);
774         hit = PAGER_HitTest(infoPtr, &clpt);
775         if ((hit == PGB_TOPORLEFT) && (infoPtr->TLbtnState == PGF_NORMAL))
776         {
777             topLeft = TRUE;
778             btnrect = &TLbtnrect;
779             infoPtr->TLbtnState = PGF_HOT;
780             btnstate = infoPtr->TLbtnState;
781         }
782         else if ((hit == PGB_BOTTOMORRIGHT) && (infoPtr->BRbtnState == PGF_NORMAL))
783         {
784             topLeft = FALSE;
785             btnrect = &BRbtnrect;
786             infoPtr->BRbtnState = PGF_HOT;
787             btnstate = infoPtr->BRbtnState;
788         }
789 
790         /* If in one of the buttons the capture and draw buttons */
791         if (btnrect)
792         {
793             TRACE("[%p] draw btn (%s), Capture %s, style %08x\n",
794                   infoPtr->hwndSelf, wine_dbgstr_rect(btnrect),
795                   (infoPtr->bCapture) ? "TRUE" : "FALSE",
796                   infoPtr->dwStyle);
797             if (!infoPtr->bCapture)
798             {
799                 TRACE("[%p] SetCapture\n", infoPtr->hwndSelf);
800                 SetCapture(infoPtr->hwndSelf);
801                 infoPtr->bCapture = TRUE;
802             }
803             if (infoPtr->dwStyle & PGS_AUTOSCROLL)
804                 SetTimer(infoPtr->hwndSelf, TIMERID1, 0x3e, 0);
805             hdc = GetWindowDC(infoPtr->hwndSelf);
806             /* OffsetRect(wnrect, 0 | 1, 0 | 1) */
807             PAGER_DrawButton(hdc, infoPtr->clrBk, *btnrect,
808                              infoPtr->dwStyle & PGS_HORZ, topLeft, btnstate);
809             ReleaseDC(infoPtr->hwndSelf, hdc);
810             return 0;
811         }
812     }
813 
814     /* If we think we are captured, then do release */
815     if (infoPtr->bCapture && (WindowFromPoint(pt) != infoPtr->hwndSelf))
816     {
817         NMHDR nmhdr;
818 
819         infoPtr->bCapture = FALSE;
820 
821         if (GetCapture() == infoPtr->hwndSelf)
822         {
823             ReleaseCapture();
824 
825             if (infoPtr->TLbtnState == PGF_GRAYED)
826             {
827                 infoPtr->TLbtnState = PGF_INVISIBLE;
828                 SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
829                              SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
830                              SWP_NOZORDER | SWP_NOACTIVATE);
831             }
832             else if (infoPtr->TLbtnState == PGF_HOT)
833             {
834                 infoPtr->TLbtnState = PGF_NORMAL;
835                 /* FIXME: just invalidate button rect */
836                 RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
837             }
838 
839             if (infoPtr->BRbtnState == PGF_GRAYED)
840             {
841                 infoPtr->BRbtnState = PGF_INVISIBLE;
842                 SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
843                              SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
844                              SWP_NOZORDER | SWP_NOACTIVATE);
845             }
846             else if (infoPtr->BRbtnState == PGF_HOT)
847             {
848                 infoPtr->BRbtnState = PGF_NORMAL;
849                 /* FIXME: just invalidate button rect */
850                 RedrawWindow(infoPtr->hwndSelf, NULL, NULL, RDW_FRAME | RDW_INVALIDATE);
851             }
852 
853             /* Notify parent of released mouse capture */
854                 memset(&nmhdr, 0, sizeof(NMHDR));
855                 nmhdr.hwndFrom = infoPtr->hwndSelf;
856                 nmhdr.idFrom   = GetWindowLongPtrW(infoPtr->hwndSelf, GWLP_ID);
857                 nmhdr.code = NM_RELEASEDCAPTURE;
858                 SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, nmhdr.idFrom, (LPARAM)&nmhdr);
859         }
860         if (IsWindow(infoPtr->hwndSelf))
861             KillTimer(infoPtr->hwndSelf, TIMERID1);
862     }
863     return 0;
864 }
865 
866 static LRESULT
867 PAGER_LButtonDown (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
868 {
869     BOOL repaintBtns = FALSE;
870     POINT pt;
871     INT hit;
872 
873     pt.x = x;
874     pt.y = y;
875 
876     TRACE("[%p] at (%d,%d)\n", infoPtr->hwndSelf, x, y);
877 
878     hit = PAGER_HitTest(infoPtr, &pt);
879 
880     /* put btn in DEPRESSED state */
881     if (hit == PGB_TOPORLEFT)
882     {
883         repaintBtns = infoPtr->TLbtnState != PGF_DEPRESSED;
884         infoPtr->TLbtnState = PGF_DEPRESSED;
885         SetTimer(infoPtr->hwndSelf, TIMERID1, INITIAL_DELAY, 0);
886     }
887     else if (hit == PGB_BOTTOMORRIGHT)
888     {
889         repaintBtns = infoPtr->BRbtnState != PGF_DEPRESSED;
890         infoPtr->BRbtnState = PGF_DEPRESSED;
891         SetTimer(infoPtr->hwndSelf, TIMERID1, INITIAL_DELAY, 0);
892     }
893 
894     if (repaintBtns)
895         SendMessageW(infoPtr->hwndSelf, WM_NCPAINT, 0, 0);
896 
897     switch(hit)
898     {
899     case PGB_TOPORLEFT:
900         if (infoPtr->dwStyle & PGS_HORZ)
901         {
902             TRACE("[%p] PGF_SCROLLLEFT\n", infoPtr->hwndSelf);
903             PAGER_Scroll(infoPtr, PGF_SCROLLLEFT);
904         }
905         else
906         {
907             TRACE("[%p] PGF_SCROLLUP\n", infoPtr->hwndSelf);
908             PAGER_Scroll(infoPtr, PGF_SCROLLUP);
909         }
910         break;
911     case PGB_BOTTOMORRIGHT:
912         if (infoPtr->dwStyle & PGS_HORZ)
913         {
914             TRACE("[%p] PGF_SCROLLRIGHT\n", infoPtr->hwndSelf);
915             PAGER_Scroll(infoPtr, PGF_SCROLLRIGHT);
916         }
917         else
918         {
919             TRACE("[%p] PGF_SCROLLDOWN\n", infoPtr->hwndSelf);
920             PAGER_Scroll(infoPtr, PGF_SCROLLDOWN);
921         }
922         break;
923     default:
924         break;
925     }
926 
927     return 0;
928 }
929 
930 static LRESULT
931 PAGER_LButtonUp (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
932 {
933     TRACE("[%p]\n", infoPtr->hwndSelf);
934 
935     KillTimer (infoPtr->hwndSelf, TIMERID1);
936     KillTimer (infoPtr->hwndSelf, TIMERID2);
937 
938     /* make PRESSED btns NORMAL but don't hide gray btns */
939     if (infoPtr->TLbtnState & (PGF_HOT | PGF_DEPRESSED))
940         infoPtr->TLbtnState = PGF_NORMAL;
941     if (infoPtr->BRbtnState & (PGF_HOT | PGF_DEPRESSED))
942         infoPtr->BRbtnState = PGF_NORMAL;
943 
944     return 0;
945 }
946 
947 static LRESULT
948 PAGER_Timer (PAGER_INFO* infoPtr, INT nTimerId)
949 {
950     INT dir;
951 
952     /* if initial timer, kill it and start the repeat timer */
953     if (nTimerId == TIMERID1) {
954         if (infoPtr->TLbtnState == PGF_HOT)
955             dir = (infoPtr->dwStyle & PGS_HORZ) ?
956                 PGF_SCROLLLEFT : PGF_SCROLLUP;
957         else
958             dir = (infoPtr->dwStyle & PGS_HORZ) ?
959                 PGF_SCROLLRIGHT : PGF_SCROLLDOWN;
960         TRACE("[%p] TIMERID1: style=%08x, dir=%d\n",
961               infoPtr->hwndSelf, infoPtr->dwStyle, dir);
962         KillTimer(infoPtr->hwndSelf, TIMERID1);
963         SetTimer(infoPtr->hwndSelf, TIMERID1, REPEAT_DELAY, 0);
964         if (infoPtr->dwStyle & PGS_AUTOSCROLL) {
965             PAGER_Scroll(infoPtr, dir);
966             SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0,
967                          SWP_FRAMECHANGED | SWP_NOSIZE | SWP_NOMOVE |
968                          SWP_NOZORDER | SWP_NOACTIVATE);
969         }
970         return 0;
971 
972     }
973 
974     TRACE("[%p] TIMERID2: dir=%d\n", infoPtr->hwndSelf, infoPtr->direction);
975     KillTimer(infoPtr->hwndSelf, TIMERID2);
976     if (infoPtr->direction > 0) {
977         PAGER_Scroll(infoPtr, infoPtr->direction);
978         SetTimer(infoPtr->hwndSelf, TIMERID2, REPEAT_DELAY, 0);
979     }
980     return 0;
981 }
982 
983 static LRESULT
984 PAGER_EraseBackground (const PAGER_INFO* infoPtr, HDC hdc)
985 {
986     POINT pt, ptorig;
987     HWND parent;
988 
989     pt.x = 0;
990     pt.y = 0;
991     parent = GetParent(infoPtr->hwndSelf);
992     MapWindowPoints(infoPtr->hwndSelf, parent, &pt, 1);
993     OffsetWindowOrgEx (hdc, pt.x, pt.y, &ptorig);
994     SendMessageW (parent, WM_ERASEBKGND, (WPARAM)hdc, 0);
995     SetWindowOrgEx (hdc, ptorig.x, ptorig.y, 0);
996 
997     return 0;
998 }
999 
1000 
1001 static LRESULT
1002 PAGER_Size (PAGER_INFO* infoPtr, INT type, INT x, INT y)
1003 {
1004     /* note that WM_SIZE is sent whenever NCCalcSize resizes the client wnd */
1005 
1006     TRACE("[%p] %d,%d\n", infoPtr->hwndSelf, x, y);
1007 
1008     if (infoPtr->dwStyle & PGS_HORZ)
1009         infoPtr->nHeight = y;
1010     else
1011         infoPtr->nWidth = x;
1012 
1013     return PAGER_RecalcSize(infoPtr);
1014 }
1015 
1016 
1017 static LRESULT 
1018 PAGER_StyleChanged(PAGER_INFO *infoPtr, WPARAM wStyleType, const STYLESTRUCT *lpss)
1019 {
1020     DWORD oldStyle = infoPtr->dwStyle;
1021 
1022     TRACE("(styletype=%lx, styleOld=0x%08x, styleNew=0x%08x)\n",
1023           wStyleType, lpss->styleOld, lpss->styleNew);
1024 
1025     if (wStyleType != GWL_STYLE) return 0;
1026   
1027     infoPtr->dwStyle = lpss->styleNew;
1028 
1029     if ((oldStyle ^ lpss->styleNew) & (PGS_HORZ | PGS_VERT))
1030     {
1031         PAGER_RecalcSize(infoPtr);
1032     }
1033 
1034     return 0;
1035 }
1036 
1037 static LRESULT WINAPI
1038 PAGER_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1039 {
1040     PAGER_INFO *infoPtr = (PAGER_INFO *)GetWindowLongPtrW(hwnd, 0);
1041 
1042     if (!infoPtr && (uMsg != WM_CREATE))
1043         return DefWindowProcW (hwnd, uMsg, wParam, lParam);
1044 
1045     switch (uMsg)
1046     {
1047         case EM_FMTLINES:
1048             return PAGER_FmtLines(infoPtr);
1049 
1050         case PGM_FORWARDMOUSE:
1051             return PAGER_ForwardMouse (infoPtr, (BOOL)wParam);
1052 
1053         case PGM_GETBKCOLOR:
1054             return PAGER_GetBkColor(infoPtr);
1055 
1056         case PGM_GETBORDER:
1057             return PAGER_GetBorder(infoPtr);
1058 
1059         case PGM_GETBUTTONSIZE:
1060             return PAGER_GetButtonSize(infoPtr);
1061 
1062         case PGM_GETPOS:
1063             return PAGER_GetPos(infoPtr);
1064 
1065         case PGM_GETBUTTONSTATE:
1066             return PAGER_GetButtonState (infoPtr, (INT)lParam);
1067 
1068 /*      case PGM_GETDROPTARGET: */
1069 
1070         case PGM_RECALCSIZE:
1071             return PAGER_RecalcSize(infoPtr);
1072 
1073         case PGM_SETBKCOLOR:
1074             return PAGER_SetBkColor (infoPtr, (COLORREF)lParam);
1075 
1076         case PGM_SETBORDER:
1077             return PAGER_SetBorder (infoPtr, (INT)lParam);
1078 
1079         case PGM_SETBUTTONSIZE:
1080             return PAGER_SetButtonSize (infoPtr, (INT)lParam);
1081 
1082         case PGM_SETCHILD:
1083             return PAGER_SetChild (infoPtr, (HWND)lParam);
1084 
1085         case PGM_SETPOS:
1086             return PAGER_SetPos(infoPtr, (INT)lParam, FALSE);
1087 
1088         case WM_CREATE:
1089             return PAGER_Create (hwnd, (LPCREATESTRUCTW)lParam);
1090 
1091         case WM_DESTROY:
1092             return PAGER_Destroy (infoPtr);
1093 
1094         case WM_SIZE:
1095             return PAGER_Size (infoPtr, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
1096 
1097         case WM_NCPAINT:
1098             return PAGER_NCPaint (infoPtr, (HRGN)wParam);
1099 
1100         case WM_WINDOWPOSCHANGING:
1101             return PAGER_WindowPosChanging (infoPtr, (WINDOWPOS*)lParam);
1102 
1103         case WM_STYLECHANGED:
1104             return PAGER_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);
1105 
1106         case WM_NCCALCSIZE:
1107             return PAGER_NCCalcSize (infoPtr, wParam, (LPRECT)lParam);
1108 
1109         case WM_NCHITTEST:
1110             return PAGER_NCHitTest (infoPtr, (short)LOWORD(lParam), (short)HIWORD(lParam));
1111 
1112         case WM_MOUSEMOVE:
1113             if (infoPtr->bForward && infoPtr->hwndChild)
1114                 PostMessageW(infoPtr->hwndChild, WM_MOUSEMOVE, wParam, lParam);
1115             return PAGER_MouseMove (infoPtr, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
1116 
1117         case WM_LBUTTONDOWN:
1118             return PAGER_LButtonDown (infoPtr, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
1119 
1120         case WM_LBUTTONUP:
1121             return PAGER_LButtonUp (infoPtr, (INT)wParam, (short)LOWORD(lParam), (short)HIWORD(lParam));
1122 
1123         case WM_ERASEBKGND:
1124             return PAGER_EraseBackground (infoPtr, (HDC)wParam);
1125 
1126         case WM_TIMER:
1127             return PAGER_Timer (infoPtr, (INT)wParam);
1128 
1129         case WM_NOTIFY:
1130         case WM_COMMAND:
1131             return SendMessageW (infoPtr->hwndNotify, uMsg, wParam, lParam);
1132 
1133         default:
1134             return DefWindowProcW (hwnd, uMsg, wParam, lParam);
1135     }
1136 }
1137 
1138 
1139 VOID
1140 PAGER_Register (void)
1141 {
1142     WNDCLASSW wndClass;
1143 
1144     ZeroMemory (&wndClass, sizeof(WNDCLASSW));
1145     wndClass.style         = CS_GLOBALCLASS;
1146     wndClass.lpfnWndProc   = PAGER_WindowProc;
1147     wndClass.cbClsExtra    = 0;
1148     wndClass.cbWndExtra    = sizeof(PAGER_INFO *);
1149     wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
1150     wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
1151     wndClass.lpszClassName = WC_PAGESCROLLERW;
1152 
1153     RegisterClassW (&wndClass);
1154 }
1155 
1156 
1157 VOID
1158 PAGER_Unregister (void)
1159 {
1160     UnregisterClassW (WC_PAGESCROLLERW, NULL);
1161 }
1162 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.