检测 WPF 中的系统主题变化 [英] Detect system theme change in WPF

查看:20
本文介绍了检测 WPF 中的系统主题变化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的 WPF 应用程序,我需要检测 DWM 何时打开/关闭或系统主题何时更改.
WinForms中有这样一个事件,但我在WPF中看不到任何.

I need, for my WPF app, to detect when the DWM is turned on/off or when the system theme changes.
There is such an event in WinForms, but I can't see any in WPF.

推荐答案

我还没有听说过 WinForms 事件 在 WinForms 窗口从系统接收消息时触发,但是它有自己的 WndProc() 方法,您可以覆盖它.您可能混淆了窗体事件的窗口消息. 啊,所以它是在 WinForms 窗口中调用的 StyleChanged 事件.我的其余答案仍然有效.

I haven't heard of a WinForms event that fires when a WinForms window receives messages from the system, however it has its own WndProc() method that you can override. You're probably confusing window messages for form events. Ah, so it's the StyleChanged event that gets invoked in WinForms windows. The rest of my answer still stands though.

WPF 与 Windows API 也没有密切联系,因为它是一种高级技术,在内部进行了大量抽象.一方面,它自己在窗口中绘制所有内容,并且不要求系统为它绘制(这就是为什么 WPF 缺少这样一个 StyleChanged 事件).也就是说,当 DWM 切换和主题更改时,Windows 会向所有窗口发送消息,您仍然可以从 WPF 层深入到低级别以访问这些消息并相应地操作您的 WPF 控件.

WPF isn't closely tied to the Windows API either as it's a high-level technology that invests a lot of abstraction away from the internals. For one, it draws everything in a window by itself, and doesn't ask the system to do the drawing for it ( which is why WPF lacks such a StyleChanged event). That said, Windows sends messages to all windows when the DWM is toggled and when the theme changes, and you can still drill down into the low level from the WPF layer to access these messages and manipulate your WPF controls accordingly.

将窗口过程附加到 WPF 窗口的 HWND(窗口句柄),作为窗口 SourceInitialized 事件的一部分.在您的窗口过程中,处理 WM_DWMCOMPOSITIONCHANGEDWM_THEMECHANGED 窗口消息.

Attach a window procedure to your WPF window's HWND (window handle) as part of your window's SourceInitialized event. In your window procedure, handle the WM_DWMCOMPOSITIONCHANGED and WM_THEMECHANGED window messages respectively.

这是一个简单的例子(样板代码改编自 我的这个问题):

Here's a quick example (with boilerplate code adapted from this question of mine):

private IntPtr hwnd;
private HwndSource hsource;

private const int WM_DWMCOMPOSITIONCHANGED= 0x31E;
private const int WM_THEMECHANGED = 0x31A;

private void Window_SourceInitialized(object sender, EventArgs e)
{
    if ((hwnd = new WindowInteropHelper(this).Handle) == IntPtr.Zero)
    {
        throw new InvalidOperationException("Could not get window handle.");
    }

    hsource = HwndSource.FromHwnd(hwnd);
    hsource.AddHook(WndProc);
}

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    switch (msg)
    {
        case WM_DWMCOMPOSITIONCHANGED: 
        case WM_THEMECHANGED:         

            // Respond to DWM being enabled/disabled or system theme being changed

            return IntPtr.Zero;

        default:
            return IntPtr.Zero;
    }
}

这篇关于检测 WPF 中的系统主题变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