鼠标事件发送者如何为空? (仅限 Windows 8.1+ TOUCH)
How can a mouse event sender be null? (Only on Windows 8.1+ TOUCH)
这只发生在 Windows 8.1+ 触控设备上。我有一些面板,用户可以在其中用手指滑动。我已经实现了 PreFilterMessage 这样我就可以在整个应用程序中全局捕获鼠标移动,而不必担心子控件的干扰。
我在触摸设备上单击表单时有时会收到一般错误:
IsCanceledMove() Object reference not set to an instance of an object.
我在没有工具栏或工具条的空白表单中进行测试。只有两个面板。一个有大标签,另一个有按钮和文本框。这是我的鼠标移动过滤器,我将引发事件的发件人传递给引发异常的函数。
private static void mouseFilter_MouseFilterMove(object sender, MouseFilterEventArgs e)
{
IsCanceledMove(sender as Control);
}
public bool PreFilterMessage(ref Message m)
{
Point mousePosition = Control.MousePosition;
var args = new MouseFilterEventArgs(MouseButtons.Left, 0, mousePosition.X, mousePosition.Y, 0);
switch (m.Msg)
{
case WM_MOUSEMOVE:
if (MouseFilterMove != null)
MouseFilterMove(Control.FromHandle(m.HWnd), args);
break;
// more cases
}
// Always allow message to continue to the next filter control
return args.Handled;
}
接下来我只是检查一下被移过的控件是否是一个文本框,以及它的文本是否被突出显示。我还检查了另一个 public class 的静态布尔变量。如果其中任何一个为真,我将 LastTouchedPanel
设置为空。 (属于 Panel
类型)
// On Mouse move check if text is behing high lighted
private static void IsCanceledMove(Control c)
{
try
{
// If highlighting text, stop moving
if (c.GetType() == typeof(TextBox))
if ((c as TextBox).SelectionLength > 0)
LastTouchedPanel = null;
// Checks a static boolean variable from another control class.
if (UKSlider.IsSliding)
LastTouchedPanel = null;
}
catch (Exception ex)
{
MessageBox.Show("IsCanceledMove() " + ex.Message);
}
}
如果对象为空,对象如何发送事件?对于 ARM 设备如何处理?这适用于 Windows 10 的 Vista,但不适用于 Windows 10 ARM。
编辑:我注意到 Control.FromHandle(m.HWnd)
有时在我的 PreMessageFilter
和 ARM 设备中 returns Null。放入空检查显然可以解决异常,但是会错过一些移动事件。
空鼠标事件发送器与在触摸设备上使用 IMessageFilter 直接相关。我在 Windows 8.1 触摸设备和 Windows 10.
上看到过这种情况
我在我的应用程序 PreFilterMessage
的事件开始时就开始了。我想确保实际上有一个由 Control.FromHandle
创建的空发件人。果然,我可以看到有时只需触摸我表单上打开的 space 就会 return 一个空控件。据推测,无法转换为 .NET 控件类型的 window 句柄。
带有自定义控件的表单是空的。我确定只使用对 Control.FromHandle
.
安全的控件
所以这引出了一个大问题 - 我怎样才能在尝试转换这些控件时获得空引用?
因为我知道有问题的控件不能转换为 .NET 控件,所以我转向 window 句柄来查找一些信息。我注意空控件上的 window 句柄。
当我单击表单中的空 space 时,我可以看到我按预期获得了表单的 window 句柄。我注意到当我得到空引用时 句柄不是来自我的应用程序中的任何控件。
我认为真的只有一个答案,手势控制器或类似的东西。这是我开始尝试一些手势的时候。就是这样,几个小时以来我第一次很高兴看到空引用异常。
事实证明,用一根手指移动会在您的表单 PreMessageFilter
中移动鼠标。用 两个 手指移动,你会得到你的表单的 mousemove AND 作为来自手势控制器的 mousemove 消息。无法将手势控制器转换为使用 Control.FromHandle
的控件。
这里发生的事情是我在测试期间变得懒惰,并在单击时将手掌放在触摸屏上。
对于我的场景,我知道我只想处理鼠标移动而不关心手势。我可以忽略空句柄。如果你想同时处理这两者,我认为你应该在 PreMessageFilter
中忽略它并使用手势消息正确处理手势。
这只发生在 Windows 8.1+ 触控设备上。我有一些面板,用户可以在其中用手指滑动。我已经实现了 PreFilterMessage 这样我就可以在整个应用程序中全局捕获鼠标移动,而不必担心子控件的干扰。
我在触摸设备上单击表单时有时会收到一般错误:
IsCanceledMove() Object reference not set to an instance of an object.
我在没有工具栏或工具条的空白表单中进行测试。只有两个面板。一个有大标签,另一个有按钮和文本框。这是我的鼠标移动过滤器,我将引发事件的发件人传递给引发异常的函数。
private static void mouseFilter_MouseFilterMove(object sender, MouseFilterEventArgs e)
{
IsCanceledMove(sender as Control);
}
public bool PreFilterMessage(ref Message m)
{
Point mousePosition = Control.MousePosition;
var args = new MouseFilterEventArgs(MouseButtons.Left, 0, mousePosition.X, mousePosition.Y, 0);
switch (m.Msg)
{
case WM_MOUSEMOVE:
if (MouseFilterMove != null)
MouseFilterMove(Control.FromHandle(m.HWnd), args);
break;
// more cases
}
// Always allow message to continue to the next filter control
return args.Handled;
}
接下来我只是检查一下被移过的控件是否是一个文本框,以及它的文本是否被突出显示。我还检查了另一个 public class 的静态布尔变量。如果其中任何一个为真,我将 LastTouchedPanel
设置为空。 (属于 Panel
类型)
// On Mouse move check if text is behing high lighted
private static void IsCanceledMove(Control c)
{
try
{
// If highlighting text, stop moving
if (c.GetType() == typeof(TextBox))
if ((c as TextBox).SelectionLength > 0)
LastTouchedPanel = null;
// Checks a static boolean variable from another control class.
if (UKSlider.IsSliding)
LastTouchedPanel = null;
}
catch (Exception ex)
{
MessageBox.Show("IsCanceledMove() " + ex.Message);
}
}
如果对象为空,对象如何发送事件?对于 ARM 设备如何处理?这适用于 Windows 10 的 Vista,但不适用于 Windows 10 ARM。
编辑:我注意到 Control.FromHandle(m.HWnd)
有时在我的 PreMessageFilter
和 ARM 设备中 returns Null。放入空检查显然可以解决异常,但是会错过一些移动事件。
空鼠标事件发送器与在触摸设备上使用 IMessageFilter 直接相关。我在 Windows 8.1 触摸设备和 Windows 10.
上看到过这种情况我在我的应用程序 PreFilterMessage
的事件开始时就开始了。我想确保实际上有一个由 Control.FromHandle
创建的空发件人。果然,我可以看到有时只需触摸我表单上打开的 space 就会 return 一个空控件。据推测,无法转换为 .NET 控件类型的 window 句柄。
带有自定义控件的表单是空的。我确定只使用对 Control.FromHandle
.
所以这引出了一个大问题 - 我怎样才能在尝试转换这些控件时获得空引用?
因为我知道有问题的控件不能转换为 .NET 控件,所以我转向 window 句柄来查找一些信息。我注意空控件上的 window 句柄。
当我单击表单中的空 space 时,我可以看到我按预期获得了表单的 window 句柄。我注意到当我得到空引用时 句柄不是来自我的应用程序中的任何控件。
我认为真的只有一个答案,手势控制器或类似的东西。这是我开始尝试一些手势的时候。就是这样,几个小时以来我第一次很高兴看到空引用异常。
事实证明,用一根手指移动会在您的表单 PreMessageFilter
中移动鼠标。用 两个 手指移动,你会得到你的表单的 mousemove AND 作为来自手势控制器的 mousemove 消息。无法将手势控制器转换为使用 Control.FromHandle
的控件。
这里发生的事情是我在测试期间变得懒惰,并在单击时将手掌放在触摸屏上。
对于我的场景,我知道我只想处理鼠标移动而不关心手势。我可以忽略空句柄。如果你想同时处理这两者,我认为你应该在 PreMessageFilter
中忽略它并使用手势消息正确处理手势。