C# 串口模拟键盘输入

原创 2015年11月20日 18:26:58

      最近遇到一个需求:需要在网站的文本输入栏上输入条码和回车; 查了一下资料,记录如下:

     最后的方案: 两台电脑用串口连接,从A机器发送信息到串口, B机器从串口读到信息,并模拟键盘输出。 

  

 public class CKeyController
    {
        [System.Runtime.InteropServices.DllImport("user32")]
        static extern void keybd_event(
            byte bVk,
            byte bScan,
            uint dwFlags,
            uint dwExtraInfo
            );
        const uint KEYEVENTF_EXTENDEDKEY = 0x1;
        const uint KEYEVENTF_KEYUP = 0x2;
        private static Dictionary<string, byte> keycode = new Dictionary<string, byte>();

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImport("User32.DLL")]
        public static extern int SendMessage(IntPtr hWnd,uint Msg, int wParam, string lParam);
        [DllImport("User32.DLL")]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);

        [DllImport("User32.DLL")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent,
            IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
        public const uint WM_SETTEXT = 0x000C;
        public const uint WM_CHAR = 0x0102;
        public static int WM_KEYDOWN = 0x0100;
        //释放一个键
        public static int WM_KEYUP = 0x0101;

        public void InitKey()
        {
            keycode = new Dictionary<string, byte>();
            keycode.Add("A", 65);
            keycode.Add("B", 66);
            keycode.Add("C", 67);
            keycode.Add("D", 68);
            keycode.Add("E", 69);
            keycode.Add("F", 70);
            keycode.Add("G", 71);
            keycode.Add("H", 72);
            keycode.Add("I", 73);
            keycode.Add("J", 74);
            keycode.Add("K", 75);
            keycode.Add("L", 76);
            keycode.Add("M", 77);
            keycode.Add("N", 78);
            keycode.Add("O", 79);
            keycode.Add("P", 80);
            keycode.Add("Q", 81);
            keycode.Add("R", 82);
            keycode.Add("S", 83);
            keycode.Add("T", 84);
            keycode.Add("U", 85);
            keycode.Add("V", 86);
            keycode.Add("W", 87);
            keycode.Add("X", 88);
            keycode.Add("Y", 89);
            keycode.Add("Z", 90);
            keycode.Add("0", 48);
            keycode.Add("1", 49);
            keycode.Add("2", 50);
            keycode.Add("3", 51);
            keycode.Add("4", 52);
            keycode.Add("5", 53);
            keycode.Add("6", 54);
            keycode.Add("7", 55);
            keycode.Add("8", 56);
            keycode.Add("9", 57);
            keycode.Add(".", 0x6E);
            keycode.Add("LEFT", 0x25);
            keycode.Add("UP", 0x26);
            keycode.Add("RIGHT", 0x27);
            keycode.Add("DOWN", 0x28);
            keycode.Add("-", 0x6D);
            keycode.Add("{ENTER}", 13);
        }

        public static void KeyBoardDo(string key)
        {
            keybd_event(keycode[key], 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0);
            keybd_event(keycode[key], 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
        }

        /// <summary>
        /// 使用keybd_event发送。 缺点是不能指定接受的窗口名称;接受窗口必须为当前活动窗口。
        /// </summary>
        /// <param name="barcode"></param>
        public void SendBarcode(string barcode)
        {
            for (int k = 0; k < barcode.Length; k++)
            {
                string ak = barcode.Substring(k, 1);
                KeyBoardDo(ak);
            }
            KeyBoardDo("{ENTER}");
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="barcode"></param>
        public void SendKeys(string barcode)
        {
            System.Windows.Forms.SendKeys.Send(barcode);
            System.Windows.Forms.SendKeys.Send("{ENTER}");
        }


        /// <summary>
        ///可以指定窗口,并且窗口可以为不活动状态; 即应用程序不在显示器最上层。
        /// </summary>
        /// <param name="hello"></param>
        public void SendKeyByMessage(string hello)
        {
            System.Diagnostics.Process[] GamesProcess = System.Diagnostics.Process.GetProcessesByName("notepad");
            if (GamesProcess.Length == 0) return;

            IntPtr hWnd = FindWindowEx(GamesProcess[0].MainWindowHandle,
            IntPtr.Zero, "Edit", null);           

            //SendMessage(hWnd, WM_SETTEXT, 0, hello); //清空记事本中内容;写入字符;并且光标回到第一行第一个位置。
            int key = 0;
            for (int k = 0; k < hello.Length; k++)
            {
                string ak = hello.Substring(k, 1);
                key = keycode[ak];
                SendMessage(hWnd, WM_CHAR, key, 0);
            }

            key = keycode["{ENTER}"];
            SendMessage(hWnd, WM_CHAR, key, 0);      //往记事本中添加内容。     
        }

    }


  类中有3中将字符串输出的功能:

1. 

keybd_event: 不能指定输出对象
2. <pre name="code" class="csharp"><pre name="code" class="csharp">SendMessage(hWnd, WM_CHAR, key, 0); 
输出一个字符到指定的窗口。
<pre name="code" class="csharp">SendMessage(hWnd, WM_SETTEXT, 0, hello);
 清空记事本中内容;写入字符;并且光标回到第一行第一个位置。 



3. <pre name="code" class="csharp">SendKeys
这个一直没有实验成功,一直会有软件不响应;除非使用手动激活其他窗口。 具体原因没有细查。
串口控制代码
<pre name="code" class="csharp"> public class CComController
    {
        private SerialPort sp = null;

        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="protName">串口号</param>
        /// <param name="baudRate">波特率</param>
        /// <param name="dataBit">数据位</param>
        /// <param name="stopBits">停止位</param>
        /// /// <param name="parity">校验位</param>
        /// <returns></returns>
        public bool OpenCom(string protName, int baudRate, int dataBit, float stopBits, int parity)
        {
            bool flag = true;
            if (sp == null)
            {
                sp = new SerialPort();
            }
            sp.PortName = protName;//串口号
            sp.BaudRate = baudRate;//波特率
            sp.ReadTimeout = 10;
            float f = stopBits;//停止位
            if (f == 0)
            {
                sp.StopBits = StopBits.None;
            }
            else if (f == 1.5)
            {
                sp.StopBits = StopBits.OnePointFive;
            }
            else if (f == 1)
            {
                sp.StopBits = StopBits.One;
            }
            else
            {
                sp.StopBits = StopBits.Two;
            }

            sp.DataBits = dataBit;//数据位

            if (parity == 0)
            {
                sp.Parity = Parity.None;
            }
            else if (parity == 1)
            {
                sp.Parity = Parity.Odd;
            }
            else if (parity == 2)
            {
                sp.Parity = Parity.Even;
            }
            else
            {
                sp.Parity = Parity.None;
            }
           
            try
            {
                if (!sp.IsOpen)
                {
                    sp.Open();
                }
            }
            catch (Exception)
            {
                flag = false;
            }
            return flag;
        }

        /// <summary>
        /// 关闭端口
        /// </summary>
        /// <returns></returns>
        public bool CloseCom()
        {
            try
            {
                if (sp.IsOpen)
                {
                    sp.Close();
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        public string ReadLine()
        {
            try
            {
                string receive = sp.ReadLine();
                return receive;
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        public bool WriteLine(string barcode)
        {
            sp.WriteLine(barcode);
            return true;
        }
    }



客户端代码:
 public partial class Form1 : Form
    {
        CComController com;
        public Form1()
        {
            InitializeComponent();




            com = new CComController();
            com.OpenCom("COM1", 115200, 8, 1, 0);
        }


        public void SendBarcode()
        {


            
        }


        private void btnSend_Click(object sender, EventArgs e)
        {           
            string barcode = txtBarcode.Text;
            com.WriteLine(barcode);
        }
    }
服务端:
namespace ComServer
{
    public partial class Form1 : Form
    {
        CComController comController;
        CKeyController keyController;
        public Form1()
        {
            InitializeComponent();
            //textBox1.Focus();


            comController = new CComController();
            comController.OpenCom("COM1", 115200, 8, 1, 0);
            
            keyController = new CKeyController();
            keyController.InitKey();
            Thread readThread = new Thread(new ThreadStart(ThreadReadBarcode));
            readThread.Start();
        }


        public void ThreadReadBarcode()
        {
            while (true)
            {
                string barcode = comController.ReadLine();
                if (barcode != "" && barcode != null)
                {                    
                    keyController.SendKeyByMessage(barcode);                    
                }


                Thread.Sleep(200);
            }
        }
    }
}
<a target=_blank href="http://http://www.cnblogs.com/slyzly/articles/1966012.html">点击打开链接</a>;网上看到的资料



相关文章推荐

C# 模拟键盘操作SendKey(),SendKeys()

模拟键盘输入就是使用以下2个语法实现的. SendKeys.Send(string keys);  //模拟汉字(文本)输入 SendKeys.SendWait(string keys); /...

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

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

C#模拟键盘输入,C#.net中怎么样模拟键盘输入

C#模拟键盘输入,C#.net中怎么样模拟键盘输入 主要用到的类SendKeys.并通过其方法Send()向当前活动的应用程序发送单击动作行为。 MSDN中对SendKeys.Send 方...

Delphi7高级应用开发随书源码

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

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

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

C# 模拟键盘 和 鼠标

在coding team学了三个月,每天真是煎熬呀,现在觉得

Delphi7高级应用开发随书源码

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

使用串口模拟工具进行串口程序开发调试

所以如何在自己的笔记本电脑上模拟串口数据就成了当务之急。托Google的福,找到了两个小工具:VSPD和串口调试助手。下面简单介绍一下如何结合这两个小工具进行串口程序调试。 1、安装好VSPD后...

c#中如何实现自动按下键盘上的某个键

(WindowsApplication) SendKeys.Send(Keys.Enter.ToString());//模拟按下回车键 SendKeys.Send("{BackSpace}")...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C# 串口模拟键盘输入
举报原因:
原因补充:

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