Enhance combobox & edit field in dark mode
1. Allow function list search to use dark mode error background. 2. Make combobox more dark and allow to use custom colors (borders, arrow head and background). 3. Use dark listbox in combobox. Fix #10178, close #10179pull/10199/head
parent
aa69711d4c
commit
81b21aae2a
|
@ -1,4 +1,4 @@
|
|||
#include "nppDarkMode.h"
|
||||
#include "nppDarkMode.h"
|
||||
|
||||
#include "DarkMode/DarkMode.h"
|
||||
#include "DarkMode/UAHMenuBar.h"
|
||||
|
@ -117,7 +117,6 @@ namespace NppDarkMode
|
|||
HEXRGB(0x809080) // edgeColor
|
||||
};
|
||||
|
||||
|
||||
// blue tone
|
||||
static const Colors darkBlueColors{
|
||||
HEXRGB(0x202040), // background
|
||||
|
@ -1223,6 +1222,109 @@ namespace NppDarkMode
|
|||
SetWindowSubclass(hwnd, TabSubclass, g_tabSubclassID, 0);
|
||||
}
|
||||
|
||||
constexpr UINT_PTR g_comboBoxSubclassID = 42;
|
||||
|
||||
LRESULT CALLBACK ComboBoxSubclass(
|
||||
HWND hWnd,
|
||||
UINT uMsg,
|
||||
WPARAM wParam,
|
||||
LPARAM lParam,
|
||||
UINT_PTR uIdSubclass,
|
||||
DWORD_PTR /*dwRefData*/
|
||||
)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_PAINT:
|
||||
{
|
||||
if (!NppDarkMode::isEnabled())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
RECT rc = { 0 };
|
||||
::GetClientRect(hWnd, &rc);
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
auto hdc = ::BeginPaint(hWnd, &ps);
|
||||
|
||||
auto holdPen = static_cast<HPEN>(::SelectObject(hdc, NppDarkMode::getEdgePen()));
|
||||
::SelectObject(hdc, reinterpret_cast<HFONT>(::SendMessage(hWnd, WM_GETFONT, 0, 0)));
|
||||
::SetBkColor(hdc, NppDarkMode::getBackgroundColor());
|
||||
|
||||
::SelectObject(hdc, ::GetStockObject(NULL_BRUSH)); // to avoid text flicker, use only border
|
||||
::Rectangle(hdc, 0, 0, rc.right, rc.bottom);
|
||||
|
||||
auto holdBrush = ::SelectObject(hdc, NppDarkMode::getBackgroundBrush());
|
||||
|
||||
// CBS_DROPDOWN text is handled by parent by WM_CTLCOLOREDIT
|
||||
auto style = ::GetWindowLongPtr(hWnd, GWL_STYLE);
|
||||
if ((style & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST)
|
||||
{
|
||||
auto index = static_cast<int>(::SendMessage(hWnd, CB_GETCURSEL, 0, 0));
|
||||
if (index != CB_ERR)
|
||||
{
|
||||
::SetTextColor(hdc, NppDarkMode::getTextColor());
|
||||
auto bufferLen = static_cast<size_t>(::SendMessage(hWnd, CB_GETLBTEXTLEN, index, 0));
|
||||
TCHAR* buffer = new TCHAR[(bufferLen + 1)];
|
||||
::SendMessage(hWnd, CB_GETLBTEXT, index, reinterpret_cast<LPARAM>(buffer));
|
||||
RECT textRc = rc;
|
||||
textRc.left += NppParameters::getInstance()._dpiManager.scaleX(4);
|
||||
textRc.right -= NppParameters::getInstance()._dpiManager.scaleX(23);
|
||||
::DrawText(hdc, buffer, -1, &textRc, DT_EDITCONTROL | DT_NOPREFIX | DT_LEFT | DT_VCENTER | DT_SINGLELINE);
|
||||
delete[]buffer;
|
||||
}
|
||||
}
|
||||
|
||||
RECT arrowRc = {
|
||||
rc.right - NppParameters::getInstance()._dpiManager.scaleX(17), rc.top + 1,
|
||||
rc.right - 1, rc.bottom - 1
|
||||
};
|
||||
|
||||
POINT ptCursor = { 0 };
|
||||
::GetCursorPos(&ptCursor);
|
||||
ScreenToClient(hWnd, &ptCursor);
|
||||
|
||||
bool isHot = PtInRect(&rc, ptCursor);
|
||||
|
||||
::SetTextColor(hdc, isHot ? NppDarkMode::getTextColor() : NppDarkMode::getDarkerTextColor());
|
||||
::SetBkColor(hdc, isHot ? NppDarkMode::getHotBackgroundColor() : NppDarkMode::getBackgroundColor());
|
||||
::ExtTextOut(hdc,
|
||||
rc.right - NppParameters::getInstance()._dpiManager.scaleX(13),
|
||||
rc.top + 4,
|
||||
ETO_OPAQUE | ETO_CLIPPED,
|
||||
&arrowRc, L"˅",
|
||||
1,
|
||||
nullptr);
|
||||
::SetBkColor(hdc, NppDarkMode::getBackgroundColor());
|
||||
|
||||
POINT edge[] = {
|
||||
{rc.right - NppParameters::getInstance()._dpiManager.scaleX(18), rc.top + 1},
|
||||
{rc.right - NppParameters::getInstance()._dpiManager.scaleX(18), rc.bottom - 1}
|
||||
};
|
||||
::Polyline(hdc, edge, _countof(edge));
|
||||
|
||||
::SelectObject(hdc, holdPen);
|
||||
::SelectObject(hdc, holdBrush);
|
||||
|
||||
::EndPaint(hWnd, &ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_NCDESTROY:
|
||||
{
|
||||
::RemoveWindowSubclass(hWnd, ComboBoxSubclass, uIdSubclass);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DefSubclassProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
void subclassComboBoxControl(HWND hwnd)
|
||||
{
|
||||
SetWindowSubclass(hwnd, ComboBoxSubclass, g_comboBoxSubclassID, 0);
|
||||
}
|
||||
|
||||
void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass, bool theme)
|
||||
{
|
||||
struct Params
|
||||
|
@ -1233,20 +1335,31 @@ namespace NppDarkMode
|
|||
};
|
||||
|
||||
Params p{
|
||||
NppDarkMode::isEnabled() ? L"DarkMode_Explorer" : L"Button"
|
||||
NppDarkMode::isEnabled() ? L"DarkMode_Explorer" : nullptr
|
||||
, subclass
|
||||
, theme
|
||||
};
|
||||
|
||||
EnumChildWindows(hwndParent, [](HWND hwnd, LPARAM lParam) {
|
||||
auto& p = *reinterpret_cast<Params*>(lParam);
|
||||
wchar_t className[16] = { 0 };
|
||||
GetClassName(hwnd, className, 9);
|
||||
if (wcscmp(className, L"Button"))
|
||||
const size_t classNameLen = 16;
|
||||
TCHAR className[classNameLen] = { 0 };
|
||||
GetClassName(hwnd, className, classNameLen);
|
||||
|
||||
if (wcscmp(className, WC_COMBOBOX) == 0)
|
||||
{
|
||||
auto style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
|
||||
|
||||
if ((style & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST || (style & CBS_DROPDOWN) == CBS_DROPDOWN)
|
||||
{
|
||||
NppDarkMode::subclassComboBoxControl(hwnd);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
DWORD nButtonStyle = (DWORD)GetWindowLong(hwnd, GWL_STYLE) & 0xF;
|
||||
|
||||
if (wcscmp(className, WC_BUTTON) == 0)
|
||||
{
|
||||
auto nButtonStyle = ::GetWindowLongPtr(hwnd, GWL_STYLE) & 0xF;
|
||||
switch (nButtonStyle)
|
||||
{
|
||||
case BS_CHECKBOX:
|
||||
|
@ -1273,6 +1386,8 @@ namespace NppDarkMode
|
|||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
return TRUE;
|
||||
}, reinterpret_cast<LPARAM>(&p));
|
||||
}
|
||||
|
||||
|
@ -1381,4 +1496,25 @@ namespace NppDarkMode
|
|||
{
|
||||
SetWindowTheme(hwnd, nullptr, nullptr);
|
||||
}
|
||||
|
||||
LRESULT onCtlColor(HDC hdc)
|
||||
{
|
||||
::SetTextColor(hdc, NppDarkMode::getTextColor());
|
||||
::SetBkColor(hdc, NppDarkMode::getBackgroundColor());
|
||||
return reinterpret_cast<LRESULT>(NppDarkMode::getBackgroundBrush());
|
||||
}
|
||||
|
||||
LRESULT onCtlColorSofter(HDC hdc)
|
||||
{
|
||||
::SetTextColor(hdc, NppDarkMode::getTextColor());
|
||||
::SetBkColor(hdc, NppDarkMode::getSofterBackgroundColor());
|
||||
return reinterpret_cast<LRESULT>(NppDarkMode::getSofterBackgroundBrush());
|
||||
}
|
||||
|
||||
LRESULT onCtlColorError(HDC hdc)
|
||||
{
|
||||
::SetTextColor(hdc, NppDarkMode::getTextColor());
|
||||
::SetBkColor(hdc, NppDarkMode::getErrorBackgroundColor());
|
||||
return reinterpret_cast<LRESULT>(NppDarkMode::getErrorBackgroundBrush());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,6 +118,7 @@ namespace NppDarkMode
|
|||
void subclassGroupboxControl(HWND hwnd);
|
||||
void subclassToolbarControl(HWND hwnd);
|
||||
void subclassTabControl(HWND hwnd);
|
||||
void subclassComboBoxControl(HWND hwnd);
|
||||
|
||||
void autoSubclassAndThemeChildControls(HWND hwndParent, bool subclass = true, bool theme = true);
|
||||
void autoThemeChildControls(HWND hwndParent);
|
||||
|
@ -131,4 +132,8 @@ namespace NppDarkMode
|
|||
|
||||
void disableVisualStyle(HWND hwnd, bool doDisable);
|
||||
void setTreeViewStyle(HWND hwnd);
|
||||
|
||||
LRESULT onCtlColor(HDC hdc);
|
||||
LRESULT onCtlColorSofter(HDC hdc);
|
||||
LRESULT onCtlColorError(HDC hdc);
|
||||
}
|
||||
|
|
|
@ -850,31 +850,45 @@ INT_PTR CALLBACK FindReplaceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM
|
|||
}
|
||||
|
||||
case WM_CTLCOLOREDIT:
|
||||
case WM_CTLCOLORDLG:
|
||||
case WM_CTLCOLORSTATIC:
|
||||
{
|
||||
if (!NppDarkMode::isEnabled())
|
||||
if (NppDarkMode::isEnabled())
|
||||
{
|
||||
return NppDarkMode::onCtlColorSofter(reinterpret_cast<HDC>(wParam));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
SetTextColor((HDC)wParam, NppDarkMode::getTextColor());
|
||||
SetBkColor((HDC)wParam, NppDarkMode::getBackgroundColor());
|
||||
return (LRESULT)NppDarkMode::getBackgroundBrush();
|
||||
case WM_CTLCOLORDLG:
|
||||
case WM_CTLCOLORSTATIC:
|
||||
case WM_CTLCOLORLISTBOX:
|
||||
{
|
||||
if (NppDarkMode::isEnabled())
|
||||
{
|
||||
return NppDarkMode::onCtlColor(reinterpret_cast<HDC>(wParam));
|
||||
}
|
||||
case WM_PRINTCLIENT:
|
||||
case WM_ERASEBKGND:
|
||||
{
|
||||
if (!NppDarkMode::isEnabled())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_PRINTCLIENT:
|
||||
{
|
||||
if (NppDarkMode::isEnabled())
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_ERASEBKGND:
|
||||
{
|
||||
if (NppDarkMode::isEnabled())
|
||||
{
|
||||
RECT rc = { 0 };
|
||||
getClientRect(rc);
|
||||
FillRect((HDC)wParam, &rc, NppDarkMode::getBackgroundBrush());
|
||||
SetWindowLongPtr(_hSelf, DWLP_MSGRESULT, TRUE);
|
||||
FillRect(reinterpret_cast<HDC>(wParam), &rc, NppDarkMode::getBackgroundBrush());
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case NPPM_INTERNAL_REFRESHDARKMODE:
|
||||
{
|
||||
|
@ -4442,19 +4456,17 @@ INT_PTR CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
|
|||
// Make edit field red if not found
|
||||
case WM_CTLCOLOREDIT :
|
||||
{
|
||||
auto hdc = reinterpret_cast<HDC>(wParam);
|
||||
|
||||
if (NppDarkMode::isEnabled())
|
||||
{
|
||||
if (FSNotFound != getFindStatus())
|
||||
{
|
||||
SetTextColor((HDC)wParam, NppDarkMode::getTextColor());
|
||||
SetBkColor((HDC)wParam, NppDarkMode::getBackgroundColor());
|
||||
return (LRESULT)NppDarkMode::getBackgroundBrush();
|
||||
return NppDarkMode::onCtlColorSofter(hdc);
|
||||
}
|
||||
else // text not found
|
||||
{
|
||||
SetTextColor((HDC)wParam, NppDarkMode::getTextColor());
|
||||
SetBkColor((HDC)wParam, NppDarkMode::getErrorBackgroundColor());
|
||||
return (LRESULT)NppDarkMode::getErrorBackgroundBrush();
|
||||
return NppDarkMode::onCtlColorError(hdc);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4465,9 +4477,9 @@ INT_PTR CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
|
|||
return FALSE; // text found, use the default color
|
||||
|
||||
// text not found
|
||||
SetTextColor((HDC)wParam, TXT_COLOR);
|
||||
SetBkColor((HDC)wParam, BCKGRD_COLOR);
|
||||
return (LRESULT)hBrushBackground;
|
||||
SetTextColor(hdc, TXT_COLOR);
|
||||
SetBkColor(hdc, BCKGRD_COLOR);
|
||||
return reinterpret_cast<LRESULT>(hBrushBackground);
|
||||
}
|
||||
|
||||
case WM_CTLCOLORDLG:
|
||||
|
@ -4478,9 +4490,7 @@ INT_PTR CALLBACK FindIncrementDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR
|
|||
return DefWindowProc(getHSelf(), message, wParam, lParam);
|
||||
}
|
||||
|
||||
SetTextColor((HDC)wParam, NppDarkMode::getTextColor());
|
||||
SetBkColor((HDC)wParam, NppDarkMode::getBackgroundColor());
|
||||
return (LRESULT)NppDarkMode::getBackgroundBrush();
|
||||
return NppDarkMode::onCtlColor(reinterpret_cast<HDC>(wParam));
|
||||
}
|
||||
|
||||
case NPPM_INTERNAL_REFRESHDARKMODE:
|
||||
|
|
|
@ -769,24 +769,31 @@ INT_PTR CALLBACK FunctionListPanel::run_dlgProc(UINT message, WPARAM wParam, LPA
|
|||
}
|
||||
}
|
||||
|
||||
if (textFound)
|
||||
{
|
||||
auto hdc = reinterpret_cast<HDC>(wParam);
|
||||
|
||||
if (NppDarkMode::isEnabled())
|
||||
{
|
||||
SetTextColor((HDC)wParam, NppDarkMode::getTextColor());
|
||||
SetBkColor((HDC)wParam, NppDarkMode::getBackgroundColor());
|
||||
return (LRESULT)NppDarkMode::getBackgroundBrush();
|
||||
if (textFound)
|
||||
{
|
||||
return NppDarkMode::onCtlColorSofter(hdc);
|
||||
}
|
||||
else
|
||||
else // text not found
|
||||
{
|
||||
return NppDarkMode::onCtlColorError(hdc);
|
||||
}
|
||||
}
|
||||
|
||||
if (textFound)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// text not found
|
||||
// if the text not found modify the background color of the editor
|
||||
static HBRUSH hBrushBackground = CreateSolidBrush(BCKGRD_COLOR);
|
||||
SetTextColor((HDC)wParam, TXT_COLOR);
|
||||
SetBkColor((HDC)wParam, BCKGRD_COLOR);
|
||||
return (LRESULT)hBrushBackground;
|
||||
SetTextColor(hdc, TXT_COLOR);
|
||||
SetBkColor(hdc, BCKGRD_COLOR);
|
||||
return reinterpret_cast<LRESULT>(hBrushBackground);
|
||||
}
|
||||
|
||||
case WM_INITDIALOG :
|
||||
|
|
Loading…
Reference in New Issue