C# 为什么在鼠标移动时使用事件\对象\位置更改触发SetWinEventHook?
我在进程上创建了一个钩子,以便在其窗口移动时进行注册。 我使用事件常量event\u OBJECT\u LOCATIONCHANGE,它根据 对象已更改位置、形状或大小。系统为以下用户界面元素发送此事件:插入符号和窗口对象。服务器应用程序为其可访问对象发送此事件 它可以工作,但也会在应用程序的简单鼠标上方触发。有人能解释为什么吗 下面是一个复制它的示例:C# 为什么在鼠标移动时使用事件\对象\位置更改触发SetWinEventHook?,c#,C#,我在进程上创建了一个钩子,以便在其窗口移动时进行注册。 我使用事件常量event\u OBJECT\u LOCATIONCHANGE,它根据 对象已更改位置、形状或大小。系统为以下用户界面元素发送此事件:插入符号和窗口对象。服务器应用程序为其可访问对象发送此事件 它可以工作,但也会在应用程序的简单鼠标上方触发。有人能解释为什么吗 下面是一个复制它的示例: using System; using System.Diagnostics; using System.Runtime.InteropSer
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
static class NativeMethods
{
[DllImport("user32.dll")]
public static extern System.IntPtr SetWinEventHook(uint eventMin, uint eventMax, System.IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
public delegate void WinEventDelegate(System.IntPtr hWinEventHook, uint eventType, System.IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
}
public partial class Form1 : Form
{
private const uint WINEVENT_OUTOFCONTEXT = 0x0000;
private const uint EVENT_OBJECT_LOCATIONCHANGE = 0x800B;
public Form1()
{
InitializeComponent();
int processId = Process.GetCurrentProcess().Id;
NativeMethods.SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, System.IntPtr.Zero, WinEventProc, (uint)processId, (uint)0, WINEVENT_OUTOFCONTEXT);
}
private void WinEventProc(System.IntPtr hWinEventHook, uint eventType, System.IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
if (hwnd == IntPtr.Zero)
{
Debug.WriteLine("Mouse moved");
}
else
{
Debug.WriteLine("Location changed");
}
}
}
}
头文件
WinUser.h
对EVENT\u OBJECT\u LOCATIONCHANGE
有这样的描述:
* Note also that USER will generate LOCATIONCHANGE notifications for two
* non-window sys objects:
* (1) System caret
* (2) Cursor
这解释了当光标移动时触发事件的原因
正如Hans在评论中所说,只需通过
OBJID\u CURSOR
过滤对象ID,我怀疑这与Winforms生成MouseEnter/Leave事件有关。或者它自动实现一个可访问性服务器。很难缩小范围,这无法轻松关闭。只需忽略回调,您希望通过idObject==OBJID_游标进行筛选。我可以确认,我还可以在鼠标光标移动时看到回调,而不仅仅是Winforms应用程序。