C# 窗体应用程序制作虚拟键盘按键功能

原创 2016年05月30日 16:43:34

这几天都在忙着写一个老板提出的傻逼功能,大致说说需求,就是要用用Ios的虚拟按键去控制PC的角色移动,如果是Unity来制作这个功能并不难弄,因为这个只需要通过网络层来传递控制信号,然后PC端进行响应即可。但是好死不死的项目需求用到的不是unity开发。项目用到的引擎是CE,这个引擎为了性能的是直接截取底层键盘信息进行响应,这样对我来说真是噩耗(PS:大部分游戏引擎都是直接获取底层键盘按键的信号来获取更快的响应时间,所以大部分的游戏引擎是直接屏蔽掉WIn32.dll,但是为毛U3D没有屏蔽掉就不得而知了)

我翻墙找资料发现,国内很多人都在用一个叫Winio的动态运行库,这个库有好几个问题、数字证书、运行库不稳定、以及被大部分杀毒的软件屏蔽掉,所以用到项目上并不合适。(PS:某企鹅,某60等大多数杀毒都将winio库视为游戏外挂)最后我在一个小的论坛网站找到一个很不错的键盘底层输出运行库(驱动级的键盘输出模拟器运行库)官方的网址:http://www.ddxoft.com/

我们先去创建一个简单的C# 窗体应用程序,然后我们设计一个简单的界面来模拟游戏常用到的方向控制键。我简单弄了一个界面如图所示:

那么我们要将DD的接口实例化出来进行调用,这里DD的作者在例子里面用了委托提供我们去调用函数,这里我懒得去删去一下没用的代码,直接用他写好的类进行调用了。

using System;
using System.Runtime.InteropServices;


namespace DDInput
{
    public enum KeyModifiers        //组合键枚举
    {
        None = 0,
        Alt = 1,
        Control = 2,
        Shift = 4,
        Windows = 8
    }
    public enum MouseBtn           //鼠标按键枚举 
    {
        左下 = 1,
        左上 = 2,
        右下 = 4,
        右上 = 8
    }

    class CDD
    {
        ~CDD()
        {
             if (!m_hinst.Equals(IntPtr.Zero))
             {
                 bool b = FreeLibrary(m_hinst);
             }
        }
        [DllImport("Kernel32")]
        private static extern IntPtr LoadLibrary(string dllfile);

        [DllImport("Kernel32")]
        private static extern IntPtr GetProcAddress(System.IntPtr hModule, string lpProcName);

        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary(IntPtr hModule);

        public delegate int pDD_btn(int btn);
        public delegate int pDD_whl(int whl);
        public delegate int pDD_key(int ddcode, int flag);
        public delegate int pDD_mov(int x, int y);
        public delegate int pDD_movR(int dx, int dy);
        public delegate int pDD_str(string str);
        public delegate int pDD_todc(int vkcode);

        public pDD_btn btn;          // 鼠标点击
        public pDD_whl whl;          // 鼠标滚轮
        public pDD_mov mov;          // 鼠标绝对移动
        public pDD_movR movR;        // 鼠标相对移动
        public pDD_key key;          // 键盘按键
        public pDD_str str;          // 键盘字符
        public pDD_todc todc;        // 标准虚拟键码转DD码

        //增强版功能
        public delegate Int32 pDD_MouseMove(IntPtr hwnd, Int32 x, Int32 y);
        public delegate Int32 pDD_SnapPic(IntPtr hwnd, Int32 x, Int32 y, Int32 w, Int32 h);
        public delegate Int32 pDD_PickColor(IntPtr hwnd, Int32 x, Int32 y, Int32 mode);
        public delegate IntPtr pDD_GetActiveWindow();

        public pDD_MouseMove MouseMove;                                     //鼠标移动
        public pDD_SnapPic SnapPic;                                         //抓图
        public pDD_PickColor PickColor;                                     //取色
        public pDD_GetActiveWindow GetActiveWindow;                         //取激活窗口句柄


        private IntPtr m_hinst;
        public int Load(string dllfile)
        {
            m_hinst = LoadLibrary(dllfile);
            if (m_hinst.Equals(IntPtr.Zero))
            {
                return -2;
            }
            else
            {
                return GetDDfunAddress(m_hinst);
            }
        }

         private int GetDDfunAddress(IntPtr hinst)
        {
            IntPtr ptr;

            ptr = GetProcAddress(hinst, "DD_btn");
            if (ptr.Equals(IntPtr.Zero)) { return -1; }
            btn = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_btn)) as pDD_btn;

            if (ptr.Equals(IntPtr.Zero)) { return -1; }
            ptr = GetProcAddress(hinst, "DD_whl");
            whl = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_whl)) as pDD_whl;
            
            if (ptr.Equals(IntPtr.Zero)) { return -1; }
            ptr = GetProcAddress(hinst, "DD_mov");
            mov = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_mov)) as pDD_mov;

            if (ptr.Equals(IntPtr.Zero)) { return -1; }
            ptr = GetProcAddress(hinst, "DD_key");
            key = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_key)) as pDD_key;

            if (ptr.Equals(IntPtr.Zero)) { return -1; }
            ptr = GetProcAddress(hinst, "DD_movR");
            movR = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_movR)) as pDD_movR;

            if (ptr.Equals(IntPtr.Zero)) { return -1; }
            ptr = GetProcAddress(hinst, "DD_str");
            str = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_str)) as pDD_str;

            if (ptr.Equals(IntPtr.Zero)) { return -1; }
            ptr = GetProcAddress(hinst, "DD_todc");
            todc = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_todc)) as pDD_todc;
          
              //下面四个函数,只有在增强版中才可用
            ptr = GetProcAddress(hinst, "DD_MouseMove"); //鼠标移动
            if (!ptr.Equals (IntPtr.Zero)) MouseMove = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_MouseMove)) as pDD_MouseMove;

            ptr = GetProcAddress(hinst, "DD_SnapPic");        //抓取图片
            if (!ptr.Equals (IntPtr.Zero)) SnapPic = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_SnapPic)) as pDD_SnapPic;

            ptr = GetProcAddress(hinst, "DD_PickColor");      //取色
            if (!ptr.Equals (IntPtr.Zero))  PickColor = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_PickColor)) as pDD_PickColor;

            ptr = GetProcAddress(hinst, "DD_GetActiveWindow");    //获取激活窗口句柄
            if (!ptr.Equals (IntPtr.Zero))   GetActiveWindow = Marshal.GetDelegateForFunctionPointer(ptr, typeof(pDD_GetActiveWindow)) as pDD_GetActiveWindow;

            if (MouseMove==null || SnapPic==null ||  PickColor ==null || GetActiveWindow==null)
            {
                return 0;     
            }

            return 1 ;
        }
    }
    
}
粗略的看了一下DD的作者提供的运行库还挺强大的,这个DLL库是非加强版的(PS:如果想要加强版功能就要去找本人要?)

然后我们继续在From1.cs编写模拟键盘的代码,因为很简单所以就直接放代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace DDInput
{
    public partial class Form1 : Form
    {
        private CDD cdd;

        private bool isUp = false;
        private bool isDown = false;
        private bool isLeft = false;
        private bool isRight = false;

        public Form1()
        {
            InitializeComponent();
            cdd = new CDD();
            groupBox1.Visible = false;
            timer1.Enabled = false;
        }

        private void LoadDllFile(string dllfile)
        {
            System.IO.FileInfo fi = new System.IO.FileInfo(dllfile);
            if (!fi.Exists)
            {
                MessageBox.Show("文件不存在");
                return;
            }
            int ret = cdd.Load(dllfile);
            if (ret == -2) { MessageBox.Show("装载库时发生错误"); return; }
            if (ret == -1) { MessageBox.Show("取函数地址时发生错误"); return; }
            if (ret == 0)
            {
                MessageBox.Show("成功安装驱动");
                //isInit = true;
                groupBox1.Visible = true;
                timer1.Enabled = true;
                button1.Visible = false;
            }
            return;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //可从注册表中直接获取
            //string dllfile = ReadDataFromReg();
            //LoadDllFile(dllfile);
            //return;
            //或手动定位
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "DD入口文件|*.DLL";
            if (ofd.ShowDialog() != DialogResult.OK)
            {
                return;
            }
            LoadDllFile(ofd.FileName);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (isUp)
                cdd.key(302, 1);
            if (isLeft)
                cdd.key(401, 1);
            if (isRight)
                cdd.key(403, 1);
            if (isDown)
                cdd.key(402, 1);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            isUp = !isUp;
            if(!isUp)
                cdd.key(302, 2);
        }

        private void button3_Click(object sender, EventArgs e)
        {
            isLeft = !isLeft;
            if (!isLeft)
                cdd.key(401, 2);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            isRight = !isRight;
            if (!isRight)
                cdd.key(403, 2);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            isDown = !isDown;
            if (!isDown)
                cdd.key(402, 2);
        }

    }
}
这里要注意DD的动态链接库是要安装的。

我就把测试文件放出来吧,源码都在上面了!别说啥了~~http://pan.baidu.com/s/1i5waMax

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

制作一个C#窗体应用程序输入数据库代码

先把题图跟代码附上,感谢前辈们的一些经验,花了七八个小时,总算把这个做出来了,昨天做的A+B,第一次运用visual的widows窗体做一个小软件, 今天就运用上录入数据库工作,感觉有点进步,不过把...

C#--第5周实验--任务1(建立Windows窗体应用程序)--随机给出一个0至99(包括0和99)之间的数字,然后让你猜是什么数字。

/* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2011, 烟台大学计算机学院学生 * All rights reserved. * 文件名称:猜数...

C#简单窗体应用程序(二)

使用C#创建控制台应用程序的基本步骤: (1)创建项目; (2)用户界面设计; (3)属性设置; (4)编写程序代码; (5)保存、调试、运行; 例题:设计登录界面,效果如下: ...

C#简单窗体应用程序(三)

使用C#创建控制台应用程序的基本步骤: (1)创建项目; (2)用户界面设计; (3)属性设置; (4)编写程序代码; (5)保存、调试、运行; 例题:设计歌曲列表界面,效果如下:   第一步:创...

C#自定义控件:WinForm将其它应用程序窗体嵌入自己内部

资源里有例子:http://download.csdn.net/detail/small5e4444/4821582 这是最近在做的一个项目中提到的需求,把一个现有的窗体应用程序界面嵌入...

C#简单窗体应用程序(一)

使用C#创建控制台应用程序的基本步骤: (1)创建项目; (2)用户界面设计; (3)属性设置; (4)编写程序代码; (5)保存、调试、运行; 例题:创建一个Windows窗体应用程序,在窗体中...

MD5加密 C#窗体应用程序

Form1窗体设计:2个Label、2个TextBox、1个Button、1个菜单项 Form2:“About”菜单项的信息 using System; using System.Coll...

C#窗体应用程序--测试插件

C#窗体应用程序–测试插件本人刚刚接触C#语言,并写了一个专门测试DLL插件的窗体应用程序。本文涉及的内容: 提示窗口 读取、设置文本框的值 中断方法的执行 获取指定路径中的文件 装入控件、获取控件信...

C#做窗体应用程序时,对excel涉及的背景色设置,边框设置,数据如何导入等的实现

using Microsoft.Office.Interop.Excel; using seaSolveWork.basedata; using seaSolveWork.model.health...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)