在窗体上捕获鼠标点击事件(无需使用IMessageFilter)

8
MouseDown 事件在鼠标位于子控件上时不会被调用。我尝试过使用 KeyPreview = true;,但这并没有帮助(尽管对于 KeyDown - 键盘点击有用)。
我正在寻找类似于 KeyPreview 的东西,但是针对鼠标事件。
我不想使用 IMessageFilter 并处理 WinAPI 消息,如果有更简单的替代方案的话(同时,IMessageFilter 是设置在整个应用程序范围内的,我只想在窗体范围内设置)。而遍历所有子控件并订阅每个控件则有其自身的缺点。

你看过MouseHover事件吗?http://msdn.microsoft.com/zh-cn/library/system.windows.forms.control.mousehover(v=vs.110).aspx - Bit
@downvoter 请问您能否评论一下原因? - ispiro
你的要求已经排除了所有可能性。你必须从这两个选择中选择一个。(我不是那个投反对票的人)。 - LarsTech
@LarsTech 谢谢。我只是假设,因为键盘按键有一种简单的方法(使用 KeyPreview = true),那么鼠标点击也会有类似的东西。 - ispiro
1个回答

13

您仍然可以使用MessageFilter并过滤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);
    }
  }
}

然后在你的表单中附加它:

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

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

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