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

[Question] Dark theme for Interaction.MsgBox #10

Open
VladWinner opened this issue Aug 31, 2023 · 5 comments
Open

[Question] Dark theme for Interaction.MsgBox #10

VladWinner opened this issue Aug 31, 2023 · 5 comments
Assignees
Labels
question Further information is requested

Comments

@VladWinner
Copy link

I'm developing a WPF application and I use Interaction.MsgBox instead of MessageBox.Show, because I want to get Windows 11 native visual style (modern buttons and icons).
MessageBox.Show:
image

Interaction.MsgBox:
image

Thanks to DarkNet, I activated the dark theme for everything I wanted, except for this dialog box. Can you help me to do this?

The beginning of my App.xaml.cs:

namespace App
{
    public partial class App : Application
    {
        void App_Startup(object sender, StartupEventArgs e)
        {
            System.Windows.Forms.Application.EnableVisualStyles(); // this is required to enable native visual styles
            DarkNet.Instance.SetCurrentProcessTheme(Theme.Auto);

Dialog box in MainWindow.xaml.cs:

        private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Escape)
            {
                string question = "Do you really want to quit?";
                MessageBoxResult result = (MessageBoxResult)
                    Interaction.MsgBox(question, MsgBoxStyle.YesNo, "App");
                if (result == MessageBoxResult.Yes)
                {
                    this.Close();
                }
            }
        }
@Aldaviva
Copy link
Owner

I had to do something similar in an automated test for a different project, let me see if that technique also works here.

@Aldaviva Aldaviva self-assigned this Aug 31, 2023
@Aldaviva Aldaviva added the question Further information is requested label Aug 31, 2023
@Aldaviva
Copy link
Owner

This brute force technique may not be the best, but I was able to turn the message box title bar dark by having another thread that finds the window by class name and PID using the mwinapi library, then uses DarkNet to set the window to dark mode using its HWND. The background task thread does this while the main thread is blocked waiting for the dialog box to return a result. I don't notice any delay before the theme is applied.

SystemWindow? dialogBox = null;
int selfPid;
using (Process selfProcess = Process.GetCurrentProcess()) {
    selfPid = selfProcess.Id;
}

Task.Run(() => {
    while (dialogBox == null) {
        dialogBox = SystemWindow.DesktopWindow.FilterDescendantWindows(false, window => {
            if (window.ClassName != "#32770") return false;
            using Process process = window.Process; // expensive
            return process.Id == selfPid;
        }).FirstOrDefault();

        if (dialogBox != null) {
            DarkNet.Instance.SetWindowThemeRaw(dialogBox.HWnd, Theme.Auto);
        }
    }
});

DialogResult dialogResult = System.Windows.Forms.MessageBox.Show("hello", "app", MessageBoxButtons.YesNo, MessageBoxIcon.None); // Forms message box
// MsgBoxResult msgBoxResult = Interaction.MsgBox("hello", MsgBoxStyle.YesNo, "App"); // Interaction message box

image

It works the same with both Forms and Interactions message boxes.

You could also add sleeps or a maximum timeout via cancellation token if those are helpful to your scenario. Also, you may be able to speed up the window finding logic if the dialog box is a child of some other window you know about, but in my testing I could only find it by searching through all windows.

There seems to be a bit of a race condition where the title bar sometimes looks deactivated, but it fixes itself if you blur and focus the window again. I'm not sure what's going on there.

This logic comes from an automated test I wrote recently which asserts that an error message is shown properly in the dialog box of a Winamp plugin, then closes the dialog box automatically, without deadlocking the test.

@memoarfaa
Copy link

memoarfaa commented Sep 2, 2023

@Aldaviva
D you now how to change the background color of the text and icon of message boxes

2023-09-02_14-22-22

2023-09-02_14-40-10

2023-09-02_14-13-44

@memoarfaa
Copy link

@Aldaviva

Thank you I get it worked

2023-09-04_00-27-36

@VladWinner
Copy link
Author

@memoarfaa Can you share the code?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants