Use dpi scaled fonts for some controls

-  prepare static dialog for hiDPI

ref: #14959

Close #14947
This commit is contained in:
ozone10 2024-04-06 16:35:51 +02:00 committed by Don Ho
parent ddc080785d
commit fc52cd3f4f
10 changed files with 130 additions and 88 deletions

View File

@ -2981,77 +2981,6 @@ namespace NppDarkMode
SetWindowSubclass(hwnd, WindowNotifySubclass, g_windowNotifySubclassID, 0); SetWindowSubclass(hwnd, WindowNotifySubclass, g_windowNotifySubclassID, 0);
} }
// currently send message only to selected buttons; listbox and edit controls with scrollbars
void sendMessageToChildControls(HWND hwndParent, UINT msg, WPARAM wParam, LPARAM lParam)
{
struct WMessage
{
UINT _msg = 0;
WPARAM _wParam = 0;
LPARAM _lParam = 0;
};
struct WMessage p { msg, wParam, lParam };
::EnumChildWindows(hwndParent, [](HWND hwnd, LPARAM childLParam) WINAPI_LAMBDA->BOOL{
auto & p = *reinterpret_cast<WMessage*>(childLParam);
constexpr size_t classNameLen = 32;
TCHAR className[classNameLen]{};
::GetClassName(hwnd, className, classNameLen);
auto style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
if (wcscmp(className, WC_BUTTON) == 0)
{
switch (style & BS_TYPEMASK)
{
case BS_CHECKBOX:
case BS_AUTOCHECKBOX:
case BS_3STATE:
case BS_AUTO3STATE:
case BS_RADIOBUTTON:
case BS_AUTORADIOBUTTON:
{
if ((style & BS_PUSHLIKE) != BS_PUSHLIKE)
{
::SendMessage(hwnd, p._msg, p._wParam, p._lParam);
}
break;
}
default:
{
break;
}
}
return TRUE;
}
if (wcscmp(className, WC_EDIT) == 0)
{
bool hasScrollBar = ((style & WS_HSCROLL) == WS_HSCROLL) || ((style & WS_VSCROLL) == WS_VSCROLL);
if (hasScrollBar)
{
::SendMessage(hwnd, p._msg, p._wParam, p._lParam);
}
return TRUE;
}
if (wcscmp(className, WC_LISTBOX) == 0)
{
if ((style & LBS_COMBOBOX) != LBS_COMBOBOX)
{
bool hasScrollBar = ((style & WS_HSCROLL) == WS_HSCROLL) || ((style & WS_VSCROLL) == WS_VSCROLL);
if (hasScrollBar)
{
::SendMessage(hwnd, p._msg, p._wParam, p._lParam);
}
}
return TRUE;
}
return TRUE;
}, reinterpret_cast<LPARAM>(&p));
}
void setDarkTitleBar(HWND hwnd) void setDarkTitleBar(HWND hwnd)
{ {
constexpr DWORD win10Build2004 = 19041; constexpr DWORD win10Build2004 = 19041;

View File

@ -222,8 +222,6 @@ namespace NppDarkMode
ULONG autoSubclassAndThemePlugin(HWND hwnd, ULONG dmFlags); ULONG autoSubclassAndThemePlugin(HWND hwnd, ULONG dmFlags);
void autoSubclassAndThemeWindowNotify(HWND hwnd); void autoSubclassAndThemeWindowNotify(HWND hwnd);
void sendMessageToChildControls(HWND hwndParent, UINT msg, WPARAM wParam, LPARAM lParam);
void setDarkTitleBar(HWND hwnd); void setDarkTitleBar(HWND hwnd);
void setDarkExplorerTheme(HWND hwnd); void setDarkExplorerTheme(HWND hwnd);
void setDarkScrollBar(HWND hwnd); void setDarkScrollBar(HWND hwnd);

View File

@ -5907,7 +5907,7 @@ int Progress::createProgressWindow()
if (_hFont == nullptr) if (_hFont == nullptr)
{ {
LOGFONT lf{ NppParameters::getDefaultGUIFont() }; LOGFONT lf{ DPIManagerV2::getDefaultGUIFontForDpi(_hwnd) };
_hFont = ::CreateFontIndirect(&lf); _hFont = ::CreateFontIndirect(&lf);
} }

View File

@ -162,7 +162,7 @@ LRESULT URLCtrl::runProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam)
if (_hfUnderlined == nullptr) if (_hfUnderlined == nullptr)
{ {
// Get the default GUI font // Get the default GUI font
LOGFONT lf{ NppParameters::getDefaultGUIFont() }; LOGFONT lf{ DPIManagerV2::getDefaultGUIFontForDpi(::GetParent(hwnd)) };
lf.lfUnderline = TRUE; lf.lfUnderline = TRUE;
// Create a new font // Create a new font

View File

@ -45,10 +45,10 @@ LRESULT CALLBACK ColourStaticTextHooker::colourStaticProc(HWND hwnd, UINT Messag
} }
// Get the default GUI font // Get the default GUI font
LOGFONT lf{ NppParameters::getDefaultGUIFont() }; LOGFONT lf{ DPIManagerV2::getDefaultGUIFontForDpi(hwnd) };
HFONT hf = ::CreateFontIndirect(&lf); HFONT hf = ::CreateFontIndirect(&lf);
HANDLE hOld = SelectObject(hdc, hf); HANDLE hOld = ::SelectObject(hdc, hf);
// Draw the text! // Draw the text!
TCHAR text[MAX_PATH]{}; TCHAR text[MAX_PATH]{};
@ -136,11 +136,10 @@ intptr_t CALLBACK WordStyleDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM
_pFgColour->init(_hInst, _hSelf); _pFgColour->init(_hInst, _hSelf);
_pBgColour->init(_hInst, _hSelf); _pBgColour->init(_hInst, _hSelf);
int cpDynamicalWidth = NppParameters::getInstance()._dpiManager.scaleX(25); const int cpDynamicalSize = DPIManagerV2::scale(25);
int cpDynamicalHeight = NppParameters::getInstance()._dpiManager.scaleY(25);
move2CtrlRight(IDC_FG_STATIC, _pFgColour->getHSelf(), cpDynamicalWidth, cpDynamicalHeight); move2CtrlRight(IDC_FG_STATIC, _pFgColour->getHSelf(), cpDynamicalSize, cpDynamicalSize);
move2CtrlRight(IDC_BG_STATIC, _pBgColour->getHSelf(), cpDynamicalWidth, cpDynamicalHeight); move2CtrlRight(IDC_BG_STATIC, _pBgColour->getHSelf(), cpDynamicalSize, cpDynamicalSize);
_pFgColour->display(); _pFgColour->display();
_pBgColour->display(); _pBgColour->display();
@ -568,7 +567,7 @@ void WordStyleDlg::move2CtrlRight(int ctrlID, HWND handle2Move, int handle2MoveW
RECT rc{}; RECT rc{};
::GetWindowRect(::GetDlgItem(_hSelf, ctrlID), &rc); ::GetWindowRect(::GetDlgItem(_hSelf, ctrlID), &rc);
p.x = rc.right + NppParameters::getInstance()._dpiManager.scaleX(5); p.x = rc.right + DPIManagerV2::scale(5);
p.y = rc.top + ((rc.bottom - rc.top) / 2) - handle2MoveHeight / 2; p.y = rc.top + ((rc.bottom - rc.top) / 2) - handle2MoveHeight / 2;
::ScreenToClient(_hSelf, &p); ::ScreenToClient(_hSelf, &p);

View File

@ -18,7 +18,7 @@
#include <windows.h> #include <windows.h>
#include "StaticDialog.h" #include "StaticDialog.h"
#include "Common.h" #include "Common.h"
#include "NppDarkMode.h" //#include "NppDarkMode.h"
StaticDialog::~StaticDialog() StaticDialog::~StaticDialog()
{ {
@ -257,11 +257,22 @@ void StaticDialog::create(int dialogID, bool isRTL, bool msgDestParent)
} }
NppDarkMode::setDarkTitleBar(_hSelf); NppDarkMode::setDarkTitleBar(_hSelf);
setDpi();
// if the destination of message NPPM_MODELESSDIALOG is not its parent, then it's the grand-parent // if the destination of message NPPM_MODELESSDIALOG is not its parent, then it's the grand-parent
::SendMessage(msgDestParent ? _hParent : (::GetParent(_hParent)), NPPM_MODELESSDIALOG, MODELESSDIALOGADD, reinterpret_cast<WPARAM>(_hSelf)); ::SendMessage(msgDestParent ? _hParent : (::GetParent(_hParent)), NPPM_MODELESSDIALOG, MODELESSDIALOGADD, reinterpret_cast<WPARAM>(_hSelf));
} }
void StaticDialog::createForDpi(int dialogID, bool isRTL, bool msgDestParent, DPI_AWARENESS_CONTEXT dpiAContext)
{
const auto dpiContext = setThreadDpiAwarenessContext(dpiAContext);
create(dialogID, isRTL, msgDestParent);
if (dpiContext != NULL)
{
setThreadDpiAwarenessContext(dpiContext);
}
}
intptr_t CALLBACK StaticDialog::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) intptr_t CALLBACK StaticDialog::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
switch (message) switch (message)

