Chat_Dialog
1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.Linq; 7 using System.Text; 8 using System.Windows.Forms; 9 using System.Threading; 10 using System.Net; 11 using System.Net.Sockets; 12 using System.Messaging; 13 using System.Reflection; 14 15 namespace JToolDemo.Tool_Chat 16 { 17 public partial class Chat_Dialog : Chat_ParentClass 18 { 19 private string getParentClickValue = string.Empty; 20 private DataInfo sendInfo; 21 private DataInfo getInfo; 22 Thread subFormSendDataThread; 23 private Image[] emoticons; 24 public Chat_Dialog(string value) 25 { 26 InitializeComponent(); 27 getParentClickValue = value; 28 } 29 30 /// <summary> 发送信息时用</summary> 31 private UdpClient _childUdpClient; 32 public UdpClient ChildUdpClient 33 { 34 set { _childUdpClient = value; } 35 get { return _childUdpClient; } 36 } 37 38 /// <summary> 取得最小化之前的状态 窗体还原时候用</summary> 39 private FormWindowState _minPreState; 40 public FormWindowState MinPreState 41 { 42 set { _minPreState = value; } 43 get { return _minPreState; } 44 } 45 46 private void Chat_Dialog_Load(object sender, EventArgs e) 47 { 48 //设置焦点 49 this.writeTextBox.Select(); 50 //修改form名称 51 this.Text = getParentClickValue; 52 this.Name = getParentClickValue; 53 getInfo = userInfoSeparate(getParentClickValue); 54 //生成图片选择框 Load Emoticon Images 55 Assembly asm = Assembly.GetExecutingAssembly(); 56 string name = asm.GetName().Name + ".Tool_Chat."; 57 emoticons = new Image[9]; 58 emoticons[0] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.AngelSmile.png")); 59 emoticons[1] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.AngrySmile.png")); 60 emoticons[2] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.Beer.png")); 61 emoticons[3] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.BrokenHeart.png")); 62 emoticons[4] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.ConfusedSmile.png")); 63 emoticons[5] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.CrySmile.png")); 64 emoticons[6] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.DevilSmile.png")); 65 emoticons[7] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.EmbarassedSmile.png")); 66 emoticons[8] = new Bitmap(asm.GetManifestResourceStream(name + "Emoticons.ThumbsUp.png")); 67 68 // Create Emoticon DropDownMenu 69 EmoticonMenuItem _menuItem; 70 int _count = 0; 71 foreach (Image _emoticon in emoticons) 72 { 73 _menuItem = new EmoticonMenuItem(_emoticon); 74 _menuItem.Click += new EventHandler(cmenu_Emoticons_Click); 75 if (_count % 2 == 0) 76 //_menuItem.BarBreak = true; 77 _menuItem.Break = true; 78 79 cmenu_Emoticons.MenuItems.Add(_menuItem); 80 ++_count; 81 } 82 } 83 84 private void cmenu_Emoticons_Click(object _sender, EventArgs _args) 85 { 86 EmoticonMenuItem _item = (EmoticonMenuItem)_sender; 87 try 88 { 89 this.writeTextBox.InsertImage(_item.Image); 90 } 91 catch (Exception _e) 92 { 93 MessageBox.Show("Rtf Image Insert Error\n\n" + _e.ToString()); 94 } 95 } 96 97 #region 局域网侦听 98 /// <summary> 99 /// 发送数据包到广播地址 100 /// </summary> 101 /// <param name="sendbStr"></param> 102 private void sendPack() 103 { 104 DataInfo tempDataInfo = sendInfo; 105 #region 不分包发送 106 /* 107 //Encoding.UTF8防止乱码 108 byte[] sendb = Chat_CommonClass.ObjectToByteA(tempDataInfo); 109 IPAddress tempAddress = IPAddress.Parse(tempDataInfo.ToMachineIp); 110 IPEndPoint tempIpEndPoint = new IPEndPoint(tempAddress, PORT); 111 try 112 { 113 114 _childUdpClient.Send(sendb, sendb.Length, tempIpEndPoint); 115 } 116 catch (Exception e) 117 { 118 MessageBox.Show(e.Message.ToString()); 119 }*/ 120 #endregion 121 122 #region 分包发送 123 int m_intBlockLength = 1400; 124 125 IPAddress tempAddress = IPAddress.Parse(tempDataInfo.ToMachineIp); 126 IPEndPoint tempIpEndPoint = new IPEndPoint(tempAddress, PORT); 127 128 byte[] BTmp = Chat_CommonClass.ObjectToByteA(tempDataInfo); 129 //发送信息的总长度 130 int m_intMessageLength = BTmp.Length; 131 //发送的包 序列数(0,1,2...) 132 int m_intSerial = 0; 133 //包数(需要分几包发送) 134 int m_intBlocks = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(m_intMessageLength) / Convert.ToDouble(m_intBlockLength))); //数据分割块数 135 //发送方ip 136 string m_stringIP = tempDataInfo.FromMachineIp; 137 //发送时间 138 string m_stringNow = DateTime.Now.ToLongTimeString(); 139 140 //如果还有剩余的未发数据 接着发 141 while (m_intMessageLength > 0) 142 { 143 try 144 { 145 int m_intLength = m_intBlockLength; //数据长度 1000 146 147 if (m_intMessageLength < m_intLength) 148 { 149 m_intLength = m_intMessageLength; 150 } 151 152 //让IP固定为最大15位 153 byte[] byteIpTemp = new byte[15]; 154 byte[] byteIp = Encoding.ASCII.GetBytes(m_stringIP); 155 Array.Copy(byteIp, byteIpTemp, byteIp.Length); 156 //让时间固定为最大8位 157 byte[] byteNowTemp = new byte[8]; 158 byte[] byteNow = Encoding.ASCII.GetBytes(m_stringNow); 159 Array.Copy(byteNow, byteNowTemp, byteNow.Length); 160 161 //在包中加入15IP位 + 8位时间 + 16位标识位 每4位一组 162 byte[] data = new byte[15 + 8 + 16 + m_intLength]; 163 164 int place = 0; 165 Buffer.BlockCopy(byteIpTemp, 0, data, place, 15); //IP(最大15位) 166 place += 15; 167 Buffer.BlockCopy(byteNowTemp, 0, data, place, 8); //时间 168 place += 8; 169 Buffer.BlockCopy(BitConverter.GetBytes(m_intSerial), 0, data, place, 4); //顺序戳 170 place += 4; 171 Buffer.BlockCopy(BitConverter.GetBytes(m_intBlocks), 0, data, place, 4); //数据总块数 172 place += 4; 173 Buffer.BlockCopy(BitConverter.GetBytes(m_intLength), 0, data, place, 4); //数据长度 174 place += 4; 175 Buffer.BlockCopy(BitConverter.GetBytes(BTmp.Length), 0, data, place, 4); //数据总长度 176 place += 4; 177 Array.Copy(BTmp, m_intSerial * m_intBlockLength, data, 15 + 8 + 16, m_intLength); //复制数据 178 179 180 _childUdpClient.Send(data, data.Length, tempIpEndPoint); 181 Thread.Sleep(20); 182 m_intSerial = m_intSerial + 1;//0,1,2... 183 m_intMessageLength = m_intMessageLength - m_intLength;//发送信息还剩下的数据长度(总长度-已经发送的长度 1000+16) 184 } 185 catch (System.Exception pe) 186 { 187 MessageBoxEx.Show(pe.ToString()); 188 } 189 } 190 #endregion 191 192 #region 队列消息模式 193 /* 194 //队列消息的服务路径 195 string msgPath = @"web000\private$\msmqdemo"; 196 //新建一个系统消息对象; 197 System.Messaging.Message msg = new System.Messaging.Message(); 198 //新建一个消息队列对象; 199 System.Messaging.MessageQueue msgQueue = new MessageQueue(msgPath); 200 201 int m_intBlockLength = 1200; 202 203 IPAddress tempAddress = IPAddress.Parse(tempDataInfo.ToMachineIp); 204 IPEndPoint tempIpEndPoint = new IPEndPoint(tempAddress, PORT); 205 206 byte[] BTmp = Chat_CommonClass.ObjectToByteA(tempDataInfo); 207 //发送信息的总长度 208 int m_intMessageLength = BTmp.Length; 209 //发送的包 序列数(0,1,2...) 210 int m_intSerial = 0; 211 //包数(需要分几包发送) 212 int m_intBlocks = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(m_intMessageLength) / Convert.ToDouble(m_intBlockLength))); //数据分割块数 213 //发送方ip 214 string m_stringIP = tempDataInfo.FromMachineIp; 215 //发送时间 216 string m_stringNow = DateTime.Now.ToLongTimeString(); 217 218 //如果还有剩余的未发数据 接着发 219 while (m_intMessageLength > 0) 220 { 221 try 222 { 223 int m_intLength = m_intBlockLength; //数据长度 1000 224 225 if (m_intMessageLength < m_intLength) 226 { 227 m_intLength = m_intMessageLength; 228 } 229 230 //让IP固定为最大15位 231 byte[] byteIpTemp = new byte[15]; 232 byte[] byteIp = Encoding.ASCII.GetBytes(m_stringIP); 233 Array.Copy(byteIp, byteIpTemp, byteIp.Length); 234 //让时间固定为最大8位 235 byte[] byteNowTemp = new byte[8]; 236 byte[] byteNow = Encoding.ASCII.GetBytes(m_stringNow); 237 Array.Copy(byteNow, byteNowTemp, byteNow.Length); 238 239 //在包中加入15IP位 + 8位时间 + 16位标识位 每4位一组 240 byte[] data = new byte[15 + 8 + 16 + m_intLength]; 241 242 int place = 0; 243 Buffer.BlockCopy(byteIpTemp, 0, data, place, 15); //IP(最大15位) 244 place += 15; 245 Buffer.BlockCopy(byteNowTemp, 0, data, place, 8); //时间 246 place += 8; 247 Buffer.BlockCopy(BitConverter.GetBytes(m_intSerial), 0, data, place, 4); //顺序戳 248 place += 4; 249 Buffer.BlockCopy(BitConverter.GetBytes(m_intBlocks), 0, data, place, 4); //数据总块数 250 place += 4; 251 Buffer.BlockCopy(BitConverter.GetBytes(m_intLength), 0, data, place, 4); //数据长度 252 place += 4; 253 Buffer.BlockCopy(BitConverter.GetBytes(BTmp.Length), 0, data, place, 4); //数据总长度 254 place += 4; 255 Array.Copy(BTmp, m_intSerial * m_intBlockLength, data, 15 + 8 + 16, m_intLength); //复制数据 256 257 //http://hi.baidu.com/dxawddd/blog/item/ac073636278e9c350b55a92f.html 258 //http://hi.baidu.com/dxawddd/blog/item/a9e9131b543bf4d1ac6e75a8.html 259 //队列的标签,在发送多条不同的队列时可用之鉴别; 260 msg.Label = m_intSerial.ToString(); 261 //队列的主体内容; 262 //msg.Body = data; 263 msg.Body = m_stringIP; 264 msg.Formatter = new System.Messaging.XmlMessageFormatter(new Type[] { typeof(string) }); 265 //执行发送; 266 msgQueue.Send(msg); 267 268 m_intSerial = m_intSerial + 1;//0,1,2... 269 m_intMessageLength = m_intMessageLength - m_intLength;//发送信息还剩下的数据长度(总长度-已经发送的长度 1000+16) 270 } 271 catch (System.Exception pe) 272 { 273 MessageBoxEx.Show(pe.ToString()); 274 } 275 } 276 * */ 277 #endregion 278 } 279 #endregion 280 281 /// <summary>拼接 用户名+IP</summary> 282 private string userInfoSplice(DataInfo tempGetInfo) 283 { 284 string hostName = Encoding.UTF8.GetString(tempGetInfo.FromMachineName); 285 string hostIp = tempGetInfo.FromMachineIp; 286 StringBuilder returnValue = new StringBuilder(); 287 if (!(string.Empty.Equals(hostName) || string.Empty.Equals(hostIp))) 288 { 289 returnValue.Append(hostName); 290 returnValue.Append("("); 291 returnValue.Append(hostIp); 292 returnValue.Append(")"); 293 } 294 295 return returnValue.ToString(); 296 } 297 298 /// <summary>分解 用户名+IP</summary> 299 private DataInfo userInfoSeparate(string tempAllStr) 300 { 301 //分解 取得 Ip 和 主机名 302 string[] ipGroup = tempAllStr.ToString().Split('('); 303 string ip = ipGroup[1].Substring(0, ipGroup[1].Length - 1); 304 string host = ipGroup[0]; 305 306 DataInfo getInfo = new DataInfo(); 307 getInfo.FromMachineIp = ip; 308 getInfo.FromMachineName = Encoding.UTF8.GetBytes(host); 309 310 return getInfo; 311 } 312 313 /// <summary>发送消息</summary> 314 private void sendMsg_Click(object sender, EventArgs e) 315 { 316 //判断发送内容是否为空 暂时没有好的办法 317 //先判断有没有图片文件 有图片文件时候 检查.Text属性是否为空 318 int count = writeTextBox.Rtf.IndexOf(@"\pict\"); 319 if ((count < 0) && (writeTextBox.Text.Trim().Length == 0)) 320 { 321 MessageBoxEx.Show(this, "请填写信息!", "信息提示"); 322 writeTextBox.Focus(); 323 writeTextBox.Text = string.Empty; 324 return; 325 } 326 327 try 328 { 329 //初始化计算机名和端口 330 IPHostEntry myEntry = Dns.GetHostEntry(Dns.GetHostName()); 331 IPAddress myAddress = new IPAddress(myEntry.AddressList[0].Address); 332 333 IPAddress groupAddress = IPAddress.Parse(getInfo.FromMachineIp); //发送地址 334 //IPAddress groupAddress = IPAddress.Parse("255.255.255.255"); //发送地址 335 IPEndPoint End2 = new IPEndPoint(groupAddress, 2525); 336 //string getText = this.writeTextBox.Text.Trim(); 337 string getText = this.writeTextBox.Rtf; 338 339 this.writeTextBox.Text = string.Empty; 340 this.writeTextBox.Focus(); 341 sendInfo.CommandFlag = COMMAND_FLAG_CHAT; 342 sendInfo.FromMachineIp = myAddress.ToString(); 343 sendInfo.FromMachineName = Encoding.UTF8.GetBytes(Dns.GetHostName()); 344 sendInfo.ToMachineIp = getInfo.FromMachineIp; 345 //sendInfo.Message = Encoding.UTF8.GetBytes(getText); 346 sendInfo.Message = Encoding.UTF8.GetBytes(getText); 347 sendInfo.Time = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString(); 348 sendInfo.SubFormName = Encoding.UTF8.GetBytes(this.Text); 349 350 subFormSendDataThread = new Thread(new ThreadStart(this.sendPack)); 351 subFormSendDataThread.Start(); 352 //sendPack(sendInfo); 353 354 if (!sendInfo.FromMachineIp.Equals(sendInfo.ToMachineIp)) 355 { 356 //把自己发送的信息显示在文本框 357 setMessage(sendInfo); 358 } 359 } 360 catch 361 { 362 MessageBoxEx.Show("所选用户已经下线,请更新用户列表。"); 363 writeTextBox.Focus(); 364 } 365 } 366 367 /// <summary>Ctrl + Enter 快捷键</summary> 368 private void writeTextBox_KeyDown(object sender, KeyEventArgs e) 369 { 370 /* 371 //Ctrl + Enter = 发送 372 if (e.Control && e.KeyCode == Keys.Enter) 373 { 374 e.Handled = true;//将Handled设置为true,指示已经处理过KeyPress事件 375 sendMsg.PerformClick(); 376 }*/ 377 } 378 379 /// <summary>显示自己的发言</summary> 380 private void setMessage(DataInfo sendInfo) 381 { 382 Chat_Main chatMain = new Chat_Main(); 383 string fromMachineName = Encoding.UTF8.GetString(sendInfo.FromMachineName); 384 string receiveMessage = Encoding.UTF8.GetString(sendInfo.Message); 385 386 //string getOldMsg = this.displayTexBox.Rtf; 387 ////处理好准备 加入新消息 388 //getOldMsg = getOldMsg.Substring(0, getOldMsg.LastIndexOf(@"\par")); 389 390 string header = fromMachineName + " " + sendInfo.Time; 391 chatMain.SetMessage(header, receiveMessage, Color.Red, displayTexBox); 392 393 //滚动条在下面 394 displayTexBox.SelectionStart = displayTexBox.Text.Length; 395 displayTexBox.SelectionLength = 0; 396 displayTexBox.ScrollToCaret(); 397 } 398 399 /// <summary>关闭子窗体</summary> 400 private void closeFrom_Click(object sender, EventArgs e) 401 { 402 this.Close(); 403 } 404 405 /// <summary>在显示窗口输入时 直接转到输入窗口</summary> 406 private void displayTexBox_KeyPress(object sender, KeyPressEventArgs e) 407 { 408 writeTextBox.Text += e.KeyChar.ToString(); 409 writeTextBox.Select(writeTextBox.Text.Length, 0); 410 writeTextBox.Focus(); 411 } 412 413 /// <summary>Ctrl + Enter 快捷键(并且去掉Enter的空行)</summary> 414 protected override bool ProcessDialogKey(Keys keyData) 415 { 416 if (((keyData & Keys.Control) == Keys.Control)) 417 { 418 Keys keys1 = keyData & Keys.KeyCode; 419 if (keys1 == Keys.Return) 420 { 421 sendMsg.PerformClick(); 422 return true; 423 } 424 } 425 return base.ProcessDialogKey(keyData); 426 } 427 428 private void displayTexBox_LinkClicked(object sender, LinkClickedEventArgs e) 429 { 430 System.Diagnostics.Process.Start(e.LinkText); 431 } 432 433 /// <summary>拖拽</summary> 434 private void writeTextBox_DragDrop(DragEventArgs e) 435 { 436 try 437 { 438 Array fileList = (System.Array)e.Data.GetData(DataFormats.FileDrop); 439 foreach (string str in fileList) 440 { 441 // If file is an icon 442 if (str.ToUpper().EndsWith(".ICO")) 443 { 444 // Create a new icon, get it's handle, and create a bitmap from 445 // its handle 446 writeTextBox.InsertImage(Bitmap.FromHicon((new Icon(str)).Handle)); 447 } 448 else if (str.ToUpper().EndsWith(".ICO") 449 //|| str.ToUpper().EndsWith(".BMP") 450 || str.ToUpper().EndsWith(".GIF") 451 || str.ToUpper().EndsWith(".JPEG") 452 || str.ToUpper().EndsWith(".JPG") 453 ) 454 { 455 // Create a bitmap from the filename 456 writeTextBox.InsertImage(Image.FromFile(str)); 457 } 458 else 459 { 460 MessageBoxEx.Show(this, "目前只支持.bmp;.ico;.gif;.jpeg;.jpg\n的图片文件传送。", "信息提示"); 461 } 462 } 463 } 464 catch (Exception _e) 465 { 466 MessageBoxEx.Show(this, "The file could not be opened:\n\n" + _e.Message, "File Open Error"); 467 } 468 } 469 470 private void writeTextBox_DragEnter(object sender, DragEventArgs e) 471 { 472 if (e.Data.GetDataPresent(DataFormats.FileDrop)) 473 e.Effect = DragDropEffects.Link; 474 else 475 e.Effect = DragDropEffects.None; 476 } 477 478 /// <summary>重写最小化事件</summary> 479 protected override void WndProc(ref System.Windows.Forms.Message m) 480 { 481 const int WM_SYSCOMMAND = 0x0112; 482 const int SC_MINIMIZE = 0xF020; 483 484 if (m.Msg == WM_SYSCOMMAND && ((int)m.WParam == SC_MINIMIZE)) 485 { 486 487 //取得最小化之前的状态 窗体还原时候用 488 _minPreState = this.WindowState; 489 this.WindowState = FormWindowState.Minimized; 490 ////最小化到系统栏 491 //this.Hide(); 492 return; 493 } 494 base.WndProc(ref m); 495 } 496 } 497 }

在Chat_Dialog.Designer.cs里添加下面两个事件
this.writeTextBox.DragDrop += new JToolDemo.Tool_Chat.ExRichTextBox.mDrag(this.writeTextBox_DragDrop);
this.writeTextBox.DragEnter += new System.Windows.Forms.DragEventHandler(this.writeTextBox_DragEnter);

浙公网安备 33010602011771号