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# Winform制作虚拟键盘,支持中文

最近在做一个虚拟键盘功能,代替鼠标键盘操作,效果如下:        实现思路:          1  构建中文-拼音 数据库,我用的是SQLite数据库,如                    ...
  • taoerit
  • taoerit
  • 2016年11月04日 18:12
  • 2623

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

C# 使用keybd_event()函数模拟键盘按键

今天碰到了一个需求,在一体机上按F10关闭一个应用。但一体机上如果不带键盘的话。很难按出F10.所以我必须用软件的方式模拟按下F10.于是查阅各种资料。总结出,模拟按键操作常用的方式有俩种: 使用wi...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

C#调用软键盘

①其实很简单,就是打开软键盘osk.exe这个课执行程序就行了。代码如下:  System.Diagnostics.Process.Start("osk.exe"); ②可能会出现的报...

c# 如何调用win8自带的屏幕键盘(非osk.exe)

private const Int32 WM_SYSCOMMAND = 274; private const UInt32 SC_CLOSE = 61536; [Dll...
  • sidely
  • sidely
  • 2014年10月04日 01:35
  • 7539

[转]C#实现的三种方式实现模拟键盘按键

原文地址1.System.Windows.Forms.SendKeys组合键:Ctrl = ^ 、Shift = + 、Alt = % 模拟按键:A private void butt...

C#自己编写软键盘

最近的一个项目需要在工控机上完成,触摸屏,包括键盘输入。此时需要一个软键盘,只完成数字的输入就可以,但是操作系统自带的软键盘是包含非数字内容,且占用面积大。因此需要自己写一个软键盘的程序,在有数字输入...

C# 怎样让上下左右方向键生效

本文属原创作品,转载请注明出处: http://blog.csdn.net/liuxianan612 做C#程序处理键盘事件时肯能会发现,想让上下左右箭头控制程序却行不通(如控制贪食蛇...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# 窗体应用程序制作虚拟键盘按键功能
举报原因:
原因补充:

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