C#外挂编写-一键呼出窗口

来源:互联网 发布:电脑摄像头特效软件 编辑:程序博客网 时间:2024/06/18 00:36

首先应当清楚一键呼出窗口的原理.其实重要技术就是使用键盘钩子函数.在wo们获取了游戏窗口的句柄后,可以把它保留在一个变量中,在后面wo们要用到这个变量和获取当前窗口函数所获取的窗口句柄对照,看看是否是同一个窗口,如果为同一个窗口,那么便弹出外挂程序窗口,反之不做任何处置.在C#中好像没提供这个函数,但wo们可以应用体系的API函数来到达这个后果,在实现前wo们应当自身定义一个API类库来储存一些体系API,这个类库里面可以包含钩子函数的定义级所需的各个事件.

   这里wo们可以使用全局键盘钩子,因为在C#中使用线程钩子没有全局钩子这么便利.先新建一个类库取名为:Win32api:

public enum HookType : int //钩子类型枚举
        {
            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            WH_KEYBOARD = 2,
            WH_GETMESSAGE = 3,
            WH_CALLWNDPROC = 4,
            WH_CBT = 5,
            WH_SYSMSGFILTER = 6,
            WH_MOUSE = 7,
            WH_HARDWARE = 8,
            WH_DEBUG = 9,
            WH_SHELL = 10,
            WH_FOREGROUNDIDLE = 11,
            WH_CALLWNDPROCRET = 12,
            WH_KEYBOARD_LL = 13,
            WH_MOUSE_LL = 14
        }

        [StructLayout(LayoutKind.Sequential)]
        public class KeyboardHookStruct //键盘键值构造定义
        {
            public int vkCode;
            public int scanCode;
            public int flags;  
            public int time;
            public int dwExtraInfo; .
        }

        public const int WM_KEYDOWN = 0x100;  //键的16进制数
        public const int WM_KEYUP = 0x101;
        public const int WM_SYSKEYDOWN = 0x104;
        public const int WM_SYSKEYUP = 0x105;

[DllImport("user32.dll", EntryPoint = "ToAscii")] //ASCII码转换
        public static extern int ToAscii(int uVirtKey,
                                         int uScanCode,
                                         byte[] lpbKeyState,
                                         byte[] lpwTransKey,
                                         int fuState);
        
        [DllImport("user32.dll", EntryPoint = "GetKeyboardState")] //取得键盘状况
        public static extern int GetKeyboardState(byte[] pbKeyState);

[DllImport("user32.dll")] //取得当前运动窗口句柄
        public static extern IntPtr GetForegroundWindow();

  public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);//钩子回调函数

        [DllImport("user32.dll", CharSet = CharSet.Auto,
            CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, //设置钩子API函数
            IntPtr hInstance, int threadId);

        [DllImport("user32.dll", CharSet = CharSet.Auto,
            CallingConvention = CallingConvention.StdCall)]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, //重载钩子函数
            int 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,//往下执行钩子
            Int32 wParam, IntPtr lParam);

   然后在工程中树立一个类文件,取名为:keyhook.cs,其功能为实现键盘钩子功效,全局键盘钩子不须要在独立的DLL中实现.

  public event KeyEventHandler KeyUp;//按键事件
        public win32API.API.HookProc keyHook;//钩子回调变量
        public int hkeyhook = 0;
        private const int WH_KEYBOARD_LL = 13;//钩子类型

public  void statrhook() //安装钩子
        {
            if (this.hkeyhook == 0)
            {
                this.keyHook = new win32API.API.HookProc(this.KeyboardHookProc);
                this.hkeyhook = win32API.API.SetWindowsHookEx(WH_KEYBOARD_LL,
                   this.keyHook,
                    Marshal.GetHINSTANCE(
                    Assembly.GetExecutingAssembly().GetModules()[0]),
                    0);
                    }
            if (this.hkeyhook == 0)
           {
               this.sotphook();
            }
                   }

public void sotphook()//卸载钩子
        {
            bool retKeyboard;
            if (this.hkeyhook != 0)
            {
                retKeyboard =win32API.API.UnhookWindowsHookEx(this.hkeyhook);
                this.hkeyhook = 0;
            }
        }

private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)//钩子处理函数
        {
            if (nCode >= 0 && this.KeyUp != null)
            {
              win32API.API.KeyboardHookStruct key=(win32API.API.KeyboardHookStruct)Marshal.PtrToStructure(lParam,typeof(win32API.API.KeyboardHookStruct));
              if ((KeyUp != null) && (wParam ==win32API.API.WM_KEYUP || wParam ==win32API.API.WM_SYSKEYUP))
              {
                  Keys keydata = (Keys)key.vkCode;
                  KeyEventArgs e = new KeyEventArgs(keydata);
                  this.KeyUp(this, e);
              }
            }
            return win32API.API.CallNextHookEx(this.hkeyhook,nCode, wParam, lParam);
        }

一键弹出窗口实现部分:
  private bool windowshow;//窗口是否弹出变量
  private youxi Youxi;//外挂窗口变量
  private IntPtr wnd;//游戏窗口句柄变量
  this.keyHook = new keyhook();//实例化钩子类并分配内存
            this.keyHook.statrhook();//安装钩子
            this.keyHook.KeyUp += new KeyEventHandler(keyHook_KeyUp);//按键事件
           Youxi = new youxi(this.openprocess, this.pid);//实例化外挂窗口并分配内存

void keyHook_KeyUp(object sender, KeyEventArgs e)//按键处置事件函数
        {
            if ((Keys)e.KeyData == Keys.Home)//当按下HOME键时
            {
                 gubin = win32API.API.GetForegroundWindow();//取得当前运动窗口句柄
                if (gubin == this.wnd)//如果当前运动窗口句柄和游戏窗口句柄变量雷同
                {
                    if (this.windowshow == false)//并且外挂窗口没有弹出
                    {
                        Youxi.Show();//显示外挂窗口
                        this.windowshow = true ;//将外挂窗口弹出变量设为真
                    }
                    else //如果窗口已显示
                    {
                        this.Youxi.Hide();//窗口暗藏
                        this.windowshow = false;//将外挂窗口弹出变量设为假
                    }
                }
            }
     }

通过以上步骤便可实现在游戏为当前窗口时按下"HOME"键弹出相应的外挂窗口,再按一下就可以暗藏.其实实现算法很简略,重点部分应当放在按键构造的定义和钩子回调函数(C#中叫做委托)以及键盘处置事件上,只要清楚了这几点便可轻易的实现外挂中比拟酷的一键弹出窗口功效,而且不止可以实现一键弹出窗口,还可以实现一键主动挂机等许多功效.相关的主题文章:

原创粉丝点击