DarkNet icon indicating copy to clipboard operation
DarkNet copied to clipboard

[Question] Dark theme for Interaction.MsgBox

Open VladWinner opened this issue 1 year ago • 5 comments

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();
                }
            }
        }

VladWinner avatar Aug 31 '23 05:08 VladWinner

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

Aldaviva avatar Aug 31 '23 07:08 Aldaviva

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.

Aldaviva avatar Aug 31 '23 07:08 Aldaviva

@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 avatar Sep 02 '23 11:09 memoarfaa

@Aldaviva

Thank you I get it worked

2023-09-04_00-27-36

memoarfaa avatar Sep 03 '23 21:09 memoarfaa

@memoarfaa Can you share the code?

VladWinner avatar Sep 03 '23 23:09 VladWinner