ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

ncscrollbar.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS uxtheme.dll
00004  * FILE:            dll/win32/uxtheme/ncscrollbar.c
00005  * PURPOSE:         uxtheme scrollbar support
00006  * PROGRAMMER:      Giannis Adamopoulos
00007  *                  This file is heavily based on code from the wine project:
00008  *                  Copyright 1993 Martin Ayotte
00009  *                  Copyright 1994, 1996 Alexandre Julliard
00010  */
00011  
00012 #include "uxthemep.h"
00013 #include "wine/debug.h"
00014 
00015 WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
00016 
00017 static BOOL SCROLL_trackVertical;
00018 static enum SCROLL_HITTEST SCROLL_trackHitTest;
00019 /* Is the moving thumb being displayed? */
00020 static BOOL SCROLL_MovingThumb = FALSE;
00021 static HWND SCROLL_TrackingWin = 0;
00022 static INT  SCROLL_TrackingBar = 0;
00023 static INT  SCROLL_TrackingPos = 0;
00024 static INT  SCROLL_TrackingVal = 0;
00025 
00026 void static ScreenToWindow( HWND hWnd, POINT* pt)
00027 {
00028     RECT rcWnd;
00029     GetWindowRect(hWnd, &rcWnd);
00030     pt->x -= rcWnd.left;
00031     pt->y -= rcWnd.top;
00032 }
00033 
00034 static BOOL SCROLL_IsVertical(HWND hwnd, INT nBar)
00035 {
00036     switch(nBar)
00037     {
00038     case SB_HORZ:
00039         return FALSE;
00040     case SB_VERT:
00041         return TRUE;
00042     default:
00043         assert(FALSE);
00044         return FALSE;
00045     }
00046 }
00047 
00048 static LONG SCROLL_getObjectId(INT nBar)
00049 {
00050     switch(nBar)
00051     {
00052     case SB_HORZ:
00053         return OBJID_HSCROLL;
00054     case SB_VERT:
00055         return OBJID_VSCROLL;
00056     default:
00057         assert(FALSE);
00058         return 0;
00059     }
00060 }
00061 
00062 /***********************************************************************
00063  *           SCROLL_PtInRectEx
00064  */
00065 static BOOL SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical )
00066 {
00067     RECT rect = *lpRect;
00068     int scrollbarWidth;
00069 
00070     /* Pad hit rect to allow mouse to be dragged outside of scrollbar and
00071      * still be considered in the scrollbar. */
00072     if (vertical)
00073     {
00074         scrollbarWidth = lpRect->right - lpRect->left;
00075         rect.left -= scrollbarWidth*8;
00076         rect.right += scrollbarWidth*8;
00077         rect.top -= scrollbarWidth*2;
00078         rect.bottom += scrollbarWidth*2;
00079     }
00080     else
00081     {
00082         scrollbarWidth = lpRect->bottom - lpRect->top;
00083         rect.left -= scrollbarWidth*2;
00084         rect.right += scrollbarWidth*2;
00085         rect.top -= scrollbarWidth*8;
00086         rect.bottom += scrollbarWidth*8;
00087     }
00088     return PtInRect( &rect, pt );
00089 }
00090 
00091 
00092 /***********************************************************************
00093  *           SCROLL_HitTest
00094  *
00095  * Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!).
00096  */
00097 static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, SCROLLBARINFO* psbi, BOOL vertical,
00098                                            POINT pt, BOOL bDragging )
00099 {
00100     if ( (bDragging && !SCROLL_PtInRectEx( &psbi->rcScrollBar, pt, vertical )) ||
00101          (!PtInRect( &psbi->rcScrollBar, pt )) ) 
00102     {
00103          return SCROLL_NOWHERE;
00104     }
00105 
00106     if (vertical)
00107     {
00108         if (pt.y < psbi->rcScrollBar.top + psbi->dxyLineButton) 
00109             return SCROLL_TOP_ARROW;
00110         if (pt.y >= psbi->rcScrollBar.bottom - psbi->dxyLineButton) 
00111             return SCROLL_BOTTOM_ARROW;
00112         if (!psbi->xyThumbTop) 
00113             return SCROLL_TOP_RECT;
00114         pt.y -= psbi->rcScrollBar.top;
00115         if (pt.y < psbi->xyThumbTop) 
00116             return SCROLL_TOP_RECT;
00117         if (pt.y >= psbi->xyThumbTop + psbi->dxyLineButton) 
00118             return SCROLL_BOTTOM_RECT;
00119     }
00120     else  /* horizontal */
00121     {
00122         if (pt.x < psbi->rcScrollBar.left + psbi->dxyLineButton)
00123             return SCROLL_TOP_ARROW;
00124         if (pt.x >= psbi->rcScrollBar.right - psbi->dxyLineButton) 
00125             return SCROLL_BOTTOM_ARROW;
00126         if (!psbi->xyThumbTop) 
00127             return SCROLL_TOP_RECT;
00128         pt.x -= psbi->rcScrollBar.left;
00129         if (pt.x < psbi->xyThumbTop) 
00130             return SCROLL_TOP_RECT;
00131         if (pt.x >= psbi->xyThumbTop + psbi->dxyLineButton) 
00132             return SCROLL_BOTTOM_RECT;
00133     }
00134     return SCROLL_THUMB;
00135 }
00136 
00137 static void SCROLL_ThemeDrawPart(PDRAW_CONTEXT pcontext, int iPartId,int iStateId,  SCROLLBARINFO* psbi, int htCurrent, int htDown, int htHot, RECT* r)
00138 {
00139     if(psbi->rgstate[htCurrent] & STATE_SYSTEM_UNAVAILABLE)
00140         iStateId += BUTTON_DISABLED - BUTTON_NORMAL;
00141     else if (htHot == htCurrent)
00142         iStateId += BUTTON_HOT - BUTTON_NORMAL;
00143     else if (htDown == htCurrent)
00144         iStateId += BUTTON_PRESSED - BUTTON_NORMAL;
00145 
00146     DrawThemeBackground(pcontext->scrolltheme, pcontext->hDC, iPartId, iStateId, r, NULL);
00147 }
00148 
00149 /***********************************************************************
00150  *           SCROLL_DrawArrows
00151  *
00152  * Draw the scroll bar arrows.
00153  */
00154 static void SCROLL_DrawArrows( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi, 
00155                                BOOL vertical, int htDown, int htHot )
00156 {
00157     RECT r;
00158     int iStateId;
00159 
00160     r = psbi->rcScrollBar;
00161     if( vertical )
00162     {
00163         r.bottom = r.top + psbi->dxyLineButton;
00164         iStateId = ABS_UPNORMAL;
00165     }
00166     else
00167     {
00168         r.right = r.left + psbi->dxyLineButton;
00169         iStateId = ABS_LEFTNORMAL;
00170     }
00171     
00172     SCROLL_ThemeDrawPart(pcontext, SBP_ARROWBTN, iStateId, psbi, SCROLL_TOP_ARROW, htDown, htHot, &r);
00173     
00174     r = psbi->rcScrollBar;
00175     if( vertical )
00176     {
00177         r.top = r.bottom - psbi->dxyLineButton;
00178         iStateId = ABS_DOWNNORMAL;
00179     }
00180     else
00181     {
00182         iStateId = ABS_RIGHTNORMAL;
00183         r.left = r.right - psbi->dxyLineButton;
00184     }
00185 
00186     SCROLL_ThemeDrawPart(pcontext, SBP_ARROWBTN, iStateId, psbi, SCROLL_BOTTOM_ARROW, htDown, htHot, &r);
00187 }
00188 
00189 static void SCROLL_DrawInterior( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
00190                                   INT thumbPos, BOOL vertical,
00191                                   int htDown, int htHot )
00192 {
00193     RECT r, rcPart;
00194 
00195     r = psbi->rcScrollBar;
00196     if (vertical)
00197     {
00198         r.top    += psbi->dxyLineButton;
00199         r.bottom -= (psbi->dxyLineButton);
00200     }
00201     else
00202     {
00203         r.left  += psbi->dxyLineButton;
00204         r.right -= psbi->dxyLineButton;
00205     }
00206 
00207     /* Draw the scroll rectangles and thumb */
00208 
00209     if (!thumbPos)  /* No thumb to draw */
00210     {
00211         rcPart = r;
00212         SCROLL_ThemeDrawPart(pcontext, vertical ? SBP_UPPERTRACKVERT: SBP_UPPERTRACKHORZ , BUTTON_NORMAL, psbi, SCROLL_THUMB, 0, 0, &rcPart);
00213         return;
00214     }
00215 
00216     if (vertical)
00217     { 
00218         rcPart = r;
00219         rcPart.bottom = rcPart.top + thumbPos - psbi->dxyLineButton;
00220         SCROLL_ThemeDrawPart(pcontext, SBP_UPPERTRACKVERT, BUTTON_NORMAL, psbi, SCROLL_TOP_RECT, htDown, htHot, &rcPart);
00221         r.top = rcPart.bottom;
00222 
00223         rcPart = r;
00224         rcPart.top += psbi->dxyLineButton;
00225         SCROLL_ThemeDrawPart(pcontext, SBP_LOWERTRACKVERT, BUTTON_NORMAL, psbi, SCROLL_BOTTOM_RECT, htDown, htHot, &rcPart); 
00226         r.bottom = rcPart.top;
00227 
00228         SCROLL_ThemeDrawPart(pcontext, SBP_THUMBBTNVERT, BUTTON_NORMAL, psbi, SCROLL_THUMB, htDown, htHot, &r); 
00229         SCROLL_ThemeDrawPart(pcontext, SBP_GRIPPERVERT, BUTTON_NORMAL, psbi, SCROLL_THUMB, htDown, htHot, &r); 
00230     }
00231     else  /* horizontal */
00232     {
00233         rcPart = r;
00234         rcPart.right = rcPart.left + thumbPos - psbi->dxyLineButton;
00235         SCROLL_ThemeDrawPart(pcontext, SBP_UPPERTRACKHORZ, BUTTON_NORMAL, psbi, SCROLL_TOP_RECT, htDown, htHot, &rcPart);
00236         r.left = rcPart.right;
00237 
00238         rcPart = r;
00239         rcPart.left += psbi->dxyLineButton;
00240         SCROLL_ThemeDrawPart(pcontext, SBP_LOWERTRACKHORZ, BUTTON_NORMAL, psbi, SCROLL_BOTTOM_RECT, htDown, htHot, &rcPart);
00241         r.right = rcPart.left;
00242 
00243         SCROLL_ThemeDrawPart(pcontext, SBP_THUMBBTNHORZ, BUTTON_NORMAL, psbi, SCROLL_THUMB, htDown, htHot, &r);
00244         SCROLL_ThemeDrawPart(pcontext, SBP_GRIPPERHORZ, BUTTON_NORMAL, psbi, SCROLL_THUMB, htDown, htHot, &r);
00245     }
00246 }
00247 
00248 static void SCROLL_DrawMovingThumb( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,  BOOL vertical)
00249 {
00250   INT pos = SCROLL_TrackingPos;
00251   INT max_size;
00252 
00253   if( vertical )
00254       max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
00255   else
00256     max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
00257 
00258   max_size -= (psbi->dxyLineButton -SCROLL_ARROW_THUMB_OVERLAP) + psbi->dxyLineButton;
00259 
00260   if( pos < (psbi->dxyLineButton-SCROLL_ARROW_THUMB_OVERLAP) )
00261     pos = (psbi->dxyLineButton-SCROLL_ARROW_THUMB_OVERLAP);
00262   else if( pos > max_size )
00263     pos = max_size;
00264 
00265   SCROLL_DrawInterior(pcontext, psbi, pos, vertical, SCROLL_THUMB, 0);  
00266 
00267   SCROLL_MovingThumb = !SCROLL_MovingThumb;
00268 }
00269 
00270 
00271 void 
00272 ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT nBar, POINT* pt)
00273 {
00274     SCROLLINFO si;
00275     SCROLLBARINFO sbi;
00276     BOOL vertical;
00277     enum SCROLL_HITTEST htHot = SCROLL_NOWHERE;
00278 
00279     /* Retrieve scrollbar info */
00280     sbi.cbSize = sizeof(sbi);
00281     si.cbSize = sizeof(si);
00282     si.fMask = SIF_ALL ;
00283     GetScrollInfo(pcontext->hWnd, nBar, &si);
00284     GetScrollBarInfo(pcontext->hWnd, SCROLL_getObjectId(nBar), &sbi);
00285     vertical = SCROLL_IsVertical(pcontext->hWnd, nBar);
00286     if(sbi.rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE  && 
00287        sbi.rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE  )
00288     {
00289         sbi.xyThumbTop = 0;
00290     }
00291 
00292 #ifndef ROS_SUCKS
00293     /* The scrollbar rect is in screen coordinates */
00294 //    OffsetRect(&sbi.rcScrollBar, -pcontext->wi.rcWindow.left, -pcontext->wi.rcWindow.top);
00295 #endif
00296 
00297     if(pt)
00298     {
00299         ScreenToWindow(pcontext->hWnd, pt);
00300         htHot = SCROLL_HitTest(pcontext->hWnd, &sbi, vertical, *pt, FALSE);
00301     }
00302     
00303     if (((nBar == SB_VERT) && !(pcontext->wi.dwStyle & WS_VSCROLL)) ||
00304         ((nBar == SB_HORZ) && !(pcontext->wi.dwStyle & WS_HSCROLL))) return;
00305 
00306     /* do not draw if the scrollbar rectangle is empty */
00307     if(IsRectEmpty(&sbi.rcScrollBar)) return;
00308 
00309     /* Draw the scrollbar */
00310     SCROLL_DrawArrows( pcontext, &sbi, vertical, 0, htHot );
00311     SCROLL_DrawInterior( pcontext, &sbi, sbi.xyThumbTop, vertical, 0, htHot );
00312 }
00313 
00314 
00315 
00316 /***********************************************************************
00317  *           SCROLL_ClipPos
00318  */
00319 static POINT SCROLL_ClipPos( LPRECT lpRect, POINT pt )
00320 {
00321     if( pt.x < lpRect->left )
00322         pt.x = lpRect->left;
00323     else
00324         if( pt.x > lpRect->right )
00325     pt.x = lpRect->right;
00326 
00327     if( pt.y < lpRect->top )
00328         pt.y = lpRect->top;
00329     else
00330     if( pt.y > lpRect->bottom )
00331         pt.y = lpRect->bottom;
00332 
00333     return pt;
00334 }
00335 
00336 
00337 
00338 /***********************************************************************
00339  *           SCROLL_GetThumbVal
00340  *
00341  * Compute the current scroll position based on the thumb position in pixels
00342  * from the top of the scroll-bar.
00343  */
00344 static UINT SCROLL_GetThumbVal( SCROLLINFO *psi, RECT *rect,
00345                                   BOOL vertical, INT pos )
00346 {
00347     INT thumbSize;
00348     INT pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
00349     INT range;
00350 
00351     if ((pixels -= 2*(GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP)) <= 0)
00352         return psi->nMin;
00353 
00354     if (psi->nPage)
00355     {
00356         thumbSize = MulDiv(pixels,psi->nPage,(psi->nMax-psi->nMin+1));
00357         if (thumbSize < SCROLL_MIN_THUMB) thumbSize = SCROLL_MIN_THUMB;
00358     }
00359     else thumbSize = GetSystemMetrics(SM_CXVSCROLL);
00360 
00361     if ((pixels -= thumbSize) <= 0) return psi->nMin;
00362 
00363     pos = max( 0, pos - (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP) );
00364     if (pos > pixels) pos = pixels;
00365 
00366     if (!psi->nPage)
00367         range = psi->nMax - psi->nMin;
00368     else
00369         range = psi->nMax - psi->nMin - psi->nPage + 1;
00370 
00371     return psi->nMin + MulDiv(pos, range, pixels);
00372 }
00373 
00374 static void 
00375 SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
00376 {
00377       /* Previous mouse position for timer events */
00378     static POINT prevPt;
00379       /* Thumb position when tracking started. */
00380     static UINT trackThumbPos;
00381       /* Position in the scroll-bar of the last button-down event. */
00382     static INT lastClickPos;
00383       /* Position in the scroll-bar of the last mouse event. */
00384     static INT lastMousePos;
00385 
00386     enum SCROLL_HITTEST hittest;
00387     HWND hwndOwner, hwndCtl;
00388     BOOL vertical;
00389     SCROLLINFO si;
00390     SCROLLBARINFO sbi;
00391     DRAW_CONTEXT context;
00392 
00393     si.cbSize = sizeof(si);
00394     sbi.cbSize = sizeof(sbi);
00395     si.fMask = SIF_ALL;
00396     GetScrollInfo(hwnd, nBar, &si);
00397     GetScrollBarInfo(hwnd, SCROLL_getObjectId(nBar), &sbi);
00398     vertical = SCROLL_IsVertical(hwnd, nBar);
00399     if(sbi.rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE  && 
00400        sbi.rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE  )
00401     {
00402         return;
00403     }
00404     ThemeInitDrawContext(&context, hwnd, 0);
00405 
00406 #ifndef ROS_SUCKS
00407     /* The scrollbar rect is in screen coordinates */
00408 //    OffsetRect(&sbi.rcScrollBar, -context.wi.rcWindow.left, -context.wi.rcWindow.top);
00409 #endif
00410 
00411     if ((SCROLL_trackHitTest == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN))
00412           return;
00413     
00414     hwndOwner = (nBar == SB_CTL) ? GetParent(hwnd) : hwnd;
00415     hwndCtl   = (nBar == SB_CTL) ? hwnd : 0;
00416 
00417     switch(msg)
00418     {
00419       case WM_LBUTTONDOWN:  /* Initialise mouse tracking */
00420           HideCaret(hwnd);  /* hide caret while holding down LBUTTON */
00421           SCROLL_trackVertical = vertical;
00422           SCROLL_trackHitTest  = hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE );
00423           lastClickPos  = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x - sbi.rcScrollBar.left);
00424           lastMousePos  = lastClickPos;
00425           trackThumbPos = sbi.xyThumbTop;
00426           prevPt = pt;
00427           SetCapture( hwnd );
00428           break;
00429 
00430       case WM_MOUSEMOVE:
00431           hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, TRUE );
00432           prevPt = pt;
00433           break;
00434 
00435       case WM_LBUTTONUP:
00436           hittest = SCROLL_NOWHERE;
00437           ReleaseCapture();
00438           /* if scrollbar has focus, show back caret */
00439           if (hwnd==GetFocus()) 
00440               ShowCaret(hwnd);
00441           break;
00442 
00443       case WM_SYSTIMER:
00444           pt = prevPt;
00445           hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE );
00446           break;
00447 
00448       default:
00449           return;  /* Should never happen */
00450     }
00451 
00452     //TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n",
00453     //      hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest );
00454 
00455     switch(SCROLL_trackHitTest)
00456     {
00457     case SCROLL_NOWHERE:  /* No tracking in progress */
00458         break;
00459 
00460     case SCROLL_TOP_ARROW:
00461         if (hittest == SCROLL_trackHitTest)
00462         {
00463             SCROLL_DrawArrows( &context, &sbi, vertical, SCROLL_trackHitTest, 0 );
00464             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
00465             {
00466                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00467                                 SB_LINEUP, (LPARAM)hwndCtl );
00468             }
00469 
00470         SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
00471                             SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL );
00472         }
00473         else
00474         {
00475             SCROLL_DrawArrows( &context, &sbi, vertical, 0, 0 );
00476             KillSystemTimer( hwnd, SCROLL_TIMER );
00477         }
00478 
00479         break;
00480 
00481     case SCROLL_TOP_RECT:
00482         SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, SCROLL_trackHitTest, 0);
00483         if (hittest == SCROLL_trackHitTest)
00484         {
00485             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
00486             {
00487                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00488                                 SB_PAGEUP, (LPARAM)hwndCtl );
00489             }
00490             SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
00491                               SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL );
00492         }
00493         else KillSystemTimer( hwnd, SCROLL_TIMER );
00494         break;
00495 
00496     case SCROLL_THUMB:
00497         if (msg == WM_LBUTTONDOWN)
00498         {
00499             SCROLL_TrackingWin = hwnd;
00500             SCROLL_TrackingBar = nBar;
00501             SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
00502             SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, 
00503                                                      vertical, SCROLL_TrackingPos );
00504             if (!SCROLL_MovingThumb)
00505                 SCROLL_DrawMovingThumb(&context, &sbi, vertical);
00506         }
00507         else if (msg == WM_LBUTTONUP)
00508         {
00509             if (SCROLL_MovingThumb)
00510                 SCROLL_DrawMovingThumb(&context, &sbi, vertical);
00511 
00512             SCROLL_DrawInterior(  &context, &sbi, sbi.xyThumbTop, vertical, 0, SCROLL_trackHitTest );
00513         }
00514         else  /* WM_MOUSEMOVE */
00515         {
00516             INT pos;
00517 
00518             if (!SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical )) 
00519                 pos = lastClickPos;
00520             else
00521             {
00522                 pt = SCROLL_ClipPos( &sbi.rcScrollBar, pt );
00523                 pos = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x - sbi.rcScrollBar.left);
00524             }
00525             if ( (pos != lastMousePos) || (!SCROLL_MovingThumb) )
00526             {
00527                 if (SCROLL_MovingThumb)
00528                     SCROLL_DrawMovingThumb( &context, &sbi, vertical);
00529                 lastMousePos = pos;
00530                 SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
00531                 SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar,
00532                                                          vertical,
00533                                                          SCROLL_TrackingPos );
00534                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00535                                 MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
00536                                 (LPARAM)hwndCtl );
00537                 if (!SCROLL_MovingThumb)
00538                     SCROLL_DrawMovingThumb( &context, &sbi, vertical);
00539             }
00540         }
00541         break;
00542 
00543     case SCROLL_BOTTOM_RECT:
00544         if (hittest == SCROLL_trackHitTest)
00545         {
00546             SCROLL_DrawInterior(  &context, &sbi, sbi.xyThumbTop, vertical, SCROLL_trackHitTest, 0 );
00547             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
00548             {
00549                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00550                                 SB_PAGEDOWN, (LPARAM)hwndCtl );
00551             }
00552             SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
00553                               SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL );
00554         }
00555         else
00556         {
00557             SCROLL_DrawInterior(  &context, &sbi, sbi.xyThumbTop, vertical, 0, 0 );
00558             KillSystemTimer( hwnd, SCROLL_TIMER );
00559         }
00560         break;
00561 
00562     case SCROLL_BOTTOM_ARROW:
00563         if (hittest == SCROLL_trackHitTest)
00564         {
00565             SCROLL_DrawArrows(  &context, &sbi, vertical, SCROLL_trackHitTest, 0 );
00566             if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
00567             {
00568                 SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00569                                 SB_LINEDOWN, (LPARAM)hwndCtl );
00570             }
00571 
00572         SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
00573                             SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL );
00574         }
00575         else
00576         {
00577             SCROLL_DrawArrows(  &context, &sbi, vertical, 0, 0 );
00578             KillSystemTimer( hwnd, SCROLL_TIMER );
00579         }
00580         break;
00581     }
00582 
00583     if (msg == WM_LBUTTONDOWN)
00584     {
00585 
00586         if (hittest == SCROLL_THUMB)
00587         {
00588             UINT val = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical,
00589                                  trackThumbPos + lastMousePos - lastClickPos );
00590             SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00591                             MAKEWPARAM( SB_THUMBTRACK, val ), (LPARAM)hwndCtl );
00592         }
00593     }
00594 
00595     if (msg == WM_LBUTTONUP)
00596     {
00597         hittest = SCROLL_trackHitTest;
00598         SCROLL_trackHitTest = SCROLL_NOWHERE;  /* Terminate tracking */
00599 
00600         if (hittest == SCROLL_THUMB)
00601         {
00602             UINT val = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical,
00603                                  trackThumbPos + lastMousePos - lastClickPos );
00604             SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00605                             MAKEWPARAM( SB_THUMBPOSITION, val ), (LPARAM)hwndCtl );
00606         }
00607         /* SB_ENDSCROLL doesn't report thumb position */
00608         SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
00609                           SB_ENDSCROLL, (LPARAM)hwndCtl );
00610 
00611         /* Terminate tracking */
00612         SCROLL_TrackingWin = 0;
00613     }
00614 
00615     ThemeCleanupDrawContext(&context);
00616 }
00617 
00618 static void 
00619 SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt )
00620 {
00621     MSG msg;
00622 
00623     ScreenToWindow(hwnd, &pt);
00624 
00625     SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
00626 
00627     do
00628     {
00629         if (!GetMessageW( &msg, 0, 0, 0 )) break;
00630         if (CallMsgFilterW( &msg, MSGF_SCROLLBAR )) continue;
00631         if (msg.message == WM_LBUTTONUP ||
00632             msg.message == WM_MOUSEMOVE ||
00633             (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER))
00634         {
00635             pt.x = GET_X_LPARAM(msg.lParam);
00636             pt.y = GET_Y_LPARAM(msg.lParam);
00637             ClientToScreen(hwnd, &pt);
00638             ScreenToWindow(hwnd, &pt);
00639             SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt );
00640         }
00641         else
00642         {
00643             TranslateMessage( &msg );
00644             DispatchMessageW( &msg );
00645         }
00646         if (!IsWindow( hwnd ))
00647         {
00648             ReleaseCapture();
00649             break;
00650         }
00651     } while (msg.message != WM_LBUTTONUP && GetCapture() == hwnd);
00652 }
00653 
00654 void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
00655 {
00656     INT scrollbar;
00657     
00658     if ((wParam & 0xfff0) == SC_HSCROLL)
00659     {
00660         if ((wParam & 0x0f) != HTHSCROLL) return;
00661         scrollbar = SB_HORZ;
00662     }
00663     else  /* SC_VSCROLL */
00664     {
00665         if ((wParam & 0x0f) != HTVSCROLL) return;
00666         scrollbar = SB_VERT;
00667     }
00668     SCROLL_TrackScrollBar( hwnd, scrollbar, pt );
00669 }

Generated on Mon May 28 2012 04:26:24 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.