C#实现微信聊天对话框

前两天的《C#实现微信聊天对话框》大师给了不少的好的建议,本文基于进步并进行了改进,望大师一路来评论辩论~~~

之前靠山的边框采取靠山图片的体式格式,今朝已采取GDI+直接绘制的体式格式,并且添加了靠山色以增长用户体验~~


具本的代码如下:

  1 using System;

  2 using System.ComponentModel;

  3 using System.Drawing;

  4 using System.Drawing.Drawing2D;

  5 using System.Windows.Forms;

  6 

  7 namespace Sun.WinFormControl

  8 {

  9     /// <summary>

 10     /// 类似微信的聊天对话框。

 11     /// </summary>

 12     /// <remarks>

 13     /// Author:SunYujing

 14     /// DateTime:2012-07-19

 15     /// </remarks>

 16     public class WxChartBox : Control

 17     {

 18         /// <summary>

 19         /// 机关办法。

 20         /// </summary>

 21         public WxChartBox()

 22         {

 23             SetStyle(ControlStyles.DoubleBuffer, true);                   //双缓冲防止重绘时闪烁

 24             SetStyle(ControlStyles.AllPaintingInWmPaint, true);           //忽视 WM_ERASEBKGND 窗口消息削减闪烁

 25             SetStyle(ControlStyles.UserPaint, true);                      //自定义绘制控件内容

 26             SetStyle(ControlStyles.SupportsTransparentBackColor, true);   //模仿透明            

 27             SetStyle(ControlStyles.Selectable, false);                     //接管核心

 28             Size = new Size(500, 60);                                      //初始大小

 29             Font = new Font("微软雅黑", 10);

 30         }

 31         /// <summary>

 32         /// 用户名。

 33         /// </summary>

 34         private string _username = "用户名";

 35         /// <summary>

 36         /// 消息日期时候。

 37         /// </summary>

 38         private DateTime _messagetime = DateTime.Now;

 39         /// <summary>

 40         /// 消息内容。

 41         /// </summary>

 42         private string _messagecontent = "消息内容";

 43         /// <summary>

 44         /// 每行消息数据的字节数。

 45         /// </summary>

 46         //private int _perlinebit = 68;

 47         /// <summary>

 48         /// 每行字符数。

 49         /// </summary>

 50         private int _perlinechar = 35;

 51         /// <summary>

 52         /// 消息内容的行高。

 53         /// </summary>

 54         private int _lineheight = 22;

 55         /// <summary>

 56         /// 靠山图高。

 57         /// </summary>

 58         private int _iheight = 8;

 59         /// <summary>

 60         /// 靠山图宽。

 61         /// </summary>

 62         private int _iwidth = 8;

 63         /// <summary>

 64         /// 消息类型。

 65         /// </summary>

 66         private MessageType _messagetype = MessageType.Receive;

 67         /// <summary>

 68         /// 获取或设置用户名。

 69         /// </summary>

 70         [Description("获取或设置用户名。")]

 71         public string UserName

 72         {

 73             get

 74             {

 75                 return _username;

 76             }

 77             set

 78             {

 79                 _username = value;

 80                 Invalidate(false);

 81             }

 82         }

 83 

 84         /// <summary>

 85         /// 获取或设置用户名。

 86         /// </summary>

 87         [Description("获取或设置用户名。")]

 88         public DateTime MessageTime

 89         {

 90             get

 91             {

 92                 return _messagetime;

 93             }

 94             set

 95             {

 96                 _messagetime = value;

 97                 Invalidate(false);

 98             }

 99         }

100 

101         /// <summary>

102         /// 获取或设置消息内容。

103         /// </summary>

104         [Description("获取或设置消息内容。")]

105         public string MessageContent

106         {

107             get

108             {

109                 return _messagecontent;

110             }

111             set

112             {

113                 _messagecontent = value;

114                 Invalidate(false);

115             }

116         }

117 

118         /// <summary>

119         /// 获取或设置消息的类型。

120         /// </summary>

121         [Description("获取或设置消息的类型。")]

122         public MessageType MType

123         {

124             get

125             {

126                 return _messagetype;

127             }

128             set

129             {

130                 _messagetype = value;

131                 Invalidate(false);

132             }

133         }

134         /// <summary>

135         /// 自定义绘制。

136         /// </summary>

137         protected override void OnPaint(PaintEventArgs e)

138         {

139             base.OnPaint(e);

140             Graphics g = e.Graphics;

141             g.SmoothingMode = SmoothingMode.HighQuality;

142             g.PixelOffsetMode = PixelOffsetMode.HighQuality;

143             Size = new Size(500, InitHeight());

144             DrawBackColor(g);

145             DrawBackGroundLine(g);

146             DrawText(g);

147             DrawLine(g);

148             DrawMessageContent(g);

149         }

150         /// <summary>

151         /// 绘制用户名和消息时候。

152         /// </summary>

153         private void DrawText(Graphics g)

154         {

155             Font f = new Font("微软雅黑", 10,FontStyle.Bold);

156             g.DrawString(UserName+"  "+MessageTime.ToString("yyyy-MM-dd HH:mm:ss"), f, new SolidBrush(ForeColor), 8+_iwidth, 2);

157         }

158         /// <summary>

159         /// 绘制一条直线。

160         /// </summary>

161         private void DrawLine(Graphics g)

162         {

163             Color color = Color.Green;

164             if(MType==MessageType.Receive)

165                 color = Color.Red;

166             Pen p = new Pen(color);

167             p.Width = 1;

168             g.DrawLine(p, 4 + _iwidth, 22, Width - 8 - _iwidth , 22);

169         }

170         /// <summary>

171         /// 绘制短信内容。

172         /// </summary>

173         private void DrawMessageContent(Graphics g)

174         {

175             int initheight = 22;

176             int rowscount = MessageLineCount();

177             string contents = MessageContent;

178             string content = "";

179             for (int i = 0; i < rowscount; i++)

180             {

181                 if (contents.Length > _perlinechar)

182                 {

183                     content = contents.Substring(0, _perlinechar);

184                     contents = contents.Remove(0, _perlinechar);

185                 }

186                 else

187                 {

188                     content = contents;

189                 }

190                 g.DrawString(content, Font, new SolidBrush(ForeColor), 4+_iwidth, initheight + i * _lineheight);

191             }

192         }

193         /// <summary>

194         /// 绘制边框。

195         /// </summary>

196         private void DrawBackGroundLine(Graphics g)

197         {

198             Pen p = new Pen(Color.Black);

199             p.Width = 1;

200             g.DrawArc(p, _iwidth, 0, _iwidth, _iheight, 180, 90);

201             g.DrawLine(p, (int)(_iwidth * 1.5), 0, Width - (int)(_iwidth * 1.5), 0);

202             g.DrawArc(p, Width - _iwidth * 2, 0, _iwidth, _iheight, 270, 90);

203             if (MType == MessageType.Send)

204             {

205                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 0.5), Width - _iwidth, (int)(_iheight * 1.5));

206                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 1.5), Width, _iheight * 2);

