Compare commits
4 commits
81b37cd193
...
063e7484ab
Author | SHA1 | Date | |
---|---|---|---|
063e7484ab | |||
fb2d35d21e | |||
c4d84e84ce | |||
cdefcc6986 |
3 changed files with 486 additions and 46 deletions
|
@ -4,12 +4,12 @@ Mods for Windhawk
|
||||||
## Classic Theme Explorer
|
## Classic Theme Explorer
|
||||||
Classic Theme mitigations for Explorer as a Windhawk mod.
|
Classic Theme mitigations for Explorer as a Windhawk mod.
|
||||||
|
|
||||||
Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it.
|
Based on [ExplorerPatcher](https://github.com/valinet/ExplorerPatcher), [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it.
|
||||||
|
|
||||||
## Classic Theme Windows
|
## Classic Theme Windows
|
||||||
Forces Classic Theme on all Windows
|
Forces Classic Theme on all Windows
|
||||||
|
|
||||||
Originally written by WinClassic user Travis. Added DWM disabler from BasicThemer2 for classic titlebars and Classic File Picker.
|
Originally written by WinClassic user Travis. Added DWM disabler ala BasicThemer2 for classic titlebars and Classic File Picker.
|
||||||
|
|
||||||
## ~~Classic File Picker~~
|
## ~~Classic File Picker~~
|
||||||
~~Restores pre-Vista file picker. Requires Classic Theme Windows mod or else Windows just upgrades the dialog.~~
|
~~Restores pre-Vista file picker. Requires Classic Theme Windows mod or else Windows just upgrades the dialog.~~
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
// @github https://github.com/Cynosphere
|
// @github https://github.com/Cynosphere
|
||||||
// @homepage https://c7.pm/
|
// @homepage https://c7.pm/
|
||||||
// @include explorer.exe
|
// @include explorer.exe
|
||||||
// @compilerOptions -lcomctl32
|
// @compilerOptions -lcomctl32 -luxtheme -lgdi32
|
||||||
// ==/WindhawkMod==
|
// ==/WindhawkMod==
|
||||||
|
|
||||||
// ==WindhawkModReadme==
|
// ==WindhawkModReadme==
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
# Classic Theme Explorer
|
# Classic Theme Explorer
|
||||||
Classic Theme mitigations for Explorer as a Windhawk mod.
|
Classic Theme mitigations for Explorer as a Windhawk mod.
|
||||||
|
|
||||||
Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it.
|
Based on [ExplorerPatcher](https://github.com/valinet/ExplorerPatcher), [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/SimpleClassicTheme.FileExplorerHook) and the AutoHotkey scripts that came before it.
|
||||||
*/
|
*/
|
||||||
// ==/WindhawkModReadme==
|
// ==/WindhawkModReadme==
|
||||||
|
|
||||||
|
@ -45,6 +45,9 @@ Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/S
|
||||||
- hideRefresh: true
|
- hideRefresh: true
|
||||||
$name: "Hide Refresh Button"
|
$name: "Hide Refresh Button"
|
||||||
$description: "Hides the refresh button from Classic Address Bar"
|
$description: "Hides the refresh button from Classic Address Bar"
|
||||||
|
- epMitigate: true
|
||||||
|
$name: "ExplorerPatcher's Mitigations"
|
||||||
|
$description: "ExplorerPatcher's Mitigations"
|
||||||
*/
|
*/
|
||||||
// ==/WindhawkModSettings==
|
// ==/WindhawkModSettings==
|
||||||
|
|
||||||
|
@ -53,6 +56,9 @@ Based on [SimpleClassicTheme.FileExplorerHook](https://github.com/AEAEAEAE4343/S
|
||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
#include <commctrl.h>
|
#include <commctrl.h>
|
||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
|
#include <uxtheme.h>
|
||||||
|
#include <wingdi.h>
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
@ -67,6 +73,7 @@ struct {
|
||||||
bool addressSyncFullPath;
|
bool addressSyncFullPath;
|
||||||
bool addressHeight;
|
bool addressHeight;
|
||||||
bool hideRefresh;
|
bool hideRefresh;
|
||||||
|
bool epMitigate;
|
||||||
} settings;
|
} settings;
|
||||||
|
|
||||||
void LoadSettings() {
|
void LoadSettings() {
|
||||||
|
@ -78,6 +85,7 @@ void LoadSettings() {
|
||||||
settings.addressSyncFullPath = Wh_GetIntSetting(L"addressSyncFullPath");
|
settings.addressSyncFullPath = Wh_GetIntSetting(L"addressSyncFullPath");
|
||||||
settings.addressHeight = Wh_GetIntSetting(L"addressHeight");
|
settings.addressHeight = Wh_GetIntSetting(L"addressHeight");
|
||||||
settings.hideRefresh = Wh_GetIntSetting(L"hideRefresh");
|
settings.hideRefresh = Wh_GetIntSetting(L"hideRefresh");
|
||||||
|
settings.epMitigate = Wh_GetIntSetting(L"epMitigate");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explorer modifications
|
// Explorer modifications
|
||||||
|
@ -457,28 +465,387 @@ HWND WINAPI SHCreateWorkerWindowHook(WNDPROC wndProc, HWND hWndParent, DWORD dwE
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// taskbar fixes from ExplorerPatcher
|
||||||
|
using CreateWindowExW_t = decltype(&CreateWindowExW);
|
||||||
|
CreateWindowExW_t CreateWindowExW_Orig;
|
||||||
|
HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) {
|
||||||
|
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd"))
|
||||||
|
{
|
||||||
|
dwExStyle |= WS_EX_STATICEDGE;
|
||||||
|
}
|
||||||
|
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"NotifyIconOverflowWindow"))
|
||||||
|
{
|
||||||
|
dwExStyle |= WS_EX_STATICEDGE;
|
||||||
|
}
|
||||||
|
if (settings.clientEdge && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"SysListView32") || !wcscmp(lpClassName, L"SysTreeView32"))) // !wcscmp(lpClassName, L"FolderView")
|
||||||
|
{
|
||||||
|
wchar_t wszClassName[200];
|
||||||
|
ZeroMemory(wszClassName, 200);
|
||||||
|
GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200);
|
||||||
|
if (!wcscmp(wszClassName, L"CabinetWClass"))
|
||||||
|
{
|
||||||
|
dwExStyle |= WS_EX_CLIENTEDGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"ReBarWindow32"))
|
||||||
|
{
|
||||||
|
wchar_t wszClassName[200];
|
||||||
|
ZeroMemory(wszClassName, 200);
|
||||||
|
GetClassNameW(hWndParent, wszClassName, 200);
|
||||||
|
if (!wcscmp(wszClassName, L"Shell_TrayWnd"))
|
||||||
|
{
|
||||||
|
dwStyle |= RBS_BANDBORDERS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND hWnd = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
|
||||||
|
|
||||||
|
return hWnd;
|
||||||
|
}
|
||||||
|
using SetWindowLongPtrW_t = decltype(&SetWindowLongPtrW);
|
||||||
|
SetWindowLongPtrW_t SetWindowLongPtrW_Orig;
|
||||||
|
LONG_PTR SetWindowLongPtrW_Hook(HWND hWnd, int nIndex, LONG_PTR dwNewLong) {
|
||||||
|
WCHAR lpClassName[200];
|
||||||
|
ZeroMemory(lpClassName, 200);
|
||||||
|
GetClassNameW(hWnd, lpClassName, 200);
|
||||||
|
HWND hWndParent = GetParent(hWnd);
|
||||||
|
|
||||||
|
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"TrayNotifyWnd"))
|
||||||
|
{
|
||||||
|
if (nIndex == GWL_EXSTYLE)
|
||||||
|
{
|
||||||
|
dwNewLong |= WS_EX_STATICEDGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"NotifyIconOverflowWindow"))
|
||||||
|
{
|
||||||
|
if (nIndex == GWL_EXSTYLE)
|
||||||
|
{
|
||||||
|
dwNewLong |= WS_EX_STATICEDGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.clientEdge && (*((WORD*)&(lpClassName)+1)) && (!wcscmp(lpClassName, L"SysListView32") || !wcscmp(lpClassName, L"SysTreeView32"))) // !wcscmp(lpClassName, L"FolderView")
|
||||||
|
{
|
||||||
|
wchar_t wszClassName[200];
|
||||||
|
ZeroMemory(wszClassName, 200);
|
||||||
|
GetClassNameW(GetAncestor(hWndParent, GA_ROOT), wszClassName, 200);
|
||||||
|
if (!wcscmp(wszClassName, L"CabinetWClass"))
|
||||||
|
{
|
||||||
|
if (nIndex == GWL_EXSTYLE)
|
||||||
|
{
|
||||||
|
dwNewLong |= WS_EX_CLIENTEDGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (settings.epMitigate && (*((WORD*)&(lpClassName)+1)) && !wcscmp(lpClassName, L"ReBarWindow32"))
|
||||||
|
{
|
||||||
|
wchar_t wszClassName[200];
|
||||||
|
ZeroMemory(wszClassName, 200);
|
||||||
|
GetClassNameW(hWndParent, wszClassName, 200);
|
||||||
|
if (!wcscmp(wszClassName, L"Shell_TrayWnd"))
|
||||||
|
{
|
||||||
|
if (nIndex == GWL_STYLE)
|
||||||
|
{
|
||||||
|
dwNewLong |= RBS_BANDBORDERS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetWindowLongPtrW_Orig(hWnd, nIndex, dwNewLong);
|
||||||
|
}
|
||||||
|
|
||||||
|
HTHEME(*pOriginalOpenThemeDataForDpi)(HWND hWnd, LPCWSTR pszClassList, UINT dpi);
|
||||||
|
HTHEME OpenThemeDataForDpiHook(HWND hWnd, LPCWSTR pszClassList, UINT dpi)
|
||||||
|
{
|
||||||
|
if (settings.epMitigate && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"Taskband2")) {
|
||||||
|
Wh_Log(L"Redirecting Taskband2 hTheme");
|
||||||
|
return (HTHEME)0xDEADBEEF;
|
||||||
|
} else if (settings.epMitigate && (*((WORD*)&(pszClassList)+1)) && !wcscmp(pszClassList, L"TrayNotifyFlyout")) {
|
||||||
|
Wh_Log(L"Redirecting TrayNotifyFlyout hTheme");
|
||||||
|
return (HTHEME)0xDEADBEFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pOriginalOpenThemeDataForDpi(hWnd, pszClassList, dpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT(*pOriginalGetThemeMetric)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int* piVal);
|
||||||
|
HRESULT GetThemeMetricHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, int* piVal) {
|
||||||
|
Wh_Log(L"hTheme: %08X", hTheme);
|
||||||
|
|
||||||
|
if (!settings.epMitigate || (hTheme != (HTHEME)0xDEADBEFF)) {
|
||||||
|
return pOriginalGetThemeMetric(hTheme, hdc, iPartId, iStateId, iPropId, piVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int TMT_WIDTH = 2416;
|
||||||
|
const int TMT_HEIGHT = 2417;
|
||||||
|
if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_WIDTH && iPartId == 3 && iStateId == 0)
|
||||||
|
{
|
||||||
|
*piVal = GetSystemMetrics(SM_CXICON);
|
||||||
|
}
|
||||||
|
else if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_HEIGHT && iPartId == 3 && iStateId == 0)
|
||||||
|
{
|
||||||
|
*piVal = GetSystemMetrics(SM_CYICON);
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT(*pOriginalGetThemeMargins)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LPCRECT prc, MARGINS* pMargins);
|
||||||
|
HRESULT GetThemeMarginsHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, int iPropId, LPCRECT prc, MARGINS* pMargins) {
|
||||||
|
Wh_Log(L"hTheme: %08X", hTheme);
|
||||||
|
|
||||||
|
if (!settings.epMitigate || (hTheme != (HTHEME)0xDEADBEEF && hTheme != (HTHEME)0xDEADBEFF)) {
|
||||||
|
return pOriginalGetThemeMargins(hTheme, hdc, iPartId, iStateId, iPropId, prc, pMargins);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int TMT_SIZINGMARGINS = 3601;
|
||||||
|
const int TMT_CONTENTMARGINS = 3602;
|
||||||
|
HRESULT hr = S_OK;
|
||||||
|
if (hTheme)
|
||||||
|
{
|
||||||
|
hr = pOriginalGetThemeMargins(
|
||||||
|
hTheme,
|
||||||
|
hdc,
|
||||||
|
iPartId,
|
||||||
|
iStateId,
|
||||||
|
iPropId,
|
||||||
|
prc,
|
||||||
|
pMargins
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_CONTENTMARGINS && iPartId == 5 && iStateId == 1) {
|
||||||
|
// task list button measurements
|
||||||
|
pMargins->cxLeftWidth = 4;
|
||||||
|
pMargins->cyTopHeight = 3;
|
||||||
|
pMargins->cxRightWidth = 4;
|
||||||
|
pMargins->cyBottomHeight = 3;
|
||||||
|
} else if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_CONTENTMARGINS && iPartId == 1 && iStateId == 0) {
|
||||||
|
// task list measurements
|
||||||
|
pMargins->cxLeftWidth = 0;
|
||||||
|
pMargins->cyTopHeight = 0;
|
||||||
|
pMargins->cxRightWidth = 4;
|
||||||
|
pMargins->cyBottomHeight = 0;
|
||||||
|
} else if (hTheme == (HTHEME)0xDEADBEEF && iPropId == TMT_SIZINGMARGINS && iPartId == 5 && iStateId == 1) {
|
||||||
|
pMargins->cxLeftWidth = 10;
|
||||||
|
pMargins->cyTopHeight = 10;
|
||||||
|
pMargins->cxRightWidth = 10;
|
||||||
|
pMargins->cyBottomHeight = 10;
|
||||||
|
} else if (hTheme == (HTHEME)0xDEADBEFF && iPropId == TMT_CONTENTMARGINS && iPartId == 3 && iStateId == 0) {
|
||||||
|
pMargins->cxLeftWidth = 4; // GetSystemMetrics(SM_CXICONSPACING);
|
||||||
|
pMargins->cyTopHeight = 4; // GetSystemMetrics(SM_CYICONSPACING);
|
||||||
|
pMargins->cxRightWidth = 4; //GetSystemMetrics(SM_CXICONSPACING);
|
||||||
|
pMargins->cyBottomHeight = 4; // GetSystemMetrics(SM_CYICONSPACING);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND hShell_TrayWnd = FindWindowEx(NULL, NULL, L"Shell_TrayWnd", NULL);
|
||||||
|
if (hShell_TrayWnd) {
|
||||||
|
LONG dwStyle = 0;
|
||||||
|
dwStyle = GetWindowLongW(hShell_TrayWnd, GWL_STYLE);
|
||||||
|
dwStyle |= WS_DLGFRAME;
|
||||||
|
SetWindowLongW(hShell_TrayWnd, GWL_STYLE, dwStyle);
|
||||||
|
dwStyle &= ~WS_DLGFRAME;
|
||||||
|
SetWindowLongW(hShell_TrayWnd, GWL_STYLE, dwStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
HWND hWnd = NULL;
|
||||||
|
do {
|
||||||
|
hWnd = FindWindowEx(
|
||||||
|
NULL,
|
||||||
|
hWnd,
|
||||||
|
L"Shell_SecondaryTrayWnd",
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
if (hWnd) {
|
||||||
|
LONG dwStyle = 0;
|
||||||
|
dwStyle = GetWindowLongW(hWnd, GWL_STYLE);
|
||||||
|
dwStyle |= WS_DLGFRAME;
|
||||||
|
SetWindowLongW(hWnd, GWL_STYLE, dwStyle);
|
||||||
|
dwStyle &= ~WS_DLGFRAME;
|
||||||
|
SetWindowLongW(hWnd, GWL_STYLE, dwStyle);
|
||||||
|
}
|
||||||
|
} while (hWnd);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT(*pOriginalDrawThemeTextEx)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const DTTOPTS* pOptions);
|
||||||
|
HRESULT DrawThemeTextExHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPCWSTR pszText, int cchText, DWORD dwTextFlags, LPRECT pRect, const DTTOPTS* pOptions) {
|
||||||
|
if (!settings.epMitigate) {
|
||||||
|
return pOriginalDrawThemeTextEx(hTheme, hdc, iPartId, iStateId, pszText, cchText, dwTextFlags, pRect, pOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
COLORREF bc = GetBkColor(hdc);
|
||||||
|
COLORREF fc = GetTextColor(hdc);
|
||||||
|
int mode = SetBkMode(hdc, TRANSPARENT);
|
||||||
|
|
||||||
|
wchar_t text[200];
|
||||||
|
GetWindowTextW(GetForegroundWindow(), text, 200);
|
||||||
|
|
||||||
|
BOOL bIsActiveUnhovered = (iPartId == 5 && iStateId == 5);
|
||||||
|
BOOL bIsInactiveUnhovered = (iPartId == 5 && iStateId == 1);
|
||||||
|
BOOL bIsInactiveHovered = (iPartId == 5 && iStateId == 2);
|
||||||
|
BOOL bIsActiveHovered = bIsInactiveHovered && !wcscmp(text, pszText);
|
||||||
|
|
||||||
|
SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
|
||||||
|
|
||||||
|
NONCLIENTMETRICSW ncm;
|
||||||
|
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
|
||||||
|
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0);
|
||||||
|
|
||||||
|
HFONT hFont = NULL;
|
||||||
|
if (bIsActiveUnhovered)
|
||||||
|
{
|
||||||
|
hFont = CreateFontIndirectW(&(ncm.lfCaptionFont));
|
||||||
|
}
|
||||||
|
else if (bIsInactiveUnhovered)
|
||||||
|
{
|
||||||
|
hFont = CreateFontIndirectW(&(ncm.lfMenuFont));
|
||||||
|
}
|
||||||
|
else if (bIsActiveHovered)
|
||||||
|
{
|
||||||
|
hFont = CreateFontIndirectW(&(ncm.lfCaptionFont));
|
||||||
|
}
|
||||||
|
else if (bIsInactiveHovered)
|
||||||
|
{
|
||||||
|
hFont = CreateFontIndirectW(&(ncm.lfMenuFont));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hFont = CreateFontIndirectW(&(ncm.lfMenuFont));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iPartId == 5 && iStateId == 0) // clock
|
||||||
|
{
|
||||||
|
pRect->top += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
HGDIOBJ hOldFont = SelectObject(hdc, hFont);
|
||||||
|
DrawTextW(
|
||||||
|
hdc,
|
||||||
|
pszText,
|
||||||
|
cchText,
|
||||||
|
pRect,
|
||||||
|
dwTextFlags
|
||||||
|
);
|
||||||
|
SelectObject(hdc, hOldFont);
|
||||||
|
DeleteObject(hFont);
|
||||||
|
SetBkColor(hdc, bc);
|
||||||
|
SetTextColor(hdc, fc);
|
||||||
|
SetBkMode(hdc, mode);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT(*pOriginalDrawThemeBackground)(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPRECT pRect, LPCRECT pClipRect);
|
||||||
|
HRESULT DrawThemeBackgroundHook(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, LPRECT pRect, LPCRECT pClipRect) {
|
||||||
|
if (settings.epMitigate) {
|
||||||
|
if (iPartId == 4 && iStateId == 1) {
|
||||||
|
COLORREF bc = GetBkColor(hdc);
|
||||||
|
COLORREF fc = GetTextColor(hdc);
|
||||||
|
int mode = SetBkMode(hdc, TRANSPARENT);
|
||||||
|
|
||||||
|
SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
|
||||||
|
|
||||||
|
NONCLIENTMETRICSW ncm;
|
||||||
|
ncm.cbSize = sizeof(NONCLIENTMETRICSW);
|
||||||
|
SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &ncm, 0);
|
||||||
|
|
||||||
|
HFONT hFont = CreateFontIndirectW(&(ncm.lfCaptionFont));
|
||||||
|
|
||||||
|
/*UINT dpiX, dpiY;
|
||||||
|
HRESULT hr = GetDpiForMonitor(
|
||||||
|
MonitorFromWindow(WindowFromDC(hdc), MONITOR_DEFAULTTOPRIMARY),
|
||||||
|
MDT_DEFAULT,
|
||||||
|
&dpiX,
|
||||||
|
&dpiY
|
||||||
|
);
|
||||||
|
double dx = dpiX / 96.0, dy = dpiY / 96.0;*/
|
||||||
|
|
||||||
|
HGDIOBJ hOldFont = SelectObject(hdc, hFont);
|
||||||
|
DWORD dwTextFlags = DT_SINGLELINE | DT_CENTER | DT_VCENTER;
|
||||||
|
RECT rc = *pRect;
|
||||||
|
rc.bottom -= 7;
|
||||||
|
DrawTextW(
|
||||||
|
hdc,
|
||||||
|
L"\u2026",
|
||||||
|
-1,
|
||||||
|
&rc,
|
||||||
|
dwTextFlags
|
||||||
|
);
|
||||||
|
SelectObject(hdc, hOldFont);
|
||||||
|
DeleteObject(hFont);
|
||||||
|
SetBkColor(hdc, bc);
|
||||||
|
SetTextColor(hdc, fc);
|
||||||
|
SetBkMode(hdc, mode);
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pOriginalDrawThemeBackground(hTheme, hdc, iPartId, iStateId, pRect, pClipRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct WINCOMPATTRDATA
|
||||||
|
{
|
||||||
|
DWORD attribute;
|
||||||
|
PVOID pData;
|
||||||
|
ULONG dataSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOL (WINAPI *pOriginalSetWindowCompositionAttribute)(HWND hWnd, WINCOMPATTRDATA* pData);
|
||||||
|
BOOL WINAPI SetWindowCompositionAttributeHook(HWND hWnd, WINCOMPATTRDATA* pData) {
|
||||||
|
if (settings.epMitigate) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pOriginalSetWindowCompositionAttribute(hWnd, pData);
|
||||||
|
}
|
||||||
|
|
||||||
// Windhawk boilerplate
|
// Windhawk boilerplate
|
||||||
BOOL Wh_ModInit() {
|
BOOL Wh_ModInit() {
|
||||||
Wh_Log(L"Init");
|
|
||||||
|
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
|
|
||||||
HMODULE hShcore = GetModuleHandle(L"shcore.dll");
|
HMODULE hShcore = GetModuleHandle(L"shcore.dll");
|
||||||
|
|
||||||
void* origFunc = (void*)GetProcAddress(hShcore, (LPCSTR)188);
|
void* origCWW = (void*)GetProcAddress(hShcore, (LPCSTR)188);
|
||||||
Wh_SetFunctionHook(origFunc, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow);
|
Wh_SetFunctionHook(origCWW, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow);
|
||||||
|
|
||||||
|
HMODULE hUxtheme = GetModuleHandle(L"uxtheme.dll");
|
||||||
|
|
||||||
|
void* origOTDFD = (void*)GetProcAddress(hUxtheme, "OpenThemeDataForDpi");
|
||||||
|
Wh_SetFunctionHook(origOTDFD, (void*)OpenThemeDataForDpiHook, (void**)&pOriginalOpenThemeDataForDpi);
|
||||||
|
|
||||||
|
void* origGTMe = (void*)GetProcAddress(hUxtheme, "GetThemeMetric");
|
||||||
|
Wh_SetFunctionHook(origGTMe, (void*)GetThemeMetricHook, (void**)&pOriginalGetThemeMetric);
|
||||||
|
|
||||||
|
void* origGTMa = (void*)GetProcAddress(hUxtheme, "GetThemeMargins");
|
||||||
|
Wh_SetFunctionHook(origGTMa, (void*)GetThemeMarginsHook, (void**)&pOriginalGetThemeMargins);
|
||||||
|
|
||||||
|
void* origDTTE = (void*)GetProcAddress(hUxtheme, "DrawThemeTextEx");
|
||||||
|
Wh_SetFunctionHook(origDTTE, (void*)DrawThemeTextExHook, (void**)&pOriginalDrawThemeTextEx);
|
||||||
|
|
||||||
|
void* origDTB = (void*)GetProcAddress(hUxtheme, "DrawThemeBackground");
|
||||||
|
Wh_SetFunctionHook(origDTB, (void*)DrawThemeBackgroundHook, (void**)&pOriginalDrawThemeBackground);
|
||||||
|
|
||||||
|
//HMODULE hUser32 = GetModuleHandle(L"user32.dll");
|
||||||
|
|
||||||
|
//void* origSWCA = (void*)GetProcAddress(hUser32, "SetWindowCompositionAttribute");
|
||||||
|
//Wh_SetFunctionHook(origSWCA, (void*)SetWindowCompositionAttributeHook, (void**)&pOriginalSetWindowCompositionAttribute);
|
||||||
|
|
||||||
|
Wh_SetFunctionHook((void*)CreateWindowExW,
|
||||||
|
(void*)CreateWindowExW_Hook,
|
||||||
|
(void**)&CreateWindowExW_Orig);
|
||||||
|
Wh_SetFunctionHook((void*)SetWindowLongPtrW,
|
||||||
|
(void*)SetWindowLongPtrW_Hook,
|
||||||
|
(void**)&SetWindowLongPtrW_Orig);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wh_ModUninit() {
|
void Wh_ModUninit() {
|
||||||
Wh_Log(L"Uninit");
|
|
||||||
|
|
||||||
if (g_uiThreadId != 0) EnumThreadWindows(g_uiThreadId, EnumBrowserWindowsUnsubclassFunc, 0);
|
if (g_uiThreadId != 0) EnumThreadWindows(g_uiThreadId, EnumBrowserWindowsUnsubclassFunc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Wh_ModSettingsChanged() {
|
void Wh_ModSettingsChanged() {
|
||||||
Wh_Log(L"SettingsChanged");
|
|
||||||
|
|
||||||
LoadSettings();
|
LoadSettings();
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
// @exclude PhoneExperienceHost.exe
|
// @exclude PhoneExperienceHost.exe
|
||||||
// @exclude SecurityHealthTray.exe
|
// @exclude SecurityHealthTray.exe
|
||||||
// @exclude Window Detective.exe
|
// @exclude Window Detective.exe
|
||||||
// @compilerOptions -luxtheme -ldwmapi -lole32 -lcomdlg32
|
// @compilerOptions -luxtheme -ldwmapi -lole32 -lcomdlg32 -lcomctl32
|
||||||
// ==/WindhawkMod==
|
// ==/WindhawkMod==
|
||||||
|
|
||||||
// ==WindhawkModReadme==
|
// ==WindhawkModReadme==
|
||||||
|
@ -43,62 +43,133 @@ Forces Classic Theme on all Windows
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <uxtheme.h>
|
#include <uxtheme.h>
|
||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
|
#include <commctrl.h>
|
||||||
DWORD thisPid = -1;
|
|
||||||
|
|
||||||
// BasicThemer2 reimplementation to render classic titlebars
|
// BasicThemer2 reimplementation to render classic titlebars
|
||||||
static const int DisableDWM = DWMNCRP_DISABLED;
|
static const int DisableDWM = DWMNCRP_DISABLED;
|
||||||
static const int EnableDWM = DWMNCRP_ENABLED;
|
static const int EnableDWM = DWMNCRP_ENABLED;
|
||||||
|
|
||||||
void BasicThemerEnable(HWND hwnd) {
|
void DisableDWMForHwnd(HWND hwnd) {
|
||||||
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &DisableDWM, sizeof(int));
|
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &DisableDWM, sizeof(int));
|
||||||
}
|
}
|
||||||
void BasicThemerDisable(HWND hwnd) {
|
void EnableDWMForHwnd(HWND hwnd) {
|
||||||
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &EnableDWM, sizeof(int));
|
DwmSetWindowAttribute(hwnd, DWMWA_NCRENDERING_POLICY, &EnableDWM, sizeof(int));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DWORD g_uiThreadId;
|
||||||
|
|
||||||
|
BOOL CALLBACK DisableDWMForAll(HWND hWnd, LPARAM lParam) {
|
||||||
|
DWORD dwProcessId = 0;
|
||||||
|
DWORD dwThreadId = GetWindowThreadProcessId(hWnd, &dwProcessId);
|
||||||
|
if (!dwThreadId || dwProcessId != GetCurrentProcessId()) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_uiThreadId && g_uiThreadId != dwThreadId) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsWindow(hWnd)) {
|
||||||
|
Wh_Log(L"[Init] Window found: %08X", (DWORD)(ULONG_PTR)hWnd);
|
||||||
|
|
||||||
|
if (!g_uiThreadId) {
|
||||||
|
g_uiThreadId = dwThreadId;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisableDWMForHwnd(hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL CALLBACK EnableDWMForAll(HWND hWnd, LPARAM lParam) {
|
||||||
|
DWORD dwProcessId = 0;
|
||||||
|
DWORD dwThreadId = GetWindowThreadProcessId(hWnd, &dwProcessId);
|
||||||
|
if (!dwThreadId || dwProcessId != GetCurrentProcessId()) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_uiThreadId && g_uiThreadId != dwThreadId) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsWindow(hWnd)) {
|
||||||
|
Wh_Log(L"[Cleanup] Window found: %08X", (DWORD)(ULONG_PTR)hWnd);
|
||||||
|
|
||||||
|
if (!g_uiThreadId) {
|
||||||
|
g_uiThreadId = dwThreadId;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnableDWMForHwnd(hWnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
using CreateWindowExW_t = decltype(&CreateWindowExW);
|
using CreateWindowExW_t = decltype(&CreateWindowExW);
|
||||||
CreateWindowExW_t CreateWindowExW_Orig;
|
CreateWindowExW_t CreateWindowExW_Orig;
|
||||||
HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) {
|
HWND WINAPI CreateWindowExW_Hook(DWORD dwExStyle,LPCWSTR lpClassName,LPCWSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) {
|
||||||
HWND res = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
|
HWND hWnd = CreateWindowExW_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
|
||||||
|
|
||||||
if (thisPid != -1) {
|
if (!hWnd) {
|
||||||
DWORD targetPid;
|
return hWnd;
|
||||||
GetWindowThreadProcessId(res, &targetPid);
|
|
||||||
if (targetPid == thisPid) {
|
|
||||||
BasicThemerEnable(res);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) {
|
||||||
|
return hWnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsWindow(hWnd)) {
|
||||||
|
Wh_Log(L"[CreateWindowExW] Window created: %08X", (DWORD)(ULONG_PTR)hWnd);
|
||||||
|
|
||||||
|
if (!g_uiThreadId) {
|
||||||
|
g_uiThreadId = GetCurrentThreadId();
|
||||||
|
}
|
||||||
|
|
||||||
|
DisableDWMForHwnd(hWnd);
|
||||||
|
EnumWindows(DisableDWMForAll, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hWnd;
|
||||||
}
|
}
|
||||||
using CreateWindowExA_t = decltype(&CreateWindowExA);
|
using CreateWindowExA_t = decltype(&CreateWindowExA);
|
||||||
CreateWindowExA_t CreateWindowExA_Orig;
|
CreateWindowExA_t CreateWindowExA_Orig;
|
||||||
HWND WINAPI CreateWindowExA_Hook(DWORD dwExStyle,LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) {
|
HWND WINAPI CreateWindowExA_Hook(DWORD dwExStyle,LPCSTR lpClassName,LPCSTR lpWindowName,DWORD dwStyle,int X,int Y,int nWidth,int nHeight,HWND hWndParent,HMENU hMenu,HINSTANCE hInstance,LPVOID lpParam) {
|
||||||
HWND res = CreateWindowExA_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
|
HWND hWnd = CreateWindowExA_Orig(dwExStyle,lpClassName,lpWindowName,dwStyle,X,Y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam);
|
||||||
|
|
||||||
if (thisPid != -1) {
|
if (!hWnd) {
|
||||||
DWORD targetPid;
|
return hWnd;
|
||||||
GetWindowThreadProcessId(res, &targetPid);
|
|
||||||
if (targetPid == thisPid) {
|
|
||||||
BasicThemerEnable(res);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
if (g_uiThreadId && g_uiThreadId != GetCurrentThreadId()) {
|
||||||
|
return hWnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsWindow(hWnd)) {
|
||||||
|
Wh_Log(L"[CreateWindowExA] Window created: %08X", (DWORD)(ULONG_PTR)hWnd);
|
||||||
|
|
||||||
|
if (!g_uiThreadId) {
|
||||||
|
g_uiThreadId = GetCurrentThreadId();
|
||||||
|
}
|
||||||
|
|
||||||
|
DisableDWMForHwnd(hWnd);
|
||||||
|
EnumWindows(DisableDWMForAll, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hWnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL CALLBACK EnableBasicThemerForAll(HWND hWnd, LPARAM lParam) {
|
HWND(WINAPI *pOriginalSHCreateWorkerWindow)(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra);
|
||||||
if (IsWindow(hWnd))
|
HWND WINAPI SHCreateWorkerWindowHook(WNDPROC wndProc, HWND hWndParent, DWORD dwExStyle, DWORD dwStyle, HMENU hMenu, LONG_PTR wnd_extra)
|
||||||
BasicThemerEnable(hWnd);
|
{
|
||||||
|
HWND result = pOriginalSHCreateWorkerWindow(wndProc, hWndParent, dwExStyle, dwStyle, hMenu, wnd_extra);
|
||||||
|
|
||||||
return TRUE;
|
if (dwExStyle == 0x10000 && dwStyle == 0x46000000 && result) {
|
||||||
}
|
DisableDWMForHwnd(hWndParent);
|
||||||
BOOL CALLBACK DisableBasicThemerForAll(HWND hWnd, LPARAM lParam) {
|
EnumWindows(DisableDWMForAll, 0);
|
||||||
if (IsWindow(hWnd))
|
}
|
||||||
BasicThemerDisable(hWnd);
|
|
||||||
|
|
||||||
return TRUE;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// File picker
|
// File picker
|
||||||
|
@ -141,9 +212,12 @@ BOOL Wh_ModInit() {
|
||||||
(void*)CreateWindowExA_Hook,
|
(void*)CreateWindowExA_Hook,
|
||||||
(void**)&CreateWindowExA_Orig);
|
(void**)&CreateWindowExA_Orig);
|
||||||
|
|
||||||
|
HMODULE hShcore = GetModuleHandle(L"shcore.dll");
|
||||||
|
void* origFunc = (void*)GetProcAddress(hShcore, (LPCSTR)188);
|
||||||
|
Wh_SetFunctionHook(origFunc, (void*)SHCreateWorkerWindowHook, (void**)&pOriginalSHCreateWorkerWindow);
|
||||||
|
|
||||||
// Iterate every window to enable BasicThemer
|
// Iterate every window to enable BasicThemer
|
||||||
thisPid = GetProcessIdOfThread(GetCurrentThread());
|
EnumWindows(DisableDWMForAll, 0);
|
||||||
EnumWindows(EnableBasicThemerForAll, thisPid);
|
|
||||||
|
|
||||||
// File picker
|
// File picker
|
||||||
Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook,
|
Wh_SetFunctionHook((void*)CoCreateInstance, (void*)CoCreateInstance_Hook,
|
||||||
|
@ -159,6 +233,5 @@ void Wh_ModUninit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate every window to disable BasicThemer
|
// Iterate every window to disable BasicThemer
|
||||||
thisPid = GetProcessIdOfThread(GetCurrentThread());
|
EnumWindows(EnableDWMForAll, 0);
|
||||||
EnumWindows(DisableBasicThemerForAll, thisPid);
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue