作者: wtujoxk
查看: 8116|回复: 13

[源码] 【键盘监控】GlobalHook 全局钩子

[复制链接]
wtujoxk 发表于 2014-12-11 13:01:24 | 显示全部楼层 |阅读模式
查看: 8116|回复: 13
效果图:


源码:
[C#] 纯文本查看 复制代码
public GlobalHookHelper()
        {
            Start();
        }

        public GlobalHookHelper(bool InstallMouseHook, bool InstallKeyboardHook)
        {
            Start(InstallMouseHook, InstallKeyboardHook);
        }

        ~GlobalHookHelper()
        {
            Stop(true, true, false);
        }

        public event MouseEventHandler OnMouseActivity;
        public event KeyEventHandler KeyDown;
        public event KeyPressEventHandler KeyPress;
        public event KeyEventHandler KeyUp;

        private int hMouseHook = 0;
        private int hKeyboardHook = 0;

        private static HookProc MouseHookProcedure;
        private static HookProc KeyboardHookProcedure;

        public void Start()
        {
            this.Start(true, true);
        }

        public void Start(bool InstallMouseHook, bool InstallKeyboardHook)
        {
            if (hMouseHook == 0 && InstallMouseHook)
            {
                MouseHookProcedure = new HookProc(MouseHookProc);
                hMouseHook = SetWindowsHookEx(
                    WH_MOUSE_LL,
                    MouseHookProcedure,
                    Marshal.GetHINSTANCE(
                        Assembly.GetExecutingAssembly().GetModules()[0]),
                    0);
                if (hMouseHook == 0)
                { 
                    int errorCode = Marshal.GetLastWin32Error();
                    Stop(true, false, false);
                    throw new Win32Exception(errorCode);
                }
            }

            if (hKeyboardHook == 0 && InstallKeyboardHook)
            {
                KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                hKeyboardHook = SetWindowsHookEx(
                    WH_KEYBOARD_LL,
                    KeyboardHookProcedure,
                    Marshal.GetHINSTANCE(
                    Assembly.GetExecutingAssembly().GetModules()[0]),
                    0);
                if (hKeyboardHook == 0)
                { 
                    int errorCode = Marshal.GetLastWin32Error();
                    Stop(false, true, false); 
                    throw new Win32Exception(errorCode);
                }
            }
        }

        public void Stop()
        {
            this.Stop(true, true, true);
        }

        public void Stop(bool UninstallMouseHook, bool UninstallKeyboardHook, bool ThrowExceptions)
        {
            if (hMouseHook != 0 && UninstallMouseHook)
            {
                int retMouse = UnhookWindowsHookEx(hMouseHook);
                hMouseHook = 0;
                if (retMouse == 0 && ThrowExceptions)
                { 
                    int errorCode = Marshal.GetLastWin32Error();
                    throw new Win32Exception(errorCode);
                }
            }

            if (hKeyboardHook != 0 && UninstallKeyboardHook)
            {
                int retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                hKeyboardHook = 0;
                if (retKeyboard == 0 && ThrowExceptions)
                { 
                    int errorCode = Marshal.GetLastWin32Error();
                    throw new Win32Exception(errorCode);
                }
            }
        }

        private int MouseHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if ((nCode >= 0) && (OnMouseActivity != null))
            {
                MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));

                MouseButtons button = MouseButtons.None;
                short mouseDelta = 0;
                switch (wParam)
                {
                    case WM_LBUTTONDOWN:
                        button = MouseButtons.Left;
                        break;
                    case WM_RBUTTONDOWN: 
                        button = MouseButtons.Right;
                        break;
                    case WM_MOUSEWHEEL:
                        mouseDelta = (short)((mouseHookStruct.mouseData >> 16) & 0xffff);
                        break;
                }

                int clickCount = 0;
                if (button != MouseButtons.None)
                    if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2;
                    else clickCount = 1;

                 MouseEventArgs e = new MouseEventArgs(
                                                    button,
                                                    clickCount,
                                                    mouseHookStruct.pt.x,
                                                    mouseHookStruct.pt.y,
                                                    mouseDelta);
                OnMouseActivity(this, e);
            }
            return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
        }

        private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
        {
            bool handled = false;
            if ((nCode >= 0) && (KeyDown != null || KeyUp != null || KeyPress != null))
            {
                KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
                if (KeyDown != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))
                {
                    Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                    KeyEventArgs e = new KeyEventArgs(keyData);
                    KeyDown(this, e);
                    handled = handled || e.Handled;
                }

                if (KeyPress != null && wParam == WM_KEYDOWN)
                {
                    bool isDownShift = ((GetKeyState(VK_SHIFT) & 0x80) == 0x80 ? true : false);
                    bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);

                    byte[] keyState = new byte[256];
                    GetKeyboardState(keyState);
                    byte[] inBuffer = new byte[2];
                    if (ToAscii(MyKeyboardHookStruct.vkCode,
                              MyKeyboardHookStruct.scanCode,
                              keyState,
                              inBuffer,
                              MyKeyboardHookStruct.flags) == 1)
                    {
                        char key = (char)inBuffer[0];
                        if ((isDownCapslock ^ isDownShift) && Char.IsLetter(key)) key = Char.ToUpper(key);
                        KeyPressEventArgs e = new KeyPressEventArgs(key);
                        KeyPress(this, e);
                        handled = handled || e.Handled;
                    }
                }

                if (KeyUp != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))
                {
                    Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;
                    KeyEventArgs e = new KeyEventArgs(keyData);
                    KeyUp(this, e);
                    handled = handled || e.Handled;
                }

            }

            if (handled)
                return 1;
            else
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
        }
    }
}