207                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 2.5), Width, _iheight * 2);

208                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 2.5), Width - _iwidth, Height - (int)(_iheight * 0.5));

209             }

210             else

211             {

212                 g.DrawLine(p, Width - _iwidth, (int)(_iheight * 0.5), Width - _iwidth, Height - (int)(_iheight * 0.5));

213             }

214             g.DrawArc(p, Width - _iwidth * 2, Height - _iheight,_iwidth,_iheight, 0, 90);

215             g.DrawLine(p, (int)(_iwidth * 1.5), Height, Width - (int)(_iwidth * 1.5), Height);

216             g.DrawArc(p, _iwidth, Height - _iheight, _iwidth, _iheight, 90, 90);

217             if (MType == MessageType.Receive)

218             {

219                 g.DrawLine(p, _iwidth, (int)(_iheight * 0.5), _iwidth, (int)(_iheight * 1.5));

220                 g.DrawLine(p, 0, _iheight * 2, _iwidth, (int)(_iheight * 1.5));

221                 g.DrawLine(p, 0, _iheight * 2, _iwidth, (int)(_iheight * 2.5));

222                 g.DrawLine(p, _iwidth, (int)(_iheight * 2.5), _iwidth, Height - (int)(_iheight * 0.5));

223             }

224             else

225             {

226                 g.DrawLine(p, _iwidth, (int)(_iheight * 0.5), _iwidth, Height - (int)(_iheight * 0.5));

227             }

228         }

229         /// <summary>

230         /// 绘制靠山色。

231         /// </summary>

232         private void DrawBackColor(Graphics g)

