Skip to content

Conversation

@tinodin
Copy link
Contributor

@tinodin tinodin commented May 19, 2025

Automatically changes between light and dark mode based on a set schedule.

@tinodin
Copy link
Contributor Author

tinodin commented May 22, 2025

For your info, I embedded ThemeTool.exe in the mod which is an old executable from Windows 7 (Blog with download link: https://rsn.home.blog/2018/10/26/change-themes-on-the-command-line).

@m417z
Copy link
Member

m417z commented May 22, 2025

Embedding an executable that way isn't acceptable for mods in the repository. One core principle of Windhawk mods is that they're open source. You have the following options:

  • Add an option to specify the path of ThemeTool.exe. The mod users will have to download it manually and provide its path.
  • Reimplement it in the mod, which will result in a better user experience but will require more work.

Also, the executable requires .NET Framework 3.5 which isn't installed by default.

I look at the way that ThemeTool is implemented. It uses the ITheme, IThemeManager interfaces, similar to the ones that can be found here. Here's another example for AHK. Porting it to C++ shouldn't be very difficult.

@tinodin
Copy link
Contributor Author

tinodin commented May 22, 2025

Ok, I will look into implementing it.

@m417z
Copy link
Member

m417z commented May 22, 2025

Here, I ported it:

// ==WindhawkMod==
// @id              apply-theme
// @name            ApplyTheme
// @description     Demo: Run mspaint.exe to ApplyTheme
// @version         0.1
// @author          m417z
// @github          https://github.com/m417z
// @twitter         https://twitter.com/m417z
// @homepage        https://m417z.com/
// @include         mspaint.exe
// @compilerOptions -lole32 -loleaut32
// ==/WindhawkMod==

#include <comdef.h>
#include <winrt/base.h>

// Based on:
// https://github.com/qwerty12/AutoHotkeyScripts/blob/a9423f59c945a3a031cb38b25cf461a34de9a6d3/SetThemeFromdotThemeFile.ahk
bool ApplyTheme(PCWSTR themePath) {
    // {C04B329E-5823-4415-9C93-BA44688947B0}
    constexpr winrt::guid CLSID_IThemeManager{
        0xC04B329E,
        0x5823,
        0x4415,
        {0x9C, 0x93, 0xBA, 0x44, 0x68, 0x89, 0x47, 0xB0}};

    // {0646EBBE-C1B7-4045-8FD0-FFD65D3FC792}
    constexpr winrt::guid IID_IThemeManager{
        0x0646EBBE,
        0xC1B7,
        0x4045,
        {0x8F, 0xD0, 0xFF, 0xD6, 0x5D, 0x3F, 0xC7, 0x92}};

    winrt::com_ptr<IUnknown> pThemeManager;
    HRESULT hr =
        CoCreateInstance(CLSID_IThemeManager, nullptr, CLSCTX_INPROC_SERVER,
                         IID_IThemeManager, pThemeManager.put_void());
    if (FAILED(hr) || !pThemeManager) {
        return false;
    }

    _bstr_t bstrTheme(themePath);
    void** vtable = *(void***)pThemeManager.get();
    using ApplyThemeFunc = HRESULT(WINAPI*)(IUnknown*, BSTR);
    ApplyThemeFunc ApplyThemeMethod = (ApplyThemeFunc)vtable[4];
    hr = ApplyThemeMethod(pThemeManager.get(), bstrTheme);
    if (FAILED(hr)) {
        return false;
    }

    return true;
}

BOOL Wh_ModInit() {
    CoInitialize(nullptr);
    ApplyTheme(L"C:\\Windows\\Resources\\Themes\\aero.theme");
    CoUninitialize();

    return TRUE;
}

@m417z
Copy link
Member

m417z commented May 23, 2025

I've been thinking about the "mods as tools" situation (#1916 (comment)). For the reasons I stated in that comment, I think it's best to have each such mod to run in a separate process. Windhawk doesn't have a built-in functionality for something like that, but for now, I implemented some code to handle that.

Here's your mod with that code added at the bottom, and with the (now unnecessary) mutex removed:
https://gist.github.com/m417z/3b2dafc3fc2f7e88dffe04883f72c8cf

Please try it and let me know if it behaves as expected in all cases. If it is, let's adapt it. In the future, such functionality might become part of Windhawk.

@tinodin
Copy link
Contributor Author

tinodin commented May 23, 2025

Yes it behaves as expected. So would this implementation only be relevant for mods that inject into explorer in order to prevent shell instability?

@tinodin
Copy link
Contributor Author

tinodin commented May 23, 2025

I've been thinking about the "mods as tools" situation (#1916 (comment)). For the reasons I stated in that comment, I think it's best to have each such mod to run in a separate process. Windhawk doesn't have a built-in functionality for something like that, but for now, I implemented some code to handle that.

Here's your mod with that code added at the bottom, and with the (now unnecessary) mutex removed: https://gist.github.com/m417z/3b2dafc3fc2f7e88dffe04883f72c8cf

Please try it and let me know if it behaves as expected in all cases. If it is, let's adapt it. In the future, such functionality might become part of Windhawk.

The only thing that is a bit annoying is that when the mod is loading you get the mouse loading indicator for 3-5 seconds

@m417z
Copy link
Member

m417z commented May 23, 2025

The only thing that is a bit annoying is that when the mod is loading you get the mouse loading indicator for 3-5 seconds

I don't see it, it loads instantly for me. Can you enable logs and post the logs that you get when the mod is enabled?

Also, are there any crash events in the event viewer? Here's a guide for finding crash reports:
https://forums.flightsimulator.com/t/how-to-find-crash-report-from-windows-event-viewer/591676

@m417z
Copy link
Member

m417z commented May 23, 2025

Actually I do see the hourglass cursor now. Here's the fix:
https://gist.github.com/m417z/3b2dafc3fc2f7e88dffe04883f72c8cf/revisions

@m417z
Copy link
Member

m417z commented May 23, 2025

Now the only thing that's missing is a readme. Please add it with a description of the mod, what it does, and how to use it.

@m417z m417z merged commit 3afd45f into ramensoftware:main May 23, 2025
3 checks passed
@m417z
Copy link
Member

m417z commented May 23, 2025

Congratulations on your first mod! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants