.net Winform绘制聊天窗口 |
您所在的位置:网站首页 › 聊天框的图片 › .net Winform绘制聊天窗口 |
近期由于需要,使用.net绘制了一个聊天窗口的demo,支持阅后即焚,先看效果图:
聊天窗口支持文字、文件、图片、视频、语音、名片、语音通话(需要搭建SIP服务器)等功能,联系人支持拖拽弹出独立窗体。 整体界面是仿照微信进行绘制的,使用GDI+进行图形绘制。 聊天窗口是最复杂的部分,目前是基于原生的ListBox进行绘制的,如果大家有好的建议可以一起交流。因为使用ListBox进行绘制的,所以Item高度有一定的限制,不要超过255像素,超过了界面显示不完整,需要将界面拖放大点才能显示全,这个问题暂时还没想好怎么解决,有兴趣的朋友可以共同研究一下,以下是部分绘制的代码,起到抛砖引玉的作用,希望大家有更好的方案。 private void MesssageListBox_DrawItem(object sender, DrawItemEventArgs e) { if (Items.Count == 0) return; int checkBoxWidth = 0; User user = (User)Items[e.Index]; if (user == null) return; e.DrawBackground(); e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; Brush pBlackBrush = Brushes.WhiteSmoke; if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) { //e.DrawFocusRectangle(); pBlackBrush = Brushes.LightGray; } Rectangle rectBg = e.Bounds; rectBg.Inflate(1, 1); e.Graphics.FillRectangle(pBlackBrush, rectBg); //e.Graphics.DrawString(this.listBox1.Items[e.Index].ToString(), this.listBox1.Font, Brushes.Black, e.Bounds); // 鼠标划过效果 if (e.Bounds.Contains(PointToClient(MousePosition))) { e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(150, Color.LightGray)), rectBg); } // 绘制头像 Image face; if (user.IsChatRoom) { face = user.Face == null ? Resources.face_group : user.Face; } else { face = user.Face == null ? Resources.face_ui : user.Face; } e.Graphics.DrawImage(face, new RectangleF(e.Bounds.X + 10, e.Bounds.Y + 10, 40, 40)); if (user.IsMessageUnRead) { // 模拟新消息提醒的红点,带阴影。 Rectangle newRect = new Rectangle(e.Bounds.X + 46, e.Bounds.Y + 6, 10, 10); //e.Graphics.FillEllipse(new SolidBrush(Color.FromArgb(120, 0, 0, 0)), newRect);//绘制阴影 newRect = new Rectangle(e.Bounds.X + 45, e.Bounds.Y + 5, 10, 10); e.Graphics.FillEllipse(Brushes.Red, newRect); } // 绘制姓名 StringFormat _sf = new StringFormat(); _sf.LineAlignment = StringAlignment.Center; _sf.Trimming = StringTrimming.EllipsisCharacter; Font font = new System.Drawing.Font("微软雅黑", 12); float fTop = (e.Bounds.Height - e.Font.Height) / 2; Rectangle Rect = new Rectangle(e.Bounds.X + 60, e.Bounds.Y + 10, e.Bounds.Width - 65 - checkBoxWidth, font.Height); e.Graphics.DrawString(user.Name, font, user.IsOnLine ? Brushes.Green : Brushes.Black, Rect, _sf); //e.Graphics.DrawRectangle(new Pen(Color.Red), Rect); //调试用矩形框 StringFormat sf = new StringFormat(); sf.Trimming = StringTrimming.EllipsisCharacter; sf.LineAlignment = StringAlignment.Center; // 绘制消息时间 string time = user.LastTime.ToString("HH:mm"); SizeF timeSize = e.Graphics.MeasureString(time, Font); Rectangle rectTime = new Rectangle(e.Bounds.Width - (int)timeSize.Width - 4, e.Bounds.Y + 36, (int)timeSize.Width + 1, e.Font.Height); if (!string.IsNullOrEmpty(user.LastMessage)) { // 当最后信息不为空时才绘制时间信息 e.Graphics.DrawString(time, Font, Brushes.Gray, rectTime, sf); } // 绘制消息 Rectangle Rect1 = new Rectangle(e.Bounds.X + 60, e.Bounds.Y + 36, e.Bounds.Width - rectTime.Width - 66, e.Font.Height); e.Graphics.DrawString(user.LastMessage, Font, Brushes.Gray, Rect1, sf); }在绘制过程中,重载了两个方法,MeasureItem和DrawItem,MeasureItem用于计算消息框的高度,DrawItem负责具体的绘制,在绘制过程中需要注意是发送的消息还是收到的消息。表情动画使用ImageAnimator进行动画分解与绘制,动画过多的要注意防止屏闪,尽量开启双缓冲绘图,能有效的减少屏闪。 拖拽联系人的效果比较简单,只要绘制一个光标替换当前的光标就行了,等拖拽完成后再恢复光标到默认即可。 由于是demo,以研究性为主,很多功能暂时还未实现,基本的单聊、群聊都实现了,支持群发文件、视频、语音、图片等,暂不支持语音群聊,只能语音一对一通话,也没有视频通话,后期完善后再来补充文档与代码。 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |