zoukankan      html  css  js  c++  java
  • C# 中使用RegisterShellHookWindow Hook窗体创建

    前言:最近在写一个桌面程序时需要全局HOOK 窗体的创建,但是在.net中SetWindowsHookEx()只可实现键盘鼠标的全局钩子,其余的全局钩子都需要使用DLL。难道就没有解决办法了么?经过长时间的搜索后在CSDN的一篇帖子中,有大神提到了RegisterShellHookWindow()这个方法。但是又经过一番搜索后,发现基本上是C++或者其他语言的使用分享。所以写下了这篇文章,给后来的人提供快速解决的途径。

    在WinForm中使用RegisterShellHook

    1.准备工作
    ......
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern bool RegisterShellHookWindow(IntPtr hWnd);
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern uint RegisterWindowMessage(string Message);
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern bool DeregisterShellHookWindow(IntPtr hHandle);
    ......
    uint WM_ShellHook;
    public enum ShellEvents
    {
        HSHELL_WINDOWCREATED = 1,
        HSHELL_WINDOWDESTROYED = 2,
        HSHELL_ACTIVATESHELLWINDOW = 3,
        HSHELL_WINDOWACTIVATED = 4,
        HSHELL_GETMINRECT = 5,
        HSHELL_REDRAW = 6,
        HSHELL_TASKMAN = 7,
        HSHELL_LANGUAGE = 8,
        HSHELL_SYSMENU = 9,
        HSHELL_ENDTASK = 10,
        HSHELL_ACCESSIBILITYSTATE = 11,
        HSHELL_APPCOMMAND = 12,
        HSHELL_WINDOWREPLACED = 13,
        HSHELL_WINDOWREPLACING = 14,
        HSHELL_HIGHBIT = 0x8000,
        HSHELL_FLASH = (HSHELL_REDRAW | HSHELL_HIGHBIT),
        HSHELL_RUDEAPPACTIVATED = (HSHELL_WINDOWACTIVATED | HSHELL_HIGHBIT)
    }
    2.注册钩子
    • 注意事项:不要在构造函数中注册钩子,此时窗体的handle未被创建。
    private void Form1_Load(object sender, EventArgs e)
    {
        if (RegisterShellHookWindow(this.Handle))
        {
            WM_ShellHook = RegisterWindowMessage("SHELLHOOK");
        }
    }

    3.处理消息

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_ShellHook)
        {
            switch ((ShellEvents)m.WParam)
            {
                case ShellEvents.HSHELL_WINDOWCREATED:
                    Console.WriteLine("窗体创建");
                    break;
                default:
                    break;
            }
        }
        base.WndProc(ref m);
    }

    4.卸载钩子

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        DeregisterShellHookWindow(this.Handle);
    }

    在WPF中使用RegisterShellHook

    • WPF较为特殊,handle不能直接取得,WndProc方法不能直接重写。

    1.准备工作

    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern bool RegisterShellHookWindow(IntPtr hWnd);
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern uint RegisterWindowMessage(string Message);
    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern bool DeregisterShellHookWindow(IntPtr hHandle);
    public enum ShellEvents
    {
        HSHELL_WINDOWCREATED = 1,
        HSHELL_WINDOWDESTROYED = 2,
        HSHELL_ACTIVATESHELLWINDOW = 3,
        HSHELL_WINDOWACTIVATED = 4,
        HSHELL_GETMINRECT = 5,
        HSHELL_REDRAW = 6,
        HSHELL_TASKMAN = 7,
        HSHELL_LANGUAGE = 8,
        HSHELL_SYSMENU = 9,
        HSHELL_ENDTASK = 10,
        HSHELL_ACCESSIBILITYSTATE = 11,
        HSHELL_APPCOMMAND = 12,
        HSHELL_WINDOWREPLACED = 13,
        HSHELL_WINDOWREPLACING = 14,
        HSHELL_HIGHBIT = 0x8000,
        HSHELL_FLASH = (HSHELL_REDRAW | HSHELL_HIGHBIT),
        HSHELL_RUDEAPPACTIVATED = (HSHELL_WINDOWACTIVATED | HSHELL_HIGHBIT)
    }
    uint WM_ShellHook;
    2.注册钩子
    private IntPtr handle;
    public MainWindow()
    {
        InitializeComponent();
        this.SourceInitialized += new EventHandler(Win_SourceInitialized);
    }
    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        handle = new WindowInteropHelper(this).Handle;
        if (RegisterShellHookWindow(handle))
        {
            WM_ShellHook = RegisterWindowMessage("SHELLHOOK");
        }
    }
    private void Win_SourceInitialized(object sender, EventArgs e)
    {
        HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
        if (source != null) source.AddHook(WndProc);
    }

    3.处理消息

    private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_ShellHook)
        {
            switch ((ShellEvents)wParam)
            {
                case ShellEvents.HSHELL_WINDOWCREATED:
                    Console.WriteLine("窗体被创建");
                    break;
            }
        }
        return IntPtr.Zero;
    }
    4.卸载钩子
    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        DeregisterShellHookWindow(handle);
    }

    引用:简书 C# 中使用RegisterShellHookWindow Hook窗体创建

  • 相关阅读:
    Linux下处理文件中的^M
    python selenium-webdriver 生成测试报告 (十四)
    Apache 配置Https 转发Tomcat Http
    自动化测试神器 之 python unittest 断言
    创建高性能索引笔记
    【转】正向代理vs反向代理
    vue 常用问题
    eslint 代码规范2
    WebStrom2018注册码
    Vue-selller 饿了吗
  • 原文地址:https://www.cnblogs.com/code1992/p/11699416.html
Copyright © 2011-2022 走看看