UserControl,WndProc和焦点的奇怪行为

时间:2013-02-04 17:52:13

标签: c# winforms user-controls wndproc

我有一个带有多个子控件的UserControl-derived控件(此处:三个停靠标签)。为了对UserControl上的任何地方的点击作出反应,我override WndProc()并寻找

  

WM_PARENTNOTIFY / WM_LBUTTONCLICK

- 这是MSDN建议的,它确实有效。

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

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

UserControl / WndProc构造有什么问题?

我要包含一个示例项目(VS2008)来说明行为:(via DropBox

2 个答案:

答案 0 :(得分:0)

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

我建议解决方法。

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

答案 1 :(得分:0)

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

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);
}