Closed legacy1477 closed 11 months ago
That's not something that can be easily done. Ideally, such breakage should be very rare, and shouldn't affect mods in the official repository. Ideally it would be a good idea to verify that all mods compile before releasing a new version, but I didn't have the time to implement such a check yet.
What breakage did you encounter? Please post the code of the mod if possible.
That's not something that can be easily done. Ideally, such breakage should be very rare, and shouldn't affect mods in the official repository. Ideally it would be a good idea to verify that all mods compile before releasing a new version, but I didn't have the time to implement such a check yet.
What breakage did you encounter? Please post the code of the mod if possible.
// ==WindhawkMod==
// @id classic-conhost
// @name Classic Conhost
// @description Forces classic theme and optionally client edge on console windows
// @version 1.0.0
// @author aubymori
// @github https://github.com/aubymori
// @include *
// @compilerOptions -luser32 -ldwmapi -luxtheme
// ==/WindhawkMod==
// ==WindhawkModReadme==
/*
# Classic Conhost
This mod will apply classic theme and optionally client edge to console windows.
**Before**:
![Before](https://raw.githubusercontent.com/aubymori/images/main/classic-conhost-before.png)
**After**:
![After](https://raw.githubusercontent.com/aubymori/images/main/classic-conhost-after.png)
*/
// ==/WindhawkModReadme==
// ==WindhawkModSettings==
/*
- classic: true
$name: Classic theme
$description: Apply classic theme to console windows. Disable this if you use classic theme system-wide.
- clientedge: true
$name: Client edge (Classic theme only)
$description: Apply a client edge to console windows
*/
// ==/WindhawkModSettings==
#include <windows.h>
#include <processthreadsapi.h>
#include <uxtheme.h>
#include <dwmapi.h>
HANDLE g_hObserverThread;
struct {
bool classic;
bool clientedge;
} settings;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
WCHAR szClass[MAX_PATH];
int nStatus = GetClassNameW(hWnd, szClass, MAX_PATH);
BOOL bIsValidString = (((ULONG_PTR)szClass & ~(ULONG_PTR)0xffff) != 0);
if (nStatus && bIsValidString && !wcscmp(szClass, L"ConsoleWindowClass"))
{
if (settings.classic)
{
/* Set window theme */
SetWindowTheme(hWnd, L" ", L" ");
SendMessage(hWnd, WM_THEMECHANGED, NULL, NULL);
/* Disable DWM NC frames */
DWORD dwPol = DWMNCRP_DISABLED;
DwmSetWindowAttribute(
hWnd,
DWMWA_NCRENDERING_POLICY,
&dwPol,
sizeof(DWORD)
);
}
if (settings.clientedge)
{
DWORD dwExStyle = GetWindowLongPtrW(hWnd, GWL_EXSTYLE);
RECT rcWnd;
GetWindowRect(hWnd, &rcWnd);
if ((dwExStyle & WS_EX_CLIENTEDGE) != WS_EX_CLIENTEDGE)
{
SetWindowLongPtrW(
hWnd,
GWL_EXSTYLE,
dwExStyle | WS_EX_CLIENTEDGE
);
/* Resize for client edge */
SetWindowPos(
hWnd,
NULL,
0, 0,
rcWnd.right - rcWnd.left + 4,
rcWnd.bottom - rcWnd.top + 4,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE
);
}
}
}
return TRUE;
}
DWORD CALLBACK ObserverThreadProc(HANDLE handle)
{
HDESK curDesktop = GetThreadDesktop(GetCurrentThreadId());
for (int i = 0; i < 2; i++)
{
EnumDesktopWindows(curDesktop, EnumWindowsProc, NULL);
Sleep(1);
}
return 0;
}
void LoadSettings(void)
{
settings.classic = Wh_GetIntSetting(L"classic");
settings.clientedge = Wh_GetIntSetting(L"clientedge");
}
BOOL Wh_ModInit(void)
{
LoadSettings();
if (settings.classic)
{
WCHAR szPath[MAX_PATH], *pBackslash = NULL;
if (GetModuleFileNameW(NULL, szPath, MAX_PATH))
{
LPWSTR szPathL = wcslwr(szPath);
pBackslash = wcsrchr(szPathL, L'\\');
if (pBackslash && !wcscmp(pBackslash, L"\\conhost.exe"))
{
SetThemeAppProperties(STAP_ALLOW_NONCLIENT);
}
}
}
g_hObserverThread = CreateThread(NULL, NULL, ObserverThreadProc, NULL, NULL, NULL);
SetPriorityClass(g_hObserverThread, REALTIME_PRIORITY_CLASS);
SetThreadPriority(g_hObserverThread, THREAD_PRIORITY_TIME_CRITICAL);
return TRUE;
}
void Wh_ModSettingsChanged(void)
{
LoadSettings();
}
Example of this one not working can be found here: https://github.com/ramensoftware/windhawk-mods/issues/422 I did copy over old .h scripts to the new compiler include folder of Windhawk and tried compiling with them and while I did not encounter issues compiling the mod behaved the same way.
I tried to compile this mod with the latest Windhawk version and it worked. Perhaps the problem was caused by copying Windhawk header files around. Once you start doing those kinds of things, nothing is guaranteed to work.
I'm closing this issue since there seems to be no problem, and since I'm not planning to implement the "old version mode" suggestion.
If you encounter mods that worked with an older version but no longer compile with the latest, unmodified Windhawk, please let me know.
I tried to compile this mod with the latest Windhawk version and it worked. Perhaps the problem was caused by copying Windhawk header files around. Once you start doing those kinds of things, nothing is guaranteed to work.
I'm closing this issue since there seems to be no problem, and since I'm not planning to implement the "old version mode" suggestion.
If you encounter mods that worked with an older version but no longer compile with the latest, unmodified Windhawk, please let me know.
The problem isn't about compiling it's that on version v1.3.1 it makes CMD/conhost classic themed without issue on current version it does the same, but CMD/conhost instantly reverts when interacted with. Can you please investigate this behavior or tell anyone looking for a way to run multiple versions how to do so to get around issues like this?
I'm not using a classic theme so I'm not sure how to test it. @aubymori any idea? I don't see a reason for it to behave differently in v1.3.1 and v1.4.1.
Ah, I remember I found what causes this but I forgot to do anything about it. I'll push an update shortly.
Thanks @aubymori
@legacy1477 from the updated description:
IMPORTANT: READ!
Windhawk and this mod need to inject into
conhost.exe
for this mod to work properly. Please navigate to Windhawk's Settings, Advanced settings, More advanced settings, and make sure thatconhost.exe
is in the Process inclusion list.
conhost.exe is marked as a system process, and Windhawk v1.4.1 doesn’t inject code into it by default. It’s tricky to find the right balance between safety and functionality, I’ll keep gathering user feedback and will adjust Windhawk accordingly.
An issue already showed up with some scripts breaking in newer versions of Windhawk.
An easy solution would be to allow multiple versions to run at the same time. Or add a line in the source code indicating Windhawk should emulate an older version.
For example: