本文来自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