案例源码下载:

评分

参与人数 1金钱 +3 收起 理由
乔克斯 + 3 感谢LZ对论坛做出的贡献~

查看全部评分

回复 论坛版权

使用道具 举报

HJL 发表于 2014-12-11 15:14:30 | 显示全部楼层
这么高大上,不知道能不能用来屏蔽 WIN键,等会试一下
Blue_Pen 发表于 2014-12-11 19:01:58 | 显示全部楼层
本帖最后由 Blue_Pen 于 2014-12-11 19:03 编辑
HJL 发表于 2014-12-11 15:14
这么高大上,不知道能不能用来屏蔽 WIN键,等会试一下

【屏蔽系统组合键】Hook键盘钩子(屏蔽键盘按键)
http://bbs.cskin.net/forum.php?mod=viewthread&tid=225&fromuid=101
我这个有屏蔽除了alt+ctl+del外的所有键,
下面的这个帖子用到了上面的Hook键盘钩子并运用逻辑方法屏蔽了alt+ctl+del键
【C#锁 屏】BinGoo软件系列之《挂机锁屏》
http://bbs.cskin.net/forum.php?mod=viewthread&tid=239&fromuid=101

617941447 发表于 2014-12-23 01:09:01 | 显示全部楼层
好厉害   磨边
膜拜
CSdmin 发表于 2015-2-15 16:43:05 | 显示全部楼层
我想到了那啥马,这玩意应该会被杀软干掉吧
大法师 发表于 2016-1-27 23:56:47 | 显示全部楼层
        感谢分享,LZ辛苦了~
hominidclint 发表于 2017-8-5 18:07:49 | 显示全部楼层
kankan xian ,ganxie..............
a445945596 发表于 2017-10-6 12:07:40 | 显示全部楼层
感谢分享~~~~~~~~~~~~~~!!!!!!!!!!1
回复

使用道具 举报

蓝色幻想 发表于 2018-1-4 14:03:16 | 显示全部楼层
好像在那里见过这个源码
succfu22 发表于 2018-2-25 00:34:11 | 显示全部楼层
谢谢,我正在整理
您需要登录后才可以回帖 登录 | 加入CSkin博客

本版积分规则

QQ|申请友链|小黑屋|手机版|Archiver|CSkin ( 粤ICP备13070794号

Powered by Discuz! X3.2  © 2001-2013 Comsenz Inc.  Designed by ARTERY.cn
GMT+8, 2024-3-29 16:50, Processed in 0.636070 second(s), 33 queries , Gzip On.

快速回复 返回顶部 返回列表