1

我有一个UserControl-derived带有几个子控件的控件(这里:三个停靠标签)。为了对用户控件上任意位置的点击做出反应,我override WndProc()寻找

WM_PARENTNOTIFY/WM_LBUTTONCLICK

- 这是在MSDN上提出的,并且效果很好。

用户点击鼠标的反应是打开一个(模态)弹出对话框。但是,当我尝试实现这一点时,出现了一个奇怪的行为:有时,对话框会闪烁几次,并且会出现 Windows 声音。关闭对话框后,用户必须单击主窗口(包含 UserControl)才能重新设置焦点。有时,没有闪烁也没有声音,但主窗体也失去了焦点。

与此相反,UserControl 旁边的按钮也会打开该弹出对话框。没有闪烁,没有声音,关闭弹出窗口后,主窗口自动重新获得焦点。

UserControl/WndProc 构造有什么问题?

我包括一个示例项目(VS2008)来说明行为:(通过 DropBox

4

2 回答 2

1

BeginInvoke在 WndProc 方法完成后尝试使用启动事件:

protected override void WndProc(ref Message m) {
  //0x210 is WM_PARENTNOTIFY
  if (m.Msg == 0x210 && m.WParam.ToInt32() == 513)    //513 is WM_LBUTTONCLICK
    {
    Console.WriteLine("## MouseClick on UserControl1 ");
    this.BeginInvoke(new Action(() => UserControlClicked(this, new EventArgs())));
    return;
  }
  /*
  else if (m.Msg == 0x2a1) // WM_MOUSEHOVER
      TTrace.Debug.Send("## WMsg " + m.Msg + " / WParam " + m.WParam.ToInt32());
  */
  base.WndProc(ref m);
}
于 2013-02-04T18:19:52.580 回答
0

这可能会发生,因为您在处理事件的同时打开了一个表单。根据计时器的时间和/或位置,可能会为主窗体或对话框窗体触发挂起的单击事件。

我建议一种解决方法。

检测到点击后,启动一个计时器,在短时间(50 毫秒左右)后打开对话框表单。这将点击事件处理与表单打开分离。这个技巧帮助我多次解决了这类问题。

于 2013-02-04T18:09:42.913 回答