新凡

  博客园 :: 首页 :: :: 联系 :: 订阅 :: 管理 ::

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);

posted on 2013-04-23 22:41  新凡  阅读(147)  评论(0)    收藏  举报