从网上找的源码很不齐全,自己补充了一下,有兴趣的可以看看。
首先是建立一个hook类WFChangeKey
using System; using System.Reflection; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WFChangeKey { class KeyboardHook { private const int WM_KEYDOWN = 0x100;//按下消息 private const int WM_KEYUP = 0x101;//松开消息 private const int WM_SYSKEYDOWN = 0x104; private const int WM_SYSKEYUP = 0x105; public event KeyEventHandler OnKeyDownEvent; public event KeyEventHandler OnKeyUpEvent; public event KeyPressEventHandler OnKeyPressEvent; private static int hKeyboardHook = 0; public const int WH_KEYBOARD_LL = 13; public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); private HookProc keyboardHookProc; [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; } //安装钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); //下一个钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); //卸载钩子 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(int idHook); private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) { if ((nCode >= 0) && ((OnKeyDownEvent != null) || (OnKeyPressEvent != null) || (OnKeyUpEvent != null))) { KeyboardHookStruct myKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { Keys keyData = (Keys)myKeyboardHookStruct.vkCode; KeyEventArgs e = new KeyEventArgs(keyData); OnKeyDownEvent(this, e); } } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } public void Start() { if (hKeyboardHook == 0) { keyboardHookProc = new HookProc(KeyboardHookProc); using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess()) using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule) hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, keyboardHookProc, GetModule(curModule.ModuleName),0); if (hKeyboardHook == 0) { Stop(); throw new Exception("找不到对应句柄!"); } } } private IntPtr GetModule(string name) { Module m = null; Module[] modules = Assembly.GetExecutingAssembly().GetModules(); foreach (var module in modules) { if (module.Name == name) m = module; } return Marshal.GetHINSTANCE(m); } public void Stop() { bool retKeyboard = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } if (!retKeyboard) { throw new Exception("关闭程序失败!"); } } public KeyboardHook() { Start(); } ~KeyboardHook() { Stop(); } } }
然后在form中监听事件
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; namespace WFChangeKey { public partial class Form1 : Form { KeyboardHook hook = new KeyboardHook(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { hook.OnKeyDownEvent += new KeyEventHandler(hook_OnKeyDownEvent); } [DllImport("USER32.dll")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("USER32.dll")] public static extern IntPtr SetForegroundWindow(IntPtr hWnd); private bool isHookEnable = false; private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; private IntPtr war3; void hook_OnKeyDownEvent(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Scroll) { isHookEnable = !isHookEnable; this.Text = isHookEnable ? "开启" : "关闭"; notifyIcon1.Text = this.Text; } if (isHookEnable) { war3 = FindWindow(null, "Warcraft III"); if (war3 != IntPtr.Zero) { SetForegroundWindow(war3); string key = e.KeyCode.ToString(); if (key == textBox1.Text) { SendMessage(war3, WM_KEYDOWN, (int)Keys.NumPad7, 0); SendMessage(war3, WM_KEYUP, (int)Keys.NumPad7, 0); } else if (key == textBox2.Text) { SendMessage(war3, WM_KEYDOWN, (int)Keys.NumPad8, 0); SendMessage(war3, WM_KEYUP, (int)Keys.NumPad8, 0); } else if (key == textBox3.Text) { SendMessage(war3, WM_KEYDOWN, (int)Keys.NumPad4, 0); SendMessage(war3, WM_KEYUP, (int)Keys.NumPad4, 0); } else if (key == textBox4.Text) { SendMessage(war3, WM_KEYDOWN, (int)Keys.NumPad5, 0); SendMessage(war3, WM_KEYUP, (int)Keys.NumPad5, 0); } else if (key == textBox5.Text) { SendMessage(war3, WM_KEYDOWN, (int)Keys.NumPad1, 0); SendMessage(war3, WM_KEYUP, (int)Keys.NumPad1, 0); } else if (key == textBox6.Text) { SendMessage(war3, WM_KEYDOWN, (int)Keys.NumPad2, 0); SendMessage(war3, WM_KEYUP, (int)Keys.NumPad2, 0); } //MessageBox.Show(e.KeyCode.ToString()); } else { //throw new Exception("找不到war3!"); } } } [DllImport("USER32.DLL")] public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam); private void button1_Click(object sender, EventArgs e) { if (button1.Text == "启动") { isHookEnable = true; button1.Text = "关闭"; } else { isHookEnable = false; button1.Text = "启动"; } } private void textBox_KeyDown(object sender, KeyEventArgs e) { TextBox tb = sender as TextBox; tb.Text = e.KeyCode.ToString(); this.SelectNextControl(this.ActiveControl, true, true, true, false); } } }