【问题标题】:Strange behaviour with UserControl, WndProc, and focusUserControl、WndProc 和焦点的奇怪行为
【发布时间】:2013-02-04 17:52:12
【问题描述】:

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

WM_PARENTNOTIFY/WM_LBUTTONCLICK

-- 这是在MSDN 上建议的,效果很好。

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

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

UserControl/WndProc 构造有什么问题?

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

【问题讨论】:

    标签: c# winforms user-controls wndproc


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      我建议一个解决方法。

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

      【讨论】:

      • 我也会尝试这个解决方案。我认为这与解耦事件/动作的原则基本相同。也谢谢你!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多