核心功能

  • 需要使用C#在Tim或QQ的聊天窗口自动发送消息
  • 先使用命令行实现最核心的功能:

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Linq;
    4. using System.Runtime.InteropServices;
    5. using System.Text;
    6. using System.Threading;
    7. using System.Threading.Tasks;
    8. using System.Windows.Forms;
    9. namespace TimSendMessage
    10. {
    11. class Program
    12. {
    13. [DllImport("user32.dll")]
    14. static extern IntPtr FindWindow(String ClassName, String WindwosName);
    15. [DllImport("user32.dll")]
    16. static extern void keybd_event(byte vk, byte vsacn, int flag, int wram);
    17. [DllImport("user32.dll")]
    18. static extern void PostMessage(IntPtr hwnd, uint msg, int w, string l);
    19. [DllImport("user32.dll")]
    20. static extern void PostMessage(IntPtr hwnd, uint msg, int w, int l);
    21. [STAThread]
    22. static void Main(string[] args)
    23. {
    24. //Console.WriteLine("发送QQ的名字");
    25. var name = "我的Android手机";
    26. Console.WriteLine("要发送的字符");
    27. var t = Console.ReadLine();
    28. //Console.WriteLine("要发送的次数");
    29. //var Count = int.Parse(Console.ReadLine());
    30. var Count = 0;
    31. while (Count > -1)
    32. {
    33. Thread.Sleep(TimeSpan.FromMilliseconds(50));
    34. Clipboard.SetText(t);
    35. SendKey(name, t);
    36. Count--;
    37. Console.WriteLine("测试次数" + Count);
    38. }
    39. }
    40. static void SendKey(string name, string l)
    41. {
    42. var win = FindWindow(null, name);
    43. keybd_event(0x01, 0, 0, 0);//激活TIM
    44. PostMessage(win, 0x0302, 0, 0);
    45. PostMessage(win, 0x0101, new Random().Next(65,128),0);//发送字符 //下面是发送回车
    46. PostMessage(win, 0x0100, 13, 0);
    47. PostMessage(win, 0x0101, 13, 0);
    48. keybd_event(0x11, 0, 0x0002, 0);
    49. }
    50. }
    51. }
  • 思想

    • 将想要发送到内容通过调用剪贴板的API存在剪贴板内
    • 寻找命名为发送方的聊天窗口(Tim或QQ特性)
    • 使用PostMessage向窗口发送消息代替鼠键功能,发送

      上位机设计

  • 该应用程序想要实现的功能是作为一个中转站

  • 将单片机通过串口发送的信息通过Tim转发到手机中,或发送给其他好友
  • 因此该应用程序还需要具备串口助手的基本功能
  • 串口助手(上位机)的设计可参考

https://www.cnblogs.com/yangfengwu/p/12382103.html

  • 结合窗口设计

image.png

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Runtime.InteropServices; using System.IO.Ports;

namespace ApeChatWay { public partial class ApeChatWay : Form { [DllImport(“user32.dll”)] static extern IntPtr FindWindow(String ClassName, String WindwosName);

