Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Openshell's taskbar doesn't properly show on latest version of Windows 11 (ExplorerPatcher) #2094

Open
Rylydemon04 opened this issue Jan 6, 2025 · 7 comments
Labels
app compatibility Issues regarding compatibility with external programs. Bug Something isn't working right.

Comments

@Rylydemon04
Copy link

Rylydemon04 commented Jan 6, 2025

image On Windows 11 24H2 the taskbar texture does not properly show with Explorer patcher's Windows 10 (explorerpatcher) settings which is the only way to make Openshell show it's start icon and taskbar correctly but in the new update it made the taskbar show like the image above. When I changed the taskbar skins or configured the settings the bug is still present. Please let me know if it's my fault, explorer patcher's fault, Windows's fault or try and fix it for the next versions. Thank you!

Area of issue

Taskbar

To reproduce

  1. Have Windows 24H2
  2. Have explorer patcher and has it settings on Windows 10 (Explorer patcher)
  3. Select any taskbar skins
  4. You will see the problem

Expected behavior

I expected just for it to work.

Open-Shell version

4_4_194

Windows version

Windows 11 24H2

Additional context

No response

@Rylydemon04 Rylydemon04 added the Bug Something isn't working right. label Jan 6, 2025
@ge0rdi ge0rdi changed the title Openshell's taskbar doesn't properly show on latest version of Windows 11 Openshell's taskbar doesn't properly show on latest version of Windows 11 (ExplorerPatcher) Jan 6, 2025
@ge0rdi ge0rdi added the app compatibility Issues regarding compatibility with external programs. label Jan 6, 2025
@ge0rdi
Copy link
Member

ge0rdi commented Jan 6, 2025

This is because ExplorerPatcher's taskbar implementation differs from original Win10 taskbar.

Win10 uses SHFillRectClr export (ordinal 197 from shlwapi.dll) to paint background of tasklist window.
Open-Shell hooks that one and ignores it (so it won't overwrite background of task bar).

ExplorerPatcher (ep_taskbar.5.dll) uses it own implementation of that API, so we cannot hook it.
The implementation calls ExtTextOutW to fill background, so we can hook this API.

@Rylydemon04
Copy link
Author

Thanks for the reply.

@ge0rdi ge0rdi mentioned this issue Jan 18, 2025
@Amrsatrio
Copy link

Amrsatrio commented Jan 19, 2025

Hi, developer of the reimplemented taskbar here, sorry for just responding to this now. I've been packed with RE adventures on the very overengineered and architected 8.1 start screen.

So yeah I know that this is a problem and I've dismissed two issues in EP's repo related to this. First I would admit that I looked at the XP code while doing the reimplementation. Because I know that function is private, exported by ordinal, and not in the public .lib files, I had to do dynamic linking or some other trick that would make it link statically to shlwapi.dll by ordinal. And then I looked at its code in the XP code, found out that the body is very simple (undoubtedly simpler than the excerpt below) so without knowing that Open-Shell or any other program makes use of it for their features, I decided to copy paste it into my codebase. Which works for unmodded, but won't be able to be made to work easily with your program.

I have several things that I can do in mind:

  1. Export my own SHFillRectClr and mark it as noinline. You can perform GetProcAddress on my taskbar module (it can be ep_taskbar.<anything>.dll) and then you can hook it.
  2. Perform dynamic linking to the private SHFillRectClr by its ordinal. Much like this:
// shlwapi.dll ordinal 279
typedef HRESULT (*SHInvokeDefaultCommand_t)(HWND hwnd, IShellFolder* psf, LPCITEMIDLIST pidl);
HRESULT SHInvokeDefaultCommand(HWND hwnd, IShellFolder* psf, LPCITEMIDLIST pidl)
{
    static SHInvokeDefaultCommand_t fn = nullptr;
    if (!fn)
    {
        HMODULE h = GetModuleHandleW(L"shlwapi.dll");
        if (h)
            fn = (SHInvokeDefaultCommand_t)GetProcAddress(h, MAKEINTRESOURCEA(279));
    }
    return fn ? fn(hwnd, psf, pidl) : E_FAIL;
}
  1. Find a way to statically link to that function so you only need to change the DLL handle to be targeting the custom taskbar.

I'm not really familiar with Open-Shell's codebase, so apologies if some things are not feasible. I'm planning for a new EP release next week, so I hope we can find an agreement soon. Thanks!

@Amrsatrio
Copy link

Amrsatrio commented Jan 19, 2025

Please let me know if it's my fault, explorer patcher's fault, Windows's fault

  • Not your fault (though honestly some will say that it's your fault for listening to Microsoft and using 24H2 despite the bugs and problems it has as well as compatibility with customization software such as this an EP).
  • ExplorerPatcher's fault for not being aware to how Open-Shell implements the taskbar texturing feature.
  • Windows's fault for nuking the classic taskbar in 24H2 so I had to reimplement the classic taskbar.

@ge0rdi
Copy link
Member

ge0rdi commented Jan 19, 2025

@Amrsatrio
Thank you for reaching out 👍

Because I know that function is private, exported by ordinal, and not in the public .lib files, I had to do dynamic linking or some other trick that would make it link statically to shlwapi.dll by ordinal.

True that. Didn't realize it is not quite easy to statically import such undocumented function by ordinal.

Export my own SHFillRectClr and mark it as noinline.
Perform dynamic linking to the private SHFillRectClr by its ordinal.

This won't work because we don't do inline hooking (patch code). We do IAT (import address table) hooking instead, where we change address of resolved API in given module we are hooking (ep_taskbar.5.dll in your case).

So we can hook only directly imported API.

Find a way to statically link to that function so you only need to change the DLL handle to be targeting the custom taskbar.

This would work for us, though not sure if that will be feasible for you. Here is some info about importing by ordinal:
https://stackoverflow.com/questions/48047497/how-to-statically-link-to-a-dll-function-that-is-exported-by-an-ordinal
In theory you will need to create .lib from .def file and link with that. Though I didn't try that, so not sure what it involves exactly.

Then there is other option, to hook ExtTextOutW that you are using in your implementation.
I have PoC for that (I guess I'll share PR soon).
I guess I'm fine with that (it will be done only in case of ExplorePatcher's taskbar, so hopefully it will be safe), though it would be better if we can hook just the same API as with original taskbar.

Anyways, thank you for your insights and your hard work on taskbar reimplementation.

ge0rdi added a commit that referenced this issue Jan 19, 2025
@ge0rdi
Copy link
Member

ge0rdi commented Jan 19, 2025

Build from #2107 PR should make taskbar texturing work with ExplorerPatcher.
Anyone, feel free to test.

I will wait for @Amrsatrio regarding static import of SHFillRectClr. And if that turns to be not feasible for them, I guess we can go with changes proposed in the PR.

@Amrsatrio
Copy link

Static importing SHFillRectClr would require me making a dummy "shlwapi.dll" project. But if the ExtTextOutW hook works for you I guess we can settle with it. Make sure you check options to be ETO_OPAQUE, lpString to be nullptr, c to be 0, and lpDx to be nullptr for extra safety.

STDAPI_(void) SHFillRectClr(HDC hdc, LPRECT prc, COLORREF clr)
{
    COLORREF clrSave = SetBkColor(hdc, clr);
    ExtTextOutW(hdc, 0, 0, ETO_OPAQUE, prc, nullptr, 0, nullptr);
    SetBkColor(hdc, clrSave);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
app compatibility Issues regarding compatibility with external programs. Bug Something isn't working right.
Projects
None yet
Development

No branches or pull requests

3 participants