Merge pull request #3678 from RaiKoHoff/Dev_RC

Dark-Mode menu bar coloring (except bottom line)
This commit is contained in:
Rainer Kottenhoff 2021-09-26 13:46:33 +02:00 committed by GitHub
commit 0ada976fb6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 262 additions and 11 deletions

View File

@ -1316,6 +1316,9 @@ void LoadSettings()
Settings2.DarkModeTxtColor = rgbDarkTxtColorRef;
}
Globals.hbrDarkModeBkgHotBrush = CreateSolidBrush(Settings2.DarkModeBtnFaceColor);
Globals.hbrDarkModeBkgSelBrush = CreateSolidBrush(Settings2.DarkModeBtnFaceColor);
#endif
// --------------------------------------------------------------------------

View File

@ -4233,7 +4233,6 @@ bool WarnIndentationDlg(HWND hwnd, EditFileIOStatus* fioStatus)
//
// RelAdjustRectForDPI()
//
//
void RelAdjustRectForDPI(LPRECT rc, const UINT oldDPI, const UINT newDPI) {
float const scale = (float)newDPI / (float)(oldDPI != 0 ? oldDPI : 1);
LONG const oldWidth = (rc->right - rc->left);
@ -4247,6 +4246,23 @@ void RelAdjustRectForDPI(LPRECT rc, const UINT oldDPI, const UINT newDPI) {
}
//=============================================================================
//
// MapRectClientToWndCoords()
//
void MapRectClientToWndCoords(HWND hwnd, RECT* rc)
{
// map to screen (left-top as point)
MapWindowPoints(hwnd, NULL, (POINT*)rc, 1);
RECT scrc;
GetWindowRect(hwnd, &scrc);
// map to window coords by substracting the window coord origin in screen coords.
OffsetRect(rc, -scrc.left, -scrc.top);
}
//=============================================================================
//
// GetMonitorInfoFromRect()

View File

@ -61,12 +61,13 @@ bool SelectDefLineEndingDlg(HWND hwnd,LPARAM piOption);
bool WarnLineEndingDlg(HWND hwnd, EditFileIOStatus* fioStatus);
bool WarnIndentationDlg(HWND hwnd, EditFileIOStatus* fioStatus);
void RelAdjustRectForDPI(LPRECT rc, const UINT oldDPI, const UINT newDPI);
bool GetMonitorInfoFromRect(const LPRECT rc, MONITORINFO *hMonitorInfo);
void WinInfoToScreenCoord(WININFO* pWinInfo);
WININFO GetMyWindowPlacement(HWND hwnd, MONITORINFO *hMonitorInfo, const int offset);
bool GetWindowRectEx(HWND hwnd, LPRECT pRect);
void FitIntoMonitorGeometry(LPRECT pRect, WININFO *pWinInfo, SCREEN_MODE mode, bool bTopLeft);
void RelAdjustRectForDPI(LPRECT rc, const UINT oldDPI, const UINT newDPI);
void MapRectClientToWndCoords(HWND hwnd, LPRECT rc);
bool GetMonitorInfoFromRect(const LPRECT rc, MONITORINFO* hMonitorInfo);
void WinInfoToScreenCoord(WININFO* pWinInfo);
WININFO GetMyWindowPlacement(HWND hwnd, MONITORINFO* hMonitorInfo, const int offset);
bool GetWindowRectEx(HWND hwnd, LPRECT pRect);
void FitIntoMonitorGeometry(LPRECT pRect, WININFO* pWinInfo, SCREEN_MODE mode, bool bTopLeft);
WINDOWPLACEMENT WindowPlacementFromInfo(HWND hwnd, const WININFO* pWinInfo, SCREEN_MODE mode);
void DialogNewWindow(HWND hwnd, bool bSaveOnRunTools, LPCWSTR lpcwFilePath, WININFO* wi);

View File

@ -26,7 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <process.h>
//#include <pathcch.h>
#include <vsstyle.h>
#include "Edit.h"
#include "Styles.h"
@ -1876,6 +1876,14 @@ LRESULT CALLBACK MainWndProc(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
Globals.bIsCJKInputCodePage = IsDBCSCodePage(Scintilla_InputCodePage());
break;
case WM_UAHINITMENU:
case WM_UAHDRAWMENU:
case WM_UAHDRAWMENUITEM:
case WM_UAHDESTROYWINDOW:
case WM_UAHMEASUREMENUITEM:
case WM_UAHNCPAINTMENUPOPUP:
return MsgUahMenuBar(hwnd, umsg, wParam, lParam);
default:
if (umsg == s_msgTaskbarCreated) {
if (!IsWindowVisible(hwnd)) {
@ -2235,6 +2243,8 @@ static void _InitEditWndFrame()
s_bIsAppThemed = IsAppThemed();
InitWindowCommon(s_hwndEditFrame, true);
if (s_bIsAppThemed) {
SetWindowLongPtr(Globals.hwndEdit, GWL_EXSTYLE, GetWindowLongPtr(Globals.hwndEdit, GWL_EXSTYLE) & ~WS_EX_CLIENTEDGE);
@ -6892,6 +6902,160 @@ LRESULT MsgSysCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
}
//=============================================================================
//
// MsgUahMenuBar() - Handles WM_UAH... commands
// https://github.com/adzm/win32-custom-menubar-aero-theme
// https://stackoverflow.com/questions/57177310/how-to-paint-over-white-line-between-menu-bar-and-client-area-of-window
//
#if 0
inline static RECT GetNonclientMenuBorderRect(HWND hwnd)
{
RECT rc;
GetClientRect(hwnd, &rc);
MapRectClientToWndCoords(hwnd, &rc);
rc.top = rc.bottom + 1;
rc.bottom += 2;
return rc;
}
#endif
LRESULT MsgUahMenuBar(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
{
static HTHEME s_darkMenuTheme = NULL;
switch (umsg) {
case WM_UAHINITMENU: {
if (!s_darkMenuTheme) {
s_darkMenuTheme = OpenThemeData(hwnd, L"Menu");
}
} break;
case WM_UAHDESTROYWINDOW: {
if (s_darkMenuTheme) {
CloseThemeData(s_darkMenuTheme);
s_darkMenuTheme = NULL;
}
} break;
case WM_UAHDRAWMENU: {
if (!UseDarkMode()) {
break;
}
UAHMENU* const pUDM = (UAHMENU*)lParam;
RECT rc = { 0 };
// get the menubar rect
MENUBARINFO mbi = { sizeof(mbi) };
GetMenuBarInfo(hwnd, OBJID_MENU, 0, &mbi);
RECT rcWindow;
GetWindowRect(hwnd, &rcWindow);
// the rcBar is offset by the window rect
rc = mbi.rcBar;
OffsetRect(&rc, -rcWindow.left, -rcWindow.top);
// fill line below bar
//~rc.bottom += 2;
FillRect(pUDM->hdc, &rc, Globals.hbrDarkModeBkgBrush);
return TRUE;
}
case WM_UAHDRAWMENUITEM: {
if (!UseDarkMode()) {
break;
}
UAHDRAWMENUITEM* pUDMI = (UAHDRAWMENUITEM*)lParam;
HBRUSH* pbrBackground = &Globals.hbrDarkModeBkgBrush;
// 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 = 0;
int iBackgroundStateID = 0;
{
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;
pbrBackground = &Globals.hbrDarkModeBkgHotBrush;
}
if (pUDMI->dis.itemState & ODS_SELECTED) {
// clicked -- MENU_POPUPITEM has no state for this, though MENU_BARITEM does
iTextStateID = MPI_HOT;
iBackgroundStateID = MPI_HOT;
pbrBackground = &Globals.hbrDarkModeBkgSelBrush;
}
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;
}
}
DTTOPTS opts = { sizeof(opts), DTT_TEXTCOLOR, iTextStateID != MPI_DISABLED ? Settings2.DarkModeTxtColor : RGB(0x80, 0x80, 0x80) };
FillRect(pUDMI->um.hdc, &pUDMI->dis.rcItem, *pbrBackground);
DrawThemeTextEx(s_darkMenuTheme, pUDMI->um.hdc, MENU_BARITEM, MBI_NORMAL, menuString, mii.cch, dwFlags, &pUDMI->dis.rcItem, &opts);
return TRUE;
} break;
case WM_UAHMEASUREMENUITEM: {
// allow the default window procedure to handle the message
// since we don't really care about changing the width
//LRESULT const res = DefWindowProc(hwnd, umsg, wParam, lParam);
// but we can modify it here to make it 1/3rd wider and higher for example
//UAHMEASUREMENUITEM* const pMmi = (UAHMEASUREMENUITEM*)lParam;
//pMmi->mis.itemWidth = (pMmi->mis.itemWidth * 4) / 3;
//pMmi->mis.itemHeight = (pMmi->mis.itemHeight * 4) / 3;
//return res;
} break;
// don't care
case WM_UAHNCPAINTMENUPOPUP:
default:
break;
}
return DefWindowProc(hwnd, umsg, wParam, lParam);
}
//=============================================================================
//
// HandleDWellStartEnd()

View File

@ -184,8 +184,10 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam);
LRESULT MsgTrayMessage(HWND hwnd, WPARAM wParam, LPARAM lParam);
//~LRESULT MsgKeyDown(HWND hwnd, WPARAM wParam, LPARAM lParam);
LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
LRESULT MsgSysCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
LRESULT MsgUahMenuBar(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
LRESULT MsgNonClientAreaPaint(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
// ----------------------------------------------------------------------------

View File

@ -280,7 +280,10 @@ typedef struct _cmq
#define rgbRedColorRef (RGB(255, 170, 170))
#define rgbGreenColorRef (RGB(170, 255, 170))
#define rgbBlueColorRef (RGB(170, 200, 255))
#define rgbDarkBtnFcColorRef (RGB(0x33, 0x33, 0x33))
// GetSysColor(...) not working for DarkMode
//#define rgbDarkBtnFcColorRef (RGB(0x33, 0x33, 0x33))
#define rgbDarkBtnFcColorRef (RGB(0x41, 0x41, 0x41))
#define rgbDarkTxtColorRef (RGB(0xDE, 0xDE, 0xDE))
#define rgbDarkBkgColorRef (RGB(0x14, 0x14, 0x14))
@ -425,6 +428,8 @@ typedef struct _globals_t
#ifdef D_NP3_WIN10_DARK_MODE
HBRUSH hbrDarkModeBkgBrush;
HBRUSH hbrDarkModeBtnFcBrush;
HBRUSH hbrDarkModeBkgHotBrush;
HBRUSH hbrDarkModeBkgSelBrush;
#endif
FR_STATES FindReplaceMatchFoundState;

View File

@ -256,8 +256,18 @@ Abstract:
#define IDC_MANAGE_LINK 1592
#endif
#ifndef RC_INVOKED
// undocumented window proc messages regarding menu bar
// https://github.com/adzm/win32-custom-menubar-aero-theme
//
#define WM_UAHDESTROYWINDOW 0x0090
#define WM_UAHDRAWMENU 0x0091 // lParam is UAHMENU
#define WM_UAHDRAWMENUITEM 0x0092 // lParam is UAHDRAWMENUITEM
#define WM_UAHINITMENU 0x0093
#define WM_UAHMEASUREMENUITEM 0x0094 // lParam is UAHMEASUREMENUITEM
#define WM_UAHNCPAINTMENUPOPUP 0x0095
//#define WM_UAHUPDATE 0x????
#ifndef RC_INVOKED
//
// Typedef Declarations.
//
@ -269,10 +279,60 @@ typedef struct tagCRGB
BYTE bExtra;
} CRGB; /* RGB Color */
// describes the sizes of the menu bar or menu item
typedef union tagUAHMENUITEMMETRICS {
struct {
DWORD cx;
DWORD cy;
} rgsizeBar[2];
struct {
DWORD cx;
DWORD cy;
} rgsizePopup[4];
} UAHMENUITEMMETRICS;
// not really used in our case but part of the other structures
typedef struct tagUAHMENUPOPUPMETRICS {
DWORD rgcx[4];
DWORD fUpdateMaxWidths : 2; // from kernel symbols, padded to full dword
} UAHMENUPOPUPMETRICS;
// hmenu is the main window menu; hdc is the context to draw in
typedef struct tagUAHMENU {
HMENU hmenu;
HDC hdc;
DWORD dwFlags; // no idea what these mean, in my testing it's either 0x00000a00 or sometimes 0x00000a10
} UAHMENU;
// menu items are always referred to by iPosition here
typedef struct tagUAHMENUITEM {
int iPosition; // 0-based position of menu item in menubar
UAHMENUITEMMETRICS umim;
UAHMENUPOPUPMETRICS umpm;
} UAHMENUITEM;
// the DRAWITEMSTRUCT contains the states of the menu items, as well as
// the position index of the item in the menu, which is duplicated in
// the UAHMENUITEM's iPosition as well
typedef struct UAHDRAWMENUITEM {
DRAWITEMSTRUCT dis; // itemID looks uninitialized
UAHMENU um;
UAHMENUITEM umi;
} UAHDRAWMENUITEM;
// the MEASUREITEMSTRUCT is intended to be filled with the size of the item
// height appears to be ignored, but width can be modified
typedef struct tagUAHMEASUREMENUITEM {
MEASUREITEMSTRUCT mis;
UAHMENU um;
UAHMENUITEM umi;
} UAHMEASUREMENUITEM;
#endif /* !RC_INVOKED */
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) */
#pragma endregion
#endif // _DLGSH_INCLUDED_