我有一个带有多个子控件的UserControl-derived
控件(此处:三个停靠标签)。为了对UserControl上的任何地方的点击作出反应,我override WndProc()
并寻找
WM_PARENTNOTIFY / WM_LBUTTONCLICK
- 这是MSDN建议的,它确实有效。
用户鼠标点击的反应是打开(模态)弹出对话框。但是,当我尝试实现此操作时,会出现一个奇怪的行为:有时,对话框会闪烁几次,并发出Windows声音。关闭对话框后,用户必须单击主窗口(包含UserControl)才能重新设置焦点。有时,没有闪烁和没有声音,但主要形式也失去了焦点。
与此相反,UserControl旁边的按钮也会打开该弹出对话框。没有闪烁和没有声音,关闭弹出窗口后,主窗口会自动重新聚焦。
UserControl / WndProc构造有什么问题?
我要包含一个示例项目(VS2008)来说明行为:(via DropBox)
答案 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);
}