  1. [DllImport("user32.dll")]
  2. static extern void keybd_event(byte vk, byte vsacn, int flag, int wram);
  3. [DllImport("user32.dll")]
  4. static extern void PostMessage(IntPtr hwnd, uint msg, int w, string l);
  5. [DllImport("user32.dll")]
  6. static extern void PostMessage(IntPtr hwnd, uint msg, int w, int l);
  7. public ApeChatWay()
  8. {
  9. InitializeComponent();
  10. //更新可用串口列表
  11. PortUpDate();
  12. //默认设置波特率参数
  13. comboBox_BaudRate.Text = "115200";
  14. }
  15. /// <summary>
  16. /// 发送功能核心
  17. /// </summary>
  18. /// <param name="message">要发送的字符串参数</param>
  19. public void chatsend(string message)
  20. {
  21. //在消息上添加系统时间戳
  22. message += "\r\n";
  23. message += DateTime.Now.ToString();
  24. //获取TIM窗口
  25. string name = textBox_receiver.Text;
  26. Thread.Sleep(TimeSpan.FromMilliseconds(50));
  27. Clipboard.SetText(message);
  28. var win = FindWindow(null, name);
  29. keybd_event(0x01, 0, 0, 0);
  30. PostMessage(win, 0x0302, 0, 0);
  31. PostMessage(win, 0x0100, 13, 0);
  32. PostMessage(win, 0x0101, 13, 0);
  33. keybd_event(0x11, 0, 0x0002, 0);
  34. //显示在命令窗中
  35. textBox_show.Text = textBox_show.Text + message + "\r\n\r\n";
  36. textBox_input.Clear();
  37. }
  38. /// <summary>
  39. /// 发送按键
  40. /// </summary>
  41. /// <param name="sender"></param>
  42. /// <param name="e"></param>
  43. private void button_send_Click(object sender, EventArgs e)
  44. {
  45. //从输入窗口获取文字内容
  46. string message = textBox_input.Text;
  47. message = "[Upper] " + message;
  48. //调用发送核心
  49. chatsend(message);
  50. }
  51. /// <summary>
  52. /// 实现文本框滚动条自动滚动,文本框的事件触发
  53. /// </summary>
  54. /// <param name="sender"></param>
  55. /// <param name="e"></param>
  56. private void textBox_show_TextChanged(object sender, EventArgs e)
  57. {
  58. textBox_show.SelectionStart = textBox_show.Text.Length;
  59. textBox_show.ScrollToCaret();
  60. }
  61. /// <summary>
  62. /// 串口功能
  63. /// </summary>
  64. /// <param name="sender"></param>
  65. /// <param name="e"></param>
  66. private void button_switch_Click(object sender, EventArgs e)
  67. {
  68. if (!sp1.IsOpen)
  69. {
  70. try
  71. {
  72. string serialName = comboBox_Com.SelectedItem.ToString();
  73. sp1.PortName = serialName;
  74. string strBaudRate = comboBox_BaudRate.Text;
  75. string strDataBits = "8";
  76. int iBaudRate = Convert.ToInt32(strBaudRate);
  77. int iDataBits = Convert.ToInt32(strDataBits);
  78. sp1.BaudRate = iBaudRate;
  79. sp1.DataBits = iDataBits;
  80. sp1.StopBits = StopBits.One;
  81. sp1.Parity = Parity.None;
  82. if (sp1.IsOpen)
  83. {
  84. sp1.Close();
  85. }
  86. comboBox_Com.Enabled = false;
  87. comboBox_BaudRate.Enabled = false;
  88. sp1.Open();
  89. button_switch.Text = "关闭串口";
  90. }
  91. catch (Exception ex)
  92. {
  93. MessageBox.Show("Error:" + ex.Message, "Error");
  94. return;
  95. }
  96. }
  97. else
  98. {
  99. comboBox_Com.Enabled = true;
  100. comboBox_BaudRate.Enabled = true;
  101. sp1.Close();
  102. button_switch.Text = "打开串口";
  103. }
  104. }
  105. private void button_refresh_Click(object sender, EventArgs e)
  106. {
  107. PortUpDate();
  108. }
  109. private void PortUpDate()
  110. {
  111. sp1.DataReceived += new SerialDataReceivedEventHandler(sp1_DataReceived);
  112. comboBox_Com.Items.Clear();
  113. string[] serial = SerialPort.GetPortNames();
  114. foreach (var s in serial)
  115. {
  116. comboBox_Com.Items.Add(s);
  117. }
  118. if (comboBox_Com.Items.Count != 0)
  119. comboBox_Com.Text = serial[0];
  120. }
  121. private void sp1_DataReceived(object sender, SerialDataReceivedEventArgs e)
  122. {
  123. try
  124. {
  125. int len = sp1.BytesToRead;//获取可以读取的字节数
  126. byte[] buff = new byte[len];//创建缓存数据数组
  127. sp1.Read(buff, 0, len);//把数据读取到buff数组
  128. string str = Encoding.Default.GetString(buff);//Byte值根据ASCII码表转为 String
  129. Invoke((new Action(() => //C# 3.0以后代替委托的新方法
  130. {
  131. //textBox_show.AppendText(str);//对话框追加显示数据
  132. //textBox_show.AppendText("\r\n");
  133. if (str != "")
  134. {
  135. str = "[Serial] " + str;
  136. chatsend(str);
  137. }
  138. })));
  139. }
  140. catch (Exception ex)
  141. {
  142. System.Media.SystemSounds.Beep.Play();
  143. MessageBox.Show(ex.Message, "error2", MessageBoxButtons.OK, MessageBoxIcon.Error);
  144. }
  145. }
  146. private void button_help_Click(object sender, EventArgs e)
  147. {
  148. Form2 helpForm = new Form2();
  149. helpForm.Show(this);
  150. }
  151. }

}

/** (C) COPYRIGHT 2020 WANGXI **END OF FILE**/

```

可应用环境

  • 将串口传来的信息通过QQ或TIM转发出去
  • 串口可接单片机,可通过虚拟串口接虚拟机

    Ubuntu仿真结束提醒

  • 在Ubuntu虚拟机通过bash运行仿真程序

  • 运行结束后通过minicom与Windows的该上位机通信
  • https://www.yuque.com/wangxi_chn/qaxke0/ssgzri
  • 该上位机转发消息至QQ/Tim远程提醒仿真已结束