Add dark mode in find/replace dialog

Dark Mode find/replace dialog box! Also supporting buffered paint animation for darkmode checkbox/radiobutton control states

Close #9800
This commit is contained in:
Adam D. Walling 2021-04-23 17:41:11 -04:00 committed by Don HO
parent 0dbdef320f
commit bd6dbd4bb6
5 changed files with 536 additions and 139 deletions

View File

@ -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()

View File

@ -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<DWORD>(SendMessage(hwnd, BM_GETSTATE, 0, 0));
bool isEnabled = IsWindowEnabled(hwnd);;
DWORD uiState = static_cast<DWORD>(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<DWORD>(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<HFONT>(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<int>(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<ButtonData*>(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<HDC>(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<DWORD_PTR>(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<HFONT>(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<LPARAM>(&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);
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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,