View File

@ -13,7 +13,9 @@
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
#pragma once #pragma once
#include "dpiManagerV2.h"
#include "Notepad_plus_msgs.h" #include "Notepad_plus_msgs.h"
#include "Window.h" #include "Window.h"
@ -36,12 +38,13 @@ struct DLGTEMPLATEEX
// The structure has more fields but are variable length // The structure has more fields but are variable length
}; };
class StaticDialog : public Window class StaticDialog : public Window, public DPIManagerV2
{ {
public : public :
virtual ~StaticDialog(); virtual ~StaticDialog();
virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true); virtual void create(int dialogID, bool isRTL = false, bool msgDestParent = true);
virtual void createForDpi(int dialogID, bool isRTL = false, bool msgDestParent = true, DPI_AWARENESS_CONTEXT dpiAContext = DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
virtual bool isCreated() const { virtual bool isCreated() const {
return (_hSelf != nullptr); return (_hSelf != nullptr);
@ -69,6 +72,18 @@ public :
::SendDlgItemMessage(_hSelf, checkControlID, BM_SETCHECK, checkOrNot ? BST_CHECKED : BST_UNCHECKED, 0); ::SendDlgItemMessage(_hSelf, checkControlID, BM_SETCHECK, checkOrNot ? BST_CHECKED : BST_UNCHECKED, 0);
} }
void setDpi() {
DPIManagerV2::setDpi(_hSelf);
}
void setPositionDpi(LPARAM lParam) {
DPIManagerV2::setPositionDpi(lParam, _hSelf);
}
void sendDpiMsgToChildCtrls(WPARAM wParam = 0, LPARAM lParam = 0) {
DPIManagerV2::sendMessageToChildControls(_hSelf, WM_DPICHANGED, wParam, lParam);
}
void destroy() override; void destroy() override;
protected: protected:

View File

@ -65,7 +65,7 @@ struct StatusBarSubclassInfo
{ {
if (!hTheme) if (!hTheme)
{ {
hTheme = OpenThemeData(hwnd, L"Status"); hTheme = ::OpenThemeData(hwnd, VSCLASS_STATUS);
} }
return hTheme != nullptr; return hTheme != nullptr;
} }
@ -99,7 +99,7 @@ struct StatusBarSubclassInfo
constexpr UINT_PTR g_statusBarSubclassID = 42; constexpr UINT_PTR g_statusBarSubclassID = 42;
LRESULT CALLBACK StatusBarSubclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) static LRESULT CALLBACK StatusBarSubclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{ {
StatusBarSubclassInfo* pStatusBarInfo = reinterpret_cast<StatusBarSubclassInfo*>(dwRefData); StatusBarSubclassInfo* pStatusBarInfo = reinterpret_cast<StatusBarSubclassInfo*>(dwRefData);
@ -240,11 +240,17 @@ LRESULT CALLBACK StatusBarSubclass(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l
break; break;
} }
case WM_DPICHANGED:
case WM_THEMECHANGED: case WM_THEMECHANGED:
{ {
pStatusBarInfo->closeTheme(); pStatusBarInfo->closeTheme();
LOGFONT lf{ NppParameters::getDefaultGUIFont(NppParameters::DefaultFontType::status) }; LOGFONT lf{ DPIManagerV2::getDefaultGUIFontForDpi(::GetParent(hWnd), DPIManagerV2::FontType::status) };
pStatusBarInfo->setFont(::CreateFontIndirect(&lf)); pStatusBarInfo->setFont(::CreateFontIndirect(&lf));
if (uMsg == WM_DPICHANGED)
{
return 0;
}
break; break;
} }
} }
@ -269,7 +275,7 @@ void StatusBar::init(HINSTANCE hInst, HWND hPere, int nbParts)
if (!_hSelf) if (!_hSelf)
throw std::runtime_error("StatusBar::init : CreateWindowEx() function return null"); throw std::runtime_error("StatusBar::init : CreateWindowEx() function return null");
LOGFONT lf{ NppParameters::getDefaultGUIFont(NppParameters::DefaultFontType::status) }; LOGFONT lf{ DPIManagerV2::getDefaultGUIFontForDpi(_hParent, DPIManagerV2::FontType::status) };
StatusBarSubclassInfo* pStatusBarInfo = new StatusBarSubclassInfo(::CreateFontIndirect(&lf)); StatusBarSubclassInfo* pStatusBarInfo = new StatusBarSubclassInfo(::CreateFontIndirect(&lf));
_pStatusBarInfo = pStatusBarInfo; _pStatusBarInfo = pStatusBarInfo;

