Add message NPPM_DARKMODESUBCLASSANDTHEME
to allow plugin authors to use generic dark mode. Unfortunately not for C# plugins. related #13572 Fix #13574, close #13596
This commit is contained in:
parent
b88456764b
commit
e7f321f21a
|
@ -45,7 +45,7 @@ CPP_DEFINE := UNICODE _UNICODE OEMRESOURCE NOMINMAX _WIN32_WINNT=_WIN32_WINNT_VI
|
|||
LD := $(CXX)
|
||||
LDFLAGS := -municode -mwindows
|
||||
LD_PATH :=
|
||||
LD_LINK := comctl32 crypt32 dbghelp ole32 sensapi shlwapi uuid uxtheme version wininet wintrust
|
||||
LD_LINK := comctl32 crypt32 dbghelp ole32 sensapi shlwapi uuid uxtheme version wininet wintrust dwmapi
|
||||
LD_LINK += $(patsubst lib%.a,%,$(SCINTILLA_TARGET)) $(patsubst lib%.a,%,$(LEXILLA_TARGET)) imm32 msimg32 ole32 oleaut32
|
||||
SUBMAKEFLAGS := -O --no-print-directory
|
||||
|
||||
|
|
|
@ -380,7 +380,7 @@ SET(rcFiles
|
|||
|
||||
IF (WIN32)
|
||||
SET(option WIN32)
|
||||
SET(win32_LIBRARIES comctl32 shlwapi dbghelp version crypt32 wintrust sensapi wininet imm32 msimg32 uxtheme)
|
||||
SET(win32_LIBRARIES comctl32 shlwapi dbghelp version crypt32 wintrust sensapi wininet imm32 msimg32 uxtheme dwmapi)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
if ( MSVC )
|
||||
#do not use for mingw builds
|
||||
|
|
|
@ -271,6 +271,11 @@ bool IsWindows11() // or later OS version
|
|||
return (g_buildNumber >= 22000);
|
||||
}
|
||||
|
||||
const DWORD GetWindowsBuildNumber()
|
||||
{
|
||||
return g_buildNumber;
|
||||
}
|
||||
|
||||
void InitDarkMode()
|
||||
{
|
||||
fnRtlGetNtVersionNumbers RtlGetNtVersionNumbers = nullptr;
|
||||
|
|
|
@ -17,3 +17,4 @@ void InitDarkMode();
|
|||
void SetDarkMode(bool useDarkMode, bool fixDarkScrollbar);
|
||||
bool IsWindows10();
|
||||
bool IsWindows11();
|
||||
const DWORD GetWindowsBuildNumber();
|
||||
|
|
|
@ -549,6 +549,47 @@ enum Platform { PF_UNKNOWN, PF_X86, PF_X64, PF_IA64, PF_ARM64 };
|
|||
// void* NPPM_GETBOOKMARKID(0, 0)
|
||||
// Returns the bookmark ID
|
||||
|
||||
#define NPPM_DARKMODESUBCLASSANDTHEME (NPPMSG + 112)
|
||||
// ULONG NPPM_DARKMODESUBCLASSANDTHEME(ULONG dmFlags, HWND hwnd)
|
||||
// Add support for generic dark mode.
|
||||
//
|
||||
// Docking panels don't need to call NPPM_DARKMODESUBCLASSANDTHEME for main hwnd.
|
||||
// Subclassing is applied automatically unless DWS_USEOWNDARKMODE flag is used.
|
||||
//
|
||||
// Might not work properly in C# plugins.
|
||||
//
|
||||
// Returns succesful combinations of flags.
|
||||
//
|
||||
|
||||
namespace NppDarkMode
|
||||
{
|
||||
// Standard flags for main parent after its children are initialized.
|
||||
constexpr ULONG dmfInit = 0x0000000BUL;
|
||||
|
||||
// Standard flags for main parent usually used in NPPN_DARKMODECHANGED.
|
||||
constexpr ULONG dmfHandleChange = 0x0000000CUL;
|
||||
};
|
||||
|
||||
// Examples:
|
||||
//
|
||||
// - after controls initializations in WM_INITDIALOG, in WM_CREATE or after CreateWindow:
|
||||
//
|
||||
//auto success = static_cast<ULONG>(::SendMessage(nppData._nppHandle, NPPM_DARKMODESUBCLASSANDTHEME, static_cast<WPARAM>(NppDarkMode::dmfInit), reinterpret_cast<LPARAM>(mainHwnd)));
|
||||
//
|
||||
// - handling dark mode change:
|
||||
//
|
||||
//extern "C" __declspec(dllexport) void beNotified(SCNotification * notifyCode)
|
||||
//{
|
||||
// switch (notifyCode->nmhdr.code)
|
||||
// {
|
||||
// case NPPN_DARKMODECHANGED:
|
||||
// {
|
||||
// ::SendMessage(nppData._nppHandle, NPPM_DARKMODESUBCLASSANDTHEME, static_cast<WPARAM>(dmfHandleChange), reinterpret_cast<LPARAM>(mainHwnd));
|
||||
// ::SetWindowPos(mainHwnd, nullptr, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); // to redraw titlebar and window
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
// For RUNCOMMAND_USER
|
||||
|
|
|
@ -3110,6 +3110,11 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
|
|||
return static_cast<LRESULT>(false);
|
||||
}
|
||||
|
||||
case NPPM_DARKMODESUBCLASSANDTHEME:
|
||||
{
|
||||
return static_cast<LRESULT>(NppDarkMode::autoSubclassAndThemePlugin(reinterpret_cast<HWND>(lParam), static_cast<ULONG>(wParam)));
|
||||
}
|
||||
|
||||
case NPPM_DOCLISTDISABLEPATHCOLUMN:
|
||||
case NPPM_DOCLISTDISABLEEXTCOLUMN:
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "DarkMode/DarkMode.h"
|
||||
#include "DarkMode/UAHMenuBar.h"
|
||||
|
||||
#include <dwmapi.h>
|
||||
#include <uxtheme.h>
|
||||
#include <vssym32.h>
|
||||
|
||||
|
@ -33,6 +34,9 @@
|
|||
#ifdef __GNUC__
|
||||
#include <cmath>
|
||||
#define WINAPI_LAMBDA WINAPI
|
||||
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
||||
#endif
|
||||
#else
|
||||
#define WINAPI_LAMBDA
|
||||
#endif
|
||||
|
@ -40,6 +44,7 @@
|
|||
// already added in project files
|
||||
// keep for plugin authors
|
||||
//#ifdef _MSC_VER
|
||||
//#pragma comment(lib, "dwmapi.lib")
|
||||
//#pragma comment(lib, "uxtheme.lib")
|
||||
//#endif
|
||||
|
||||
|
@ -548,6 +553,11 @@ namespace NppDarkMode
|
|||
return IsWindows11();
|
||||
}
|
||||
|
||||
const DWORD getWindowsBuildNumber()
|
||||
{
|
||||
return GetWindowsBuildNumber();
|
||||
}
|
||||
|
||||
COLORREF invertLightness(COLORREF c)
|
||||
{
|
||||
WORD h = 0;
|
||||
|
@ -2511,16 +2521,15 @@ namespace NppDarkMode
|
|||
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
auto nmhdr = reinterpret_cast<LPNMHDR>(lParam);
|
||||
|
||||
constexpr size_t classNameLen = 16;
|
||||
TCHAR className[classNameLen]{};
|
||||
GetClassName(nmhdr->hwndFrom, className, classNameLen);
|
||||
|
||||
const auto nmhdr = reinterpret_cast<LPNMHDR>(lParam);
|
||||
switch (nmhdr->code)
|
||||
{
|
||||
case NM_CUSTOMDRAW:
|
||||
{
|
||||
constexpr size_t classNameLen = 16;
|
||||
TCHAR className[classNameLen]{};
|
||||
GetClassName(nmhdr->hwndFrom, className, classNameLen);
|
||||
|
||||
if (wcscmp(className, TOOLBARCLASSNAME) == 0)
|
||||
{
|
||||
return NppDarkMode::darkToolBarNotifyCustomDraw(lParam);
|
||||
|
@ -2550,6 +2559,97 @@ namespace NppDarkMode
|
|||
NppDarkMode::autoSubclassAndThemeChildControls(hwnd, true, g_isAtLeastWindows10);
|
||||
}
|
||||
|
||||
ULONG autoSubclassAndThemePlugin(HWND hwnd, ULONG dmFlags)
|
||||
{
|
||||
// Used on parent of edit, listbox, static text, treeview, listview and toolbar controls.
|
||||
// Should be used only one time on parent control after its creation
|
||||
// even when starting in light mode.
|
||||
// e.g. in WM_INITDIALOG, in WM_CREATE or after CreateWindow.
|
||||
constexpr ULONG dmfSubclassParent = 0x00000001UL;
|
||||
// Should be used only one time on main control/window after initializations of all its children controls
|
||||
// even when starting in light mode.
|
||||
// Will also use dmfSetThemeChildren flag.
|
||||
// e.g. in WM_INITDIALOG, in WM_CREATE or after CreateWindow.
|
||||
constexpr ULONG dmfSubclassChildren = 0x00000002UL;
|
||||
// Will apply theme on buttons with style:
|
||||
// BS_PUSHLIKE, BS_PUSHBUTTON, BS_DEFPUSHBUTTON, BS_SPLITBUTTON or BS_DEFSPLITBUTTON.
|
||||
// Will apply theme for scrollbars on edit, listbox and rich edit controls.
|
||||
// Will apply theme for tooltips on listview, treeview and toolbar buttons.
|
||||
// Should be handled after controls initializations and in NPPN_DARKMODECHANGED.
|
||||
// Requires at least Windows 10 to work properly.
|
||||
constexpr ULONG dmfSetThemeChildren = 0x00000004UL;
|
||||
// Set dark title bar.
|
||||
// Should be handled after controls initializations and in NPPN_DARKMODECHANGED.
|
||||
// Requires at least Windows 10 and WS_CAPTION style to work properly.
|
||||
constexpr ULONG dmfSetTitleBar = 0x00000008UL;
|
||||
// Will apply dark explorer theme.
|
||||
// Used mainly for scrollbars and tooltips not handled with dmfSetThemeChildren.
|
||||
// Might also change style for other elements.
|
||||
// Should be handled after controls initializations and in NPPN_DARKMODECHANGED.
|
||||
// Requires at least Windows 10 to work properly.
|
||||
constexpr ULONG dmfSetThemeDirectly = 0x00000010UL;
|
||||
|
||||
// defined in Notepad_plus_msgs.h
|
||||
//constexpr ULONG dmfInit = dmfSubclassParent | dmfSubclassChildren | dmfSetTitleBar; // 0x000000BUL
|
||||
//constexpr ULONG dmfHandleChange = dmfSetThemeChildren | dmfSetTitleBar; // 0x000000CUL
|
||||
|
||||
constexpr ULONG dmfRequiredMask = dmfSubclassParent | dmfSubclassChildren | dmfSetThemeChildren | dmfSetTitleBar | dmfSetThemeDirectly;
|
||||
//constexpr ULONG dmfAllMask = dmfSubclassParent | dmfSubclassChildren | dmfSetThemeChildren | dmfSetTitleBar | dmfSetThemeDirectly;
|
||||
|
||||
if (hwnd == nullptr || (dmFlags & dmfRequiredMask) == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
auto dmfBitwiseCheck = [dmFlags](ULONG flag) -> bool {
|
||||
return (dmFlags & flag) == flag;
|
||||
};
|
||||
|
||||
ULONG result = 0UL;
|
||||
|
||||
if (dmfBitwiseCheck(dmfSubclassParent))
|
||||
{
|
||||
const bool success = ::SetWindowSubclass(hwnd, PluginDockWindowSubclass, g_pluginDockWindowSubclassID, 0) == TRUE;
|
||||
if (success)
|
||||
{
|
||||
result |= dmfSubclassParent;
|
||||
}
|
||||
}
|
||||
|
||||
const bool subclassChildren = dmfBitwiseCheck(dmfSubclassChildren);
|
||||
if (dmfBitwiseCheck(dmfSetThemeChildren) || subclassChildren)
|
||||
{
|
||||
NppDarkMode::autoSubclassAndThemeChildControls(hwnd, subclassChildren, g_isAtLeastWindows10);
|
||||
result |= dmfSetThemeChildren;
|
||||
|
||||
if (subclassChildren)
|
||||
{
|
||||
result |= dmfSubclassChildren;
|
||||
}
|
||||
}
|
||||
|
||||
if (dmfBitwiseCheck(dmfSetTitleBar))
|
||||
{
|
||||
const auto style = ::GetWindowLongPtr(hwnd, GWL_STYLE);
|
||||
if (NppDarkMode::isExperimentalSupported() && ((style & WS_CAPTION) == WS_CAPTION))
|
||||
{
|
||||
NppDarkMode::setDarkTitleBar(hwnd);
|
||||
result |= dmfSetTitleBar;
|
||||
}
|
||||
}
|
||||
|
||||
if (dmfBitwiseCheck(dmfSetThemeDirectly))
|
||||
{
|
||||
if (NppDarkMode::isWindows10())
|
||||
{
|
||||
NppDarkMode::setDarkExplorerTheme(hwnd);
|
||||
result |= dmfSetThemeDirectly;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr UINT_PTR g_windowNotifySubclassID = 42;
|
||||
|
||||
LRESULT CALLBACK WindowNotifySubclass(
|
||||
|
@ -2760,8 +2860,17 @@ namespace NppDarkMode
|
|||
|
||||
void setDarkTitleBar(HWND hwnd)
|
||||
{
|
||||
NppDarkMode::allowDarkModeForWindow(hwnd, NppDarkMode::isEnabled());
|
||||
NppDarkMode::setTitleBarThemeColor(hwnd);
|
||||
constexpr DWORD win10Build2004 = 19041;
|
||||
if (NppDarkMode::getWindowsBuildNumber() >= win10Build2004)
|
||||
{
|
||||
BOOL value = NppDarkMode::isEnabled() ? TRUE : FALSE;
|
||||
::DwmSetWindowAttribute(hwnd, DWMWA_USE_IMMERSIVE_DARK_MODE, &value, sizeof(value));
|
||||
}
|
||||
else
|
||||
{
|
||||
NppDarkMode::allowDarkModeForWindow(hwnd, NppDarkMode::isEnabled());
|
||||
NppDarkMode::setTitleBarThemeColor(hwnd);
|
||||
}
|
||||
}
|
||||
|
||||
void setDarkExplorerTheme(HWND hwnd)
|
||||
|
|
|
@ -119,6 +119,7 @@ namespace NppDarkMode
|
|||
|
||||
bool isWindows10();
|
||||
bool isWindows11();
|
||||
const DWORD getWindowsBuildNumber();
|
||||
|
||||
COLORREF invertLightness(COLORREF c);
|
||||
COLORREF invertLightnessSofter(COLORREF c);
|
||||
|
@ -216,6 +217,7 @@ namespace NppDarkMode
|
|||
LRESULT darkTreeViewNotifyCustomDraw(LPARAM lParam);
|
||||
|
||||
void autoSubclassAndThemePluginDockWindow(HWND hwnd);
|
||||
ULONG autoSubclassAndThemePlugin(HWND hwnd, ULONG dmFlags);
|
||||
void autoSubclassAndThemeWindowNotify(HWND hwnd);
|
||||
|
||||
bool subclassTabUpDownControl(HWND hwnd);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
|
||||
intptr_t CALLBACK GoToLineDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM)
|
||||
{
|
||||
switch (message)
|
||||
switch (message)
|
||||
{
|
||||
case WM_INITDIALOG :
|
||||
{
|
||||
|
@ -135,6 +135,7 @@ intptr_t CALLBACK GoToLineDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM)
|
|||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
default :
|
||||
|
|
|
@ -294,7 +294,7 @@ bool FunctionListPanel::serialize(const generic_string & outputFilename)
|
|||
|
||||
for (auto & i : j[nodesLabel])
|
||||
{
|
||||
if (nodeName == i[nameLabel])
|
||||
if (nodeName == std::string{ i[nameLabel] })
|
||||
{
|
||||
i[leavesLabel].push_back(leafName.c_str());
|
||||
isFound = true;
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<AnalyzeExternalRuleset>NativeRecommendedRules.ruleset</AnalyzeExternalRuleset>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>comctl32.lib;shlwapi.lib;shell32.lib;Dbghelp.lib;Version.lib;Crypt32.lib;wintrust.lib;Sensapi.lib;wininet.lib;imm32.lib;msimg32.lib;uxtheme.lib;libscintilla.lib;liblexilla.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>comctl32.lib;shlwapi.lib;shell32.lib;Dbghelp.lib;Version.lib;Crypt32.lib;wintrust.lib;Sensapi.lib;wininet.lib;imm32.lib;msimg32.lib;uxtheme.lib;dwmapi.lib;libscintilla.lib;liblexilla.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>LinkVerboseLib</ShowProgress>
|
||||
<OutputFile>$(OutDir)notepad++.exe</OutputFile>
|
||||
<Version>1.0</Version>
|
||||
|
|
Loading…
Reference in New Issue