除了特定面板之外,在winform上的任何位置添加click事件

时间:2018-01-24 08:40:33

标签: c# winforms

我正在寻找答案,并在@LarsTech找到了一个几乎完整的答案,但没有例外: 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...
}

我想要的是隐藏通知面板,但不是在点击其内容或显示它的个人资料图片时。 我有一个名为NotificationVisible(bool IsVisible)的程序 非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

因此,只要用户点击表单,您的mouseFilter_FormClicked就会触发。现在,您唯一需要做的就是检测鼠标光标后面的控件,然后您可以确定是否需要隐藏面板。

您可以使用WindowFromPoint方法执行此操作。查看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();
        }
    }
}