技术经验解读:【转】c#实现魔兽(warIII)中显血和改键功能(附源码)(不影响聊天打字)

简介: 技术经验解读:【转】c#实现魔兽(warIII)中显血和改键功能(附源码)(不影响聊天打字)

本文来自CSDN博客,转载请标明出处:


在论坛中看到有人提到 这个功能,感觉应该能实现,周末就抽时间写出来了,在这里分享下:


思路:Hook+SendMessage,


首先,因为我们要改的键war3不是自己写的程序,所以只能用Hook来监控键盘的按键:


键盘Hook:


+ expand sourceview plaincopy to clipboardprint?


using System;


using System.Runtime.InteropServices;


using System.Windows.Forms; //代码效果参考:http://hnjlyzjd.com/hw/wz_24387.html


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;


///


/// 声明键盘钩子的封送结构类型


///


【StructLayout(LayoutKind.Sequential)】 //代码效果参考:http://hnjlyzjd.com/hw/wz_24385.html


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();


}


}


}


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;


///


/// 声明键盘钩子的封送结构类型


///


【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:


view plaincopy to clipboardprint?


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());


}


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里面的按键,


我的思路是向窗口发送消息,必须找到获取窗口的句柄才行:


view plaincopy to clipboardprint?


【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了");


}


}


}


【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窗口的句柄了


,剩下就是向窗口发送按键的消息了:


view plaincopy to clipboardprint?


先声明:


【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);


}


}


先声明:


【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,嗯?创建游戏了,说明消息发送成功


这样就可以将截获的按键来发送指定消息来“更改”按键了


view plaincopy to clipboardprint?


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);//松开


}


}


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


界面如下:


在论坛中看到有人提到 这个功能,感觉应该能实现,周末就抽时间写出来了,在这里分享下:


思路:Hook+SendMessage,


首先,因为我们要改的键war3不是自己写的程序,所以只能用Hook来监控键盘的按键:


键盘Hook:


+ expand sourceview plaincopy to clipboardprint?


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;


///


/// 声明键盘钩子的封送结构类型


///


【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 (hKey

目录
打赏
0
0
0
0
32
分享
相关文章
c# erp源码(简单进销存)
c# erp源码(简单进销存)
69 1
如何运用C#.NET技术快速开发一套掌上医院系统?
本方案基于C#.NET技术快速构建掌上医院系统,结合模块化开发理念与医院信息化需求。核心功能涵盖用户端的预约挂号、在线问诊、报告查询等,以及管理端的排班管理和数据统计。采用.NET Core Web API与uni-app实现前后端分离,支持跨平台小程序开发。数据库选用SQL Server 2012,并通过读写分离与索引优化提升性能。部署方案包括Windows Server与负载均衡设计,确保高可用性。同时针对API差异、数据库老化及高并发等问题制定应对措施,保障系统稳定运行。推荐使用Postman、Redgate等工具辅助开发,提升效率与质量。
基于 C# 网络套接字算法的局域网实时监控技术探究
在数字化办公与网络安全需求增长的背景下,局域网实时监控成为企业管理和安全防护的关键。本文介绍C#网络套接字算法在局域网实时监控中的应用,涵盖套接字创建、绑定监听、连接建立和数据传输等操作,并通过代码示例展示其实现方式。服务端和客户端通过套接字进行屏幕截图等数据的实时传输,保障网络稳定与信息安全。同时,文章探讨了算法的优缺点及优化方向,如异步编程、数据压缩与缓存、错误处理与重传机制,以提升系统性能。
41 2
C# 网页截图全攻略:三种技术与 Chrome 路径查找指南
本文主要介绍了在 C# 中实现网页截图的几种技术及相关要点。涵盖了 PuppeteerSharp、Selenium 和 HtmlToImage 三种方式,分别阐述了它们的安装步骤及核心代码。同时,针对在 C# 中寻找 Windows 上 chrome.exe 路径这一问题,分析了未安装 Google Chrome 和已安装两种情况下的查找原因,并给出了相关参考链接,还列举了一系列与 C# 使用 Selenium、获取 chrome.exe 路径以及在 Linux 上部署相关的参考资料。
116 11
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 15 期(2024年11.25-11.30)
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
C#/.NET/.NET Core技术前沿周刊 | 第 16 期(2024年12.01-12.08)
C# 比较对象新思路,利用反射技术打造更灵活的比较工具
中途接手的项目,碰到需要在更新对象信息时比较并记录差异的需求,最变态的还有附加要求,怎么办?有没有既能满足需求又能对项目影响最小的方法呢?分享这个我封装的方法,一个利用反射技术打造的更灵活的比较工具
基于C#开源、功能强大、灵活的跨平台开发框架 - Uno Platform
基于C#开源、功能强大、灵活的跨平台开发框架 - Uno Platform
174 3
C#/.NET/.NET Core技术前沿周刊 | 第 12 期(2024年11.01-11.10)
C#/.NET/.NET Core技术前沿周刊 | 第 12 期(2024年11.01-11.10)
C#一分钟浅谈:Visual Studio IDE 高级功能
【10月更文挑战第24天】本文从初学者角度介绍了 Visual Studio 的高级功能,包括安装与配置、创建项目、运行与调试、常见问题及解决方案(如代码格式化、重构、导航、单元测试、代码分析),以及智能感知、Live Unit Testing、代码生成和代码片段等高级功能,帮助开发者提高效率和代码质量。
97 1