using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; using System.Threading; using System.IO; namespace MYQQ { /// <summary> /// 聊天窗体:2015.12.23; 聊天窗体第一个图片; /// </summary> public partial class ChatForm : Form { //0 设置成员变量,4个 public int friendId; // 当前聊天的好友号码 public string nickName; // 当前聊天的好友昵称 public int faceId; // 当前聊天的好友头像Id public string myName; //自己的昵称; //****************************以下构造函数不要动 public ChatForm() { InitializeComponent(); } //**************************不要动 //第1步:窗体加载时的动作 private void ChatForm_Load(object sender, EventArgs e) { // 设置窗体标题 this.Text = string.Format("与{0}聊天中",nickName); // 设置窗体顶部显示的好友信息 picFace.Image = ilFaces.Images[faceId]; lblFriend.Text = string.Format("{0}({1})",nickName,friendId); ShowMessage(); // 读取所有的未读消息,显示在窗体中 } // 关闭窗体 private void btnClose_Click(object sender, EventArgs e) { this.Close(); } /// <summary> /// 将单引号'转换为双引号" /// //Sql参数化实现,避免sql单引号问题,但是没有学,所以没有研究! /// </summary> /// <param name="str"></param> /// <returns></returns> private string CheckString(string str) { string returnStr = ""; if (str.IndexOf("'") != -1) //判断字符串是否含有单引号 { returnStr = str.Replace("'", "''"); str = returnStr; } return str; } //4 发送消息 private void btnSend_Click(object sender, EventArgs e) { if (txtChat.Text.Trim() == "") // 不能发送空消息 { MessageBox.Show("不能发送空消息!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } else if (txtChat.Text.Trim().Length > 50) { MessageBox.Show("消息内容过长,请分为几条发送!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); return; } else // 发送消息,写入数据库 {// MessageTypeId:1-表示聊天消息,为简化操作没有读取数据表,到S2可以用常量或者枚举实现 lblMessages.AppendText("\r\n"+myName+":\r\n\t"+txtChat.Text); int result = -1; // 表示操作数据库的结果 string sql = string.Format( @"INSERT Messages(FromUserId, ToUserId, Message, MessageTypeId, MessageState) VALUES ({0},{1},'{2}',{3},{4})", UserHelper.loginId, friendId, CheckString(txtChat.Text.Trim()), 1, 0); try { // 执行命令 SqlCommand command = new SqlCommand(sql, DBHelper.conn); DBHelper.conn.Open(); result = command.ExecuteNonQuery(); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { DBHelper.conn.Close(); } if (result != 1) { MessageBox.Show("服务器出现意外错误!", "抱歉", MessageBoxButtons.OK, MessageBoxIcon.Error); } txtChat.Text = ""; // 输入消息清空 } } //********************************************************************发送消息结束!!!!!!!!!! /// <summary> ///第2步:读取所有的未读消息,显示在窗体中 /// </summary> private void ShowMessage() { string messageIdsString = ""; // 消息的Id组成的字符串;可以用ids代替这么长的变量; string message; // 消息内容 string messageTime; // 消息发出的时间 string sql = string.Format( "SELECT Id, Message,MessageTime From Messages WHERE FromUserId={0} AND ToUserId={1} AND MessageTypeId=1 AND MessageState=0", friendId, UserHelper.loginId); // 读取消息的SQL语句;消息类型为 1:普通聊天消息;0:消息状态:未读 try { SqlCommand command = new SqlCommand(sql, DBHelper.conn); DBHelper.conn.Open(); SqlDataReader reader = command.ExecuteReader(); //读到一个临时表; while (reader.Read()) // 循环将消息添加到窗体上 { messageIdsString += Convert.ToString(reader["Id"]) + ","; //46,47,147,157,159, message = Convert.ToString(reader["Message"]); messageTime = Convert.ToDateTime(reader["MessageTime"]).ToString(); // 转换为日期类型,告诉学员 //lblMessages:上面的文本框;消息太多了,需要回车换行 lblMessages.Text += string.Format("\r\n{0} {1}\r\n {2}",nickName,messageTime,message); } reader.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { DBHelper.conn.Close(); } //2.2 把显示出的消息置为已读;我登陆了,点过头像闪烁,就表示已读! if (messageIdsString.Length > 1) { //SetMessageRead(messageIdsString, ','); //读过之后,需要设置状态为1 SetMessageRead2(messageIdsString.Remove(messageIdsString.Length - 1)); //Remove():消除一个长度的逗号;去掉最后面的那个, } } /// <summary> /// 使用新方法,来更新数据库,把获取的IdString作为参数; /// </summary> /// <param name="messageIdsString"></param> private void SetMessageRead2(string messageIdsString) //46,47,147,157,159 { string sql = string.Format("Update Messages SET MessageState=1 WHERE Id in ({0})", messageIdsString); ; // 更新状态的SQL语句的固定部分 try { SqlCommand command = new SqlCommand(); // 创建Command对象 command.Connection = DBHelper.conn; // 指定数据库连接 DBHelper.conn.Open(); // 打开数据库连接 command.CommandText = sql; // 指定要执行的SQL语句 int result = command.ExecuteNonQuery(); // 执行命令 } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { DBHelper.conn.Close(); } } //**************************************************************读取消息方法结束! /// <summary> ///3 把显示出的消息置为已读 /// </summary> private void SetMessageRead(string messageIdsString, char separator) //151,152,153,154; 分隔符, { string[] messageIds = messageIdsString.Split(separator); // 分割出每个消息Id,Split,按照某个字符进行分割成数组151 152 153 154 string sql = "Update Messages SET MessageState=1 WHERE Id="; // 更新状态的SQL语句的固定部分 string updateSql; // 执行的SQL语句 try { SqlCommand command = new SqlCommand(); // 创建Command对象 command.Connection = DBHelper.conn; // 指定数据库连接 DBHelper.conn.Open(); // 打开数据库连接 foreach (string id in messageIds) //逐个从数组取数据151 152 153 154 { if (id != "") { updateSql = sql + id; // 补充完整的SQL语句 command.CommandText = updateSql; // 指定要执行的SQL语句 int result = command.ExecuteNonQuery(); // 执行命令 } } } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { DBHelper.conn.Close(); } } //**********************************************************设置消息已读结束!!!!! private void timer1_Tick(object sender, EventArgs e) { ShowMessage(); //每隔3秒读下消息! } private void toolStripButton3_Click(object sender, EventArgs e) { Vibration();
//可以向数据库插入一个震动标志指令,对方收到这个指令,则本矿口震动! } //震动方法 private void Vibration() { Point pOld = this.Location;//原来的位置 int radius = 3;//半径 for (int n = 0; n < 3; n++) //旋转圈数 { //右半圆逆时针 for (int i = -radius; i <= radius; i++) { int x = Convert.ToInt32(Math.Sqrt(radius * radius - i * i)); int y = -i; this.Location = new Point(pOld.X + x, pOld.Y + y); Thread.Sleep(10); } //左半圆逆时针 for (int j = radius; j >= -radius; j--) { int x = -Convert.ToInt32(Math.Sqrt(radius * radius - j * j)); int y = -j; this.Location = new Point(pOld.X + x, pOld.Y + y); Thread.Sleep(10); } } //抖动完成,恢复原来位置 this.Location = pOld; } //字体代码 private void toolStripButton1_Click(object sender, EventArgs e) { fontDialog1.ShowDialog(); lblMessages.Font = fontDialog1.Font; } //颜色代码 private void toolStripDropDownButton2_Click(object sender, EventArgs e) { colorDialog1.ShowDialog(); lblMessages.ForeColor = colorDialog1.Color; } //发图片 private void toolStripButton4_Click(object sender, EventArgs e) { FileSend("PNG文件|*.png|GIF文件|*.gif|BMP文件|*.bmp|JPG文件|*.jpg|所有文件(*.*)|*.*"); } public string Cuser = string.Empty; public string CuserIP = string.Empty; #region 文件传送,待完善 private void FileSend(string Filter) { try { OpenFileDialog Dlg = new OpenFileDialog(); FileInfo FI; Dlg.Filter = Filter; Dlg.CheckFileExists = true; Dlg.InitialDirectory = "C:\\Documents and Settings\\" + System.Environment.UserName + "\\桌面\\"; if (Dlg.ShowDialog() == DialogResult.OK) { FI = new FileInfo(Dlg.FileName); string sendMsg = ":DATA:" + Cuser + "|" + System.Environment.UserName + "|" + CuserIP + "|" + Dlg.FileName + "|" + FI.Length + "|"; byte[] buff = Encoding.Default.GetBytes(sendMsg); this.lblMessages.SelectionColor = Color.Red; this.lblMessages.AppendText("【发送文件】" + Dlg.FileName + "\r\n"); this.lblMessages.ForeColor = Color.Black; this.lblMessages.ScrollToCaret(); } } catch { MessageBox.Show("文件发送失败!" + "\r\n"); } } #endregion private void button1_Click(object sender, EventArgs e) { if (btnZd.Text.Equals(">>")) { btnZd.Text = "<<"; this.Width = 400; } else { btnZd.Text = ">>"; this.Width = 610; } } private void toolStripButton2_Click(object sender, EventArgs e) { } } }