Further dark magic, no pun intended. Now for the menu bar.

This commit is contained in:
Henrik Rydgård 2023-01-02 18:23:33 +01:00
parent 62e5a5dfc3
commit 8037eaa456
5 changed files with 209 additions and 10 deletions

View file

@ -57,6 +57,7 @@
#include "Windows/GEDebugger/GEDebugger.h"
#endif
#include "Windows/W32Util/DarkMode.h"
#include "Windows/W32Util/UAHMenuBar.h"
#include "Windows/Debugger/Debugger_Disasm.h"
#include "Windows/Debugger/Debugger_MemoryDlg.h"
@ -730,6 +731,11 @@ namespace MainWindow
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
LRESULT darkResult = 0;
if (UAHDarkModeWndProc(hWnd, message, wParam, lParam, &darkResult)) {
return darkResult;
}
switch (message) {
case WM_CREATE:
if (!DoesVersionMatchWindows(6, 0, 0, 0, true)) {

View file

@ -248,7 +248,7 @@
<AdditionalOptions>$(EXTERNAL_COMPILE_OPTIONS)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86/lib</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@ -287,7 +287,7 @@
<AdditionalOptions>$(EXTERNAL_COMPILE_OPTIONS)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86_64/lib</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
@ -322,7 +322,7 @@
<AdditionalOptions>$(EXTERNAL_COMPILE_OPTIONS)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/aarch64/lib</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
@ -355,7 +355,7 @@
<AdditionalOptions>$(EXTERNAL_COMPILE_OPTIONS)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/arm/lib</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(OutDir)$(ProjectName).pdb</ProgramDatabaseFile>
@ -392,7 +392,7 @@
<AdditionalOptions>$(EXTERNAL_COMPILE_OPTIONS)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -440,7 +440,7 @@
<AdditionalOptions>$(EXTERNAL_COMPILE_OPTIONS)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;opengl32.lib;glu32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/x86_64/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@ -482,7 +482,7 @@
<AdditionalOptions>$(EXTERNAL_COMPILE_OPTIONS)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/aarch64/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@ -522,7 +522,7 @@
<AdditionalOptions>$(EXTERNAL_COMPILE_OPTIONS)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalDependencies>mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>uxtheme.lib;mf.lib;mfplat.lib;mfreadwrite.lib;mfuuid.lib;shlwapi.lib;Winmm.lib;Ws2_32.lib;dsound.lib;comctl32.lib;d3d9.lib;dxguid.lib;avcodec.lib;avformat.lib;avutil.lib;swresample.lib;swscale.lib;oleaut32.lib;comdlg32.lib;shell32.lib;user32.lib;gdi32.lib;advapi32.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>../ffmpeg/Windows/arm/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
@ -940,6 +940,7 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="W32Util\UAHMenuBar.cpp" />
<ClCompile Include="WASAPIStream.cpp" />
<ClCompile Include="WindowsAudio.cpp" />
<ClCompile Include="WindowsHost.cpp" />
@ -1495,6 +1496,7 @@
<ClInclude Include="MainWindow.h" />
<ClInclude Include="DSoundStream.h" />
<ClInclude Include="GPU\WindowsGLContext.h" />
<ClInclude Include="W32Util\UAHMenuBar.h" />
<ClInclude Include="WASAPIStream.h" />
<ClInclude Include="WindowsAudio.h" />
<ClInclude Include="WindowsHost.h" />
@ -1766,4 +1768,4 @@
<UserProperties RESOURCE_FILE="DaSh.rc" />
</VisualStudio>
</ProjectExtensions>
</Project>
</Project>

View file

@ -277,6 +277,9 @@
<ClCompile Include="W32Util\DarkMode.cpp">
<Filter>Windows\W32Util</Filter>
</ClCompile>
<ClCompile Include="W32Util\UAHMenuBar.cpp">
<Filter>Windows\W32Util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Debugger\CtrlDisAsmView.h">
@ -565,6 +568,9 @@
<ClInclude Include="W32Util\IatHook.h">
<Filter>Windows\W32Util</Filter>
</ClInclude>
<ClInclude Include="W32Util\UAHMenuBar.h">
<Filter>Windows\W32Util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="icon1.ico">
@ -832,4 +838,4 @@
<Filter>Other Platforms\SDL</Filter>
</Text>
</ItemGroup>
</Project>
</Project>

View file

@ -0,0 +1,111 @@
#include "Common/CommonWindows.h"
#include <Uxtheme.h>
#include <vsstyle.h>
#include "Windows/W32Util/UAHMenuBar.h"
static HTHEME g_menuTheme = nullptr;
// processes messages related to UAH / custom menubar drawing.
// return true if handled, false to continue with normal processing in your wndproc
bool UAHDarkModeWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *lr)
{
switch (message)
{
case WM_UAHDRAWMENU:
{
UAHMENU *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);
rc.top -= 1;
}
if (!g_menuTheme) {
g_menuTheme = OpenThemeData(hWnd, L"Menu");
}
DrawThemeBackground(g_menuTheme, pUDM->hdc, MENU_POPUPITEM, MPI_NORMAL, &rc, nullptr);
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 };
{
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;
}
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");
}
DrawThemeBackground(g_menuTheme, pUDMI->um.hdc, MENU_POPUPITEM, iBackgroundStateID, &pUDMI->dis.rcItem, nullptr);
DrawThemeText(g_menuTheme, pUDMI->um.hdc, MENU_POPUPITEM, iTextStateID, menuString, mii.cch, dwFlags, 0, &pUDMI->dis.rcItem);
return true;
}
case WM_THEMECHANGED:
{
if (g_menuTheme) {
CloseThemeData(g_menuTheme);
g_menuTheme = nullptr;
}
// continue processing in main wndproc
return false;
}
default:
return false;
}
}

View file

@ -0,0 +1,74 @@
#pragma once
// MIT license, see LICENSE
// Copyright(c) 2021 adzm / Adam D. Walling
// processes messages related to UAH / custom menubar drawing.
// return true if handled, false to continue with normal processing in your wndproc
bool UAHDarkModeWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT* lr);
// window messages related to menu bar drawing
#define WM_UAHDESTROYWINDOW 0x0090 // handled by DefWindowProc
#define WM_UAHDRAWMENU 0x0091 // lParam is UAHMENU
#define WM_UAHDRAWMENUITEM 0x0092 // lParam is UAHDRAWMENUITEM
#define WM_UAHINITMENU 0x0093 // handled by DefWindowProc
#define WM_UAHMEASUREMENUITEM 0x0094 // lParam is UAHMEASUREMENUITEM
#define WM_UAHNCPAINTMENUPOPUP 0x0095 // handled by DefWindowProc
// describes the sizes of the menu bar or menu item
typedef union tagUAHMENUITEMMETRICS
{
// cx appears to be 14 / 0xE less than rcItem's width!
// cy 0x14 seems stable, i wonder if it is 4 less than rcItem's height which is always 24 atm
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;