18

So I want to instantly, as this portion of the program relies on speed, trigger a function when the windowstate is changed in my main form. I need it to be something like this:

private void goButton_Click(object sender, EventArgs e)
{
   //Code
}

I checked through the events tab of the form, I have no WindowStateChanged, etc. How do I do this?

The form will be resized a lot, so checking when the size changes won't work.

Jon
  • 2,566
  • 6
  • 32
  • 52
  • Why would the form be resized a lot and what would the performance hit be of an 'if (WindowState == x)' be relative to responding to a WindowStateChanged event (if it existed)? – Mufaka Sep 04 '12 at 19:53

4 Answers4

28

The Resize event (or SizeChanged) will fire when the WindowState changes.


On a side note, WPF does include a StateChanged event for this directly.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Thanks a lot! Does anyone know a way to fire an event when The window is floated to one side of the screen? (Click on caption and drag window to side of screen) The size changed will fire for sure but is there a field or something to get that info? – Noel Widmer Aug 14 '14 at 06:53
  • @NoelWidmer You'd probably need to use windows API calls for win7+ functionality. Not sure what they'd be off hand, though. – Reed Copsey Aug 14 '14 at 17:55
  • 1
    @ReedCopsey Since this really is just changes the position and size of the window I had to check the window position and size on each resize. I am catching the window messages and used MINMAXINFO to get the client workarea. It works now, but thx anyway! – Noel Widmer Aug 15 '14 at 07:58
  • This doesn't work when going from normal->maximized or vice-versa when the size of the window doesn't actually change. Uncommon maybe, but not impossible. – Walt D Jul 07 '17 at 18:43
11

I hope i'm not too late for the party.

The way I chose to implement it is pretty straight forward and doesn't require allocating global variables, simply check the form's WindowState value before and after base.WndProc is called:

    protected override void WndProc(ref Message m)
    {
        FormWindowState org = this.WindowState;
        base.WndProc(ref m);
        if (this.WindowState != org)
            this.OnFormWindowStateChanged(EventArgs.Empty);
    }

    protected virtual void OnFormWindowStateChanged(EventArgs e)
    {
        // Do your stuff
    }

Bottom line - it works.

Nissim
  • 6,395
  • 5
  • 49
  • 74
1

You could try overriding the WndProc function as this link suggests.

From the post:

protected override void WndProc(ref Message m) 
{
    if (m.Msg == /*WM_SIZE*/ 0x0005)
    {
        if(this.WindowState == FormWindowState.Minimized) 
        {
            // do something here
        }
    }

    base.WndProc(ref m);
}

This code just checks what the form state is whenever a Resize event is fired.

Alternatively, you could probably just grab the form's Resize event and check the Window State from there. But I hear that it doesn't fire when a control (or Form?) is Maximized.

Hope this helps!

Calcolat
  • 878
  • 2
  • 11
  • 22
funseiki
  • 9,167
  • 9
  • 36
  • 59
0

You can chage the window state of a form, from another thread using this. This works in .Net Framework 3.5

Invoke(new Action(() => { this.WindowState = FormWindowState.Normal; }));

I hope this might help you.

public partial class Form1 : Form {
private FormWindowState mLastState;
public Form1() {
  InitializeComponent();
  mLastState = this.WindowState;
}
protected override void OnClientSizeChanged(EventArgs e) {
  if (this.WindowState != mLastState) {
    mLastState = this.WindowState;
    OnWindowStateChanged(e);
  }
  base.OnClientSizeChanged(e);
}
protected void OnWindowStateChanged(EventArgs e) {
  // Do your stuff
}
}
Krishna Thota
  • 6,646
  • 14
  • 54
  • 79