首页 > 系统相关 >Windows的消息沟子

Windows的消息沟子

时间:2023-04-11 18:14:50浏览次数:32  
标签:IntPtr Windows 钩子 CharSet private 沟子 int 线程 消息

using System.Windows.Interop;

public partial class MainWindow : Window
{
    private const int WM_LBUTTONDOWN = 0x0201;
    private IntPtr _hookID = IntPtr.Zero;

    // 钩子回调函数
    private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);

    // 创建一个成员委托,将其用作成员以防止被垃圾收集
    private HookProc _proc;

    // 注册指定窗口的鼠标钩子
    private void RegisterMouseHook()
    {
        var hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
        hwndSource.AddHook(WndProc);

        _proc = HookCallback;
        _hookID = SetWindowsHookEx(WH_MOUSE_LL, _proc, IntPtr.Zero, GetCurrentThreadId());
    }

    // 取消注册指定窗口的鼠标钩子
    private void UnregisterMouseHook()
    {
        if (_hookID != IntPtr.Zero)
        {
            UnhookWindowsHookEx(_hookID);
            _proc = null;

            var hwndSource = HwndSource.FromHwnd(new WindowInteropHelper(this).Handle);
            hwndSource.RemoveHook(WndProc);
        }
    }

    // 窗口消息处理函数
    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case WM_DESTROY:
                UnregisterMouseHook();
                break;
        }

        return IntPtr.Zero;
    }

    // 钩子回调函数
    private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_LBUTTONDOWN)
        {
            // 处理鼠标左键按下事件
        }

        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }
}

// 声明 Windows API 函数和常量
private const int WH_MOUSE_LL = 14;

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern uint GetCurrentThreadId();

注册沟子简单,核心容易忘的一点就是全局沟子还是单窗口沟子

安装钩子和卸载钩子关键就是SetWindowsHookEx和UnhookWindowsHookEx方法。

 SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)  函数将钩子加入到钩子链表中,说明一下四个参数:

idHook 钩子类型,即确定钩子监听哪种消息, 可以监视窗口过程,也监视消息队列。上面的代码中设为2,即监听键盘消息并且是线程钩子,如果是全局钩子监听键盘消息应设为13,线程钩子监听鼠标消息设为7,全局钩子监听鼠标消息设为14。

代码为5,即C++中的WH_CBT (WH_CBT 当Windows激活、产生、释放(关闭)、最小化、最大化或改变窗口时都将触发此事件)

lpfn 钩子回调的地址指针。根据钩子类型,设置不同的回调函数。如果threadId参数为0 或是一个由别的进程创建的线程的标识,lpfn必须指向DLL中的钩子子程。 除此以外,lpfn可以指向当前进程的一段钩子回调代码。钩子函数的入口地址,当钩子钩到任何消息后立刻调用这个函数。

hInstance 应用程序(dll)实例的句柄。标识包含lpfn所指的回调的DLL。如果threadId 表示当前进程创建的一个线程,而且子程代码位于当前进程,hInstance必须为NULL(即线程钩子传null)。

threadId 设置钩子的线程ID,如果为0 则设置为全局钩子

上面代码中的SetWindowsHookEx方法安装的是线程钩子,用GetCurrentThreadId()函数得到当前的线程ID,钩子就只监听当前线程的键盘消息。

UnhookWindowsHookEx (int idHook) 函数用来卸载钩子,卸载钩子与加入钩子链表的顺序无关,并非后进先出

标签:IntPtr,Windows,钩子,CharSet,private,沟子,int,线程,消息
From: https://www.cnblogs.com/stweily/p/17307148.html

相关文章

  • windows下安装skywalking 9.2
      下载地址:https://skywalking.apache.org/downloads/安装,在skywalking9.0版本以后,APM包和agen包是分离的,解压后默认没有agent文件夹,需要手动创建,然后将解压后的skywalking-agent中的文件复制到agent文件夹下默认解压后的包含的文件创建agent后,目录结构在w......
  • C# Kafka重置到最新的偏移量,即从指定的Partition订阅消息使用Assign方法
    在使用Kafka的过程中,消费者断掉之后,再次开始消费时,消费者会从断掉时的位置重新开始消费。场景再现:比如昨天消费者晚上断掉了,今天上午我们会发现kafka消费的数据不是最新的,而是昨天晚上的数据,由于数据量比较多,也不会及时的消费到今天上午的数据,这个时候就需要我们对偏移量进行重置......
  • C# 控制台应用windows修改host文件
    配置文件修改App.config部分主要是IP与地址<?xmlversion="1.0"encoding="utf-8"?><configuration><startup><supportedRuntimeversion="v4.0"sku=".NETFramework,Version=v4.7.2"/></star......
  • 哪吒探针 - Windows 和Linux端agent安装(详细注意版)
    一、Windows端agent安装配置环境准备环境:Windows服务器软件:哪吒探针点击下载、nssm点击下载(探针agent和nssm都要下载准备好)设置环境变量下载软件后,解压到任意位置,然后按win+R打开运行窗口,输入sysdm.cpl打开系统属性–>高级–>环境变量–>系统变量–>Path在最后把......
  • 微信客服指定客服发送消息
    2023年4月11日15:43:17官方文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html#7参看的easywechat的代码:https://easywechat.com/3.x/staff.html#指定客服发送消息我有点奇怪的是我在官方文档里没有找到对应的指定客服发......
  • 快速把Nginx安装为Windows服务,把软件加入系统服务自动启动方法windows下
    用nssm软件下载地址:https://nssm.cc/download 首先介绍一个NSSM这个小工具,将exe做成系统服务,非常方便实用。官网:NSSM-theNon-SuckingServiceManager直接下载:nssm-2-24NSSM是一个服务封装程序,它可以将普通exe程序封装成服务,使之像windows服务一样运行。同类型的工具还......
  • 在Ubuntu系统上安装windows
    需要的工具:U盘 1.打开ubuntu启动盘制作工具,下载ubuntu镜像,制作启动器2.u盘启动,进入tryubuntu3.终端打开gparted  分割出一块合适大小的nfts区域用来装windows,如果直接用ubuntu的话由于本身的磁盘就在使用所以不能操作,只能在类似pe的系统里面操作4.制作windows启动盘......
  • Studio 3T 2023.3 (macOS, Linux, Windows) - MongoDB 的专业 GUI、IDE 和 客户端,现在
    TheprofessionalGUI,IDEandclientforMongoDB请访问原文链接:https://sysin.org/blog/studio-3t-2023/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgStudio3T,MongoDB的专业GUI、IDE和客户端适用于MongoDB的所有IDE、客户端和GUI工具——在Atlas......
  • 云图说|图解云消息服务KooMessage
    摘要:云消息服务(KooMessage)是提供数字化营销新入口,覆盖全行业、全场景、全终端的一站式富媒体消息服务。本文分享自华为云社区《【开天aPaaS】图解云消息服务KooMessage》,作者:开天aPaaS小助手。云消息服务(KooMessage)是提供数字化营销新入口,覆盖全行业、全场景、全终端的一站式富......
  • Windows汇总
    文件目录高级权限默认共享-赋予读写权限(增删改查)高级共享(无视)安全选项-删除完全控制,修改权限(可以创建文件,并修改创建的文件)-高级权限:保留,写入文件/文件夹......