1. 程式人生 > >C# 鉤子函式

C# 鉤子函式

本章講述:鉤子函式

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Linq;
    using System.Text;
    using System.Runtime.InteropServices;

    public class KeyboardHook		//鉤子函式類  
    {
        #region 屬性

        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;
        }

        private IntPtr _hookWindowPtr = IntPtr.Zero;
        #endregion

        #region

        //設定鉤子
        [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);

        #endregion

        #region 事件
        //構造器
        public KeyboardHook() { }

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

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

            // 安裝鍵盤鉤子
            if (_hHookValue == 0)
            {
                _KeyBoardHookProcedure = new HookHandle(GetHookProc);

                _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方法轉發到客戶端應用。
        private static int GetHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                //轉換結構
                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);
        }
        #endregion
    }
}




//鉤子的使用
private KeyboardHook _keyboardHook;//全域性變數

private string inputKey;
public string InputKey
{
	get { return inputKey; }
	set
	{
		inputKey = value;
		NotifyOfPropertyChange(() => InputKey);
	}
}

internal bool inputFlag = false;
internal  bool isPress = false;      
internal string Password = "SKYWORTHQX";

//介面後臺程式碼,或者繫結的源  
public void Loaded()
{
	//註冊鍵盤鉤子事件
	_keyboardHook = new KeyboardHook();
	_keyboardHook.InstallHook(this.KeyPress);
}

public void UserControl_Unloaded(object sender, RoutedEventArgs e)
{
	//解除安裝鉤子事件
	_keyboardHook.UninstallHook();
}

//鍵盤鉤子   按F8輸入密碼,按Enter結束輸入
public void KeyPress(KeyboardHook.HookStruct hookStruct, out bool handle)
{
	//截獲F8
	if (hookStruct.vkCode == (int)System.Windows.Forms.Keys.F8)
	{
		handle = true;
		inputFlag = true;
		return;
	}

	if (inputFlag == false)
	{
		handle = false;
		return;
	}
	handle = true;
	if (hookStruct.vkCode == (int)System.Windows.Forms.Keys.Enter)
	{
		inputFlag = false;
		
		if (InputKey == Password)//密碼正確顯示對應的控制元件 或者 操作
		{
			IsOpenAdvance = Visibility.Visible;
		}
		InputKey = null;
	}
	else
	{
		if (isPress == false)
		{
			string Pass = ((System.Windows.Forms.Keys)hookStruct.vkCode).ToString();
			InputKey += Pass;
			isPress = true;
		}
		else
			isPress = false;
	   
	}