c#实现魔兽(warIII)中显血和改键功能 (附源码)(Hook中start方法已改进)
2010-04-15 00:16
896 查看
在论坛中看到有人提到 这个功能,感觉应该能实现,周末就抽时间写出来了,在这里分享下:
思路:Hook+SendMessage,
首先,因为我们要改的键war3不是自己写的程序,所以只能用Hook来监控键盘的按键:
键盘Hook:
创建全局Hook:
打开war3,在里面按了几下键盘,弹出了看,有好几个对话框,说明可以监测到war3里面的按键,
我的思路是向窗口发送消息,必须找到获取窗口的句柄才行:
运行,按了下弹出“找到war3了”这样就获得了war3窗口的句柄了
,剩下就是向窗口发送按键的消息了:
打开war3到创建游戏界面,按了下D,嗯?创建游戏了,说明消息发送成功
这样就可以将截获的按键来发送指定消息来“更改”按键了
ok,大体 就是这个思路,具体的代码可以到下面下载,
over
界面如下:
程序源代码(写的比较乱,将就了):quickey.rar:http://download.csdn.net/source/1755782
转载于:http://www.javaeye.com/topic/601061
思路:Hook+SendMessage,
首先,因为我们要改的键war3不是自己写的程序,所以只能用Hook来监控键盘的按键:
键盘Hook:
using System; using System.Runtime.InteropServices; using System.Windows.Forms; namespace quickey { public 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; static int hKeyboardHook = 0; //鼠标常量 public const int WH_KEYBOARD_LL = 13; public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); //声明键盘钩子事件类型 HookProc KeyboardHookProcedure; /// <summary> /// 声明键盘钩子的封送结构类型 /// </summary> [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode;//表示一个1到254间的虚拟键盘码 public int scanCode;//表示硬件扫描码 public int flags; public int time; public int dwExtraInfo; } //安装钩子 [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 || OnKeyUpEvent != null || OnKeyPressEvent != null)) { KeyboardHookStruct MyKBHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); //引发OnKeyDownEvent if (OnKeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) { Keys keyData = (Keys)MyKBHookStruct.vkCode; KeyEventArgs e = new KeyEventArgs(keyData); OnKeyDownEvent(this, e); } } return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam); } public void Start() { if (hKeyboardHook == 0) { KeyboardHookProcedure = new HookProc(KeyboardHookProc); //hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0); using (System.Diagnostics.Process curProcess = System.Diagnostics.Process.GetCurrentProcess()) using (System.Diagnostics.ProcessModule curModule = curProcess.MainModule) hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure,GetModuleHandle(curModule.ModuleName), 0); if (hKeyboardHook == 0) { Stop(); throw new Exception("Set GlobalKeyboardHook failed!"); } } } public void Stop() { bool retKeyboard = true; if (hKeyboardHook != 0) { retKeyboard = UnhookWindowsHookEx(hKeyboardHook); hKeyboardHook = 0; } if (!retKeyboard) throw new Exception("Unload GlobalKeyboardHook failed!"); } //构造函数中安装钩子 public KeyboardHook() { Start(); } //析构函数中卸载钩子 ~KeyboardHook() { Stop(); } } }
创建全局Hook:
KeyboardHook hook = new KeyboardHook(); private void Form1_Load(object sender, EventArgs e) { hook.OnKeyDownEvent += new KeyEventHandler(hook_OnKeyDownEvent); } void hook_OnKeyDownEvent(object sender, KeyEventArgs e){ //在这里就可以截获到所有的键盘按键了 MessageBox.show(e.keyValue.toString()); }
打开war3,在里面按了几下键盘,弹出了看,有好几个对话框,说明可以监测到war3里面的按键,
我的思路是向窗口发送消息,必须找到获取窗口的句柄才行:
[DllImport("USER32.DLL")] public static extern IntPtr FindWindow(string lpClassName,string lpWindowName); bool isHookEnable = true;//全局变量,指示Hook是否作用 private const int WM_KEYDOWN = 0x100; private const int WM_KEYUP = 0x101; void hook_OnKeyDownEvent(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Scroll) { isHookEnable = !isHookEnable; this.Text = isHookEnable ? "quickey-开启":"quickey-停用"; notifyIcon1.Text = this.Text; } if (isHookEnable) { IntPtr war3 = FindWindow(null, "Warcraft III"); if (war3 != IntPtr.Zero) { MessageBox.show("找到war3了"); } } }
运行,按了下弹出“找到war3了”这样就获得了war3窗口的句柄了
,剩下就是向窗口发送按键的消息了:
先声明: [DllImport("User32.DLL")] public static extern int SendMessage(IntPtr hWnd,uint Msg, int wParam, int lParam); if (isHookEnable) { IntPtr war3 = FindWindow(null, "Warcraft III"); if (war3 != IntPtr.Zero) { if (e.KeyCode == Keys.D) SendMessage(war3, WM_KEYDOWN, (int)Keys.C, 0); } }
打开war3到创建游戏界面,按了下D,嗯?创建游戏了,说明消息发送成功
这样就可以将截获的按键来发送指定消息来“更改”按键了
private const int KEY_QUOTLEFT = 219;//键盘上 [ 键的代码 private const int KEY_QUOTRIGHT = 221;//键盘上 ] 键的代码 if (isHookEnable) { IntPtr war3 = FindWindow(null, "Warcraft III"); if (war3 != IntPtr.Zero) { SetForegroundWindow(war3);//将war3窗口置前,这一句我自己测试时可以不用,但去掉这一句后朋友那里说不行 SendMessage(war3, WM_KEYDOWN, KEY_QUOTLEFT,0);//按下[键就可以显示友军的血了 SendMessage(war3, WM_KEYDOWN, KEY_QUOTRIGHT, 0); SendMessage(war3, WM_KEYDOWN, int.Parse(hash[e.KeyValue.ToString()].ToString()), 0);//按下 SendMessage(war3, WM_KEYUP, int.Parse(hash[e.KeyValue.ToString()].ToString()), 0);//松开 } }
ok,大体 就是这个思路,具体的代码可以到下面下载,
over
界面如下:
程序源代码(写的比较乱,将就了):quickey.rar:http://download.csdn.net/source/1755782
转载于:http://www.javaeye.com/topic/601061
相关文章推荐
- c#实现魔兽(warIII)中显血和改键功能 (附源码)(不影响聊天打字)
- c#实现魔兽(warIII)中显血和改键功能 (附源码)(代码参考sohighthesky)
- 【转】c#实现魔兽(warIII)中显血和改键功能 (附源码)(不影响聊天打字)
- c#实现魔兽(warIII)中显血和改键功能
- C#怎么实现文件下载功能的四种方法
- C# 在主窗口中打开一个带有计算器功能的子窗口,有三种实现方法
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)
- C#实现更改IP功能源码
- C#实现更改IP功能源码
- C# 鼠标穿透窗体功能的实现方法
- php基于ob_start(ob_gzhandler)实现网页压缩功能的方法
- C#实现导出List数据到xml文件的方法【附demo源码下载】
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)
- C#实现下载网页HTML源码的方法
- C#实现树型结构TreeView节点拖拽的简单功能,附全部源码,供有需要的参考
- C#实现DevExpress控件换肤功能[vjsdn]改进篇
- C# ASP.NET 最常用的通用权限的3个方法例子展示(每个功能一行代码实现)
- C#中如何实现JAVA中的String.replaceAll()方法功能
- C#匿名方法实现Java匿名类功能
- ReactiveSwift源码解析(九) SignalProducerProtocol延展中的Start、Lift系列方法的代码实现