Author: gadamopoulos
Date: Mon Jul 11 22:29:33 2011
New Revision: 52645
URL:
http://svn.reactos.org/svn/reactos?rev=52645&view=rev
Log:
[uxtheme]
- Implement drawing non client scrollbars. This code is heavily based on code from wine
and modified properly to use themes
Added:
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncscrollbar.c (with props)
Modified:
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/CMakeLists.txt
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncthm.h
branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/nonclient.c
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/CMakeLists.txt [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/CMakeLists.txt [iso-8859-1] Mon Jul
11 22:29:33 2011
@@ -11,6 +11,7 @@
main.c
metric.c
msstyles.c
+ ncscrollbar.c
nonclient.c
property.c
stylemap.c
Added: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncscrollbar.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncscrollbar.c (added)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncscrollbar.c [iso-8859-1] Mon Jul
11 22:29:33 2011
@@ -1,0 +1,676 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS uxtheme.dll
+ * FILE: dll/win32/uxtheme/ncscrollbar.c
+ * PURPOSE: uxtheme scrollbar support
+ * PROGRAMMER: Giannis Adamopoulos
+ * This file is heavily based on code from the wine project:
+ * Copyright 1993 Martin Ayotte
+ * Copyright 1994, 1996 Alexandre Julliard
+ */
+
+#include <windows.h>
+#include "undocuser.h"
+#include "vfwmsgs.h"
+#include "uxtheme.h"
+#include <tmschema.h>
+#include <Windowsx.h>
+#include "ncthm.h"
+#include <assert.h>
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(uxtheme);
+
+static BOOL SCROLL_trackVertical;
+static enum SCROLL_HITTEST SCROLL_trackHitTest;
+/* Is the moving thumb being displayed? */
+static HWND SCROLL_TrackingWin = 0;
+static INT SCROLL_TrackingBar = 0;
+static INT SCROLL_TrackingPos = 0;
+static INT SCROLL_TrackingVal = 0;
+
+void static ScreenToWindow( HWND hWnd, POINT* pt)
+{
+ RECT rcWnd;
+ GetWindowRect(hWnd, &rcWnd);
+ pt->x -= rcWnd.left;
+ pt->y -= rcWnd.top;
+}
+
+static BOOL SCROLL_IsVertical(HWND hwnd, INT nBar)
+{
+ switch(nBar)
+ {
+ case SB_HORZ:
+ return FALSE;
+ case SB_VERT:
+ return TRUE;
+ default:
+ assert(FALSE);
+ return FALSE;
+ }
+}
+
+static LONG SCROLL_getObjectId(INT nBar)
+{
+ switch(nBar)
+ {
+ case SB_HORZ:
+ return OBJID_HSCROLL;
+ case SB_VERT:
+ return OBJID_VSCROLL;
+ default:
+ assert(FALSE);
+ return 0;
+ }
+}
+
+/***********************************************************************
+ * SCROLL_PtInRectEx
+ */
+static BOOL SCROLL_PtInRectEx( LPRECT lpRect, POINT pt, BOOL vertical )
+{
+ RECT rect = *lpRect;
+ int scrollbarWidth;
+
+ /* Pad hit rect to allow mouse to be dragged outside of scrollbar and
+ * still be considered in the scrollbar. */
+ if (vertical)
+ {
+ scrollbarWidth = lpRect->right - lpRect->left;
+ rect.left -= scrollbarWidth*8;
+ rect.right += scrollbarWidth*8;
+ rect.top -= scrollbarWidth*2;
+ rect.bottom += scrollbarWidth*2;
+ }
+ else
+ {
+ scrollbarWidth = lpRect->bottom - lpRect->top;
+ rect.left -= scrollbarWidth*2;
+ rect.right += scrollbarWidth*2;
+ rect.top -= scrollbarWidth*8;
+ rect.bottom += scrollbarWidth*8;
+ }
+ return PtInRect( &rect, pt );
+}
+
+
+/***********************************************************************
+ * SCROLL_HitTest
+ *
+ * Scroll-bar hit testing (don't confuse this with WM_NCHITTEST!).
+ */
+static enum SCROLL_HITTEST SCROLL_HitTest( HWND hwnd, SCROLLBARINFO* psbi, BOOL
vertical,
+ POINT pt, BOOL bDragging )
+{
+ if ( (bDragging && !SCROLL_PtInRectEx( &psbi->rcScrollBar, pt,
vertical )) ||
+ (!PtInRect( &psbi->rcScrollBar, pt )) )
+ {
+ return SCROLL_NOWHERE;
+ }
+
+ if (vertical)
+ {
+ if (pt.y < psbi->rcScrollBar.top + psbi->dxyLineButton)
+ return SCROLL_TOP_ARROW;
+ if (pt.y >= psbi->rcScrollBar.bottom - psbi->dxyLineButton)
+ return SCROLL_BOTTOM_ARROW;
+ if (!psbi->xyThumbTop)
+ return SCROLL_TOP_RECT;
+ pt.y -= psbi->rcScrollBar.top;
+ if (pt.y < psbi->xyThumbTop)
+ return SCROLL_TOP_RECT;
+ if (pt.y >= psbi->xyThumbTop + psbi->dxyLineButton)
+ return SCROLL_BOTTOM_RECT;
+ }
+ else /* horizontal */
+ {
+ if (pt.x < psbi->rcScrollBar.left + psbi->dxyLineButton)
+ return SCROLL_TOP_ARROW;
+ if (pt.x >= psbi->rcScrollBar.right - psbi->dxyLineButton)
+ return SCROLL_BOTTOM_ARROW;
+ if (!psbi->xyThumbTop)
+ return SCROLL_TOP_RECT;
+ pt.x -= psbi->rcScrollBar.left;
+ if (pt.x < psbi->xyThumbTop)
+ return SCROLL_TOP_RECT;
+ if (pt.x >= psbi->xyThumbTop + psbi->dxyLineButton)
+ return SCROLL_BOTTOM_RECT;
+ }
+ return SCROLL_THUMB;
+}
+
+static void SCROLL_ThemeDrawPart(PDRAW_CONTEXT pcontext, int iPartId,int iStateId,
SCROLLBARINFO* psbi, int htCurrent, int htDown, int htHot, RECT* r)
+{
+ if(psbi->rgstate[htCurrent] & STATE_SYSTEM_UNAVAILABLE)
+ iStateId += BUTTON_DISABLED - BUTTON_NORMAL;
+ else if (htHot == htCurrent)
+ iStateId += BUTTON_HOT - BUTTON_NORMAL;
+ else if (htDown == htCurrent)
+ iStateId += BUTTON_PRESSED - BUTTON_NORMAL;
+
+ DrawThemeBackground(pcontext->scrolltheme, pcontext->hDC, iPartId, iStateId, r,
NULL);
+}
+
+/***********************************************************************
+ * SCROLL_DrawArrows
+ *
+ * Draw the scroll bar arrows.
+ */
+static void SCROLL_DrawArrows( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
+ BOOL vertical, int htDown, int htHot )
+{
+ RECT r;
+ int iStateId;
+
+ r = psbi->rcScrollBar;
+ if( vertical )
+ {
+ r.bottom = r.top + psbi->dxyLineButton;
+ iStateId = ABS_UPNORMAL;
+ }
+ else
+ {
+ r.right = r.left + psbi->dxyLineButton;
+ iStateId = ABS_LEFTNORMAL;
+ }
+
+ SCROLL_ThemeDrawPart(pcontext, SBP_ARROWBTN, iStateId, psbi, SCROLL_TOP_ARROW,
htDown, htHot, &r);
+
+ r = psbi->rcScrollBar;
+ if( vertical )
+ {
+ r.top = r.bottom - psbi->dxyLineButton;
+ iStateId = ABS_DOWNNORMAL;
+ }
+ else
+ {
+ iStateId = ABS_RIGHTNORMAL;
+ r.left = r.right - psbi->dxyLineButton;
+ }
+
+ SCROLL_ThemeDrawPart(pcontext, SBP_ARROWBTN, iStateId, psbi, SCROLL_BOTTOM_ARROW,
htDown, htHot, &r);
+}
+
+static void SCROLL_DrawInterior( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi,
+ INT thumbPos, BOOL vertical,
+ int htDown, int htHot )
+{
+ RECT r, rcPart;
+
+ r = psbi->rcScrollBar;
+ if (vertical)
+ {
+ r.top += psbi->dxyLineButton;
+ r.bottom -= (psbi->dxyLineButton);
+ }
+ else
+ {
+ r.left += psbi->dxyLineButton;
+ r.right -= psbi->dxyLineButton;
+ }
+
+ /* Draw the scroll rectangles and thumb */
+
+ if (!thumbPos) /* No thumb to draw */
+ {
+ rcPart = r;
+ SCROLL_ThemeDrawPart(pcontext, vertical ? SBP_UPPERTRACKVERT: SBP_UPPERTRACKHORZ
, BUTTON_NORMAL, psbi, SCROLL_THUMB, 0, 0, &rcPart);
+ return;
+ }
+
+ if (vertical)
+ {
+ rcPart = r;
+ rcPart.bottom = rcPart.top + thumbPos - psbi->dxyLineButton;
+ SCROLL_ThemeDrawPart(pcontext, SBP_UPPERTRACKVERT, BUTTON_NORMAL, psbi,
SCROLL_TOP_RECT, htDown, htHot, &rcPart);
+ r.top = rcPart.bottom;
+
+ rcPart = r;
+ rcPart.top += psbi->dxyLineButton;
+ SCROLL_ThemeDrawPart(pcontext, SBP_LOWERTRACKVERT, BUTTON_NORMAL, psbi,
SCROLL_BOTTOM_RECT, htDown, htHot, &rcPart);
+ r.bottom = rcPart.top;
+
+ SCROLL_ThemeDrawPart(pcontext, SBP_THUMBBTNVERT, BUTTON_NORMAL, psbi,
SCROLL_THUMB, htDown, htHot, &r);
+ SCROLL_ThemeDrawPart(pcontext, SBP_GRIPPERVERT, BUTTON_NORMAL, psbi,
SCROLL_THUMB, htDown, htHot, &r);
+ }
+ else /* horizontal */
+ {
+ rcPart = r;
+ rcPart.right = rcPart.left + thumbPos - psbi->dxyLineButton;
+ SCROLL_ThemeDrawPart(pcontext, SBP_UPPERTRACKHORZ, BUTTON_NORMAL, psbi,
SCROLL_TOP_RECT, htDown, htHot, &rcPart);
+ r.left = rcPart.right;
+
+ rcPart = r;
+ rcPart.left += psbi->dxyLineButton;
+ SCROLL_ThemeDrawPart(pcontext, SBP_LOWERTRACKHORZ, BUTTON_NORMAL, psbi,
SCROLL_BOTTOM_RECT, htDown, htHot, &rcPart);
+ r.right = rcPart.left;
+
+ SCROLL_ThemeDrawPart(pcontext, SBP_THUMBBTNHORZ, BUTTON_NORMAL, psbi,
SCROLL_THUMB, htDown, htHot, &r);
+ SCROLL_ThemeDrawPart(pcontext, SBP_GRIPPERHORZ, BUTTON_NORMAL, psbi,
SCROLL_THUMB, htDown, htHot, &r);
+ }
+}
+
+static void SCROLL_DrawMovingThumb( PDRAW_CONTEXT pcontext, SCROLLBARINFO* psbi, BOOL
vertical)
+{
+ INT pos = SCROLL_TrackingPos;
+ INT max_size;
+
+ if( vertical )
+ max_size = psbi->rcScrollBar.bottom - psbi->rcScrollBar.top;
+ else
+ max_size = psbi->rcScrollBar.right - psbi->rcScrollBar.left;
+
+ max_size -= (psbi->dxyLineButton -SCROLL_ARROW_THUMB_OVERLAP) +
psbi->dxyLineButton;
+
+ if( pos < (psbi->dxyLineButton-SCROLL_ARROW_THUMB_OVERLAP) )
+ pos = (psbi->dxyLineButton-SCROLL_ARROW_THUMB_OVERLAP);
+ else if( pos > max_size )
+ pos = max_size;
+
+ SCROLL_DrawInterior(pcontext, psbi, pos, vertical, SCROLL_THUMB, 0);
+
+ SCROLL_MovingThumb = !SCROLL_MovingThumb;
+}
+
+
+void
+ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT nBar, POINT* pt)
+{
+ BOOL Save_SCROLL_MovingThumb = SCROLL_MovingThumb;
+ SCROLLINFO si;
+ SCROLLBARINFO sbi;
+ BOOL vertical;
+ enum SCROLL_HITTEST htHot = SCROLL_NOWHERE;
+
+ /* Retrieve scrollbar info */
+ sbi.cbSize = sizeof(sbi);
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL ;
+ GetScrollInfo(pcontext->hWnd, nBar, &si);
+ GetScrollBarInfo(pcontext->hWnd, SCROLL_getObjectId(nBar), &sbi);
+ vertical = SCROLL_IsVertical(pcontext->hWnd, nBar);
+ if(sbi.rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE &&
+ sbi.rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE )
+ {
+ sbi.xyThumbTop = 0;
+ }
+
+#ifndef ROS_SUCKS
+ /* The scrollbar rect is in screen coordinates */
+// OffsetRect(&sbi.rcScrollBar, -pcontext->wi.rcWindow.left,
-pcontext->wi.rcWindow.top);
+#endif
+
+ if(pt)
+ {
+ ScreenToWindow(pcontext->hWnd, pt);
+ htHot = SCROLL_HitTest(pcontext->hWnd, &sbi, vertical, *pt, FALSE);
+ }
+
+ if (((nBar == SB_VERT) && !(pcontext->wi.dwStyle & WS_VSCROLL)) ||
+ ((nBar == SB_HORZ) && !(pcontext->wi.dwStyle & WS_HSCROLL)))
return;
+
+ /* do not draw if the scrollbar rectangle is empty */
+ if(IsRectEmpty(&sbi.rcScrollBar)) return;
+
+ /* Draw the scrollbar */
+ SCROLL_DrawArrows( pcontext, &sbi, vertical, 0, htHot );
+ SCROLL_DrawInterior( pcontext, &sbi, sbi.xyThumbTop, vertical, 0, htHot );
+}
+
+
+
+/***********************************************************************
+ * SCROLL_ClipPos
+ */
+static POINT SCROLL_ClipPos( LPRECT lpRect, POINT pt )
+{
+ if( pt.x < lpRect->left )
+ pt.x = lpRect->left;
+ else
+ if( pt.x > lpRect->right )
+ pt.x = lpRect->right;
+
+ if( pt.y < lpRect->top )
+ pt.y = lpRect->top;
+ else
+ if( pt.y > lpRect->bottom )
+ pt.y = lpRect->bottom;
+
+ return pt;
+}
+
+
+
+/***********************************************************************
+ * SCROLL_GetThumbVal
+ *
+ * Compute the current scroll position based on the thumb position in pixels
+ * from the top of the scroll-bar.
+ */
+static UINT SCROLL_GetThumbVal( SCROLLINFO *psi, RECT *rect,
+ BOOL vertical, INT pos )
+{
+ INT thumbSize;
+ INT pixels = vertical ? rect->bottom-rect->top : rect->right-rect->left;
+ INT range;
+
+ if ((pixels -= 2*(GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP)) <=
0)
+ return psi->nMin;
+
+ if (psi->nPage)
+ {
+ thumbSize = MulDiv(pixels,psi->nPage,(psi->nMax-psi->nMin+1));
+ if (thumbSize < SCROLL_MIN_THUMB) thumbSize = SCROLL_MIN_THUMB;
+ }
+ else thumbSize = GetSystemMetrics(SM_CXVSCROLL);
+
+ if ((pixels -= thumbSize) <= 0) return psi->nMin;
+
+ pos = max( 0, pos - (GetSystemMetrics(SM_CXVSCROLL) - SCROLL_ARROW_THUMB_OVERLAP) );
+ if (pos > pixels) pos = pixels;
+
+ if (!psi->nPage)
+ range = psi->nMax - psi->nMin;
+ else
+ range = psi->nMax - psi->nMin - psi->nPage + 1;
+
+ return psi->nMin + MulDiv(pos, range, pixels);
+}
+
+static void
+SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt)
+{
+ /* Previous mouse position for timer events */
+ static POINT prevPt;
+ /* Thumb position when tracking started. */
+ static UINT trackThumbPos;
+ /* Position in the scroll-bar of the last button-down event. */
+ static INT lastClickPos;
+ /* Position in the scroll-bar of the last mouse event. */
+ static INT lastMousePos;
+
+ enum SCROLL_HITTEST hittest;
+ HWND hwndOwner, hwndCtl;
+ BOOL vertical;
+ SCROLLINFO si;
+ SCROLLBARINFO sbi;
+ DRAW_CONTEXT context;
+
+ si.cbSize = sizeof(si);
+ sbi.cbSize = sizeof(sbi);
+ si.fMask = SIF_ALL;
+ GetScrollInfo(hwnd, nBar, &si);
+ GetScrollBarInfo(hwnd, SCROLL_getObjectId(nBar), &sbi);
+ vertical = SCROLL_IsVertical(hwnd, nBar);
+ if(sbi.rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE &&
+ sbi.rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE )
+ {
+ return;
+ }
+ ThemeInitDrawContext(&context, hwnd, 0);
+
+#ifndef ROS_SUCKS
+ /* The scrollbar rect is in screen coordinates */
+// OffsetRect(&sbi.rcScrollBar, -context.wi.rcWindow.left,
-context.wi.rcWindow.top);
+#endif
+
+ if ((SCROLL_trackHitTest == SCROLL_NOWHERE) && (msg != WM_LBUTTONDOWN))
+ return;
+
+ hwndOwner = (nBar == SB_CTL) ? GetParent(hwnd) : hwnd;
+ hwndCtl = (nBar == SB_CTL) ? hwnd : 0;
+
+ switch(msg)
+ {
+ case WM_LBUTTONDOWN: /* Initialise mouse tracking */
+ HideCaret(hwnd); /* hide caret while holding down LBUTTON */
+ SCROLL_trackVertical = vertical;
+ SCROLL_trackHitTest = hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt,
FALSE );
+ lastClickPos = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x -
sbi.rcScrollBar.left);
+ lastMousePos = lastClickPos;
+ trackThumbPos = sbi.xyThumbTop;
+ prevPt = pt;
+ SetCapture( hwnd );
+ break;
+
+ case WM_MOUSEMOVE:
+ hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, TRUE );
+ prevPt = pt;
+ break;
+
+ case WM_LBUTTONUP:
+ hittest = SCROLL_NOWHERE;
+ ReleaseCapture();
+ /* if scrollbar has focus, show back caret */
+ if (hwnd==GetFocus())
+ ShowCaret(hwnd);
+ break;
+
+ case WM_SYSTIMER:
+ pt = prevPt;
+ hittest = SCROLL_HitTest( hwnd, &sbi, vertical, pt, FALSE );
+ break;
+
+ default:
+ return; /* Should never happen */
+ }
+
+ //TRACE("Event: hwnd=%p bar=%d msg=%s pt=%d,%d hit=%d\n",
+ // hwnd, nBar, SPY_GetMsgName(msg,hwnd), pt.x, pt.y, hittest );
+
+ switch(SCROLL_trackHitTest)
+ {
+ case SCROLL_NOWHERE: /* No tracking in progress */
+ break;
+
+ case SCROLL_TOP_ARROW:
+ if (hittest == SCROLL_trackHitTest)
+ {
+ SCROLL_DrawArrows( &context, &sbi, vertical, SCROLL_trackHitTest, 0
);
+ if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
+ {
+ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+ SB_LINEUP, (LPARAM)hwndCtl );
+ }
+
+ SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
+ SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL );
+ }
+ else
+ {
+ SCROLL_DrawArrows( &context, &sbi, vertical, 0, 0 );
+ KillSystemTimer( hwnd, SCROLL_TIMER );
+ }
+
+ break;
+
+ case SCROLL_TOP_RECT:
+ SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical,
SCROLL_trackHitTest, 0);
+ if (hittest == SCROLL_trackHitTest)
+ {
+ if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
+ {
+ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+ SB_PAGEUP, (LPARAM)hwndCtl );
+ }
+ SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
+ SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL );
+ }
+ else KillSystemTimer( hwnd, SCROLL_TIMER );
+ break;
+
+ case SCROLL_THUMB:
+ if (msg == WM_LBUTTONDOWN)
+ {
+ SCROLL_TrackingWin = hwnd;
+ SCROLL_TrackingBar = nBar;
+ SCROLL_TrackingPos = trackThumbPos + lastMousePos - lastClickPos;
+ SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar,
+ vertical, SCROLL_TrackingPos );
+ if (!SCROLL_MovingThumb)
+ SCROLL_DrawMovingThumb(&context, &sbi, vertical);
+ }
+ else if (msg == WM_LBUTTONUP)
+ {
+ if (SCROLL_MovingThumb)
+ SCROLL_DrawMovingThumb(&context, &sbi, vertical);
+
+ SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, 0,
SCROLL_trackHitTest );
+ }
+ else /* WM_MOUSEMOVE */
+ {
+ INT pos;
+
+ if (!SCROLL_PtInRectEx( &sbi.rcScrollBar, pt, vertical ))
+ pos = lastClickPos;
+ else
+ {
+ pt = SCROLL_ClipPos( &sbi.rcScrollBar, pt );
+ pos = vertical ? (pt.y - sbi.rcScrollBar.top) : (pt.x -
sbi.rcScrollBar.left);
+ }
+ if ( (pos != lastMousePos) || (!SCROLL_MovingThumb) )
+ {
+ if (SCROLL_MovingThumb)
+ SCROLL_DrawMovingThumb( &context, &sbi, vertical);
+ lastMousePos = pos;
+ SCROLL_TrackingPos = trackThumbPos + pos - lastClickPos;
+ SCROLL_TrackingVal = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar,
+ vertical,
+ SCROLL_TrackingPos );
+ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+ MAKEWPARAM( SB_THUMBTRACK, SCROLL_TrackingVal),
+ (LPARAM)hwndCtl );
+ if (!SCROLL_MovingThumb)
+ SCROLL_DrawMovingThumb( &context, &sbi, vertical);
+ }
+ }
+ break;
+
+ case SCROLL_BOTTOM_RECT:
+ if (hittest == SCROLL_trackHitTest)
+ {
+ SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical,
SCROLL_trackHitTest, 0 );
+ if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
+ {
+ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+ SB_PAGEDOWN, (LPARAM)hwndCtl );
+ }
+ SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
+ SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL );
+ }
+ else
+ {
+ SCROLL_DrawInterior( &context, &sbi, sbi.xyThumbTop, vertical, 0, 0
);
+ KillSystemTimer( hwnd, SCROLL_TIMER );
+ }
+ break;
+
+ case SCROLL_BOTTOM_ARROW:
+ if (hittest == SCROLL_trackHitTest)
+ {
+ SCROLL_DrawArrows( &context, &sbi, vertical, SCROLL_trackHitTest, 0
);
+ if ((msg == WM_LBUTTONDOWN) || (msg == WM_SYSTIMER))
+ {
+ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+ SB_LINEDOWN, (LPARAM)hwndCtl );
+ }
+
+ SetSystemTimer( hwnd, SCROLL_TIMER, (msg == WM_LBUTTONDOWN) ?
+ SCROLL_FIRST_DELAY : SCROLL_REPEAT_DELAY, NULL );
+ }
+ else
+ {
+ SCROLL_DrawArrows( &context, &sbi, vertical, 0, 0 );
+ KillSystemTimer( hwnd, SCROLL_TIMER );
+ }
+ break;
+ }
+
+ if (msg == WM_LBUTTONDOWN)
+ {
+
+ if (hittest == SCROLL_THUMB)
+ {
+ UINT val = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical,
+ trackThumbPos + lastMousePos - lastClickPos );
+ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+ MAKEWPARAM( SB_THUMBTRACK, val ), (LPARAM)hwndCtl );
+ }
+ }
+
+ if (msg == WM_LBUTTONUP)
+ {
+ hittest = SCROLL_trackHitTest;
+ SCROLL_trackHitTest = SCROLL_NOWHERE; /* Terminate tracking */
+
+ if (hittest == SCROLL_THUMB)
+ {
+ UINT val = SCROLL_GetThumbVal( &si, &sbi.rcScrollBar, vertical,
+ trackThumbPos + lastMousePos - lastClickPos );
+ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+ MAKEWPARAM( SB_THUMBPOSITION, val ), (LPARAM)hwndCtl );
+ }
+ /* SB_ENDSCROLL doesn't report thumb position */
+ SendMessageW( hwndOwner, vertical ? WM_VSCROLL : WM_HSCROLL,
+ SB_ENDSCROLL, (LPARAM)hwndCtl );
+
+ /* Terminate tracking */
+ SCROLL_TrackingWin = 0;
+ }
+
+ ThemeCleanupDrawContext(&context);
+}
+
+static void
+SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt )
+{
+ MSG msg;
+
+ ScreenToWindow(hwnd, &pt);
+
+ SCROLL_HandleScrollEvent( hwnd, scrollbar, WM_LBUTTONDOWN, pt );
+
+ do
+ {
+ if (!GetMessageW( &msg, 0, 0, 0 )) break;
+ if (CallMsgFilterW( &msg, MSGF_SCROLLBAR )) continue;
+ if (msg.message == WM_LBUTTONUP ||
+ msg.message == WM_MOUSEMOVE ||
+ (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER))
+ {
+ pt.x = GET_X_LPARAM(msg.lParam);
+ pt.y = GET_Y_LPARAM(msg.lParam);
+ ClientToScreen(hwnd, &pt);
+ ScreenToWindow(hwnd, &pt);
+ SCROLL_HandleScrollEvent( hwnd, scrollbar, msg.message, pt );
+ }
+ else
+ {
+ TranslateMessage( &msg );
+ DispatchMessageW( &msg );
+ }
+ if (!IsWindow( hwnd ))
+ {
+ ReleaseCapture();
+ break;
+ }
+ } while (msg.message != WM_LBUTTONUP && GetCapture() == hwnd);
+}
+
+void NC_TrackScrollBar( HWND hwnd, WPARAM wParam, POINT pt )
+{
+ INT scrollbar;
+
+ if ((wParam & 0xfff0) == SC_HSCROLL)
+ {
+ if ((wParam & 0x0f) != HTHSCROLL) return;
+ scrollbar = SB_HORZ;
+ }
+ else /* SC_VSCROLL */
+ {
+ if ((wParam & 0x0f) != HTVSCROLL) return;
+ scrollbar = SB_VERT;
+ }
+ SCROLL_TrackScrollBar( hwnd, scrollbar, pt );
+}
Propchange: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncscrollbar.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncthm.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncthm.h [iso-8859-1] (original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/ncthm.h [iso-8859-1] Mon Jul 11
22:29:33 2011
@@ -4,6 +4,7 @@
HWND hWnd;
HDC hDC;
HTHEME theme;
+ HTHEME scrolltheme;
HTHEME hPrevTheme;
WINDOWINFO wi;
BOOL Active; /* wi.dwWindowStatus isn't correct for mdi child windows */
@@ -36,6 +37,17 @@
BUTTON_INACTIVE
} THEME_BUTTON_STATES;
+ /* Scroll-bar hit testing */
+enum SCROLL_HITTEST
+{
+ SCROLL_NOWHERE, /* Outside the scroll bar */
+ SCROLL_TOP_ARROW, /* Top or left arrow */
+ SCROLL_TOP_RECT, /* Rectangle between the top arrow and the thumb */
+ SCROLL_THUMB, /* Thumb rectangle */
+ SCROLL_BOTTOM_RECT, /* Rectangle between the thumb and the bottom arrow */
+ SCROLL_BOTTOM_ARROW /* Bottom or right arrow */
+};
+
#define HASSIZEGRIP(Style, ExStyle, ParentStyle, WindowRect, ParentClientRect) \
((!(Style & WS_CHILD) && (Style & WS_THICKFRAME) &&
!(Style & WS_MAXIMIZE)) || \
((Style & WS_CHILD) && (ParentStyle & WS_THICKFRAME)
&& !(ParentStyle & WS_MAXIMIZE) && \
@@ -48,4 +60,36 @@
#define MENU_BAR_ITEMS_SPACE (12)
+#define SCROLL_TIMER 0 /* Scroll timer id */
+
+ /* Overlap between arrows and thumb */
+#define SCROLL_ARROW_THUMB_OVERLAP 0
+
+ /* Delay (in ms) before first repetition when holding the button down */
+#define SCROLL_FIRST_DELAY 200
+
+ /* Delay (in ms) between scroll repetitions */
+#define SCROLL_REPEAT_DELAY 50
+
+/* Minimum size of the thumb in pixels */
+#define SCROLL_MIN_THUMB 6
+
+/* Minimum size of the rectangle between the arrows */
+#define SCROLL_MIN_RECT 4
+
+void
+ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT Bar, POINT* pt);
+
+VOID
+NC_TrackScrollBar(HWND Wnd, WPARAM wParam, POINT Pt);
+
+void
+ThemeInitDrawContext(PDRAW_CONTEXT pcontext,
+ HWND hWnd,
+ HRGN hRgn);
+
+void
+ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext);
+
+
extern ATOM atWindowTheme;
Modified: branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/nonclient.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/ThemesSupport/dll/win…
==============================================================================
--- branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/nonclient.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/ThemesSupport/dll/win32/uxtheme/nonclient.c [iso-8859-1] Mon Jul 11
22:29:33 2011
@@ -156,7 +156,7 @@
return S_OK;
}
-static void
+void
ThemeInitDrawContext(PDRAW_CONTEXT pcontext,
HWND hWnd,
HRGN hRgn)
@@ -167,6 +167,7 @@
pcontext->Active = IsWindowActive(hWnd, pcontext->wi.dwExStyle);
pcontext->hPrevTheme = GetPropW(hWnd, (LPCWSTR)MAKEINTATOM(atWindowTheme));
pcontext->theme = OpenThemeData(pcontext->hWnd, L"WINDOW");
+ pcontext->scrolltheme = OpenThemeData(pcontext->hWnd,
L"SCROLLBAR");
pcontext->CaptionHeight = pcontext->wi.cyWindowBorders;
pcontext->CaptionHeight += GetSystemMetrics(pcontext->wi.dwExStyle &
WS_EX_TOOLWINDOW ? SM_CYSMCAPTION : SM_CYCAPTION );
@@ -180,12 +181,13 @@
pcontext->hDC = GetDCEx(hWnd, hRgn, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE |
DCX_KEEPCLIPRGN);
}
-static void
+void
ThemeCleanupDrawContext(PDRAW_CONTEXT pcontext)
{
ReleaseDC(pcontext->hWnd ,pcontext->hDC);
CloseThemeData (pcontext->theme);
+ CloseThemeData (pcontext->scrolltheme);
SetPropW(pcontext->hWnd, (LPCWSTR)MAKEINTATOM(atWindowTheme),
pcontext->hPrevTheme);
@@ -629,12 +631,6 @@
}
static void
-ThemeDrawScrollBar(PDRAW_CONTEXT pcontext, INT Bar)
-{
-
-}
-
-static void
ThemePaintWindow(PDRAW_CONTEXT pcontext, RECT* prcCurrent)
{
if(!(pcontext->wi.dwStyle & WS_VISIBLE))
@@ -662,10 +658,10 @@
ThemeDrawMenuBar(pcontext, prcCurrent);
if(pcontext->wi.dwStyle & WS_HSCROLL)
- ThemeDrawScrollBar(pcontext, OBJID_VSCROLL);
+ ThemeDrawScrollBar(pcontext, SB_HORZ , NULL);
if(pcontext->wi.dwStyle & WS_VSCROLL)
- ThemeDrawScrollBar(pcontext, OBJID_HSCROLL);
+ ThemeDrawScrollBar(pcontext, SB_VERT, NULL);
}
/*
@@ -690,7 +686,7 @@
}
static LRESULT
-ThemeHandleNcMouseMove(HWND hWnd, DWORD ht)
+ThemeHandleNcMouseMove(HWND hWnd, DWORD ht, POINT* pt)
{
DRAW_CONTEXT context;
TRACKMOUSEEVENT tme;
@@ -708,6 +704,13 @@
ThemeInitDrawContext(&context, hWnd, 0);
ThemeDrawCaptionButtons(&context, ht, 0);
+
+ if(context.wi.dwStyle & WS_HSCROLL)
+ ThemeDrawScrollBar(&context, SB_HORZ , ht == HTHSCROLL ? pt : NULL);
+
+ if(context.wi.dwStyle & WS_VSCROLL)
+ ThemeDrawScrollBar(&context, SB_VERT, ht == HTVSCROLL ? pt : NULL);
+
ThemeCleanupDrawContext(&context);
return 0;
@@ -720,6 +723,13 @@
ThemeInitDrawContext(&context, hWnd, 0);
ThemeDrawCaptionButtons(&context, 0, 0);
+
+ if(context.wi.dwStyle & WS_HSCROLL)
+ ThemeDrawScrollBar(&context, SB_HORZ, NULL);
+
+ if(context.wi.dwStyle & WS_VSCROLL)
+ ThemeDrawScrollBar(&context, SB_VERT, NULL);
+
ThemeCleanupDrawContext(&context);
return 0;
@@ -1021,7 +1031,12 @@
ThemeHandleNCPaint(hWnd, (HRGN)1);
return TRUE;
case WM_NCMOUSEMOVE:
- return ThemeHandleNcMouseMove(hWnd, wParam);
+ {
+ POINT Point;
+ Point.x = GET_X_LPARAM(lParam);
+ Point.y = GET_Y_LPARAM(lParam);
+ return ThemeHandleNcMouseMove(hWnd, wParam, &Point);
+ }
case WM_NCMOUSELEAVE:
return ThemeHandleNcMouseLeave(hWnd);
case WM_NCLBUTTONDOWN:
@@ -1044,6 +1059,21 @@
Point.y = GET_Y_LPARAM(lParam);
return DefWndNCHitTest(hWnd, Point);
}
+ case WM_SYSCOMMAND:
+ {
+ if((wParam & 0xfff0) == SC_VSCROLL ||
+ (wParam & 0xfff0) == SC_HSCROLL)
+ {
+ POINT Pt;
+ Pt.x = (short)LOWORD(lParam);
+ Pt.y = (short)HIWORD(lParam);
+ NC_TrackScrollBar(hWnd, wParam, Pt);
+ }
+ else
+ {
+ return DefWndProc(hWnd, Msg, wParam, lParam);
+ }
+ }
case WM_NCUAHDRAWCAPTION:
case WM_NCUAHDRAWFRAME:
/* FIXME: how should these be handled? */