Zhiyi Zhang : comctl32/datetime: Implement themed painting.
Alexandre Julliard
julliard at winehq.org
Thu Mar 4 15:53:38 CST 2021
Module: wine
Branch: master
Commit: 52992a99d602fd929aaeee24ffb977aaa50c4423
URL: https://source.winehq.org/git/wine.git/?a=commit;h=52992a99d602fd929aaeee24ffb977aaa50c4423
Author: Zhiyi Zhang <zzhang at codeweavers.com>
Date: Thu Mar 4 16:45:57 2021 +0800
comctl32/datetime: Implement themed painting.
Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/comctl32/datetime.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 136 insertions(+), 1 deletion(-)
diff --git a/dlls/comctl32/datetime.c b/dlls/comctl32/datetime.c
index 71bb3d238b0..f44b52c3b65 100644
--- a/dlls/comctl32/datetime.c
+++ b/dlls/comctl32/datetime.c
@@ -43,6 +43,8 @@
#include "winnls.h"
#include "commctrl.h"
#include "comctl32.h"
+#include "uxtheme.h"
+#include "vsstyle.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(datetime);
@@ -62,6 +64,7 @@ typedef struct
RECT checkbox; /* checkbox allowing the control to be enabled/disabled */
RECT calbutton; /* button that toggles the dropdown of the monthcal control */
BOOL bCalDepressed; /* TRUE = cal button is depressed */
+ BOOL bCalHot; /* TRUE if calendar button is hovered */
BOOL bDropdownEnabled;
int select;
WCHAR charsEntered[4];
@@ -128,6 +131,7 @@ static BOOL DATETIME_SendSimpleNotify (const DATETIME_INFO *infoPtr, UINT code);
static BOOL DATETIME_SendDateTimeChangeNotify (const DATETIME_INFO *infoPtr);
static const WCHAR allowedformatchars[] = L"dhHmMstyX";
static const int maxrepetition [] = {4,2,2,2,4,2,2,4,-1};
+static const WCHAR *themeClass = WC_SCROLLBARW;
/* valid date limits */
static const SYSTEMTIME max_allowed_date = { .wYear = 9999, .wMonth = 12, .wDayOfWeek = 0, .wDay = 31 };
@@ -708,6 +712,9 @@ static int DATETIME_GetFieldWidth (const DATETIME_INFO *infoPtr, HDC hdc, int co
static void
DATETIME_Refresh (DATETIME_INFO *infoPtr, HDC hdc)
{
+ HTHEME theme;
+ int state;
+
TRACE("\n");
if (infoPtr->dateValid) {
@@ -771,7 +778,27 @@ DATETIME_Refresh (DATETIME_INFO *infoPtr, HDC hdc)
SelectObject (hdc, oldFont);
}
- if (!(infoPtr->dwStyle & DTS_UPDOWN)) {
+ if (infoPtr->dwStyle & DTS_UPDOWN)
+ return;
+
+ theme = GetWindowTheme(infoPtr->hwndSelf);
+ if (theme)
+ {
+ if (infoPtr->dwStyle & WS_DISABLED)
+ state = ABS_DOWNDISABLED;
+ else if (infoPtr->bCalDepressed)
+ state = ABS_DOWNPRESSED;
+ else if (infoPtr->bCalHot)
+ state = ABS_DOWNHOT;
+ else
+ state = ABS_DOWNNORMAL;
+
+ if (IsThemeBackgroundPartiallyTransparent(theme, SBP_ARROWBTN, state))
+ DrawThemeParentBackground(infoPtr->hwndSelf, hdc, &infoPtr->calbutton);
+ DrawThemeBackground(theme, hdc, SBP_ARROWBTN, state, &infoPtr->calbutton, NULL);
+ }
+ else
+ {
DrawFrameControl(hdc, &infoPtr->calbutton, DFC_SCROLL,
DFCS_SCROLLDOWN | (infoPtr->bCalDepressed ? DFCS_PUSHED : 0) |
(infoPtr->dwStyle & WS_DISABLED ? DFCS_INACTIVE : 0) );
@@ -1280,6 +1307,85 @@ DATETIME_NCCreate (HWND hwnd, const CREATESTRUCTW *lpcs)
return 1;
}
+static LRESULT DATETIME_NCPaint (HWND hwnd, HRGN region)
+{
+ INT cxEdge, cyEdge;
+ HRGN clipRgn;
+ HTHEME theme;
+ LONG exStyle;
+ RECT r;
+ HDC dc;
+
+ theme = OpenThemeData(NULL, WC_EDITW);
+ if (!theme)
+ return DefWindowProcW(hwnd, WM_NCPAINT, (WPARAM)region, 0);
+
+ exStyle = GetWindowLongW(hwnd, GWL_EXSTYLE);
+ if (!(exStyle & WS_EX_CLIENTEDGE))
+ {
+ CloseThemeData(theme);
+ return DefWindowProcW(hwnd, WM_NCPAINT, (WPARAM)region, 0);
+ }
+
+ cxEdge = GetSystemMetrics(SM_CXEDGE);
+ cyEdge = GetSystemMetrics(SM_CYEDGE);
+ GetWindowRect(hwnd, &r);
+
+ /* New clipping region passed to default proc to exclude border */
+ clipRgn = CreateRectRgn(r.left + cxEdge, r.top + cyEdge, r.right - cxEdge, r.bottom - cyEdge);
+ if (region != (HRGN)1)
+ CombineRgn(clipRgn, clipRgn, region, RGN_AND);
+ OffsetRect(&r, -r.left, -r.top);
+
+ dc = GetDCEx(hwnd, region, DCX_WINDOW | DCX_INTERSECTRGN);
+ if (IsThemeBackgroundPartiallyTransparent(theme, 0, 0))
+ DrawThemeParentBackground(hwnd, dc, &r);
+ DrawThemeBackground(theme, dc, 0, 0, &r, 0);
+ ReleaseDC(hwnd, dc);
+ CloseThemeData(theme);
+
+ /* Call default proc to get the scrollbars etc. also painted */
+ DefWindowProcW(hwnd, WM_NCPAINT, (WPARAM)clipRgn, 0);
+ DeleteObject(clipRgn);
+ return 0;
+}
+
+static LRESULT DATETIME_MouseMove (DATETIME_INFO *infoPtr, LONG x, LONG y)
+{
+ TRACKMOUSEEVENT event;
+ POINT point;
+ BOOL hot;
+
+ point.x = x;
+ point.y = y;
+ hot = PtInRect(&infoPtr->calbutton, point);
+ if (hot != infoPtr->bCalHot)
+ {
+ infoPtr->bCalHot = hot;
+ RedrawWindow(infoPtr->hwndSelf, &infoPtr->calbutton, 0, RDW_INVALIDATE | RDW_UPDATENOW);
+ }
+
+ if (!hot)
+ return 0;
+
+ event.cbSize = sizeof(TRACKMOUSEEVENT);
+ event.dwFlags = TME_QUERY;
+ if (!TrackMouseEvent(&event) || event.hwndTrack != infoPtr->hwndSelf || !(event.dwFlags & TME_LEAVE))
+ {
+ event.hwndTrack = infoPtr->hwndSelf;
+ event.dwFlags = TME_LEAVE;
+ TrackMouseEvent(&event);
+ }
+
+ return 0;
+}
+
+static LRESULT DATETIME_MouseLeave (DATETIME_INFO *infoPtr)
+{
+ infoPtr->bCalHot = FALSE;
+ RedrawWindow(infoPtr->hwndSelf, &infoPtr->calbutton, 0, RDW_INVALIDATE | RDW_UPDATENOW);
+ return 0;
+}
static LRESULT
DATETIME_SetFocus (DATETIME_INFO *infoPtr, HWND lostFocus)
@@ -1430,6 +1536,16 @@ DATETIME_StyleChanged(DATETIME_INFO *infoPtr, WPARAM wStyleType, const STYLESTRU
return 0;
}
+static LRESULT DATETIME_ThemeChanged (DATETIME_INFO *infoPtr)
+{
+ HTHEME theme;
+
+ theme = GetWindowTheme(infoPtr->hwndSelf);
+ CloseThemeData(theme);
+ OpenThemeData(infoPtr->hwndSelf, themeClass);
+ return 0;
+}
+
static BOOL DATETIME_GetIdealSize(DATETIME_INFO *infoPtr, SIZE *size)
{
SIZE field_size;
@@ -1508,6 +1624,7 @@ DATETIME_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
infoPtr->hwndNotify = lpcs->hwndParent;
infoPtr->select = -1; /* initially, nothing is selected */
infoPtr->bDropdownEnabled = TRUE;
+ infoPtr->bCalHot = FALSE;
DATETIME_StyleChanged(infoPtr, GWL_STYLE, &ss);
DATETIME_SetFormatW (infoPtr, 0);
@@ -1522,6 +1639,7 @@ DATETIME_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
infoPtr->hFont = GetStockObject(DEFAULT_GUI_FONT);
SetWindowLongPtrW (hwnd, 0, (DWORD_PTR)infoPtr);
+ OpenThemeData(hwnd, themeClass);
return 0;
}
@@ -1531,6 +1649,11 @@ DATETIME_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
static LRESULT
DATETIME_Destroy (DATETIME_INFO *infoPtr)
{
+ HTHEME theme;
+
+ theme = GetWindowTheme(infoPtr->hwndSelf);
+ CloseThemeData(theme);
+
if (infoPtr->hwndCheckbut)
DestroyWindow(infoPtr->hwndCheckbut);
if (infoPtr->hUpdown)
@@ -1656,6 +1779,15 @@ DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_NCCREATE:
return DATETIME_NCCreate (hwnd, (LPCREATESTRUCTW)lParam);
+ case WM_NCPAINT:
+ return DATETIME_NCPaint(hwnd, (HRGN)wParam);
+
+ case WM_MOUSEMOVE:
+ return DATETIME_MouseMove(infoPtr, (SHORT)LOWORD(lParam), (SHORT)HIWORD(lParam));
+
+ case WM_MOUSELEAVE:
+ return DATETIME_MouseLeave(infoPtr);
+
case WM_SETFOCUS:
return DATETIME_SetFocus (infoPtr, (HWND)wParam);
@@ -1686,6 +1818,9 @@ DATETIME_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_STYLECHANGED:
return DATETIME_StyleChanged(infoPtr, wParam, (LPSTYLESTRUCT)lParam);
+ case WM_THEMECHANGED:
+ return DATETIME_ThemeChanged(infoPtr);
+
case WM_SETFONT:
return DATETIME_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam);
More information about the wine-cvs
mailing list