我的微信群——软件开发测试工程师交流群,欢迎扫码:

改键是一种习惯,比如在玩儿lol或者dota的时候。理论上玩儿什么游戏都可以改键。

做一个窗体(点击Install——应用改键,点击Uninstall——撤销应用):

窗体定义代码如下:

using System.Windows.Forms;

namespace KeysExchange
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null; /// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
} #region Windows Form Designer generated code /// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.intall_button = new System.Windows.Forms.Button();
this.uninstall_button = new System.Windows.Forms.Button();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.comboBox2 = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// intall_button
//
this.intall_button.Location = new System.Drawing.Point(, );
this.intall_button.Name = "intall_button";
this.intall_button.Size = new System.Drawing.Size(, );
this.intall_button.TabIndex = ;
this.intall_button.Text = "Install";
this.intall_button.UseVisualStyleBackColor = true;
this.intall_button.Click += new System.EventHandler(this.intall_button_Click);
//
// uninstall_button
//
this.uninstall_button.Location = new System.Drawing.Point(, );
this.uninstall_button.Name = "uninstall_button";
this.uninstall_button.Size = new System.Drawing.Size(, );
this.uninstall_button.TabIndex = ;
this.uninstall_button.Text = "Uninstall";
this.uninstall_button.UseVisualStyleBackColor = true;
this.uninstall_button.Click += new System.EventHandler(this.uninstall_button_Click);
//
// comboBox1
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(, );
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(, );
this.comboBox1.TabIndex = ;
this.comboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
//
// comboBox2
//
this.comboBox2.FormattingEnabled = true;
this.comboBox2.Location = new System.Drawing.Point(, );
this.comboBox2.Name = "comboBox2";
this.comboBox2.Size = new System.Drawing.Size(, );
this.comboBox2.TabIndex = ;
this.comboBox2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(, );
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(, );
this.label1.TabIndex = ;
this.label1.Text = "改为:";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(, );
this.Controls.Add(this.label1);
this.Controls.Add(this.comboBox2);
this.Controls.Add(this.comboBox1);
this.Controls.Add(this.uninstall_button);
this.Controls.Add(this.intall_button);
this.Name = "Form1";
this.Text = "KeysExchange";
this.ResumeLayout(false);
this.PerformLayout();
} #endregion
private System.Windows.Forms.Button intall_button;
private System.Windows.Forms.Button uninstall_button;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.ComboBox comboBox2;
private System.Windows.Forms.Label label1;
} struct ComboItem
{
private string text;
private string value; public ComboItem(string text, string value)
{
this.text = text;
this.value = value;
} public override string ToString()
{
return this.text;
} public string ToValue()
{
return this.value;
}
}
}

钩子代码如下:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices; namespace KeysExchange
{
public class KeyboardHookLib
{
private const int WH_KEYBOARD_LL = ;
private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);
public delegate void ProcessKeyHandle(HookStruct param, out bool handle);
private static int _hHookValue = ;
private HookHandle _KeyBoardHookProcedure;
[StructLayout(LayoutKind.Sequential)]
public class HookStruct
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
[DllImport("user32.dll")]
private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll")]
private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern int GetCurrentThreadId();
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string name);
private IntPtr _hookWindowPtr = IntPtr.Zero;
public KeyboardHookLib() { }
private static ProcessKeyHandle _clientMethod = null;
[DllImport("user32")]
public static extern int GetKeyboardState(byte[] pbKeyState);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern short GetKeyState(int vKey);
private const int WM_KEYDOWN = 0x100;//KEYDOWN
private const int WM_KEYUP = 0x101;//KEYUP
private const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWN
private const int WM_SYSKEYUP = 0x105;//SYSKEYUP public void InstallHook(ProcessKeyHandle clientMethod)
{
_clientMethod = clientMethod;
if (_hHookValue == )
{
_KeyBoardHookProcedure = new HookHandle(OnHookProc);
_hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
_hHookValue = SetWindowsHookEx(WH_KEYBOARD_LL, _KeyBoardHookProcedure, _hookWindowPtr, );
if (_hHookValue == ) UninstallHook();
}
} public void UninstallHook()
{
if (_hHookValue != )
{
if (UnhookWindowsHookEx(_hHookValue))
{
_hHookValue = ;
}
}
} private static int OnHookProc(int nCode, int wParam, IntPtr lParam)
{
if (nCode >= )
{
HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));
if (_clientMethod != null)
{
bool handle = false;
///Tylan: Judge if the event is KeyDown or not.
if (lParam.ToInt32() > && wParam == 0x100)
{
_clientMethod(hookStruct, out handle);
}
if (handle) return ;
}
}
return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
}
}
}

逻辑部分代码如下:

using System;
using System.Windows.Forms; namespace KeysExchange
{
public partial class Form1 : Form
{
private KeyboardHookLib _keyboardHook = null; public Form1()
{
InitializeComponent();
for (int alp = ; alp <= ; alp++)
{
ComboItem item = new ComboItem(((Keys)alp).ToString(), alp.ToString());
comboBox1.Items.Add(item);
comboBox2.Items.Add(item);
}
} private void intall_button_Click(object sender, EventArgs e)
{
//Install the hook.
_keyboardHook = new KeyboardHookLib();
_keyboardHook.InstallHook(this.OnKeyPress);
} private void uninstall_button_Click(object sender, EventArgs e)
{
//Cancel the hook.
if (_keyboardHook != null) _keyboardHook.UninstallHook();
} public void OnKeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle)
{
handle = false;
if (((Keys)hookStruct.vkCode).ToString() == comboBox1.SelectedItem.ToString())
{
handle = true;
//Exchange the keys.
hookStruct.vkCode = int.Parse(((ComboItem)comboBox2.SelectedItem).ToValue());
Keys key = (Keys)hookStruct.vkCode;
//MessageBox.Show((key == Keys.None ? "" : key.ToString()));
System.Windows.Forms.SendKeys.Send(key.ToString().ToLower());
}
}
}
}

F5运行,找个游戏试一下,改键成功啦(按p成功打开背包)~

用C#钩子写一个改键外挂的更多相关文章

  1. 表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这种写法就是把组件嵌套改为配置方式

    表单配置项写法,表单写成JSON数组套对象,一行是一个数组单位,一列是一个对象单位,然后再写一个公共组件读取这个配置,循环加载slot,外层载入slot的自定义部分,比如input select等,这 ...

  2. 改变滚动条的原始样式: chrome 可以改变, IE只能变相关颜色,firfox好像也不好改。最好是自己写一个或是用插件

    相关作者链接地址: https://www.lyblog.net/detail/314.html 问题: 1.我在项目中遇到的问题: 在设置了::-webkit-scrollbar 后,滚动条不见了! ...

  3. 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

    这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...

  4. 一起写一个JSON解析器

    [本篇博文会介绍JSON解析的原理与实现,并一步一步写出来一个简单但实用的JSON解析器,项目地址:SimpleJSON.希望通过这篇博文,能让我们以后与JSON打交道时更加得心应手.由于个人水平有限 ...

  5. 写一个EF的CodeFirst的Demo

    写一个EF的CodeFirst的Demo 今天打算写一个关于EF的CodeFirs的一个小Demo.先略说一个EF的三种与数据库,怎么说,叫映射么,好吧,那就这么叫吧,就是一个是ModelFirst就 ...

  6. (转)如何基于FFMPEG和SDL写一个少于1000行代码的视频播放器

    原文地址:http://www.dranger.com/ffmpeg/ FFMPEG是一个很好的库,可以用来创建视频应用或者生成特定的工具.FFMPEG几乎为你把所有的繁重工作都做了,比如解码.编码. ...

  7. 写一个TODO App学习Flutter本地存储工具Moor

    写一个TODO App学习Flutter本地存储工具Moor Flutter的数据库存储, 官方文档: https://flutter.dev/docs/cookbook/persistence/sq ...

  8. Vue3语法快速入门以及写一个倒计时组件

    Vue3写一个倒计时组件 vue3 beta版本发布已有一段时间了,文档也大概看了一下,不过对于学一门技术,最好的方法还是实战,于是找了一个比较简单的组件用vue3来实现,参考的是vant的count ...

  9. 如何给LG gram写一个Linux下的驱动?

    其实就是实现一下几个Fn键的功能,没有标题吹得那么牛. 不知道为啥,LG gram这本子意外的小众. 就因为这个,装Linux遇到的硬件问题就没法在网上直接搜到解决办法了. Fn + F9 实现阅读模 ...

随机推荐

  1. SQL 数据库 触发器 、事务

    触发器类型有两种: 1.AFTER(FOR)触发器 在动作执行之后触发(增删改执行完成后,触发器中的代码再执行),不能为视图指定for触发器,只能为表指定该触发器. 2.instead of触发器 可 ...

  2. Codeforce Round #220 Div2

    这场气场太大,居然一个题不会! 所以没交! 赛后发现 A:陷阱多- -!不要超过上下界,可以上去再下来! B:不会做! C:自己想太多- -!

  3. [原创]java WEB学习笔记50:文件上传案例

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  4. Cocos2d-x游戏开发之计时器

    首先写一个计时器的头文件GameTimer.h: #ifndef _GAME_TIMER_H_ #define _GAME_TIMER_H_ #include "cocos2d.h" ...

  5. angular form 验证

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 夺命雷公狗—angularjs—5—ng-switch的用法实现下拉更换板块的实现

    这个方法一般都会是和别的块状元素进行绑定同时使用的,废话不多说,直接上代码: <!doctype html> <html lang="en"> <he ...

  7. scan design flow(二)

    在scan stitch之后,scan synthesis就已经完成, Scan extraction主要用来从scan design中extracing所有的instance,来保证scan cha ...

  8. 【转】转换到 COFF 期间失败: 文件无效或损坏

    不知怎么本来编译好好的VS2010环境,忽然出现“转换到 COFF 期间失败: 文件无效或损坏”的链接错误.花了好多天,试了好多方法,最终解决了这个问题.   现在罗列一下这几种解决方案:   方案1 ...

  9. 《zw版·Halcon-delphi系列原创教程》 邮票艺术品自动分类脚本

    <zw版·Halcon-delphi系列原创教程> 邮票艺术品自动分类脚本 邮票艺术品自动分类脚本,是个综合应用,有不同尺寸图像的自动识别.区域分割 还有作品附近文字的自动分割 此类项目, ...

  10. 【ruby】快速安装gems的方法

    在使用gem install ...的时候增加参数: --no-ri 可以不安装ri部分 --no-rdoc 可以不安装rdoc部分