Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在鼠标移动时使用事件\对象\位置更改触发SetWinEventHook?_C# - Fatal编程技术网

C# 为什么在鼠标移动时使用事件\对象\位置更改触发SetWinEventHook?

C# 为什么在鼠标移动时使用事件\对象\位置更改触发SetWinEventHook?,c#,C#,我在进程上创建了一个钩子,以便在其窗口移动时进行注册。 我使用事件常量event\u OBJECT\u LOCATIONCHANGE,它根据 对象已更改位置、形状或大小。系统为以下用户界面元素发送此事件:插入符号和窗口对象。服务器应用程序为其可访问对象发送此事件 它可以工作,但也会在应用程序的简单鼠标上方触发。有人能解释为什么吗 下面是一个复制它的示例: using System; using System.Diagnostics; using System.Runtime.InteropSer

我在进程上创建了一个钩子,以便在其窗口移动时进行注册。 我使用事件常量event\u OBJECT\u LOCATIONCHANGE,它根据

对象已更改位置、形状或大小。系统为以下用户界面元素发送此事件:插入符号和窗口对象。服务器应用程序为其可访问对象发送此事件

它可以工作,但也会在应用程序的简单鼠标上方触发。有人能解释为什么吗

下面是一个复制它的示例:

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应用程序。