首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SetWindowsHookEx和WH_MOUSE_LL使鼠标慢了几秒钟

SetWindowsHookEx和WH_MOUSE_LL使鼠标慢了几秒钟
EN

Stack Overflow用户
提问于 2010-07-12 12:01:49
回答 6查看 10.9K关注 0票数 4

我正在使用下面的代码获取当前进程上的鼠标消息。

代码语言:javascript
运行
复制
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
    return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}

由于某种原因,当此代码运行时,鼠标会慢几秒钟,然后恢复正常。

有什么想法吗?

谢谢

编辑钩子方法

代码语言:javascript
运行
复制
private static IntPtr mouseEvent(int nCode, IntPtr wParam, IntPtr lParam)
{
    if (nCode >= 0 && MouseMessages.WM_LBUTTONDOWN == (MouseMessages)wParam)
    {
        MSLLHOOKSTRUCT hookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));     
        LastLeftClick = new ClickInfo { Time = DateTime.Now, X = hookStruct.pt.x, Y = hookStruct.pt.y };
    }
    return CallNextHookEx(hookID, nCode, wParam, lParam);
}

public class ClickInfo
{
    public int X { get; set; }
    public int Y { get; set; }
    public DateTime Time { get; set; }
}
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-07-12 13:22:53

你的钩子程序是什么样子的?

如果您的进程只有一个UI线程,则使用消息筛选器:http://msdn.microsoft.com/en-us/library/system.windows.forms.application.addmessagefilter.aspx

票数 2
EN

Stack Overflow用户

发布于 2010-07-19 23:28:08

我也有同样的问题(只是它是c++项目,而不是c#),并通过将钩子从WH_MOUSE_LL改为WH_MOUSE (从低级到普通级别)来解决它。对于WM_LBUTTONUP和WM_RBUTTONUP消息,它工作正常。

有趣的是,在我编写WH_MOUSE_LL的时候,它的代码做得很好(没有鼠标冻结等等)。Windows的一些安全更新似乎改变了鼠标钩子的行为,而以前的精细代码就成了一个问题。

票数 3
EN

Stack Overflow用户

发布于 2018-09-06 10:26:49

我很抱歉在这么长时间之后继续跟进,但我已经通过生成一个单独的线程来解决这个问题,该线程处理钩子(我没有在代码中添加所有内容,因为它也翻译了消息,但主要思想应该是明确的):

代码语言:javascript
运行
复制
    public Form1()
    {
        InitializeComponent();

        Thread thread = new Thread(HookThread);
        thread.IsBackground = true;
        thread.Start();
    }

    private void HookThread()
    {
        _hookControl = new Control();
        IntPtr handle = _hookControl.Handle;

        _hookProc = new HookProc(HookFunction);
        using (Process curProcess = Process.GetCurrentProcess())
        using (ProcessModule curModule = curProcess.MainModule)
        {
            _hook = SetWindowsHookEx(HookType.WH_MOUSE_LL, _hookProc, GetModuleHandle(curModule.ModuleName), 0);// (uint)AppDomain.GetCurrentThreadId());
        }

        Application.Run();

        UnhookWindowsHookEx(_hook);
        _hook = IntPtr.Zero;
    }

    private IntPtr HookFunction(int code, IntPtr wParam, IntPtr lParam)
    {
        if (code < 0)
        {
            //you need to call CallNextHookEx without further processing
            //and return the value returned by CallNextHookEx
            return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
        }

        int msg = wParam.ToInt32();
        string messages = string.Join(", ", _messageMapping.Where(t => t.Item1 == msg).Select(t => t.Item2));
        if (string.IsNullOrWhiteSpace(messages))
            messages = msg.ToString();
        Trace.WriteLine($"Messages: { messages }");

        //return the value returned by CallNextHookEx
        return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
    }

通过在创建的BeginInvoke上调用_hookControl,您可以从任何其他线程终止线程:

代码语言:javascript
运行
复制
        _hookControl.BeginInvoke(((Action)(() => Application.ExitThread())));
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3228293

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档