diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 8959e777e..5cc447dd8 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -7504,6 +7504,7 @@ void Notepad_plus::refreshDarkMode() { SendMessage(_pPublicInterface->getHSelf(), NPPM_SETEDITORBORDEREDGE, 0, NppParameters::getInstance().getSVP()._showBorderEdge); RedrawWindow(_pPublicInterface->getHSelf(), nullptr, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN); + RedrawWindow(_findReplaceDlg.getHSelf(), nullptr, nullptr, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN); } void Notepad_plus::launchDocumentBackupTask() diff --git a/PowerEditor/src/NppDarkMode.cpp b/PowerEditor/src/NppDarkMode.cpp index b8951ec09..79dee3d0c 100644 --- a/PowerEditor/src/NppDarkMode.cpp +++ b/PowerEditor/src/NppDarkMode.cpp @@ -226,124 +226,124 @@ namespace NppDarkMode UNREFERENCED_PARAMETER(wParam); switch (message) { - case WM_UAHDRAWMENU: + case WM_UAHDRAWMENU: + { + UAHMENU* pUDM = (UAHMENU*)lParam; + RECT rc = { 0 }; + + // get the menubar rect { - UAHMENU* pUDM = (UAHMENU*)lParam; - RECT rc = { 0 }; + MENUBARINFO mbi = { sizeof(mbi) }; + GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi); - // get the menubar rect - { - MENUBARINFO mbi = { sizeof(mbi) }; - GetMenuBarInfo(hWnd, OBJID_MENU, 0, &mbi); + RECT rcWindow; + GetWindowRect(hWnd, &rcWindow); - RECT rcWindow; - GetWindowRect(hWnd, &rcWindow); + // the rcBar is offset by the window rect + rc = mbi.rcBar; + OffsetRect(&rc, -rcWindow.left, -rcWindow.top); - // the rcBar is offset by the window rect - rc = mbi.rcBar; - OffsetRect(&rc, -rcWindow.left, -rcWindow.top); - - rc.top -= 1; - } - - FillRect(pUDM->hdc, &rc, NppDarkMode::getPureBackgroundBrush()); - - *lr = 0; - - return true; + rc.top -= 1; } - case WM_UAHDRAWMENUITEM: + + FillRect(pUDM->hdc, &rc, NppDarkMode::getPureBackgroundBrush()); + + *lr = 0; + + return true; + } + case WM_UAHDRAWMENUITEM: + { + UAHDRAWMENUITEM* pUDMI = (UAHDRAWMENUITEM*)lParam; + + // get the menu item string + wchar_t menuString[256] = { 0 }; + MENUITEMINFO mii = { sizeof(mii), MIIM_STRING }; { - UAHDRAWMENUITEM* pUDMI = (UAHDRAWMENUITEM*)lParam; + mii.dwTypeData = menuString; + mii.cch = (sizeof(menuString) / 2) - 1; - // get the menu item string - wchar_t menuString[256] = { 0 }; - MENUITEMINFO mii = { sizeof(mii), MIIM_STRING }; - { - mii.dwTypeData = menuString; - mii.cch = (sizeof(menuString) / 2) - 1; - - GetMenuItemInfo(pUDMI->um.hmenu, pUDMI->umi.iPosition, TRUE, &mii); - } - - // get the item state for drawing - - DWORD dwFlags = DT_CENTER | DT_SINGLELINE | DT_VCENTER; - - int iTextStateID = MPI_NORMAL; - int iBackgroundStateID = MPI_NORMAL; - { - if ((pUDMI->dis.itemState & ODS_INACTIVE) | (pUDMI->dis.itemState & ODS_DEFAULT)) - { - // normal display - iTextStateID = MPI_NORMAL; - iBackgroundStateID = MPI_NORMAL; - } - if (pUDMI->dis.itemState & ODS_HOTLIGHT) - { - // hot tracking - iTextStateID = MPI_HOT; - iBackgroundStateID = MPI_HOT; - } - if (pUDMI->dis.itemState & ODS_SELECTED) - { - // clicked -- MENU_POPUPITEM has no state for this, though MENU_BARITEM does - iTextStateID = MPI_HOT; - iBackgroundStateID = MPI_HOT; - } - if ((pUDMI->dis.itemState & ODS_GRAYED) || (pUDMI->dis.itemState & ODS_DISABLED)) - { - // disabled / grey text - iTextStateID = MPI_DISABLED; - iBackgroundStateID = MPI_DISABLED; - } - if (pUDMI->dis.itemState & ODS_NOACCEL) - { - dwFlags |= DT_HIDEPREFIX; - } - } - - if (!g_menuTheme) - { - g_menuTheme = OpenThemeData(hWnd, L"Menu"); - } - - if (iBackgroundStateID == MPI_NORMAL || iBackgroundStateID == MPI_DISABLED) - { - FillRect(pUDMI->um.hdc, &pUDMI->dis.rcItem, NppDarkMode::getPureBackgroundBrush()); - } - else if (iBackgroundStateID == MPI_HOT || iBackgroundStateID == MPI_DISABLEDHOT) - { - FillRect(pUDMI->um.hdc, &pUDMI->dis.rcItem, NppDarkMode::getHotBackgroundBrush()); - } - else - { - DrawThemeBackground(g_menuTheme, pUDMI->um.hdc, MENU_POPUPITEM, iBackgroundStateID, &pUDMI->dis.rcItem, nullptr); - } - DTTOPTS dttopts = { sizeof(dttopts) }; - if (iTextStateID == MPI_NORMAL || iTextStateID == MPI_HOT) - { - dttopts.dwFlags |= DTT_TEXTCOLOR; - dttopts.crText = NppDarkMode::getTextColor(); - } - DrawThemeTextEx(g_menuTheme, pUDMI->um.hdc, MENU_POPUPITEM, iTextStateID, menuString, mii.cch, dwFlags, &pUDMI->dis.rcItem, &dttopts); - - *lr = 0; - - return true; + GetMenuItemInfo(pUDMI->um.hmenu, pUDMI->umi.iPosition, TRUE, &mii); } - case WM_THEMECHANGED: + + // get the item state for drawing + + DWORD dwFlags = DT_CENTER | DT_SINGLELINE | DT_VCENTER; + + int iTextStateID = MPI_NORMAL; + int iBackgroundStateID = MPI_NORMAL; { - if (g_menuTheme) + if ((pUDMI->dis.itemState & ODS_INACTIVE) | (pUDMI->dis.itemState & ODS_DEFAULT)) { - CloseThemeData(g_menuTheme); - g_menuTheme = nullptr; + // normal display + iTextStateID = MPI_NORMAL; + iBackgroundStateID = MPI_NORMAL; + } + if (pUDMI->dis.itemState & ODS_HOTLIGHT) + { + // hot tracking + iTextStateID = MPI_HOT; + iBackgroundStateID = MPI_HOT; + } + if (pUDMI->dis.itemState & ODS_SELECTED) + { + // clicked -- MENU_POPUPITEM has no state for this, though MENU_BARITEM does + iTextStateID = MPI_HOT; + iBackgroundStateID = MPI_HOT; + } + if ((pUDMI->dis.itemState & ODS_GRAYED) || (pUDMI->dis.itemState & ODS_DISABLED)) + { + // disabled / grey text + iTextStateID = MPI_DISABLED; + iBackgroundStateID = MPI_DISABLED; + } + if (pUDMI->dis.itemState & ODS_NOACCEL) + { + dwFlags |= DT_HIDEPREFIX; } - // continue processing in main wndproc - return false; } - default: - return false; + + if (!g_menuTheme) + { + g_menuTheme = OpenThemeData(hWnd, L"Menu"); + } + + if (iBackgroundStateID == MPI_NORMAL || iBackgroundStateID == MPI_DISABLED) + { + FillRect(pUDMI->um.hdc, &pUDMI->dis.rcItem, NppDarkMode::getPureBackgroundBrush()); + } + else if (iBackgroundStateID == MPI_HOT || iBackgroundStateID == MPI_DISABLEDHOT) + { + FillRect(pUDMI->um.hdc, &pUDMI->dis.rcItem, NppDarkMode::getHotBackgroundBrush()); + } + else + { + DrawThemeBackground(g_menuTheme, pUDMI->um.hdc, MENU_POPUPITEM, iBackgroundStateID, &pUDMI->dis.rcItem, nullptr); + } + DTTOPTS dttopts = { sizeof(dttopts) }; + if (iTextStateID == MPI_NORMAL || iTextStateID == MPI_HOT) + { + dttopts.dwFlags |= DTT_TEXTCOLOR; + dttopts.crText = NppDarkMode::getTextColor(); + } + DrawThemeTextEx(g_menuTheme, pUDMI->um.hdc, MENU_POPUPITEM, iTextStateID, menuString, mii.cch, dwFlags, &pUDMI->dis.rcItem, &dttopts); + + *lr = 0; + + return true; + } + case WM_THEMECHANGED: + { + if (g_menuTheme) + { + CloseThemeData(g_menuTheme); + g_menuTheme = nullptr; + } + // continue processing in main wndproc + return false; + } + default: + return false; } } @@ -377,6 +377,7 @@ namespace NppDarkMode struct ButtonData { HTHEME hTheme = nullptr; + int iStateID = 0; ~ButtonData() { @@ -402,44 +403,19 @@ namespace NppDarkMode } }; - void paintButton(HWND hwnd, HDC hdc, ButtonData& buttonData) + void renderButton(HWND hwnd, HDC hdc, HTHEME hTheme, int iPartID, int iStateID) { RECT rcClient = { 0 }; WCHAR szText[256] = { 0 }; DWORD nState = static_cast(SendMessage(hwnd, BM_GETSTATE, 0, 0)); - bool isEnabled = IsWindowEnabled(hwnd);; DWORD uiState = static_cast(SendMessage(hwnd, WM_QUERYUISTATE, 0, 0)); DWORD nStyle = GetWindowLong(hwnd, GWL_STYLE); - DWORD nButtonStyle = nStyle & 0xF; - - int iPartID = BP_CHECKBOX; - if (nButtonStyle == BS_CHECKBOX || nButtonStyle == BS_AUTOCHECKBOX) - { - iPartID = BP_CHECKBOX; - } - else if (nButtonStyle == BS_RADIOBUTTON || nButtonStyle == BS_AUTORADIOBUTTON) - { - iPartID = BP_RADIOBUTTON; - } - else - { - assert(false); - } - - // states of BP_CHECKBOX and BP_RADIOBUTTON are the same - int iStateID = RBS_UNCHECKEDNORMAL; - - if (!isEnabled) iStateID = RBS_UNCHECKEDDISABLED; - else if (nState & BST_PUSHED) iStateID = RBS_UNCHECKEDPRESSED; - else if (nState & BST_HOT) iStateID = RBS_UNCHECKEDHOT; - - if (nState & BST_CHECKED) iStateID += 4; HFONT hFont = nullptr; HFONT hOldFont = nullptr; HFONT hCreatedFont = nullptr; LOGFONT lf = { 0 }; - if (SUCCEEDED(GetThemeFont(buttonData.hTheme, hdc, iPartID, iStateID, TMT_FONT, &lf))) + if (SUCCEEDED(GetThemeFont(hTheme, hdc, iPartID, iStateID, TMT_FONT, &lf))) { hCreatedFont = CreateFontIndirect(&lf); hFont = hCreatedFont; @@ -466,10 +442,10 @@ namespace NppDarkMode GetWindowText(hwnd, szText, _countof(szText)); SIZE szBox = { 13, 13 }; - GetThemePartSize(buttonData.hTheme, hdc, iPartID, iStateID, NULL, TS_DRAW, &szBox); + GetThemePartSize(hTheme, hdc, iPartID, iStateID, NULL, TS_DRAW, &szBox); RECT rcText = rcClient; - GetThemeBackgroundContentRect(buttonData.hTheme, hdc, iPartID, iStateID, &rcClient, &rcText); + GetThemeBackgroundContentRect(hTheme, hdc, iPartID, iStateID, &rcClient, &rcText); RECT rcBackground = rcClient; if (dtFlags & DT_SINGLELINE) @@ -481,18 +457,18 @@ namespace NppDarkMode rcText.left = rcBackground.right + 3; DrawThemeParentBackground(hwnd, hdc, &rcClient); - DrawThemeBackground(buttonData.hTheme, hdc, iPartID, iStateID, &rcBackground, nullptr); + DrawThemeBackground(hTheme, hdc, iPartID, iStateID, &rcBackground, nullptr); DTTOPTS dtto = { sizeof(DTTOPTS), DTT_TEXTCOLOR }; dtto.crText = NppDarkMode::getTextColor(); - DrawThemeTextEx(buttonData.hTheme, hdc, iPartID, iStateID, szText, -1, dtFlags, &rcText, &dtto); + DrawThemeTextEx(hTheme, hdc, iPartID, iStateID, szText, -1, dtFlags, &rcText, &dtto); if ((nState & BST_FOCUS) && !(uiState & UISF_HIDEFOCUS)) { RECT rcTextOut = rcText; dtto.dwFlags |= DTT_CALCRECT; - DrawThemeTextEx(buttonData.hTheme, hdc, iPartID, iStateID, szText, -1, dtFlags | DT_CALCRECT, &rcTextOut, &dtto); + DrawThemeTextEx(hTheme, hdc, iPartID, iStateID, szText, -1, dtFlags | DT_CALCRECT, &rcTextOut, &dtto); RECT rcFocus = rcTextOut; rcFocus.bottom++; rcFocus.left--; @@ -504,6 +480,76 @@ namespace NppDarkMode SelectObject(hdc, hOldFont); } + void paintButton(HWND hwnd, HDC hdc, ButtonData& buttonData) + { + DWORD nState = static_cast(SendMessage(hwnd, BM_GETSTATE, 0, 0)); + DWORD nStyle = GetWindowLong(hwnd, GWL_STYLE); + DWORD nButtonStyle = nStyle & 0xF; + + int iPartID = BP_CHECKBOX; + if (nButtonStyle == BS_CHECKBOX || nButtonStyle == BS_AUTOCHECKBOX) + { + iPartID = BP_CHECKBOX; + } + else if (nButtonStyle == BS_RADIOBUTTON || nButtonStyle == BS_AUTORADIOBUTTON) + { + iPartID = BP_RADIOBUTTON; + } + else + { + assert(false); + } + + // states of BP_CHECKBOX and BP_RADIOBUTTON are the same + int iStateID = RBS_UNCHECKEDNORMAL; + + if (nStyle & WS_DISABLED) iStateID = RBS_UNCHECKEDDISABLED; + else if (nState & BST_PUSHED) iStateID = RBS_UNCHECKEDPRESSED; + else if (nState & BST_HOT) iStateID = RBS_UNCHECKEDHOT; + + if (nState & BST_CHECKED) iStateID += 4; + + if (BufferedPaintRenderAnimation(hwnd, hdc)) + { + return; + } + + BP_ANIMATIONPARAMS animParams = { sizeof(animParams) }; + animParams.style = BPAS_LINEAR; + if (iStateID != buttonData.iStateID) + { + GetThemeTransitionDuration(buttonData.hTheme, iPartID, buttonData.iStateID, iStateID, TMT_TRANSITIONDURATIONS, &animParams.dwDuration); + } + + RECT rcClient = { 0 }; + GetClientRect(hwnd, &rcClient); + + HDC hdcFrom = nullptr; + HDC hdcTo = nullptr; + HANIMATIONBUFFER hbpAnimation = BeginBufferedAnimation(hwnd, hdc, &rcClient, BPBF_COMPATIBLEBITMAP, nullptr, &animParams, &hdcFrom, &hdcTo); + if (hbpAnimation) + { + if (hdcFrom) + { + renderButton(hwnd, hdcFrom, buttonData.hTheme, iPartID, buttonData.iStateID); + } + if (hdcTo) + { + renderButton(hwnd, hdcTo, buttonData.hTheme, iPartID, iStateID); + } + + buttonData.iStateID = iStateID; + + EndBufferedAnimation(hbpAnimation, TRUE); + } + else + { + renderButton(hwnd, hdc, buttonData.hTheme, iPartID, iStateID); + + buttonData.iStateID = iStateID; + } + } + constexpr UINT_PTR g_buttonSubclassID = 42; LRESULT CALLBACK ButtonSubclass( @@ -567,6 +613,10 @@ namespace NppDarkMode { break; } + case WM_SIZE: + case WM_DESTROY: + BufferedPaintStopAllAnimations(hWnd); + break; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } @@ -577,6 +627,153 @@ namespace NppDarkMode SetWindowSubclass(hwnd, ButtonSubclass, g_buttonSubclassID, pButtonData); } + void paintGroupbox(HWND hwnd, HDC hdc, ButtonData& buttonData) + { + DWORD nStyle = GetWindowLong(hwnd, GWL_STYLE); + int iPartID = BP_GROUPBOX; + int iStateID = GBS_NORMAL; + + if (nStyle & WS_DISABLED) + { + iStateID = GBS_DISABLED; + } + + RECT rcClient = { 0 }; + GetClientRect(hwnd, &rcClient); + + RECT rcText = rcClient; + RECT rcBackground = rcClient; + + HFONT hFont = nullptr; + HFONT hOldFont = nullptr; + HFONT hCreatedFont = nullptr; + LOGFONT lf = { 0 }; + if (SUCCEEDED(GetThemeFont(buttonData.hTheme, hdc, iPartID, iStateID, TMT_FONT, &lf))) + { + hCreatedFont = CreateFontIndirect(&lf); + hFont = hCreatedFont; + } + + if (!hFont) { + hFont = reinterpret_cast(SendMessage(hwnd, WM_GETFONT, 0, 0)); + } + + SelectObject(hdc, hFont); + + + WCHAR szText[256] = { 0 }; + GetWindowText(hwnd, szText, _countof(szText)); + + if (szText[0]) + { + SIZE textSize = { 0 }; + GetTextExtentPoint32(hdc, szText, static_cast(wcslen(szText)), &textSize); + rcBackground.top += textSize.cy / 2; + rcText.left += 7; + rcText.bottom = rcText.top + textSize.cy; + rcText.right = rcText.left + textSize.cx + 4; + + ExcludeClipRect(hdc, rcText.left, rcText.top, rcText.right, rcText.bottom); + } + else + { + SIZE textSize = { 0 }; + GetTextExtentPoint32(hdc, L"M", 1, &textSize); + rcBackground.top += textSize.cy / 2; + } + + RECT rcContent = rcBackground; + GetThemeBackgroundContentRect(buttonData.hTheme, hdc, BP_GROUPBOX, iStateID, &rcBackground, &rcContent); + ExcludeClipRect(hdc, rcContent.left, rcContent.top, rcContent.right, rcContent.bottom); + + DrawThemeParentBackground(hwnd, hdc, &rcClient); + DrawThemeBackground(buttonData.hTheme, hdc, BP_GROUPBOX, iStateID, &rcBackground, nullptr); + + SelectClipRgn(hdc, nullptr); + + if (szText[0]) + { + rcText.right -= 2; + rcText.left += 2; + + DTTOPTS dtto = { sizeof(DTTOPTS), DTT_TEXTCOLOR }; + dtto.crText = NppDarkMode::getTextColor(); + + DrawThemeTextEx(buttonData.hTheme, hdc, BP_GROUPBOX, iStateID, szText, -1, DT_LEFT | DT_SINGLELINE, &rcText, &dtto); + } + + if (hCreatedFont) DeleteObject(hCreatedFont); + SelectObject(hdc, hOldFont); + } + + constexpr UINT_PTR g_groupboxSubclassID = 42; + + LRESULT CALLBACK GroupboxSubclass( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + UINT_PTR uIdSubclass, + DWORD_PTR dwRefData + ) + { + UNREFERENCED_PARAMETER(uIdSubclass); + + auto pButtonData = reinterpret_cast(dwRefData); + + switch (uMsg) + { + case WM_NCDESTROY: + RemoveWindowSubclass(hWnd, GroupboxSubclass, g_groupboxSubclassID); + delete pButtonData; + break; + case WM_ERASEBKGND: + if (NppDarkMode::isEnabled() && pButtonData->ensureTheme(hWnd)) + { + return TRUE; + } + else + { + break; + } + case WM_THEMECHANGED: + pButtonData->closeTheme(); + break; + case WM_PRINTCLIENT: + case WM_PAINT: + if (NppDarkMode::isEnabled() && pButtonData->ensureTheme(hWnd)) + { + PAINTSTRUCT ps = { 0 }; + HDC hdc = reinterpret_cast(wParam); + if (!hdc) + { + hdc = BeginPaint(hWnd, &ps); + } + + paintGroupbox(hWnd, hdc, *pButtonData); + + if (ps.hdc) + { + EndPaint(hWnd, &ps); + } + + return 0; + } + else + { + break; + } + break; + } + return DefSubclassProc(hWnd, uMsg, wParam, lParam); + } + + void subclassGroupboxControl(HWND hwnd) + { + DWORD_PTR pButtonData = reinterpret_cast(new ButtonData()); + SetWindowSubclass(hwnd, GroupboxSubclass, g_groupboxSubclassID, pButtonData); + } + constexpr UINT_PTR g_toolbarSubclassID = 42; LRESULT CALLBACK ToolbarSubclass( @@ -604,5 +801,136 @@ namespace NppDarkMode { SetWindowSubclass(hwnd, ToolbarSubclass, g_toolbarSubclassID, 0); } + + constexpr UINT_PTR g_tabSubclassID = 42; + + LRESULT CALLBACK TabSubclass( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + UINT_PTR uIdSubclass, + DWORD_PTR dwRefData + ) + { + UNREFERENCED_PARAMETER(uIdSubclass); + UNREFERENCED_PARAMETER(dwRefData); + + switch (uMsg) + { + case WM_PAINT: + { + if (!NppDarkMode::isEnabled()) + { + break; + } + + LONG_PTR dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE); + if ((dwStyle & TCS_BOTTOM) || (dwStyle & TCS_BUTTONS) || (dwStyle & TCS_VERTICAL)) + { + break; + } + + PAINTSTRUCT ps; + HDC hdc = BeginPaint(hWnd, &ps); + FillRect(hdc, &ps.rcPaint, NppDarkMode::getPureBackgroundBrush()); + + static HPEN g_hpen = CreatePen(PS_SOLID, 1, NppDarkMode::getEdgeColor()); + + HPEN holdPen = (HPEN)SelectObject(hdc, g_hpen); + + HRGN holdClip = CreateRectRgn(0, 0, 0, 0); + if (1 != GetClipRgn(hdc, holdClip)) + { + DeleteObject(holdClip); + holdClip = nullptr; + } + + HFONT hFont = reinterpret_cast(SendMessage(hWnd, WM_GETFONT, 0, 0)); + auto hOldFont = SelectObject(hdc, hFont); + + POINT ptCursor = { 0 }; + ::GetCursorPos(&ptCursor); + ScreenToClient(hWnd, &ptCursor); + + int nTabs = TabCtrl_GetItemCount(hWnd); + + int nSelTab = TabCtrl_GetCurSel(hWnd); + for (int i = 0; i < nTabs; ++i) + { + RECT rcItem = { 0 }; + TabCtrl_GetItemRect(hWnd, i, &rcItem); + + RECT rcIntersect = { 0 }; + if (IntersectRect(&rcIntersect, &ps.rcPaint, &rcItem)) + { + bool bHot = PtInRect(&rcItem, ptCursor); + + POINT edges[] = { + {rcItem.right - 1, rcItem.top}, + {rcItem.right - 1, rcItem.bottom} + }; + Polyline(hdc, edges, _countof(edges)); + rcItem.right -= 1; + + HRGN hClip = CreateRectRgnIndirect(&rcItem); + + SelectClipRgn(hdc, hClip); + + SetTextColor(hdc, (bHot || (i == nSelTab) ) ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor()); + + FillRect(hdc, &rcItem, (i == nSelTab) ? NppDarkMode::getPureBackgroundBrush() : NppDarkMode::getBackgroundBrush()); + + SetBkMode(hdc, TRANSPARENT); + + TCHAR label[MAX_PATH]; + TCITEM tci = { 0 }; + tci.mask = TCIF_TEXT; + tci.pszText = label; + tci.cchTextMax = MAX_PATH - 1; + + ::SendMessage(hWnd, TCM_GETITEM, i, reinterpret_cast(&tci)); + + RECT rcText = rcItem; + rcText.left += NppParameters::getInstance()._dpiManager.scaleX(6); + rcText.right -= NppParameters::getInstance()._dpiManager.scaleX(3); + + if (i == nSelTab) { + rcText.bottom -= NppParameters::getInstance()._dpiManager.scaleX(4); + } + + DrawText(hdc, label, -1, &rcText, DT_LEFT | DT_VCENTER | DT_SINGLELINE); + + DeleteObject(hClip); + + SelectClipRgn(hdc, holdClip); + } + } + + SelectObject(hdc, hOldFont); + + SelectClipRgn(hdc, holdClip); + if (holdClip) + { + DeleteObject(holdClip); + holdClip = nullptr; + } + + SelectObject(hdc, holdPen); + + EndPaint(hWnd, &ps); + return 0; + } + case WM_NCDESTROY: + RemoveWindowSubclass(hWnd, TabSubclass, g_tabSubclassID); + break; + } + return DefSubclassProc(hWnd, uMsg, wParam, lParam); + } + + void subclassTabControl(HWND hwnd) + { + SetWindowSubclass(hwnd, TabSubclass, g_tabSubclassID, 0); + } } diff --git a/PowerEditor/src/NppDarkMode.h b/PowerEditor/src/NppDarkMode.h index dc17e8e14..dae1d3ec1 100644 --- a/PowerEditor/src/NppDarkMode.h +++ b/PowerEditor/src/NppDarkMode.h @@ -58,6 +58,8 @@ namespace NppDarkMode void enableDarkScrollBarForWindowAndChildren(HWND hwnd); void subclassButtonControl(HWND hwnd); + void subclassGroupboxControl(HWND hwnd); void subclassToolbarControl(HWND hwnd); + void subclassTabControl(HWND hwnd); } diff --git a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp index 7db333ce6..389ea7a31 100644 --- a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp @@ -272,6 +272,7 @@ void FindReplaceDlg::create(int dialogID, bool isRTL, bool msgDestParent) //::GetWindowRect(_hSelf, &rect); getClientRect(rect); _tab.init(_hInst, _hSelf, false, true); + NppDarkMode::subclassTabControl(_tab.getHSelf()); int tabDpiDynamicalHeight = NppParameters::getInstance()._dpiManager.scaleY(13); _tab.setFont(TEXT("Tahoma"), tabDpiDynamicalHeight); @@ -848,8 +849,72 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM return TRUE; } + case WM_CTLCOLOREDIT: + case WM_CTLCOLORDLG: + case WM_CTLCOLORSTATIC: + { + if (!NppDarkMode::isEnabled()) + { + break; + } + + SetTextColor((HDC)wParam, NppDarkMode::getTextColor()); + SetBkColor((HDC)wParam, NppDarkMode::getPureBackgroundColor()); + return (LRESULT)GetStockObject(BLACK_BRUSH); + } + case WM_PRINTCLIENT: + case WM_ERASEBKGND: + { + if (!NppDarkMode::isEnabled()) + { + break; + } + RECT rc = { 0 }; + getClientRect(rc); + FillRect((HDC)wParam, &rc, NppDarkMode::getPureBackgroundBrush()); + SetWindowLongPtr(_hSelf, DWLP_MSGRESULT, TRUE); + return TRUE; + } + + case WM_SETTINGCHANGE: + { + if (NppDarkMode::handleSettingChange(_hSelf, lParam)) + { + // dark mode may have been toggled by the OS + NppDarkMode::refreshDarkMode(_hSelf, true); + } + break; + } + case WM_INITDIALOG : { + if (NppDarkMode::isExperimentalEnabled()) + { + NppDarkMode::allowDarkModeForWindow(_hSelf, true); + NppDarkMode::refreshTitleBarThemeColor(_hSelf); + } + + EnumChildWindows(_hSelf, [](HWND hwnd, LPARAM) { + wchar_t className[16] = { 0 }; + GetClassName(hwnd, className, 9); + if (wcscmp(className, L"Button")) { + return TRUE; + } + DWORD nButtonStyle = (DWORD)GetWindowLong(hwnd, GWL_STYLE) & 0xF; + switch (nButtonStyle) { + case BS_CHECKBOX: + case BS_AUTOCHECKBOX: + case BS_RADIOBUTTON: + case BS_AUTORADIOBUTTON: + NppDarkMode::subclassButtonControl(hwnd); + break; + case BS_GROUPBOX: + NppDarkMode::subclassGroupboxControl(hwnd); + break; + } + return TRUE; + }, NULL); + HWND hFindCombo = ::GetDlgItem(_hSelf, IDFINDWHAT); HWND hReplaceCombo = ::GetDlgItem(_hSelf, IDREPLACEWITH); HWND hFiltersCombo = ::GetDlgItem(_hSelf, IDD_FINDINFILES_FILTERS_COMBO); @@ -957,6 +1022,7 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM ::SetWindowTextW(::GetDlgItem(_hSelf, IDC_FINDPREV), TEXT("▲")); ::SetWindowTextW(::GetDlgItem(_hSelf, IDC_FINDNEXT), TEXT("▼ Find Next")); + return TRUE; } diff --git a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.rc b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.rc index e294972eb..d4e342e37 100644 --- a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.rc +++ b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.rc @@ -56,7 +56,7 @@ BEGIN CONTROL "Backward direction", IDC_BACKWARDDIRECTION, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 12, 76, 140, 15 CONTROL "Match &whole word only",IDWHOLEWORD,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,88,140,15 CONTROL "Match &case",IDMATCHCASE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,100,140,15 - CONTROL "Wra&p around",IDWRAP,"Button",BS_AUTOCHECKBOX | BS_MULTILINE | WS_TABSTOP,12,112,140,15 + CONTROL "Wra&p around",IDWRAP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,112,140,15 GROUPBOX "Search Mode",IDC_MODE_STATIC,6,131,159,48 CONTROL "&Normal",IDNORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,12,143,126,10 CONTROL "E&xtended (\\n, \\r, \\t, \\0, \\x...)",IDEXTENDED,