Abdelrhman-AK / WinPaletter

Advanced Windows Appearance Editor
Other
1.38k stars 57 forks source link

Feature ideas : add support for High Contrast mode. #40

Open OrthodoxWindows opened 2 years ago

OrthodoxWindows commented 2 years ago

The high contrast mode is a mode introduced in Windows 8, to compensate for the discontinuation of support for the classic theme for visually impaired users. For Win32 programs, it uses the Aero Lite visual style in a particular mode (much like Aero's "Dark" mode), which forces rendering by Win32 color settings. In UWP/WinUI apps, it forces the use of Win32 color settings, which is the only way, since UWP apps don't work with the classic theme. The parameters used are only certain colors, less than with the classic theme. Tomorrow I will post the links to the Microsoft documentation on this subject, as well as the research I have done on the parameters used, and the results on the Win32 and UWP type elements and for the Windows 10 taskbar and start menu (I don't is not sought for Windows 8 and 11).

It seems to me that the result Win32 programs are almost between Windows 8/10/11, but much less the UWP type elements.

Abdelrhman-AK commented 2 years ago

That is great! I'll work on it when you post the documentation.

OrthodoxWindows commented 7 months ago

I will try to quickly provide you with the necessary documentation (probably in the coming days).

Abdelrhman-AK commented 7 months ago

I am finalizing version 1.0.9.1 because I won't have any time in a few days. I might include this feature if it functions correctly.

This user32 function manages to enable/disable high contrast colors:

        /// <summary>
        /// Enable or disable the high contrast mode.
        /// </summary>
        /// <param name="enable"></param>
        /// <returns></returns>
        public static bool SetHighContrast(bool enable)
        {
            HIGHCONTRAST highContrast = new()
            {
                cbSize = Marshal.SizeOf(typeof(User32.HIGHCONTRAST)),
                dwFlags = enable ? 0x1u : 0x0u // Set to HCF_HIGHCONTRASTON to enable, 0 to disable
            };

            return User32.SystemParametersInfo(0x0043 /*User32.SPI.SPI_SETHIGHCONTRAST*/, highContrast.cbSize, ref highContrast, 0x01 | 0x02);
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct HIGHCONTRAST
        {
            public int cbSize;
            [MarshalAs(UnmanagedType.U4)]
            public uint dwFlags;
            public string lpszDefaultScheme;
        }

Unfortunately, customizing colors is not working as it should. To make colors synchronized with the system, I should apply classic colors two or more times, and sometimes not applied at all, and this won't be suitable for users.

Abdelrhman-AK commented 6 months ago

This feature is coming soon in a new update.

OrthodoxWindows commented 6 months ago

Thank you for these changes, and sorry for having forgotten this discussion a little... To clarify, high contrast mode (or rather the associated API) has the particularity of applying certain classic Win32 colors to modern elements (taskbar, start screen, UWP applications). What I promised to provide you with is a detailed plan of the colors corresponding to the different elements. I will provide this to you in the future, in a separate discussion.

OrthodoxWindows commented 6 months ago

Regarding the synchronization problem, it may be because of the registry keys in which WinPaletter writes. You may remember the problem with the HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\DefaultColors\Standard key; there is a neighboring key (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\DefaultColors\HighContrast), which takes care of the colors used in high contrast mode. Obviously, the colors are written in duplicate in this key and the standard key for colors (HKCU\Control Panel\Colors), only if a high contrast theme is applied I'm not sure if this is the only problem, but it might be part of the answer.

OrthodoxWindows commented 6 months ago

After testing, I noticed that the colors applied (regardless of the selected scheme) are those of the previous high contrast theme applied with the default theme engine. For example, I had just applied the High Contrast White theme with the system, then switched to Windows Aero (so I was no longer in high contrast mode). Then, I activated the high contrast with WinPaletter, keeping the same color scheme (Aero fallback); the majority of the colors went to High Contrast White. The only colors that apply seem to be those that are not managed by the visual style and therefore appear all the time (like the window background), and the colors on "modern" elements (UWP type).

OrthodoxWindows commented 6 months ago

If you want a screen recording of that, I can provide it.

Abdelrhman-AK commented 6 months ago

If you want a screen recording of that, I can provide it.

If this is possible, then please post it so that I can understand it more, or write steps to be made into the Windows Registry.

OrthodoxWindows commented 6 months ago

Here is the screen recording :

https://github.com/Abdelrhman-AK/WinPaletter/assets/100134023/8018f559-6012-4ab5-b113-db44d40531ee

And additional screenshots : ApplicationFrameHost_Xy43k6JqjH imdisplay_2IBqQLLdSz

The theme applied is the default Windows theme (including AeroFallback). The last high contrast theme applied was HighContrastWhite. When enabling high contrast mode with WinPaletter, the following are correctly applied: Metro/UWP, Win32 with classic theme and DWM title bar. In contrast, Win32 elements dependent on the visual style are displayed with the colors of the previous high contrast theme (here High contrast white).

Abdelrhman-AK commented 6 months ago

Thank you for these information!

     // Broadcast the system message to notify about the setting change
     User32.SendMessage(IntPtr.Zero, User32.WindowsMessages.WM_SETTINGCHANGE | User32.WindowsMessages.WM_THEMECHANGED | User32.WindowsMessages.WM_SYSCOLORCHANGE, IntPtr.Zero, IntPtr.Zero);

Using real Windows 11:

This is the first applying trial: 0

This is the third trial: 1

This is after trying a different scheme: 2


Using Windows 10 VM:

This is the first applying trial: 10_0

This is the second applying trial: 10_1

This is after a logoff and logon. It wasn't colored correctly until I did that: 10_2


The conclusion is that I don't know the correct method to synchronize colors when high-contrast mode is enabled.

Temporarily, reapplying Classic Colors multiple times, then logging off and back on, fixes the issue.

If I (or you) find a solution , I'll implement it in 2 or 3 weeks from now, as I currently don't have enough time for coding.