233         {

234             Brush b = Brushes.YellowGreen;

235             Point[] ps = new Point[3];

236             if (MType == MessageType.Receive)

237             {

238                 ps[0] = new Point(0, _iheight * 2);

239                 ps[1] = new Point(_iwidth, (int)(_iheight * 1.5));

240                 ps[2] = new Point(_iwidth, (int)(_iheight * 2.5));

241             }

242             else

243             {

244                 b = Brushes.Goldenrod;

245                 ps[0] = new Point(Width - _iwidth, (int)(_iheight * 1.5));

246                 ps[1] = new Point(Width - _iwidth, (int)(_iheight * 2.5));

247                 ps[2] = new Point(Width, _iheight * 2);

248             }

249             g.FillEllipse(b, _iwidth, 0, _iwidth, _iheight);

250             g.FillEllipse(b, Width - _iwidth * 2, 0, _iwidth, _iheight);

251             g.FillEllipse(b, Width - _iwidth * 2, Height-_iheight, _iwidth, _iheight);

252             g.FillEllipse(b, _iwidth, Height - _iheight, _iwidth, _iheight);

253             g.FillRectangle(b, _iwidth, (int)(_iheight*0.5), Width - _iwidth * 2, Height - _iheight);

254             g.FillRectangle(b, (int)(_iwidth * 1.5), 0, Width - _iwidth * 3, (int)(_iheight * 0.5));

255             g.FillRectangle(b, (int)(_iwidth * 1.5), Height - (int)(_iheight * 0.5), Width - _iwidth * 3, (int)(_iheight * 0.5));

256             g.FillPolygon(b, ps);

257         }

258         /// <summary>

259         /// 动态策画控件高度。

260         /// </summary>

261         /// <returns>控件高度。</returns>

262         public int InitHeight()

263         {

264             int rowCount = MessageLineCount();

265             int iRows = rowCount == 0 ? 1 : rowCount;

266             return iRows * _lineheight + 22;

267         }

268         /// <summary>

269         /// 获作废息行数。

270         /// </summary>

271         /// <returns>消息行数。</returns>

272         private int MessageLineCount()

273         {

274             //int MessageBits = Encoding.Default.GetByteCount(MessageContent.Trim());

275             //return (int)Math.Ceiling(MessageBits * 1.0 / _perlinebit);

276             int MessageCharCount = MessageContent.Trim().Length;

277             return (int)Math.Ceiling(MessageCharCount * 1.0 / _perlinechar);

278         }

279     }

280 

281     /// <summary>

282     /// 消息类型。

283     /// </summary>

284     public enum MessageType

285     {

286         /// <summary>

287         /// 发送消息。

288         /// </summary>

289         Send,

290         /// <summary>

291         /// 接管消息。

292         /// </summary>

293         Receive

294     }

