非原创using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using System.Windows.Forms; using System.Threading;namespace WC_key { class hook {
//委托 public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); static int hHook = 0; public const int WH_KEYBOARD_LL = 13; //LowLevel键盘截获,如果是WH_KEYBOARD=2,并不能对系统键盘截取,Acrobat Reader会在你截取之前获得键盘。 HookProc KeyBoardHookProcedure; //键盘Hook结构函数 [StructLayout(LayoutKind.Sequential)] public class KeyBoardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } #region DllImport //设置钩子 [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 bool UnhookWindowsHookEx(int idHook); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] //调用下一个钩子 public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern IntPtr GetModuleHandle(string lpModuleName); //导入进程传递键盘消息 [DllImport("USER32.DLL")] public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); [DllImport("USER32.DLL")] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("User32.dll")] public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo); private const int KEYEVENTF_KEYUP = 2; #endregion #region 自定义事件 public void Hook_Start() { // 安装键盘钩子 if (hHook == 0) { KeyBoardHookProcedure = new HookProc(KeyBoardHookProc); hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0); //如果设置钩子失败. if (hHook == 0) { MessageBox.Show("设置Hook失败!"); Hook_Clear(); try { throw new Exception("设置Hook失败!"); } catch (ArithmeticException e) { Console.WriteLine("ArithmeticException Handler: {0}", e.ToString()); } catch (Exception e) { Console.WriteLine("Generic Exception Handler: {0}", e.ToString()); } } } } //取消钩子事件 public void Hook_Clear() { bool retKeyboard = true; if (hHook != 0) { retKeyboard = UnhookWindowsHookEx(hHook); hHook = 0; } //如果去掉钩子失败. if (!retKeyboard) throw new Exception("UnhookWindowsHookEx failed."); } //处理键盘消息的子程 public static int KeyBoardHookProc(int nCode, IntPtr wParam, IntPtr lParam) { KeyBoardHookStruct input = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
定义委托类型的时候,可以使用访问修饰符 public、private和protected
多点委托被调用时,并不保证严格按关联顺序来执行各个方法,应避免编写要求严格按顺序执行方法的代码。
怎么让ALT键处于长按下状态不变?
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
using System.Threading;namespace WC_key
{
class hook
{
//委托
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); static int hHook = 0;
public const int WH_KEYBOARD_LL = 13;
//LowLevel键盘截获,如果是WH_KEYBOARD=2,并不能对系统键盘截取,Acrobat Reader会在你截取之前获得键盘。
HookProc KeyBoardHookProcedure;
//键盘Hook结构函数
[StructLayout(LayoutKind.Sequential)]
public class KeyBoardHookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
#region DllImport
//设置钩子
[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 bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
//调用下一个钩子
public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam); [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr GetModuleHandle(string lpModuleName); //导入进程传递键盘消息
[DllImport("USER32.DLL")]
public static extern IntPtr FindWindow(string lpClassName,
string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("User32.dll")]
public static extern void keybd_event(Byte bVk, Byte bScan, Int32 dwFlags, Int32 dwExtraInfo); private const int KEYEVENTF_KEYUP = 2; #endregion
#region 自定义事件
public void Hook_Start()
{ // 安装键盘钩子
if (hHook == 0)
{
KeyBoardHookProcedure = new HookProc(KeyBoardHookProc); hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyBoardHookProcedure, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
//如果设置钩子失败.
if (hHook == 0)
{
MessageBox.Show("设置Hook失败!");
Hook_Clear();
try
{ throw new Exception("设置Hook失败!");
}
catch (ArithmeticException e)
{
Console.WriteLine("ArithmeticException Handler: {0}", e.ToString());
}
catch (Exception e)
{
Console.WriteLine("Generic Exception Handler: {0}", e.ToString());
} }
}
} //取消钩子事件
public void Hook_Clear()
{
bool retKeyboard = true;
if (hHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hHook);
hHook = 0;
}
//如果去掉钩子失败.
if (!retKeyboard) throw new Exception("UnhookWindowsHookEx failed.");
} //处理键盘消息的子程
public static int KeyBoardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{ KeyBoardHookStruct input = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
//截获Home,显血
if (input.vkCode == (int)Keys.Home)
{
//获得魔兽程序的句柄
IntPtr wcHandle = FindWindow(null, "Warcraft III");
if (wcHandle != IntPtr.Zero)
{
SetForegroundWindow(wcHandle);
byte VK_NUM1 = 219;
byte VK_NUM2 = 221;
keybd_event(VK_NUM1,0,0,0);
keybd_event(VK_NUM2, 0, 0, 0);
}
return 1;
}
if (input.vkCode == (int)Keys.End)
new hook().Hook_Clear();
return CallNextHookEx(hHook, nCode, wParam, lParam); }
#endregion
}
}
public static extern void Keybd_event(byte vk, byte scan, int flags, int extrainfo);
const int KEYEVENTF_EXTENDEDKEY = 0x1;
const int KEYEVENTF_KEYUP = 0x2;//VK_MENU 相当于Alt键
Keybd_event((byte)12, 0x45, KEYEVENTF_EXTENDEDKEY, 0);//按下Keybd_event((byte)12, 0x45, KEYEVENTF_KEYUP, 0);//抬起使用委托需要注意线程接操作的问题,参考Control.Invoke方法。
//获得魔兽程序的句柄
IntPtr wcHandle = FindWindow(null, "Warcraft III");这里的"Warcraft III"是魔兽的可执行文件路径(.exe)还是上一级目录呀?
楼主也玩Dota吖 这儿可以在游戏选项里设置 一直显示血条 不过楼主的精神可赞
是的 你可以看看FindWindow方法的注释