diff --git a/PowerEditor/src/NppDarkMode.cpp b/PowerEditor/src/NppDarkMode.cpp index aa757b9f3..27b57c787 100644 --- a/PowerEditor/src/NppDarkMode.cpp +++ b/PowerEditor/src/NppDarkMode.cpp @@ -1952,6 +1952,172 @@ namespace NppDarkMode SetWindowSubclass(hwnd, ListViewSubclass, g_listViewSubclassID, 0); } + constexpr UINT_PTR g_upDownSubclassID = 42; + + LRESULT CALLBACK UpDownSubclass( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + UINT_PTR uIdSubclass, + DWORD_PTR dwRefData + ) + { + auto pButtonData = reinterpret_cast(dwRefData); + + switch (uMsg) + { + case WM_PRINTCLIENT: + case WM_PAINT: + { + if (!NppDarkMode::isEnabled()) + { + break; + } + + const auto style = ::GetWindowLongPtr(hWnd, GWL_STYLE); + const bool isHorizontal = ((style & UDS_HORZ) == UDS_HORZ); + + bool hasTheme = pButtonData->ensureTheme(hWnd); + + RECT rcClient{}; + ::GetClientRect(hWnd, &rcClient); + + PAINTSTRUCT ps{}; + auto hdc = ::BeginPaint(hWnd, &ps); + + ::FillRect(hdc, &rcClient, NppDarkMode::getDarkerBackgroundBrush()); + + RECT rcArrowPrev{}; + RECT rcArrowNext{}; + + if (isHorizontal) + { + RECT rcArrowLeft{ + rcClient.left, rcClient.top, + rcClient.right - ((rcClient.right - rcClient.left) / 2), rcClient.bottom + }; + + RECT rcArrowRight{ + rcArrowLeft.right - 1, rcClient.top, + rcClient.right, rcClient.bottom + }; + + rcArrowPrev = rcArrowLeft; + rcArrowNext = rcArrowRight; + } + else + { + RECT rcArrowTop{ + rcClient.left, rcClient.top, + rcClient.right, rcClient.bottom - ((rcClient.bottom - rcClient.top) / 2) + }; + + RECT rcArrowBottom{ + rcClient.left, rcArrowTop.bottom - 1, + rcClient.right, rcClient.bottom + }; + + rcArrowPrev = rcArrowTop; + rcArrowNext = rcArrowBottom; + } + + POINT ptCursor{}; + ::GetCursorPos(&ptCursor); + ::ScreenToClient(hWnd, &ptCursor); + + bool isHotPrev = ::PtInRect(&rcArrowPrev, ptCursor); + bool isHotNext = ::PtInRect(&rcArrowNext, ptCursor); + + ::SetBkMode(hdc, TRANSPARENT); + + if (hasTheme) + { + ::DrawThemeBackground(pButtonData->hTheme, hdc, BP_PUSHBUTTON, isHotPrev ? PBS_HOT : PBS_NORMAL, &rcArrowPrev, nullptr); + ::DrawThemeBackground(pButtonData->hTheme, hdc, BP_PUSHBUTTON, isHotNext ? PBS_HOT : PBS_NORMAL, &rcArrowNext, nullptr); + } + else + { + ::FillRect(hdc, &rcArrowPrev, isHotPrev ? NppDarkMode::getHotBackgroundBrush() : NppDarkMode::getBackgroundBrush()); + ::FillRect(hdc, &rcArrowNext, isHotNext ? NppDarkMode::getHotBackgroundBrush() : NppDarkMode::getBackgroundBrush()); + } + + const auto arrowTextFlags = DT_NOPREFIX | DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP; + + ::SetTextColor(hdc, isHotPrev ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor()); + ::DrawText(hdc, isHorizontal ? L"<" : L"˄", -1, &rcArrowPrev, arrowTextFlags); + + ::SetTextColor(hdc, isHotNext ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor()); + ::DrawText(hdc, isHorizontal ? L">" : L"˅", -1, &rcArrowNext, arrowTextFlags); + + if (!hasTheme) + { + NppDarkMode::paintRoundFrameRect(hdc, rcArrowPrev, NppDarkMode::getEdgePen()); + NppDarkMode::paintRoundFrameRect(hdc, rcArrowNext, NppDarkMode::getEdgePen()); + } + + ::EndPaint(hWnd, &ps); + return FALSE; + } + + case WM_THEMECHANGED: + { + pButtonData->closeTheme(); + break; + } + + case WM_NCDESTROY: + { + ::RemoveWindowSubclass(hWnd, UpDownSubclass, uIdSubclass); + delete pButtonData; + break; + } + + case WM_ERASEBKGND: + { + if (NppDarkMode::isEnabled()) + { + RECT rcClient{}; + ::GetClientRect(hWnd, &rcClient); + ::FillRect(reinterpret_cast(wParam), &rcClient, NppDarkMode::getDarkerBackgroundBrush()); + return TRUE; + } + break; + } + } + return DefSubclassProc(hWnd, uMsg, wParam, lParam); + } + + void subclassAndThemeUpDownControl(HWND hwnd, NppDarkModeParams p) + { + if (p._subclass) + { + auto pButtonData = reinterpret_cast(new ButtonData()); + SetWindowSubclass(hwnd, UpDownSubclass, g_upDownSubclassID, pButtonData); + } + + if (p._theme) + { + SetWindowTheme(hwnd, p._themeClassName, nullptr); + } + } + + bool subclassTabUpDownControl(HWND hwnd) + { + constexpr size_t classNameLen = 16; + TCHAR className[classNameLen]{}; + GetClassName(hwnd, className, classNameLen); + if (wcscmp(className, UPDOWN_CLASS) == 0) + { + auto pButtonData = reinterpret_cast(new ButtonData()); + SetWindowSubclass(hwnd, UpDownSubclass, g_upDownSubclassID, pButtonData); + NppDarkMode::setDarkExplorerTheme(hwnd); + return true; + } + + return false; + } + void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass, bool theme) { NppDarkModeParams p{ @@ -2023,6 +2189,13 @@ namespace NppDarkMode return TRUE; } + // For plugins + if (wcscmp(className, UPDOWN_CLASS) == 0) + { + NppDarkMode::subclassAndThemeUpDownControl(hwnd, p); + return TRUE; + } + /* // for debugging if (wcscmp(className, L"#32770") == 0) @@ -2711,153 +2884,6 @@ namespace NppDarkMode SetWindowSubclass(hwnd, WindowNotifySubclass, g_windowNotifySubclassID, 0); } - constexpr UINT_PTR g_tabUpDownSubclassID = 42; - - LRESULT CALLBACK TabUpDownSubclass( - HWND hWnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam, - UINT_PTR uIdSubclass, - DWORD_PTR dwRefData - ) - { - auto pButtonData = reinterpret_cast(dwRefData); - - switch (uMsg) - { - case WM_PRINTCLIENT: - case WM_PAINT: - { - if (!NppDarkMode::isEnabled()) - { - break; - } - - bool hasTheme = pButtonData->ensureTheme(hWnd); - - RECT rcClient{}; - ::GetClientRect(hWnd, &rcClient); - - PAINTSTRUCT ps{}; - auto hdc = ::BeginPaint(hWnd, &ps); - - ::FillRect(hdc, &rcClient, NppDarkMode::getDarkerBackgroundBrush()); - - auto dpiManager = NppParameters::getInstance()._dpiManager; - - RECT rcArrowLeft = { - rcClient.left, rcClient.top, - rcClient.right - ((rcClient.right - rcClient.left) / 2) , rcClient.bottom - }; - - RECT rcArrowRight = { - rcArrowLeft.right, rcClient.top, - rcClient.right, rcClient.bottom - }; - - POINT ptCursor{}; - ::GetCursorPos(&ptCursor); - ::ScreenToClient(hWnd, &ptCursor); - - bool isHotLeft = ::PtInRect(&rcArrowLeft, ptCursor); - bool isHotRight = ::PtInRect(&rcArrowRight, ptCursor); - - ::SetBkMode(hdc, TRANSPARENT); - - if (hasTheme) - { - ::DrawThemeBackground(pButtonData->hTheme, hdc, BP_PUSHBUTTON, isHotLeft ? PBS_HOT : PBS_NORMAL, &rcArrowLeft, nullptr); - ::DrawThemeBackground(pButtonData->hTheme, hdc, BP_PUSHBUTTON, isHotRight ? PBS_HOT : PBS_NORMAL, &rcArrowRight, nullptr); - } - else - { - ::FillRect(hdc, &rcArrowLeft, isHotLeft ? NppDarkMode::getHotBackgroundBrush() : NppDarkMode::getBackgroundBrush()); - ::FillRect(hdc, &rcArrowRight, isHotRight ? NppDarkMode::getHotBackgroundBrush() : NppDarkMode::getBackgroundBrush()); - } - - LOGFONT lf{}; - auto font = reinterpret_cast(SendMessage(hWnd, WM_GETFONT, 0, 0)); - ::GetObject(font, sizeof(lf), &lf); - lf.lfHeight = (dpiManager.scaleY(16) - 5) * -1; - auto holdFont = static_cast(::SelectObject(hdc, CreateFontIndirect(&lf))); - - auto mPosX = ((rcArrowLeft.right - rcArrowLeft.left - dpiManager.scaleX(7) + 1) / 2); - auto mPosY = ((rcArrowLeft.bottom - rcArrowLeft.top + lf.lfHeight - dpiManager.scaleY(1) - 3) / 2); - - ::SetTextColor(hdc, isHotLeft ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor()); - ::ExtTextOut(hdc, - rcArrowLeft.left + mPosX, - rcArrowLeft.top + mPosY, - ETO_CLIPPED, - &rcArrowLeft, L"<", - 1, - nullptr); - - ::SetTextColor(hdc, isHotRight ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor()); - ::ExtTextOut(hdc, - rcArrowRight.left + mPosX - dpiManager.scaleX(2) + 3, - rcArrowRight.top + mPosY, - ETO_CLIPPED, - &rcArrowRight, L">", - 1, - nullptr); - - if (!hasTheme) - { - NppDarkMode::paintRoundFrameRect(hdc, rcArrowLeft, NppDarkMode::getEdgePen()); - NppDarkMode::paintRoundFrameRect(hdc, rcArrowRight, NppDarkMode::getEdgePen()); - } - - ::SelectObject(hdc, holdFont); - ::EndPaint(hWnd, &ps); - return FALSE; - } - - case WM_THEMECHANGED: - { - pButtonData->closeTheme(); - break; - } - - case WM_NCDESTROY: - { - ::RemoveWindowSubclass(hWnd, TabUpDownSubclass, uIdSubclass); - delete pButtonData; - break; - } - - case WM_ERASEBKGND: - { - if (NppDarkMode::isEnabled()) - { - RECT rcClient{}; - ::GetClientRect(hWnd, &rcClient); - ::FillRect(reinterpret_cast(wParam), &rcClient, NppDarkMode::getDarkerBackgroundBrush()); - return TRUE; - } - break; - } - } - return DefSubclassProc(hWnd, uMsg, wParam, lParam); - } - - bool subclassTabUpDownControl(HWND hwnd) - { - constexpr size_t classNameLen = 16; - TCHAR className[classNameLen]{}; - GetClassName(hwnd, className, classNameLen); - if (wcscmp(className, UPDOWN_CLASS) == 0) - { - auto pButtonData = reinterpret_cast(new ButtonData()); - SetWindowSubclass(hwnd, TabUpDownSubclass, g_tabUpDownSubclassID, pButtonData); - NppDarkMode::setDarkExplorerTheme(hwnd); - return true; - } - - return false; - } - void setDarkTitleBar(HWND hwnd) { constexpr DWORD win10Build2004 = 19041; diff --git a/PowerEditor/src/NppDarkMode.h b/PowerEditor/src/NppDarkMode.h index e6194c529..f14abca51 100644 --- a/PowerEditor/src/NppDarkMode.h +++ b/PowerEditor/src/NppDarkMode.h @@ -201,6 +201,8 @@ namespace NppDarkMode void subclassTabControl(HWND hwnd); void subclassComboBoxControl(HWND hwnd); + bool subclassTabUpDownControl(HWND hwnd); + void subclassAndThemeButton(HWND hwnd, NppDarkModeParams p); void subclassAndThemeComboBox(HWND hwnd, NppDarkModeParams p); void subclassAndThemeListBoxOrEditControl(HWND hwnd, NppDarkModeParams p, bool isListBox); @@ -220,8 +222,6 @@ namespace NppDarkMode ULONG autoSubclassAndThemePlugin(HWND hwnd, ULONG dmFlags); void autoSubclassAndThemeWindowNotify(HWND hwnd); - bool subclassTabUpDownControl(HWND hwnd); - void setDarkTitleBar(HWND hwnd); void setDarkExplorerTheme(HWND hwnd); void setDarkScrollBar(HWND hwnd);