295 }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现微信聊天功能需要使用微信开发者工具和微信公众平台开发接口进行开发。以下是一个简单的实现微信聊天功能的C#代码示例: ```csharp using System; using System.Net; using System.IO; using System.Text; using System.Web.Script.Serialization; namespace WeChatChat { class Program { static void Main(string[] args) { // 设置微信公众平台的参数 string appId = "your_app_id"; string appSecret = "your_app_secret"; string token = "your_token"; string encodingAESKey = "your_encoding_aes_key"; // 获取微信服务器发送的消息 string postStr = GetPostStr(); if (!string.IsNullOrEmpty(postStr)) { // 对消息进行解密 string decryptStr = WeChatEncrypt.AESDecrypt(postStr, encodingAESKey, appId); if (!string.IsNullOrEmpty(decryptStr)) { // 解析消息内容 JavaScriptSerializer serializer = new JavaScriptSerializer(); Message message = serializer.Deserialize<Message>(decryptStr); // 处理消息 if (message.MsgType == "text") { // 回复消息 string content = "您发送的消息是:" + message.Content; string response = WeChatEncrypt.AESEncrypt(WeChatResponse.TextResponse(message.FromUserName, message.ToUserName, content), encodingAESKey, appId); Console.WriteLine(response); } } } } // 获取微信服务器发送的消息 private static string GetPostStr() { Stream inputStream = Console.OpenStandardInput(); byte[] bytes = new byte[1024]; int length = inputStream.Read(bytes, 0, 1024); return Encoding.UTF8.GetString(bytes, 0, length); } } // 微信消息类 public class Message { public string ToUserName { get; set; } public string FromUserName { get; set; } public long CreateTime { get; set; } public string MsgType { get; set; } public string Content { get; set; } public string MsgId { get; set; } } // 微信消息响应类 public class WeChatResponse { public static string TextResponse(string toUserName, string fromUserName, string content) { string response = string.Format(@"<xml> <ToUserName><![CDATA[{0}]]></ToUserName> <FromUserName><![CDATA[{1}]]></FromUserName> <CreateTime>{2}</CreateTime> <MsgType><![CDATA[text]]></MsgType> <Content><![CDATA[{3}]]></Content> </xml>", toUserName, fromUserName, DateTime.Now.Ticks, content); return response; } } // 微信加解密类 public class WeChatEncrypt { public static string AESEncrypt(string content, string encodingAESKey, string appId) { byte[] key = Convert.FromBase64String(encodingAESKey + "="); byte[] iv = new byte[16]; Array.Copy(key, iv, 16); byte[] data = Encoding.UTF8.GetBytes(content); byte[] pad = PKCS7Padding(data); byte[] encrypted = null; using (var aes = new System.Security.Cryptography.AesCryptoServiceProvider()) { aes.KeySize = 256; aes.BlockSize = 128; aes.Key = key; aes.IV = iv; aes.Mode = System.Security.Cryptography.CipherMode.CBC; aes.Padding = System.Security.Cryptography.PaddingMode.None; using (var encryptor = aes.CreateEncryptor()) { encrypted = encryptor.TransformFinalBlock(pad, 0, pad.Length); } } string base64 = Convert.ToBase64String(encrypted); string nonce = Guid.NewGuid().ToString().Replace("-", ""); string timestamp = DateTime.Now.Ticks.ToString().Substring(0, 10); string signature = SHA1($"{token}\n{timestamp}\n{nonce}\n{base64}"); string response = string.Format(@"<xml> <Encrypt><![CDATA[{0}]]></Encrypt> <MsgSignature><![CDATA[{1}]]></MsgSignature> <TimeStamp>{2}</TimeStamp> <Nonce><![CDATA[{3}]]></Nonce> </xml>", base64, signature, timestamp, nonce); return response; } public static string AESDecrypt(string content, string encodingAESKey, string appId) { byte[] key = Convert.FromBase64String(encodingAESKey + "="); byte[] iv = new byte[16]; Array.Copy(key, iv, 16); string[] arr = content.Split('\n'); string base64 = arr[1].Replace("<Encrypt><![CDATA[", "").Replace("]]></Encrypt>", ""); string signature = arr[2].Replace("<MsgSignature><![CDATA[", "").Replace("]]></MsgSignature>", ""); string timestamp = arr[3].Replace("<TimeStamp>", "").Replace("</TimeStamp>", ""); string nonce = arr[4].Replace("<Nonce><![CDATA[", "").Replace("]]></Nonce>", ""); string plainText = null; try { byte[] encrypted = Convert.FromBase64String(base64); using (var aes = new System.Security.Cryptography.AesCryptoServiceProvider()) { aes.KeySize = 256; aes.BlockSize = 128; aes.Key = key; aes.IV = iv; aes.Mode = System.Security.Cryptography.CipherMode.CBC; aes.Padding = System.Security.Cryptography.PaddingMode.None; using (var decryptor = aes.CreateDecryptor()) { byte[] decrypted = decryptor.TransformFinalBlock(encrypted, 0, encrypted.Length); plainText = Encoding.UTF8.GetString(PKCS7Unpadding(decrypted)); } } } catch { return null; } string hash = SHA1($"{token}\n{timestamp}\n{nonce}\n{plainText}"); if (hash == signature) { return plainText; } else { return null; } } private static byte[] PKCS7Padding(byte[] data) { int length = data.Length; int pad = 32 - length % 32; byte[] padding = new byte[pad]; for (int i = 0; i < pad; i++) { padding[i] = (byte)pad; } byte[] result = new byte[length + pad]; Array.Copy(data, result, length); Array.Copy(padding, 0, result, length, pad); return result; } private static byte[] PKCS7Unpadding(byte[] data) { int length = data.Length; int pad = (int)data[length - 1]; byte[] result = new byte[length - pad]; Array.Copy(data, result, length - pad); return result; } private static string SHA1(string data) { byte[] bytes = Encoding.UTF8.GetBytes(data); using (var sha1 = System.Security.Cryptography.SHA1.Create()) { byte[] hash = sha1.ComputeHash(bytes); return BitConverter.ToString(hash).Replace("-", "").ToLower(); } } } } ``` 上述代码中使用了微信加解密算法进行消息的加解密,同时使用了微信消息响应类进行消息的回复。需要注意的是,该代码只是一个简单的示例,实际开发中需要根据需求进行更详细的开发。同时,微信公众平台开发需要符合微信的开发规范和要求,需要进行相关的认证和申请,开发前需要进行充分了解和准备。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值