最近遇到一个需求:需要在网站的文本输入栏上输入条码和回车; 查了一下资料,记录如下:
最后的方案: 两台电脑用串口连接,从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);
- }
- }
- }
- }