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

Windows API "Subset" support for custom themes #77

Closed
wjk opened this issue Jun 14, 2020 · 5 comments
Closed

Windows API "Subset" support for custom themes #77

wjk opened this issue Jun 14, 2020 · 5 comments

Comments

@wjk
Copy link

wjk commented Jun 14, 2020

Proposal: Support custom themes in the Windows API "Subset"

Summary

When I write an application, I sometimes desire to theme my app to look different from the system default. If I am using WPF, this is easy. If I am using Windows Forms (which I prefer), this is very difficult.

Rationale

  • Windows’ UXTHEME subsystem has a very sophisticated custom-theming system already in place, but only Microsoft can supply the msstyles files that are used to store the data (at least without applying deep-seated hacks to the system).
  • According to the roadmap, Reunion will include “Windowing…and GUI subsystem functionality.” In my opinion, the easiest way to implement this feature is to hook into or redefine the comctl32 controls. Reunion’s “subset” feature seems like a good place to do this.

Scope

Capability Priority
Applications can replace the system theme classes for Win32 controls on a per-window basis Must
Applications will still respect High Contrast settings, including using the system High Contrast theme unless the app provides a custom one Must
Applications can define and use new theme classes not present in Windows’ aero.msstyles Should
This proposal will allow end users to re-theme the entire system, including other applications Won't

Important Notes

I would consider implementing this feature using a copy of the comctl32 controls, and registering them using the <windowClass/> element in an SxS manifest, so that Windows uses our implementation to create e.g. a BUTTON, instead of the one in Windows. This implementation could be forked from the one in Windows proper (better, but unlikely), or written from scratch.

If implemented, this feature would best be served as having both a replacement uxtheme.dll (which contains code for interfacing with application-supplied msstyles files), and a replacement comctl32.dll (which references our replacement uxtheme.dll). This will allow for P/Invoking into the replacement uxtheme from Windows Forms apps, if required.

Our replacement implementation of uxtheme.dll must be able to call into the system uxtheme.dll, so that controls that are not overridden to be custom-themed still use the default Windows theme.

I would suggest parroting the semantics (but not the exact file format, which appears to have been obfuscated) of aero.msstyles in our replacement theming library. For example, this means I can define a style class called Custom::Button, which has the same function and semantics as the default button theme part, but I need to call SetWindowTheme(hWnd, "Custom", NULL) before it would be used.

It is impractical to replace comctl32.dll entirely, because that file (or the SxS assemblies that contain it) does quite a bit more than just rendering the common controls, including large amounts of undocumented functionality.

Open Questions

The SxS assembly manifest schema specifies that I can specify window classes as "versioned" so that they won't clobber each other. If so, then how would I ensure that when I do CreateWindowEx("BUTTON"), that I get the version from the subset project instead of Windows’ comctlv6 (or comctlv5, for that matter)? Keep in mind I still need to reference comctlv6, so I can use TaskDialogs, or theme common controls in windows other than the ones I’ve opted into this new system (e.g. MessageBoxes).

@ghost ghost added the needs-triage label Jun 14, 2020
@mdtauk
Copy link

mdtauk commented Jun 15, 2020

If Microsoft were to open up the msstyles format, and make a per app implementation of UxTheme - you could potentially bundle a visual style with the app, and then WinForms could load the assets when creating the window.

It would require a number of things to happen, but it would allow for this kind of thing to be supported, without changing Windows, or reintroducing user changable Visual Styles for the OS Shell.

@stevewri
Copy link
Contributor

Accessibility options like high-contrast white and black are partially implemented with theming. Should an app be able to exempt itself from a session-wide theme a user has chosen to ensure they can control their experience?

@stevewri stevewri self-assigned this Jun 15, 2020
@wjk
Copy link
Author

wjk commented Jun 15, 2020

@stevewri You raise a good point. I’ve added proper High Contrast support to the “Must” list above.

As an aside, the only reason I filed this issue is because I find the default Windows 10 theme to look somewhat bland (IMO the Windows 7 theme was and is the best-looking of all the common-control themes; Windows 8.1 is a distant second). Furthermore, I have also run into problems wherein aero.msstyles contains high-contrast bitmaps that don’t scale in the way that I would prefer them to. I’ve filed a Feedback Hub issue about the latter issue; as expected, there has been no response there whatsoever.

@wjk
Copy link
Author

wjk commented Jun 15, 2020

Please see also #79. If you want to close this issue and continue the discussion there, that’s fine by me. Thanks!

@stevewri
Copy link
Contributor

Yes: let's merge these; closing this one.

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

No branches or pull requests

4 participants