短信猫软件的实现(C#)<十一>软件实现(完结篇)

短信猫软件终于完成,虽然不很完善,但已可以完成所需的大多功能。在软件完成期间有很多的支持,在这里感谢大家的支持,谢谢大家。

运行主界面:

image_thumb

界面实现:Form1,主界面 上方pictureBox控件,下方用splitContainer控件分为两个部分,左边嵌套菜单窗体,右边嵌套对应每个菜单项要显示的窗体;Form2,菜单窗体;其他Form,对应菜单项窗体。

Form1:设置MaxmizeBox属性为False,使最大化按钮无效;设置AutoSizeMode属性为GrowAndShrink,不能手动调整窗体的大小;设置Start Position属性为CenterScreen。
clip_image002_thumb     clip_image0024_thumb    clip_image0026_thumb
构造函数完成窗体的嵌套

 1:  public Form1()
 2:  {
 3:      InitializeComponent();
 4:   
 5:      //菜单窗体
 6:      f2 = new Form2();
 7:      f2.TopLevel = false;
 8:      f2.FormBorderStyle = FormBorderStyle.None;
 9:      f2.Parent = this.splitContainer1.Panel1;
10:      f2.Show();
11:      f2.F2Event += new Form2.F2EventHandler(f2_F2Event);         //绑定Form2事件
12:   
13:      //首页窗体
14:      f3 = new Form3();
15:      f3.TopLevel = false;
16:      f3.FormBorderStyle = FormBorderStyle.None;
17:      f3.Parent = this.splitContainer1.Panel2;
18:      f3.Show();
19:      f3.BringToFront();
20:   
21:      //发送短信窗体
22:      f4 = new Form4();
23:      f4.TopLevel = false;
24:      f4.FormBorderStyle = FormBorderStyle.None;
25:      f4.Parent = this.splitContainer1.Panel2;
26:      f4.Show();
27:   
28:      //读取短信窗体
29:      f5 = new Form5();
30:      f5.TopLevel = false;
31:      f5.FormBorderStyle = FormBorderStyle.None;
32:      f5.Parent = this.splitContainer1.Panel2;
33:      f5.Show();
34:   
35:      //设备管理窗体
36:      f6 = new Form6();
37:      f6.TopLevel = false;
38:      f6.FormBorderStyle = FormBorderStyle.None;
39:      f6.Parent = this.splitContainer1.Panel2;
40:      f6.Show();
41:   
42:      //帮助窗体
43:      f7 = new Form7();
44:      f7.TopLevel = false;
45:      f7.FormBorderStyle = FormBorderStyle.None;
46:      f7.Parent = this.splitContainer1.Panel2;
47:      f7.Show();
48:  }

Form2:菜单窗体,仅有6个菜单按钮,单击时引发相应事件(退出按钮除外,退出按钮单击后只运行Application.Exit();即退出程序)

1:  private void button_Click(object sender, EventArgs e)
2:  {
3:      GSMEventArgs ge = new GSMEventArgs();
4:      ge.Message = ((Button)sender).Text;
5:      if (F2Event != null)
6:      {
7:          F2Event(this, ge);
8:      }
9:  }

ge传递按钮信息到主窗体,由主窗体处理相关信息

 1:  void f2_F2Event(object sender, GSMEventArgs e)
 2:  {
 3:      switch (e.Message)
 4:      {
 5:          case "首页":
 6:              f3.BringToFront();          //首页窗体移至最前
 7:              break;
 8:   
 9:          case "发送短信":
10:              f4.BringToFront();          //发送短信窗体移至最前
11:              break;
12:   
13:          case "读取短信":
14:              f5.BringToFront();          //读取短信窗体移至最前
15:              break;
16:   
17:          case "设备管理":
18:              f6.BringToFront();          //设备管理窗体移至最前
19:              break;
20:   
21:          case "帮助":
22:              f7.BringToFront();          //帮助窗体移至最前
23:              break;
24:   
25:          default: break;
26:   
27:      }
28:  }

事件F2Event对应代码

1:  //委托
2:   public delegate void F2EventHandler(object sender, GSMEventArgs e);
3:   
4:  //事件
5:  public event F2EventHandler F2Event;

GSMEventArgs 代码(位于Form1代码的下面)

1:  public class GSMEventArgs : EventArgs
2:  {
3:      public string Message;
4:  }

GSMEventArgs用于在不同窗体的事件传递有关信息

然后每个窗体上放上对应控件,界面设计完成!


首页和退出功能上面已经完成,下面不再讲解

  • 设备类实例化:使用设备类前要添加对GSMMODEM.Dll的引用并:
    1:  using GSMMODEM;

    设备类完成短信的发送、接收、和读取;要允许多个窗体访问;C#中没有全局变量的概念,所有变量都必须在类中定义;所以本程序采用了一个替代方案
         在类Program(位于文件Program.cs中)中定义并实例化静态设备对象,代码如下

 1:  static class Program
 2:  {
 3:      public static GSMModem gm = new GSMModem();         //设备类,全局变量,方便不同窗体使用 添加代码,定义并实例化设备类
 4:  
 5:      /// <summary>
 6:      /// 应用程序的主入口点。
 7:      /// </summary>
 8:      [STAThread]
 9:      static void Main()
10:      {
11:          Application.EnableVisualStyles();
12:          Application.SetCompatibleTextRenderingDefault(false);
13:          Application.Run(new Form1());
14:      }
15:  }

这样,在所有窗体中均可访问这个设备对象。访问方式:Program.gm

  • 设备管理:设备管理目前只支持单个猫的控制,需要可以自己添加。

设备管理完成设备端口、波特率设置及设备的打开与关闭。Form6为设备管理串口,可以完成设备的设置与管理,设置波特率和串口号,及是否自动打开设备

构造函数添加控件初始化代码:

 1:  //初始化控件comboBox1
 2:  foreach (string s in SerialPort.GetPortNames())
 3:  {
 4:      comboBox1.Items.Add(s);
 5:  }
 6:  if (comboBox1.Items.Count > 0)
 7:  {
 8:      //comboBox1.SelectedIndex = 0;
 9:  }
10:  else
11:  {
12:      label3.Text = "未检测到串口";
13:  }
14:   
15:  //初始化控件comboBox2
16:  //comboBox2.SelectedIndex = 0;

串口号用静态方法SerialPort.GetPortNames()扫描得到,是当前电脑注册表里的串口号。

设置文件位于Properties文件夹下,双击Settings.settings文件进入设置的管理窗口,添加ComPort、BaudRate、AutoOpen属性,类型分别为:string、string、bool;用于程序设置;

 1:  private void Form6_Load(object sender, EventArgs e)
 2:  {
 3:      comboBox1.SelectedText = Properties.Settings.Default.ComPort;               //读取设置
 4:  
 5:      comboBox2.SelectedText = Properties.Settings.Default.BaudRate;
 6:   
 7:      checkBox1.Checked = Properties.Settings.Default.AutoOpen;
 8:   
 9:      //设备属性初始化
10:      Program.gm.ComPort = Properties.Settings.Default.ComPort;
11:      Program.gm.BaudRate = Convert.ToInt32(Properties.Settings.Default.BaudRate);
12:      Program.gm.AutoDelMsg = true;
13:   
14:      if (Properties.Settings.Default.AutoOpen)                                   //根据设置决定是否打开设备
15:      {
16:          button1_Click(sender, e);                                               //调用button1的事件,完成设备的打开
17:      }
18:  }

窗体加载时写入上次程序关闭时的(设置文件中的)端口号、波特率、是否自动打开设备;若自动打开为true则打开设备

 1:  private void button1_Click(object sender, EventArgs e)
 2:  {
 3:      if (Program.gm.IsOpen == false)
 4:      {
 5:          try
 6:          {
 7:              Program.gm.Open();
 8:              label3.Text = "打开成功";
 9:              label3.ForeColor = Color.Green;
10:   
11:              button1.Text = "关闭设备";
12:          }
13:          catch
14:          {
15:              label3.Text = "打开失败";
16:              label3.ForeColor = Color.Red;
17:          }
18:      }
19:      else
20:      {
21:          try
22:          {
23:              Program.gm.Close();
24:              label3.Text = "关闭成功";
25:              label3.ForeColor = Color.Red;
26:   
27:              button1.Text = "打开设备";
28:          }
29:          catch
30:          {
31:              label3.Text = "关闭失败";
32:              label3.ForeColor = Color.Yellow;
33:          }
34:      }
35:  }

button1_Click事件完成设备的打开、关闭。

当comboBox1、comboBox2、checkBox1选项改变时,写入设置并保存设置

1:  private void checkBox1_CheckedChanged(object sender, EventArgs e)
2:  {
3:      Properties.Settings.Default.AutoOpen = checkBox1.Checked;                   //更改设置文件
4:  
5:      Properties.Settings.Default.Save();                                         //保存设置文件
6:  }

三个事件的代码一致,其他两个仅多出了设备类属性的改变,这里就不贴出来了,详见工程项目文件的源代码

  • 发送短信:窗体Form4完成短信的发送。

发送短信 目标号码部分:用listview控件实现,添加按钮完成单个号码的添加

 1:  private void button6_Click(object sender, EventArgs e)
 2:  {
 3:      Form9 adNum = new Form9();
 4:      adNum.Owner = this;
 5:   
 6:      //事件 传值
 7:      adNum.AddNumEvent += new Form9.AddNumEventHandler(adNum_AddNumEvent);
 8:   
 9:      adNum.ShowDialog();
10:  }

Form9是添加号码窗体 通过事件AddNumEvent完成号码等信息的传递

1:  void adNum_AddNumEvent(object sender, GSMEventArgs e)
2:  {
3:      string[] s = e.Message.Split(',');
4:   
5:      listView2.Items.Add(s[1]);
6:      listView2.Items[listView2.Items.Count - 1].SubItems.Add(s[0]);
7:      listView2.Items[listView2.Items.Count - 1].SubItems.Add(s[2]);
8:  }

Form9中对应代码:

 1:  private void button1_Click(object sender, EventArgs e)
 2:  {
 3:      if (Regex.IsMatch(textBox2.Text, @"^(1[3|5|8][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])$"))
 4:      {
 5:          //引发事件
 6:          if (AddNumEvent != null)
 7:          {
 8:              GSMEventArgs ge = new GSMEventArgs();
 9:              ge.Message = textBox1.Text + "," + textBox2.Text + "," + textBox3.Text;
10:              AddNumEvent(this, ge);
11:          }
12:          this.Close();
13:      }
14:      else
15:      {
16:          MessageBox.Show("手机号码不正确");
17:      }
18:  }

事件的定义:

1:  //委托
2:  public delegate void AddNumEventHandler(object sender, GSMEventArgs e);
3:   
4:  //事件
5:  public event AddNumEventHandler AddNumEvent;

这样即完成了listview的号码添加。

删除号码:

 1:  private void button7_Click(object sender, EventArgs e)
 2:  {
 3:      ListView.SelectedIndexCollection numToRemove = listView2.SelectedIndices;
 4:      try
 5:      {
 6:          int j = 0;
 7:          foreach (int i in numToRemove)
 8:          {
 9:              listView2.Items.RemoveAt(i - j);
10:              j = j + 1;
11:          }
12:      }
13:      catch (Exception ex)
14:      {
15:          MessageBox.Show(ex.Message);
16:      }
17:  }

这是从listview控件中删除对应条目,完成手机号码删除。

另外还有号码导入功能,完成多个号码的添加,目前只能从excel中导入;而且需要满足格式要求。代码如下:

 1:  private void button8_Click(object sender, EventArgs e)
 2:  {
 3:      //xPath指示excel文件路径
 4:      string xPath = null;
 5:      OpenFileDialog openFileDialog1 = new OpenFileDialog();
 6:      openFileDialog1.Filter = "Excel Files(*.xls)|*.xls";
 7:      openFileDialog1.Title = "导入手机号码";
 8:      listView2.SelectedItems.Clear();
 9:      // Show the Dialog.
10:      // If the user clicked OK in the dialog and
11:      // a .CUR file was selected, open it.
12:      if (openFileDialog1.ShowDialog() == DialogResult.OK)
13:      {
14:          xPath = openFileDialog1.FileName;
15:          string strCon;
16:          strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + xPath + ";Extended Properties='Excel 8.0;HDR=False;IMEX=1'";
17:          OleDbConnection OleConn = new OleDbConnection(strCon);
18:          string sql = "SELECT * FROM  [Sheet1$]";
19:          DataSet ds = new DataSet();
20:          try
21:          {
22:              OleConn.Open();
23:              OleDbDataAdapter da = new OleDbDataAdapter(sql, strCon);
24:              da.Fill(ds, "sheet1");
25:              OleConn.Close();
26:          }
27:          catch
28:          {
29:              MessageBox.Show("无法打开!\n请关闭其他打开此文件的程序后再试");
30:          }
31:          DataTable dt = ds.Tables[0];
32:          try
33:          {
34:              foreach (DataRow row in dt.Rows)
35:              {
36:                  string str = row["手机号码"].ToString();
37:                  if (Regex.IsMatch(str, @"^(1[3|5|8][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])$"))
38:                  {
39:                      ListViewItem lvi = new ListViewItem(str);
40:                      lvi.SubItems.Add(row["姓名"].ToString());
41:                      lvi.SubItems.Add(row["备注"].ToString());
42:                      listView2.Items.Add(lvi);
43:                  }
44:                  else
45:                  {
46:                      MessageBox.Show("表格第二列不是手机号码或是有错误号码!\n请检查后再试");
47:                      break;
48:                  }
49:              }
50:          }
51:          catch
52:          {
53:              MessageBox.Show("程序支持文件为前三列都有内容的xls表格\n第一列“姓名”,第二列“手机号码”,第三列“备注”");
54:          }
55:      }
56:   
57:  }

excel文件第一行前三列容:第一列“姓名”,第二列“手机号码”,第三列“备注”,这样才能正常导入号码。

发送部分,类 MsgList负责存储要发送的短信及目的号码,对多存储255个号码(同一条短信)

 1:  //类 MsgList 每次发送创建对象,开启另一线程 根据此类的数据发送短信
 2:  class MsgList
 3:  {
 4:      public MsgList(string[] phonelist, string msg)
 5:      {
 6:          PhoneList = phonelist;
 7:          Msg = msg;
 8:      }
 9:   
10:      //号码列表
11:      public string[] PhoneList;
12:   
13:      //短信内容
14:      public string Msg;
15:  }

下面是发送按钮的函数,首先判断字数及号码是否符合规范,上一条是否发送完成(群发 多个号码一条短信)如果完成,则准备发送:更改进度条和前面标签控件的相应属性,以给用户指示发送的状态。最后创建另外线程发送短信。

 1:  private void button9_Click(object sender, EventArgs e)
 2:  {
 3:      if (textBox1.Text.Length > 70)
 4:      {
 5:          MessageBox.Show("短信字数太长");
 6:          return;
 7:      }
 8:      else if (textBox1.Text.Length == 0)
 9:      {
10:          MessageBox.Show("不允许发送空短信");
11:      }
12:      else if (listView2.Items.Count == 0||listView2.Items.Count>255)
13:      {
14:          MessageBox.Show("没有号码或是号码超过255个");
15:      }
16:      else if (msgList != null)
17:      {
18:          MessageBox.Show("上一条尚未发送完成!无法发送");
19:      }
20:      else
21:      {
22:          //发送短信时 对应有控件显示
23:          progressBar1.Visible = true;
24:          progressBar1.Minimum = 0;
25:          progressBar1.Maximum = listView2.Items.Count;
26:          progressBar1.Value = 0;
27:   
28:          label5.Visible = true;
29:          label5.Text = "正在发送";
30:          label5.ForeColor = Color.Black;
31:   
32:          string[] s = new string[255];                     //最多255条号码
33:          for (int i = 0; i < listView2.Items.Count; i++)
34:          {
35:              s[i] = listView2.Items[i].Text;
36:          }
37:          msgList = new MsgList(s, textBox1.Text);         //赋值
38:          SendOneMsg = new SendEventHandler(OnSendOneMsg);  //实例化SendOneMsg,以每次发送完一条短信回调OnSendOneMsg函数
39:   
40:          Thread threadSendMsg = new Thread(SendMsg);
41:          threadSendMsg.Start();                          //创建并运行新线程
42:      }
43:  }

新建线程对应的函数:

 1:  private void SendMsg()
 2:  {
 3:      foreach (string s in msgList.PhoneList)
 4:      {
 5:          if (s != null && s.Length != 0)
 6:          {
 7:              try
 8:              {
 9:                  Program.gm.SendMsg(s, msgList.Msg);
10:                  GSMEventArgs ge = new GSMEventArgs();
11:                  ge.Message = s;
12:                  //SendOneMsg(this, ge);
13:                  Invoke(SendOneMsg,this,ge);
14:              }
15:              catch
16:              {
17:                  GSMEventArgs ge = new GSMEventArgs();
18:                  ge.Message = "发送失败" + s;
19:                  Invoke(SendOneMsg, this, ge);
20:                  return;
21:              }
22:          }
23:          else
24:          {
25:              GSMEventArgs ge = new GSMEventArgs();
26:              ge.Message = "发送完成";
27:              Invoke(SendOneMsg, this, ge);
28:          }
29:      }
30:  }

发送一条或是失败、完成均调用SendOneMsg指向的函数OnSendOneMsg

OnSendOneMsg函数:

 1:  void OnSendOneMsg(object sender, GSMEventArgs ge)
 2:  {
 3:      if (ge.Message.Substring(0, 4) == "发送失败")
 4:      {
 5:          label5.Text = "发送失败";
 6:          label5.ForeColor = Color.Red;
 7:      }
 8:      else if (ge.Message.Substring(0, 4) == "发送完成")
 9:      {
10:          //发送完成,控件隐藏
11:          label5.Visible = false;
12:          progressBar1.Visible = false;
13:          label5.Text = "发送完成";
14:          label5.ForeColor = Color.Green;
15:   
16:          msgList = null;
17:      }
18:      else
19:      {
20:          progressBar1.Value += 1;
21:      }
22:  }

判断发送一条,或者失败,或者完成而改变控件属性,通知用户短信发送的当前状态。

1:  //委托 完成窗体的变化 事件
2:  delegate void SendEventHandler(object sender, GSMEventArgs ge);
3:   
4:  //异步调用 每发送一条调用一次
5:  SendEventHandler SendOneMsg = null;

这是对应委托和回调的声明,两个参数object sender, GSMEventArgs ge传递相关信息。

至此发送窗体部分完成。

  • 读取短信: 读取信息窗体Form5

读取信收到短信: 收到短信,在设备OnRecieved事件中调用ReadNewMsg方法读取信息,回调主线程函数完成相应控件的更改
回调声明和实例化:

1:  //委托 收到短信时回调
2:  delegate void RecievedMsgHandler(string s);
3:  RecievedMsgHandler RecievedMsg = null;

在Form5_Load中完成实例化和事件OnRecieved的绑定。

1:  private void Form5_Load(object sender, EventArgs e)
2:  {
3:   
4:      //添加事件,收到短信
5:      Program.gm.OnRecieved += new GSMMODEM.GSMModem.OnRecievedHandler(gm_OnRecieved);
6:      //实例化回调函数
7:      RecievedMsg = new RecievedMsgHandler(UpdateCtrols);
8:   
9:  }

在事件OnRecieved中完成已读短信的保存和回调相应函数:

 1:  void gm_OnRecieved(object sender, EventArgs e)
 2:  {
 3:      string s = Program.gm.ReadNewMsg();
 4:   
 5:      //把收到短信内容写入文件
 6:      using (StreamWriter sw = File.AppendText("已收短信.txt"))
 7:      {
 8:          sw.WriteLine(s);
 9:          sw.Close();
10:      }
11:   
12:      //回调
13:      Invoke(RecievedMsg, s);
14:  }

RecievedMsg指向的方法是UpdateCtrols,其完成listview控件属性更改,在界面显示短信内容。

1:  private void UpdateCtrols(string s)
2:  {
3:      listView3.Items.Add(s.Split(',')[1]);
4:      listView3.Items[listView3.Items.Count - 1].SubItems.Add(s.Split(',')[3]);
5:      listView3.Items[listView3.Items.Count - 1].SubItems.Add(s.Split(',')[0]);
6:      listView3.Items[listView3.Items.Count - 1].SubItems.Add(s.Split(',')[2]);
7:  }

控件listview3添加入手机号码列,短信内容列 和不显示的短信中心及时间字符串(用于详细信息显示)。这样新短息就能正常读取,保存并显示在listview中。

读取设备中已收到,但未读短信:设备打开时可能已有未读信息,这里解决这一问题,设备打开时从设备管理窗体引发一个事件,通知本窗体设备被打开,相关代码如下:

1:      //委托 事件 通知其他窗体,设备打开
2:  public delegate void GSMOpenHandler(object sender, GSMEventArgs ge);
3:   
4:  public event GSMOpenHandler GSMOpen = null;

委托和事件 用来通知其他窗体设备打开。事件引发代码:

1:  //新线程 事件引发
2:  Thread thread = new Thread(GSMOpened);
3:  thread.Start();

这两句代码添加在设备打开的下方,设备打开后即开启另一个线程(事件要读取未读信息,可能要较长时间),引发事件。私有方法GSMOpened代码

1:  //新线程函数 事件引发执行
2:  private void GSMOpened()
3:  {
4:      if (GSMOpen != null)
5:      {
6:          GSMOpen(this, new GSMEventArgs("设备成功打开"));
7:      }
8:  }

引发事件,通知其他窗体。

本窗体相关内容:响应事件,在其中读取并保存未读信息,回调相关函数显示未读信息

 1:  void f6_GSMOpen(object sender, GSMEventArgs ge)
 2:  {
 3:      string[] strs = null;
 4:      try
 5:      {
 6:          strs = Program.gm.GetUnreadMsg();
 7:          if (strs == null) return;
 8:      }
 9:      catch(Exception ex)
10:      {
11:          MessageBox.Show(ex.Message);
12:      }
13:   
14:      foreach (string s in strs)
15:      {
16:          if (s == null || s.Length == 0)                 //未读信息已读完
17:          {
18:              return;
19:          }
20:   
21:          //把收到短信内容写入文件
22:          using (StreamWriter sw = File.AppendText("已收短信.txt"))
23:          {
24:              sw.WriteLine(s);
25:              sw.Close();
26:          }
27:   
28:          Invoke(HaveUnreadMsg,s);
29:      }
30:  }

事件代码:HaveUnreadMsg指向的是UpdateCtrols方法,让listview做出相关显示。

详细信息、回复:详细信息和回复功能相同,显示详细信息窗体(其中包含回复所需控件)

 1:  //详细信息
 2:  private void button19_Click(object sender, EventArgs e)
 3:  {
 4:      if (listView3.SelectedItems.Count == 0)
 5:      {
 6:          MessageBox.Show("没有选择项");
 7:          return;
 8:      }
 9:   
10:      Form8 f8 = new Form8(listView3.SelectedItems[0].SubItems[2].Text,
11:          listView3.SelectedItems[0].SubItems[3].Text,
12:          listView3.SelectedItems[0].SubItems[0].Text,
13:          listView3.SelectedItems[0].SubItems[1].Text);
14:      f8.TopLevel = false;
15:      f8.FormBorderStyle = FormBorderStyle.None;
16:      f8.Parent = this.Parent;
17:      f8.Show();
18:   
19:      f8.BringToFront();
20:  }

Form8即使是详细信息窗体 其通过构造函数完成参数的传递
Form8构造函数

 1:  /// <summary>
 2:  /// 构造函数 传递参数
 3:  /// </summary>
 4:  /// <param name="msgCenter">短信中心</param>
 5:  /// <param name="time">时间字符串</param>
 6:  /// <param name="phone">手机号码</param>
 7:  /// <param name="msg">短信内容</param>
 8:  public Form8(string msgCenter,string time,string phone,string msg)
 9:  {
10:      InitializeComponent();
11:   
12:      //
13:      textBox1.Text = msgCenter;
14:      textBox2.Text = time.Substring(0, 4) + "-" + time.Substring(4, 2) + "-" + time.Substring(6, 2) + " " +
15:          time.Substring(8, 2) + ":" + time.Substring(10, 2) + ":" + time.Substring(12);
16:      textBox3.Text = phone;
17:      textBox4.Text = msg;
18:  }

Form8中的回复按钮

 1:  private void button1_Click(object sender, EventArgs e)
 2:  {
 3:      if (textBox5.Text == null || textBox5.Text.Length == 0)
 4:      {
 5:          MessageBox.Show("不允许发送空短信");
 6:      }
 7:      else if (textBox5.Text.Length > 70)
 8:      {
 9:          MessageBox.Show("短信字数过长");
10:      }
11:      else
12:      {
13:          label6.Visible = true;
14:          try
15:          {
16:              Program.gm.SendMsg(textBox3.Text, textBox5.Text);
17:          }
18:          catch
19:          {
20:              MessageBox.Show("发送失败");
21:          }
22:          label6.Visible = false;
23:   
24:          this.Close();
25:      }
26:  }

仅完成单条信息发送,而且还会阻塞主线程,这个可以做进一步改进。

读取信息部分完成,这一部分完成的质量最不好,希望大家不要介意,这里只为大家提供了一个使用示例。

  • 帮助:帮助部分仅有一个窗体,未加入其他内容,在这里就不做讲解了。

短信猫软件的实现(C#)系列文章到此全部结束了,类库如有错误或是严重Bug还会更新,更新时会更新相应文件并在文章最后予以说明,或是添加其他文章对其说明,关于程序的bug或是不足之处,欢迎拍砖。

程序中肯定有不少错误或是Bug,欢迎大家提出宝贵意见,谢谢大家支持了啊。

附件:工程项目文件

你可能感兴趣的:(C#)