Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cancel the WPF form minimize event

Tags:

c#

winforms

wpf

I want to cancel the natural minimizing behavior and change a WPF form size instead.

I have a solution with the Window_StateChanged but it doesn't look so nice - the window first minimized then jumps back and does the size alteration. Is there a way to accomplish this? I Googled for Window_StateChanging but couldn't figure it out, some sort of external lib that I prefer not to use.

That's what I have:

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

Thanks,

EP

like image 388
LazyZebra Avatar asked Oct 23 '12 02:10

LazyZebra


People also ask

How to disable minimize maximize button in WPF?

In WPF you can indeed set the WindowStyle property of a Window to System. Windows. WindowStyle. ToolWindow to get rid of the minimize and maximize buttons completely, but the window will then look slightly different compared to when the property is set to its default value of SingleBorderWindow.

How to remove minimize and maximize button in c# WPF?

When you want to change the window style, you should pass the GWL_STYLE (= -16) constant as the second argument to the method. To disable and also remove both of the minimize and maximize buttons, call the SetWindowLong with the 0x30000 value.

How do I close a WPF window?

Pressing ALT + F4 . Pressing the Close button.


2 Answers

Try this simple solution:

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;
    }
}
like image 33
Ria Avatar answered Sep 26 '22 20:09

Ria


You'll need to intercept the minimize command before your form fires Window_StateChanged, to avoid the minimize/restore dance you're seeing. I believe the easiest way to do this is to have your form listen for Windows messages and when the minimize command is received, cancel it and resize your form.

Register the SourceInitialized event, in your form constructor:

this.SourceInitialized += new EventHandler(OnSourceInitialized); 

Add these two handlers to your form:

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

I suspect this is the approach you were hoping to avoid but boiled down to the code I show it's not too difficult to implement.

Code based on this SO question.

like image 83
Jay Riggs Avatar answered Sep 24 '22 20:09

Jay Riggs