我在一个进程上创建了一个钩子,以便在Window移动时进行注册。 我使用事件常量EVENT_OBJECT_LOCATIONCHANGE,每MSDN
对象已更改位置,形状或大小。系统为以下用户界面元素发送此事件:插入符号和窗口对象。服务器应用程序为其可访问对象发送此事件。
它可以工作,但它也会在应用程序的简单鼠标上触发。任何人都可以解释原因吗?
以下是重现它的示例:
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");
}
}
}
}
答案 0 :(得分:0)
头文件WinUser.h
关于EVENT_OBJECT_LOCATIONCHANGE
这样说:
* Note also that USER will generate LOCATIONCHANGE notifications for two
* non-window sys objects:
* (1) System caret
* (2) Cursor
这说明了为什么光标移动时会触发事件。
就像汉斯在评论中说的那样,只需用OBJID_CURSOR
过滤对象ID。