如何取消WPF窗体最小化事件

5

我希望取消自然最小化行为,改变WPF表单的大小。

我有一个使用Window_StateChanged的解决方案,但它看起来不太好 - 窗口首先最小化,然后跳回并进行大小调整。有没有办法实现这一点?我尝试了Google Window_StateChanging,但无法弄清楚,还有一些外部库,我不想使用。

这就是我目前的代码:

private void Window_StateChanged(object sender, EventArgs e)
{
    switch (this.WindowState)
    {
        case WindowState.Minimized:
            {
                WindowState = System.Windows.WindowState.Normal;
                this.Width = 500;
                this.Height = 800;
                break;
            }
    }
}

谢谢,
EP
2个回答

13

在您的窗体触发 Window_StateChanged 事件之前,您需要拦截最小化命令,以避免出现您所看到的最小化/恢复舞蹈。我相信最简单的方法是使您的窗体监听 Windows 消息,并在接收到最小化命令时取消它并调整您的窗体大小。

在您的窗体构造函数中注册 SourceInitialized 事件:

this.SourceInitialized += new EventHandler(OnSourceInitialized); 

在您的表单中添加这两个处理程序:

private void OnSourceInitialized(object sender, EventArgs e) {
    HwndSource source = (HwndSource)PresentationSource.FromVisual(this);
    source.AddHook(new HwndSourceHook(HandleMessages));
} 

private IntPtr HandleMessages(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {
    // 0x0112 == WM_SYSCOMMAND, 'Window' command message.
    // 0xF020 == SC_MINIMIZE, command to minimize the window.
    if (msg == 0x0112 && ((int)wParam & 0xFFF0) == 0xF020) {
        // Cancel the minimize.
        handled = true;

        // Resize the form.
        this.Width = 500;
        this.Height = 500;
    }

    return IntPtr.Zero;
} 
我怀疑这是你希望避免的方法,但是从我展示的代码中可以看出,实现起来并不太困难。
基于这个SO问题的代码。

上述代码取消了窗口系统菜单中的最小化命令,但Win-Down热键仍然有效。 - Aleksandr
我相信你可以重写OnSourceInitialized而不是设置事件处理程序;这样会稍微简单一些。 - StayOnTarget

1

尝试这个简单的解决方案:

public partial class MainWindow : Window
{
    private int SC_MINIMIZE = 0xf020;
    private int SYSCOMMAND = 0x0112;

    public MainWindow()
    {
        InitializeComponent();
        SourceInitialized += (sender, e) =>
                                 {
                                     HwndSource source = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
                                     source.AddHook(WndProc);
                                 };
    }

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        // process minimize button
        if (msg == SYSCOMMAND && SC_MINIMIZE == wParam.ToInt32())
        {
            //Minimize clicked
            handled = true;
        }
        return IntPtr.Zero;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接