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

Dark scrollbars #6

Open
AndnixSH opened this issue May 9, 2023 · 9 comments
Open

Dark scrollbars #6

AndnixSH opened this issue May 9, 2023 · 9 comments
Assignees

Comments

@AndnixSH
Copy link

AndnixSH commented May 9, 2023

Do you know if it's possible to enable dark scrollbars natively in WinForm? Notepad++ and Windows Explorer are using native dark scrollbars

@Aldaviva
Copy link
Owner

Aldaviva commented May 9, 2023

That's a good question. I remember seeing some light scrollbars in WPF but haven't looked at Windows Forms yet. I'll check to see if the Win32 demo has dark scrollbars.

@Aldaviva Aldaviva self-assigned this May 9, 2023
@Aldaviva
Copy link
Owner

Aldaviva commented May 12, 2023

I'm not exactly sure what C++ nonsense this is, but it looks like win32-darkmode is making their native scrollbars dark by wrapping a method from comctl32.dll in FixDarkScrollBar() to force the class name to a different value that gets skinned dark by Windows:

void FixDarkScrollBar()
{
	HMODULE hComctl = LoadLibraryExW(L"comctl32.dll", nullptr, LOAD_LIBRARY_SEARCH_SYSTEM32);
	if (hComctl)
	{
		auto addr = FindDelayLoadThunkInModule(hComctl, "uxtheme.dll", 49); // OpenNcThemeData
		if (addr)
		{
			DWORD oldProtect;
			if (VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), PAGE_READWRITE, &oldProtect))
			{
				auto MyOpenThemeData = [](HWND hWnd, LPCWSTR classList) -> HTHEME {
					if (wcscmp(classList, L"ScrollBar") == 0)
					{
						hWnd = nullptr;
						classList = L"Explorer::ScrollBar";
					}
					return _OpenNcThemeData(hWnd, classList);
				};

				addr->u1.Function = reinterpret_cast<ULONG_PTR>(static_cast<fnOpenNcThemeData>(MyOpenThemeData));
				VirtualProtect(addr, sizeof(IMAGE_THUNK_DATA), oldProtect, &oldProtect);
			}
		}
	}
}

win32-darkmode

I have no idea how to do this in C#, but I might try to give it a shot.

@memoarfaa
Copy link

@AndnixSH
@Aldaviva
To enable dark scrollbars natively in WinForm you need to use "SetWindowTheme" function
https://learn.microsoft.com/en-us/windows/win32/api/uxtheme/nf-uxtheme-setwindowtheme

[DllImport("uxtheme.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
public static extern int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);

SetWindowTheme(control.Handle, "DarkMode_Explorer", "ScrollBar");

example to dark scrollbar and treeView

https://www.mediafire.com/file/4m0uieavnkityje/DarkWinForm.zip/file

2023-08-18_01-04-06

@Aldaviva
Copy link
Owner

Aldaviva commented Aug 18, 2023

Oh wow thanks, that's way easier than the win32-darkmode C++ function wrapping technique.

I'll try to see if there's a good way to handle this automatically in this library, but at the very least, this method can be called manually (either directly by the dependent UI app, or proxied by this library for convenience).

Aldaviva added a commit that referenced this issue Aug 20, 2023
…ifferent windows? [appears to work, API is neither documented nor finalized]
@memoarfaa
Copy link

@Aldaviva
Can you support Dark built in ScrollBar of MdiClient and Dark TreeView

Controls.Cast<Control>().ToList().ForEach(control =>
            {
                if (control.GetType().Name == nameof(MdiClient))
                {
                    SetWindowTheme(control.Handle, "DarkMode_Explorer", "ScrollBar");
                }
                else if(control.GetType().Name == nameof(TreeView))
                {
                   control.ForeColor = Color.White;
                   control..BackColor = Color.FromArgb(25, 25, 25);
                    SetWindowTheme(control.Handle, "DarkMode_Explorer", "TreeView");
                }

            });
2023-08-20_20-22-57.mp4

@Aldaviva
Copy link
Owner

Aldaviva commented Aug 20, 2023

Thanks, let me try that out! I'm definitely not a Forms expert so I appreciate the assistance.

Aldaviva added a commit that referenced this issue Aug 21, 2023
@AndnixSH
Copy link
Author

@memoarfaa that's nice. Would it support buttons, textboxes and dropdowns too, like how Notepad++ and foobar2000 implemented them?

image

@memoarfaa
Copy link

memoarfaa commented Aug 25, 2023

@Aldaviva
@AndnixSH

[DllImport("user32.dll", CharSet = CharSet.Auto)]
 public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

  Controls.Cast<Control>().ToList().ForEach(control =>
            {
                if (control.GetType().Name == nameof(MdiClient) | control.GetType().BaseType.Name == nameof(ScrollBar))
                {
                    SetWindowTheme(control.Handle, "DarkMode_Explorer", "ScrollBar");
                    // Fix scrollbar corners and TreeView borders not repainting with the new theme
                    SendMessage(control.Handle, WM_THEMECHANGED, 0, 0);
                }
                else if(control.GetType().Name == nameof(TreeView))
                {
                    control.ForeColor = Color.White;
                    control.BackColor = Color.FromArgb(25, 25, 25);
                    SetWindowTheme(control.Handle, "DarkMode_Explorer", "TreeView");
                    SendMessage(control.Handle, WM_THEMECHANGED, 0, 0);
                }
                else if (control.GetType().Name == nameof(Button))
                {
                   
                    ((Button)control).FlatStyle = FlatStyle.System;
                    SetWindowTheme(control.Handle, "DarkMode_Explorer", "Button");
                    SendMessage(control.Handle, WM_THEMECHANGED, 0, 0);
                }

                else if (control.GetType().Name == nameof(TextBox))
                {
                    control.ForeColor = Color.White;
                    SetWindowTheme(control.Handle, "DarkMode_InActiveAddressComposited", "Edit");
                    // Another Dark Theme for Edit
                   // SetWindowTheme(control.Handle, "DarkMode_CFD", "Edit");
                    SendMessage(control.Handle, WM_THEMECHANGED, 0, 0);
                }
                
                else if (control.GetType().Name == nameof(CheckBox))
                {
                    ((CheckBox)control).FlatStyle = FlatStyle.System;
                    SetWindowTheme(control.Handle, "DarkMode_Explorer", "CheckBox");
                    SendMessage(control.Handle, WM_THEMECHANGED, 0, 0);
                }
                
                else if (control.GetType().Name == nameof(ComboBox))
                {
                    control.ForeColor = Color.White;
                    control.BackColor = Color.FromArgb(19,19,19);
                    SetWindowTheme(control.Handle, "DarkMode_CFD", "ComboBox");
                    // Another Dark Theme for ComboBox
                    // SetWindowTheme(control.Handle, "DarkMode_AddressComposited", "ComboBox");
                    SendMessage(control.Handle, WM_THEMECHANGED, 0, 0);
                }
              

            });

2023-08-25_06-49-48

@Aldaviva
Copy link
Owner

Nice, I'll take a look at that.

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

No branches or pull requests

3 participants