0

I was looking for an answer and found an almost complete one by @LarsTech but without the exception : https://stackoverflow.com/a/21314496/7026554

//You can still use MessageFilter and just filter for the ActiveForm:

private class MouseDownFilter : IMessageFilter {
  public event EventHandler FormClicked;
  private int WM_LBUTTONDOWN = 0x201;
  private Form form = null;

  [DllImport("user32.dll")]
  public static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd);

  public MouseDownFilter(Form f) {
    form = f;
  }

  public bool PreFilterMessage(ref Message m) {
    if (m.Msg == WM_LBUTTONDOWN) {
      if (Form.ActiveForm != null && Form.ActiveForm.Equals(form)) {
        OnFormClicked();
      }
    }
    return false;
  }

  protected void OnFormClicked() {
    if (FormClicked != null) {
      FormClicked(form, EventArgs.Empty);
    }
  }
}

//Then in your form, attach it:

public Form1() {
  InitializeComponent();
  MouseDownFilter mouseFilter = new MouseDownFilter(this);
  mouseFilter.FormClicked += mouseFilter_FormClicked;
  Application.AddMessageFilter(mouseFilter);
}

void mouseFilter_FormClicked(object sender, EventArgs e) {
  // do something...
}

What I want is to hide the notifications panel but not when clicking on its content or the profile picture that shows it. I have a procedure called NotificationVisible(bool IsVisible) Any help is greatly appreciated.

Outman
  • 3,100
  • 2
  • 15
  • 26
  • 2
    i would create a label or panel covering all the screen and then attach on click to it, and another smaller panel, attached the same onClick as the big panel and check the panel name to see where i clicked – styx Jan 24 '18 at 08:47

1 Answers1

1

So your mouseFilter_FormClicked fires whenever user clickes on form. Now the only thing you need to do is to detect the control that is placed behind the mouse cursor and with that you can deside whether you need to hide your panel or not.

You can do this with WindowFromPoint method. Check this thread.

[System.Runtime.InteropServices.DllImport("user32.dll")]
private static extern IntPtr WindowFromPoint(Point pnt);

void mouseFilter_FormClicked(object sender, EventArgs e) {        
    IntPtr hWnd = WindowFromPoint(Control.MousePosition);
    if (hWnd != IntPtr.Zero) {
        Control ctl = Control.FromHandle(hWnd);
        if (ctl != YourPanelControl) {
             HideThePanel();
        }
    }
}
  • Thank you so much for this! One thing: This would work when clicking on the panel itself but not on its content (A bunch of docked buttons), so should I just add them to the `if` or there is a better way? – Outman Jan 24 '18 at 17:03
  • You can also check that the control is a child of a panel control. Take a look at this https://stackoverflow.com/questions/8595425/how-to-get-all-children-of-a-parent-control – Sergey Shevchenko Jan 25 '18 at 08:37