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窗体创建

posted @ 2019-10-18 17:12  quanzhan  阅读(1087)  评论(0)    收藏  举报