View File

@ -17,6 +17,17 @@
#include "dpiManagerV2.h" #include "dpiManagerV2.h"
#include <CommCtrl.h>
#if defined(__GNUC__) && __GNUC__ > 8
#define WINAPI_LAMBDA_RETURN(return_t) -> return_t WINAPI
#elif defined(__GNUC__)
#define WINAPI_LAMBDA_RETURN(return_t) WINAPI -> return_t
#else
#define WINAPI_LAMBDA_RETURN(return_t) -> return_t
#endif
template <typename P> template <typename P>
bool ptrFn(HMODULE handle, P& pointer, const char* name) bool ptrFn(HMODULE handle, P& pointer, const char* name)
{ {
@ -182,3 +193,74 @@ LOGFONT DPIManagerV2::getDefaultGUIFontForDpi(UINT dpi, FontType type)
return lf; return lf;
} }
// currently send message only to selected buttons; listbox and edit controls with scrollbars
void DPIManagerV2::sendMessageToChildControls(HWND hwndParent, UINT msg, WPARAM wParam, LPARAM lParam)
{
struct WMessage
{
UINT _msg = 0;
WPARAM _wParam = 0;
LPARAM _lParam = 0;
};
struct WMessage p { msg, wParam, lParam };
::EnumChildWindows(hwndParent, [](HWND hwnd, LPARAM childLParam) WINAPI_LAMBDA_RETURN(BOOL) {
auto & p = *reinterpret_cast<WMessage*>(childLParam);
constexpr size_t classNameLen = 32;
TCHAR className[classNameLen]{};
::GetClassName(hwnd, className, classNameLen);
auto style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
if (wcscmp(className, WC_BUTTON) == 0)
{
switch (style & BS_TYPEMASK)
{
case BS_CHECKBOX:
case BS_AUTOCHECKBOX:
case BS_3STATE:
case BS_AUTO3STATE:
case BS_RADIOBUTTON:
case BS_AUTORADIOBUTTON:
{
if ((style & BS_PUSHLIKE) != BS_PUSHLIKE)
{
::SendMessage(hwnd, p._msg, p._wParam, p._lParam);
}
break;
}
default:
{
break;
}
}
return TRUE;
}
if (wcscmp(className, WC_EDIT) == 0)
{
bool hasScrollBar = ((style & WS_HSCROLL) == WS_HSCROLL) || ((style & WS_VSCROLL) == WS_VSCROLL);
if (hasScrollBar)
{
::SendMessage(hwnd, p._msg, p._wParam, p._lParam);
}
return TRUE;
}
if (wcscmp(className, WC_LISTBOX) == 0)
{
if ((style & LBS_COMBOBOX) != LBS_COMBOBOX)
{
bool hasScrollBar = ((style & WS_HSCROLL) == WS_HSCROLL) || ((style & WS_VSCROLL) == WS_VSCROLL);
if (hasScrollBar)
{
::SendMessage(hwnd, p._msg, p._wParam, p._lParam);
}
}
return TRUE;
}
return TRUE;
}, reinterpret_cast<LPARAM>(&p));
}

View File

@ -115,6 +115,8 @@ public:
return getDefaultGUIFontForDpi(getDpiForWindow(hWnd), type); return getDefaultGUIFontForDpi(getDpiForWindow(hWnd), type);
} }
static void sendMessageToChildControls(HWND hwndParent, UINT msg, WPARAM wParam, LPARAM lParam);
private: private:
UINT _dpi = USER_DEFAULT_SCREEN_DPI; UINT _dpi = USER_DEFAULT_SCREEN_DPI;
}; };