KeyboardHook.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
using System.Windows.Forms;

namespace PrintScreen
{
    public class KeyboardHook
    {
        private const int WH_KEYBOARD_LL = 13; //鍵盤

        //鍵盤處理事件委託 ,當捕獲鍵盤輸入時調用定義該委託的方法.
        private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);

        //客戶端鍵盤處理事件
        public delegate void ProcessKeyHandle(HookStruct param, out bool handle);

        //接收SetWindowsHookEx返回值
        private static int hHookValue = 0;

        //勾子程序處理事件
        private HookHandle KeyBoardHookProcedure;

        //Hook結構
        [StructLayout(LayoutKind.Sequential)]
        public class HookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        //設置鉤子 
        [DllImport("user32.dll")]
        private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);

        //取消鉤子 
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);

        //調用下一個鉤子 
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

        ////獲取當前線程ID
        //[DllImport("kernel32.dll")]
        //private static extern int GetCurrentThreadId();

        //Gets the main module for the associated process.
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string name);

        private IntPtr hookWindowPtr = IntPtr.Zero;

        //構造器
        public KeyboardHook() { }

        //外部調用的鍵盤處理事件
        private static ProcessKeyHandle _clientMethod = null;

        /// <summary>
        /// 安裝勾子
        /// </summary>
        /// <param name="hookProcess">外部調用的鍵盤處理事件</param>
        public void InstallHook(ProcessKeyHandle clientMethod)
        {
            _clientMethod = clientMethod;

            // 安裝鍵盤鉤子 
            if (hHookValue == 0)
            {
                KeyBoardHookProcedure = new HookHandle(OnHookProc);

                hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);

                hHookValue = SetWindowsHookEx(
                    WH_KEYBOARD_LL,
                    KeyBoardHookProcedure,
                    hookWindowPtr,
                    0);

                //如果設置鉤子失敗. 
                if (hHookValue == 0) UninstallHook();
            }
        }

        //取消鉤子事件 
        public void UninstallHook()
        {
            if (hHookValue != 0)
            {
                bool ret = UnhookWindowsHookEx(hHookValue);
                if (ret) hHookValue = 0;
            }
        }

        //鉤子事件內部調用,調用_clientMethod方法轉發到客戶端應用。
        // 0x101  keyup
        private static int OnHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0 && wParam == 0x0100)
            {
                //轉換結構
                HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));

                if (_clientMethod != null)
                {
                    bool handle = false;
                    //調用客戶提供的事件處理程序。
                    _clientMethod(hookStruct, out handle);
                    if (handle) return 1; //1:表示攔截鍵盤,return 退出
                }
            }
            return CallNextHookEx(hHookValue, nCode, wParam, lParam);
        }

    }
}
使用方法:
private KeyboardHook _keyboardHook = null;
private void SetKeyBoardHook()
        {
            _keyboardHook = new KeyboardHook();
            _keyboardHook.InstallHook(this.OnKeyPress);
        }
        private void UnhookKeyBoard()
        {
            if (_keyboardHook != null) _keyboardHook.UninstallHook();
        }


        private void OnKeyPress(KeyboardHook.HookStruct hookStruct, out bool handle)
        {
            handle = false;
             if (!isKeyDown)
            {
                //截獲control+alt+x
                if (hookStruct.vkCode == (int)Keys.C && (int)Control.ModifierKeys == (int)Keys.Alt + (int)Keys.Control)
                {
                    StartApp("SnapShot.exe");
                    isKeyDown = true;
                }
            }
        }

load之後調用SetKeyBoardHook();即可;


下面是啓動外部exe

private static bool ifExit;
 private static bool isKeyDown;

/// <summary>
        /// 啓動外部程序,通過事件監視其退出
        /// </summary>
        public void StartApp(string appName)
        {
            // 啓動外部程序
            Process proc = Process.Start(appName);
            ifExit = false;
            if (proc != null)
            {
                // 監視進程退出
                proc.EnableRaisingEvents = true;
                // 指定退出事件方法
                proc.Exited += new EventHandler(proc_Exited);
            }
        }


        /// <summary>
        /// 啓動外部程序退出事件
        /// </summary>
        private void proc_Exited(object sender, EventArgs e)
        {
            ifExit = true;
            isKeyDown = false;
        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章