最近遇到一个需求:需要在网站的文本输入栏上输入条码和回车; 查了一下资料,记录如下:
最后的方案: 两台电脑用串口连接,从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 keycode = new Dictionary();
[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();
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);
}
///
/// 使用keybd_event发送。 缺点是不能指定接受的窗口名称;接受窗口必须为当前活动窗口。
///
///
public void SendBarcode(string barcode)
{
for (int k = 0; k < barcode.Length; k++)
{
string ak = barcode.Substring(k, 1);
KeyBoardDo(ak);
}
KeyBoardDo("{ENTER}");
}
///
///
///
///
public void SendKeys(string barcode)
{
System.Windows.Forms.SendKeys.Send(barcode);
System.Windows.Forms.SendKeys.Send("{ENTER}");
}
///
///可以指定窗口,并且窗口可以为不活动状态; 即应用程序不在显示器最上层。
///
///
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. SendMessage(hWnd, WM_CHAR, key, 0);
输出一个字符到指定的窗口。
SendMessage(hWnd, WM_SETTEXT, 0, hello);
清空记事本中内容;写入字符;并且光标回到第一行第一个位置。
3. SendKeys
这个一直没有实验成功,一直会有软件不响应;除非使用手动激活其他窗口。 具体原因没有细查。
串口控制代码
public class CComController
{
private SerialPort sp = null;
///
/// 打开串口
///
/// 串口号
/// 波特率
/// 数据位
/// 停止位
/// /// 校验位
///
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;
}
///
/// 关闭端口
///
///
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);
}
}
}
}
点击打开链接;网上看到的资料