/// <summary> /// 根据关键字搜索当前或所有好友的聊天记录,并显示 /// </summary> /// <param name="strSearch">关键字</param> /// <param name="friendList">搜索对象链表</param> /// <param name="fmProgress">搜索过程中步进的进度窗口</param> /// <returns>搜索到的记录数</returns> private int SearchHistory(string strSearch, Dictionary<string, FriendInfo> friendList, ProgressForm fmProgress) { bool bAll = true; // 当前是否搜索所有好友 if (friendList.Count == 1) bAll = false; // 存储找到的聊天记录内容,并保存起来,其中: // FriendInfo - 与该好友的聊天记录中存在搜索关键字 // string - 关键字 // int - 关键字所在的页码 // string - 将关键字的前后聊天内容显示在列表中 List<KeyValuePair<KeyValuePair<FriendInfo, string>, KeyValuePair<int, string>>> foundList = new List<KeyValuePair<KeyValuePair<FriendInfo, string>, KeyValuePair<int, string>>>(); foreach (KeyValuePair<string, FriendInfo> kvp in friendList) { string strUsrName = kvp.Value.strUsrName; if (bAll) fmProgress.progressBar.PerformStep(); SQLiteConnection connection = new SQLiteConnection("Data Source=" + m_strSqlFile); connection.Open(); MD5 md5Hash = MD5.Create(); string strFriendMD5 = GetMd5Hash(md5Hash, strUsrName); string table = "Chat_" + strFriendMD5; SQLiteCommand cmd = new SQLiteCommand(connection); SQLiteDataReader dr; //int nTotal = 0; try { // 开始读取数据 cmd.CommandText = "select message from " + table + " order by CreateTime asc"; cmd.ExecuteNonQuery(); } catch (System.Data.SQLite.SQLiteException ex) { MessageBox.Show(ex.Message); } dr = cmd.ExecuteReader(); int nCount = 0; int nPage = 1; while (dr.Read()) { string strMessage = dr.GetString(0); // 消息内容 if (bAll == false) fmProgress.progressBar.PerformStep(); if (strMessage.ToLower().Contains(strSearch.ToLower())) { const int nShowLen = 20; int nHead = strMessage.IndexOf(strSearch) - nShowLen; int nTail = strMessage.IndexOf(strSearch) + strSearch.Length + nShowLen; string strHead = "..."; string strTail = "..."; if (nHead < 0) { strHead = ""; nHead = 0; } if (nTail > strMessage.Length) { strTail = ""; nTail = strMessage.Length; } strMessage = strHead + strMessage.Substring(nHead, nTail - nHead) + strTail; KeyValuePair<int, string> kvpValue = new KeyValuePair<int, string>(nPage, strMessage); KeyValuePair<FriendInfo, string> kvpKey = new KeyValuePair<FriendInfo, string>(kvp.Value, strSearch); KeyValuePair<KeyValuePair<FriendInfo, string>, KeyValuePair<int, string>> kvpNode = new KeyValuePair<KeyValuePair<FriendInfo, string>, KeyValuePair<int, string>>(kvpKey, kvpValue); //KeyValuePair<string, string> kvpNode = new KeyValuePair<string, string>(strUsrName, strMessage); foundList.Add(kvpNode); } // end of if (strMessage.Contains(strSearch)) // 达到每页最大记录数,换页 if (++nCount >= m_nMaxRecord) { nPage++; nCount = 0; } } // end of while (dr.Read()) } // end of foreach MessageSearchResultsForm msgResFm = new MessageSearchResultsForm(this); foreach (KeyValuePair<KeyValuePair<FriendInfo, string>, KeyValuePair<int, string>> kvpNode in foundList) { ListViewItem lvItem = new ListViewItem(); lvItem.Text = "与“" + kvpNode.Key.Key.strDisplayName + "”的聊天记录中:" + kvpNode.Value.Value; lvItem.Tag = kvpNode; msgResFm.listView.Items.Add(lvItem); } if (foundList.Count != 0) msgResFm.Show(); else msgResFm.Close(); return foundList.Count; }
/// <summary> /// 加载某好友的聊天记录 /// </summary> /// <param name="info">要加载好友的信息</param> /// <param name="nPageCountOut">返回:聊天记录的总页数</param> /// <returns>返回聊天记录文件的路径</returns> private string LoadHistory(FriendInfo info, out int nPageCountOut) { string strUsrName = info.strUsrName; string strShowName = info.strRemarkName; if (info.strRemarkName.Length == 0) strShowName = info.strNickName; SQLiteConnection connection = new SQLiteConnection("Data Source=" + m_strSqlFile); connection.Open(); MD5 md5Hash = MD5.Create(); string strFriendMD5 = GetMd5Hash(md5Hash, strUsrName); string table = "Chat_" + strFriendMD5; SQLiteCommand cmd = new SQLiteCommand(connection); SQLiteDataReader dr; int nTotal = 0; try { // 获取记录总数 cmd.CommandText = "select count(*) from " + table; dr = cmd.ExecuteReader(); dr.Read(); nTotal = dr.GetInt32(0); dr.Close(); // 开始读取数据 cmd.CommandText = "select datetime(createtime, 'unixepoch', 'localtime'),* from " + table + " order by CreateTime asc"; cmd.ExecuteNonQuery(); } catch (System.Data.SQLite.SQLiteException ex) { MessageBox.Show(ex.Message); } string strHtml = ""; strHtml = m_strStyle + m_strBody; string[] strDivArr = new string[m_nMaxRecord]; int nCount = 0; int nPageCount = 0; string strLastFile = ""; string strTmpPath = GetTempFileName() + "\\"; m_strTmpPath = strTmpPath.Replace(".tmp", "_tmp"); Directory.CreateDirectory(m_strTmpPath); ProgressForm progressform = new ProgressForm(); progressform.progressBar.Minimum = 0; progressform.progressBar.Maximum = nTotal; progressform.progressBar.Step = 1; progressform.Show(); dr = cmd.ExecuteReader(); int nDivIndex = 0; while (dr.Read()) { progressform.progressBar.PerformStep(); string strTime = dr.GetString(0); // 产生时间 string strMessage = dr.GetString(5); // 消息内容 int nType = dr.GetInt32(8); // 消息类型 int nDes = dr.GetInt32(9); // 0-我发的 1-对方发的 int nMesLocalID = dr.GetInt32(2); // 消息的本地资源 ID switch (nType) { case 1: // 文字 //if (strFriendMD5 == "ffcc9697ac3309e93d80f7773b133f88") if (strMessage.StartsWith("<mmreader>")) strMessage = "<a style=\"color:#888\">腾讯新闻,尚未开发……</a>"; break; case 3: // 图片 string strImgDir = m_strRoot + "Img\\" + strFriendMD5 + "\\"; string strImgSmall = strImgDir + nMesLocalID + ".pic_thum"; string strImgBig = strImgDir + nMesLocalID + ".pic"; string strImgHuge = strImgDir + nMesLocalID + ".pic_hd"; string strImgName = ""; // 点开之后的大图 string strImgThum = ""; // 缩略图 // 默认显示更清晰的图 if (File.Exists(strImgHuge)) strImgName = strImgHuge; else if (File.Exists(strImgBig)) strImgName = strImgBig; else strImgName = strImgSmall; // 确保能显示缩略图 if (File.Exists(strImgSmall)) strImgThum = strImgSmall; else if (File.Exists(strImgBig)) strImgThum = strImgBig; else strImgThum = strImgHuge; // 最终 html strMessage = "<IMG style=\"cursor:hand;max-width:150px;max-height:150px\" src=\"" + strImgThum + "\" name=\"" + strImgName + "\">"; break; case 43: // 视频 case 62: // 小视频 string strVideoDir = m_strRoot + "Video\\" + strFriendMD5 + "\\"; string strVideoThum = strVideoDir + nMesLocalID + ".video_thum"; string strVideo = strVideoDir + nMesLocalID + ".mp4"; string strPlayBtn = m_strPlayBtn.Replace("%REPLACE%", strVideo); // 由于 block div 已经覆盖了图片的UI区域,所以不必像图片那样在 IMG 中添加视频路径 strMessage = strPlayBtn + "<IMG style=\"cursor:hand;max-width:150px;max-height:150px\" src=\"" + strVideoThum + "\">"; break; case 34: // 语音 // 提取语音文件 string strAudioDir = m_strRoot + "Audio\\" + strFriendMD5 + "\\"; string strAudio = strAudioDir + nMesLocalID + ".aud"; // 提取语音长度 const string strKeyWord = "voicelength=\""; int nStartIndex = strMessage.IndexOf(strKeyWord) + strKeyWord.Length; string strAudioLen = strMessage.Substring(nStartIndex, strMessage.IndexOf('\"', nStartIndex) - nStartIndex); int nAudioLen = int.Parse(strAudioLen); nAudioLen = nAudioLen / 1000 + (nAudioLen % 1000) / 500; // 四舍五入 strAudioLen = nAudioLen + "\""; // 根据语音长度增加泡泡的长度 int nWidth = 70 + (nAudioLen - 1) * 10; nWidth = nWidth > 190 ? 190 : nWidth; // 组织 HTML 语句 if (nDes == 0) { strAudioLen = m_strAudioLenR.Replace("%REPLACE%", strAudioLen); strMessage = strAudioLen + m_strAudioIconR + m_strSpeechAudioR; strMessage = strMessage.Replace("%REPLACE_WIDTH%", nWidth + ""); strMessage = strMessage.Replace("%REPLACE_NAME%", strAudio); } else { strAudioLen = m_strAudioLenL.Replace("%REPLACE%", strAudioLen); strMessage = strAudioLen + m_strAudioIconL + m_strSpeechAudioL; strMessage = strMessage.Replace("%REPLACE_WIDTH%", nWidth + ""); strMessage = strMessage.Replace("%REPLACE_NAME%", strAudio); } break; case 49: // 分享链接 string strType = ""; string strTitle = ""; string strDesc = ""; string strUrl = ""; try { // 解析 XML 数据 if (strMessage.Contains("<msg>")) strMessage = strMessage.Substring(strMessage.IndexOf("<msg>")); MemoryStream msXmlLink = new MemoryStream(Encoding.UTF8.GetBytes(strMessage)); XmlReader xmlLink = XmlReader.Create(msXmlLink); while (xmlLink.Read()) { if (xmlLink.NodeType == XmlNodeType.Element) { if (xmlLink.Name == "type") strType = xmlLink.ReadString(); else if (xmlLink.Name == "title") strTitle = xmlLink.ReadString(); else if (xmlLink.Name == "des") strDesc = xmlLink.ReadString(); else if (xmlLink.Name == "url") strUrl = xmlLink.ReadString(); } } xmlLink.Close(); msXmlLink.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } if (strType == "17") strMessage = "<a style=\"color:#888\"> 实时位置信息... </a>"; else { if (strUrl.Trim().Length == 0) strMessage = string.Format("分享链接:<a>{1}</br>" + "<a style=\"color:#888\">{2}</a></a>", strUrl, strTitle, strDesc); else strMessage = string.Format("分享链接:<a href=\"{0}\" target=\"_blank\">{1}</br>" + "<a style=\"color:#888\">{2}</a></a>", strUrl, strTitle, strDesc); } break; case 48: // 位置 string strX = ""; string strY = ""; string strLabel = ""; string strPoiname = ""; try { // 解析 XML 数据 if (strMessage.Contains("<msg>")) strMessage = strMessage.Substring(strMessage.IndexOf("<msg>")); MemoryStream msXmlLoc = new MemoryStream(Encoding.UTF8.GetBytes(strMessage)); XmlTextReader xmlLoc = new XmlTextReader(msXmlLoc); while (xmlLoc.Read()) { if (xmlLoc.NodeType == XmlNodeType.Element) { if (xmlLoc.Name == "location") { strX = xmlLoc.GetAttribute("x"); strY = xmlLoc.GetAttribute("y"); strLabel = xmlLoc.GetAttribute("label"); strPoiname = xmlLoc.GetAttribute("poiname"); if (strLabel.Length == 0) strLabel = " "; if (strPoiname.Length == 0) strPoiname = " "; } } } xmlLoc.Close(); msXmlLoc.Close(); } catch (Exception ex) { } strMessage = string.Format("<a target=\"_blank\" href=\"http://apis.map.qq.com/uri/v1/marker?" + "marker=coord:{0},{1};title:{2};addr:{3}\">位置信息</a>", strX, strY, strPoiname, strLabel); break; case 50: // 语音、视频通话 string strDuration = ""; try { // 解析 XML 数据 XmlReaderSettings settings = new XmlReaderSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; // Tell the XmlReader to not be so picky MemoryStream msXmlVoice = new MemoryStream(Encoding.UTF8.GetBytes(strMessage)); XmlReader xmlVoice = XmlReader.Create(msXmlVoice, settings); while (xmlVoice.Read()) { if (xmlVoice.NodeType == XmlNodeType.Element) { if (xmlVoice.Name == "duration") strDuration = xmlVoice.ReadString(); } } xmlVoice.Close(); msXmlVoice.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } if (strDuration.Length == 0) strDuration = "0"; int nDuration = int.Parse(strDuration); int nHour = nDuration / 3600; int nMin = nDuration / 60 - nHour * 60; int nSec = nDuration - nHour * 3600 - nMin * 60; if (nHour == 0) strMessage = string.Format("<a style=\"color:#888\">通话时长:{0:00}:{1:00}</a>", nMin, nSec); else strMessage = string.Format("<a style=\"color:#888\">通话时长:{2:00}:{0:00}:{1:00}</a>", nMin, nSec, nHour); break; case 47: // 表情(暂不可提取) string strEmotPath = AppDomain.CurrentDomain.BaseDirectory + "emoticon1\\"; string strMD5 = ""; string strProductId = ""; try { // 解析 XML 数据 XmlReaderSettings settings = new XmlReaderSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; // Tell the XmlReader to not be so picky if (strMessage.Contains("<msg")) strMessage = strMessage.Substring(strMessage.IndexOf("<msg")); MemoryStream msXmlVoice = new MemoryStream(Encoding.UTF8.GetBytes(strMessage)); XmlReader xmlVoice = XmlReader.Create(msXmlVoice, settings); while (xmlVoice.Read()) { if (xmlVoice.NodeType == XmlNodeType.Element) { if (xmlVoice.Name == "emoji") { strMD5 = xmlVoice.GetAttribute("md5"); strProductId = xmlVoice.GetAttribute("productid"); break; } } } xmlVoice.Close(); msXmlVoice.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } bool bDisplay = true; if (strMD5.Length == 0) bDisplay = false; string strEmoji = strEmotPath + strMD5 + ".pic"; if (File.Exists(strEmoji) == false) bDisplay = false; if (bDisplay) strMessage = String.Format("<img width=\"150px\" src=\"{0}\">", strEmoji); else strMessage = "<a style=\"color:#888\">表情信息(暂不可提取)</a>"; break; case 42: // 名片 string strNick = ""; string strUserName = ""; try { // 解析 XML 数据 XmlReaderSettings settings = new XmlReaderSettings(); settings.ConformanceLevel = ConformanceLevel.Fragment; // Tell the XmlReader to not be so picky if (strMessage.Contains("<msg")) strMessage = strMessage.Substring(strMessage.IndexOf("<msg")); MemoryStream msXmlVoice = new MemoryStream(Encoding.UTF8.GetBytes(strMessage)); XmlReader xmlVoice = XmlReader.Create(msXmlVoice, settings); while (xmlVoice.Read()) { if (xmlVoice.NodeType == XmlNodeType.Element) { if (xmlVoice.Name == "msg") { strNick = xmlVoice.GetAttribute("nickname"); strUserName = xmlVoice.GetAttribute("username"); } } } xmlVoice.Close(); msXmlVoice.Close(); } catch (Exception ex) { MessageBox.Show(ex.Message); } strMessage = string.Format("<a style=\"color:#888\">名片信息:</br>微信ID:{0}</br>微信名:{1}</a>", strUserName, strNick); break; } if (nDes == 0) { string strUserTime = ""; if (strUsrName.Contains("@chatroom")) { strUserTime = m_strDivImgR.Replace("%REPLACE%", "我" + " " + strTime); } else strUserTime = m_strDivImgR.Replace("%REPLACE%", strTime); string strSpeech = m_strSpeechR.Replace("%REPLACE%", strMessage); // 将图片在居中泡泡 if (nType == 3 || nType == 43) strSpeech = strSpeech.Replace("class=\"speech right\"", "class=\"speech right\" align=\"center\""); // 语音的话格式不一样 if (nType == 34) strSpeech = strMessage; strDivArr[nDivIndex++] = m_strDivR.Replace("%REPLACE%", strUserTime) + m_strDivR.Replace("%REPLACE%", strSpeech); } else { string strUserTime = ""; if (strUsrName.Contains("@chatroom")) { // 群成员发消息显示成员,而非群名 string strOriMessage = dr.GetString(5); int nColonIndex = strOriMessage.IndexOf(':'); string strUser = ""; if (nColonIndex >= 0) strUser = strOriMessage.Substring(0, nColonIndex); if (strUser.Length == 0) { // 解析 XML 数据 if (strOriMessage.Contains("<msg>")) //strOriMessage = strOriMessage.Substring(strOriMessage.IndexOf("<msg>")); { MemoryStream msXmlLink = new MemoryStream(Encoding.UTF8.GetBytes(strOriMessage)); XmlReader xmlLink = XmlReader.Create(msXmlLink); while (xmlLink.Read()) { if (xmlLink.NodeType == XmlNodeType.Element) { if (xmlLink.Name == "videomsg") strUser = xmlLink.GetAttribute("fromusername"); } } xmlLink.Close(); msXmlLink.Close(); } } if (strUser.Length == 0) strUser = "******"; // 显示中文名,而非微信ID bool bFound = false; FriendInfo tmpInfo;// = m_FriendList[strUser]; if (m_FriendList.TryGetValue(strUser, out tmpInfo)) // 此处若用 try...catch 将导致性能大大降低! { strShowName = tmpInfo.strRemarkName; if (tmpInfo.strRemarkName.Length == 0) strShowName = tmpInfo.strNickName; bFound = true; } if (bFound == false) strShowName = strUser; strUserTime = m_strDivImgL.Replace("%REPLACE%", strShowName + " " + strTime); //if (strMessage.Contains(strUser) == false) // strMessage = strUser + ": " + strMessage; } else strUserTime = m_strDivImgL.Replace("%REPLACE%", strShowName + " " + strTime); string strSpeech = m_strSpeechL.Replace("%REPLACE%", strMessage); // 将图片在居中泡泡 if (nType == 3 || nType == 43) strSpeech = strSpeech.Replace("class=\"speech left\"", "class=\"speech left\" align=\"center\""); // 语音的话格式不一样 if (nType == 34) strSpeech = strMessage; strDivArr[nDivIndex++] = m_strDivL.Replace("%REPLACE%", strUserTime) + m_strDivL.Replace("%REPLACE%", strSpeech); } // 达到每页最大记录数,换页 if (++nCount >= m_nMaxRecord) { string strDivAll = ""; for (int i = 0; i < m_nMaxRecord; i++) { strDivAll += strDivArr[i]; strDivArr[i] = ""; } strHtml = m_strStyle + m_strBody.Replace("%REPLACE%", strDivAll); ReplaceEmoji(ref strHtml); // 替换官方表情 nDivIndex = 0; FileInfo fileInfo = new FileInfo(m_strTmpPath + "WechatHistory_" + ++nPageCount + ".html"); FileStream fs = fileInfo.Open(FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.GetEncoding("UTF-8")); sw.WriteLine(strHtml); sw.Flush(); sw.Close(); strLastFile = fileInfo.FullName; nCount = 0; } } if (nCount != 0) { string strDivAll = ""; for (int i = 0; i < m_nMaxRecord; i++) { strDivAll += strDivArr[i]; strDivArr[i] = ""; } strHtml = m_strStyle + m_strBody.Replace("%REPLACE%", strDivAll); ReplaceEmoji(ref strHtml); // 替换官方表情 nDivIndex = 0; FileInfo fileInfo = new FileInfo(m_strTmpPath + "WechatHistory_" + ++nPageCount + ".html"); FileStream fs = fileInfo.Open(FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.GetEncoding("UTF-8")); sw.WriteLine(strHtml); sw.Flush(); sw.Close(); strLastFile = fileInfo.FullName; } progressform.Hide(); nPageCountOut = nPageCount; return strLastFile; }
/// <summary> /// 加载好友列表 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void MainForm_Load(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "MM.sqlite|MM.sqlite"; DialogResult dlgRes = dlg.ShowDialog(); if (dlgRes == System.Windows.Forms.DialogResult.Cancel) { m_bShouldExit = true; return; } m_strSqlFile = dlg.FileName; try { m_strRoot = Directory.GetParent(m_strSqlFile).Parent.FullName + "\\"; } catch (System.Exception ex) { MessageBox.Show("聊天记录文件夹结构不完整,详细信息:\r\n" + ex.Message); return; } SQLiteConnection connection = new SQLiteConnection("Data Source=" + m_strSqlFile); connection.Open(); SQLiteCommand cmd = new SQLiteCommand(connection); // 获取好友个数 cmd.CommandText = "select count(*) from friend where type != 4 and type != 6"; cmd.ExecuteNonQuery(); SQLiteDataReader dr = cmd.ExecuteReader(); int nTotal = 0; if (dr.Read()) nTotal = dr.GetInt32(0); else { MessageBox.Show("读取好友列表时出现异常!"); return; } dr.Close(); // 开始获取好友信息 cmd.CommandText = "select * from friend where type != 4 and type != 6"; cmd.ExecuteNonQuery(); dr = cmd.ExecuteReader(); TreeView[] tvArr = new TreeView[3]; tvArr[0] = tvFriends; tvArr[1] = tvGroup; tvArr[2] = tvOthers; ProgressForm progressForm = new ProgressForm(); progressForm.progressBar.Minimum = 0; progressForm.progressBar.Maximum = nTotal; progressForm.progressBar.Step = 1; progressForm.Show(); while (dr.Read()) { progressForm.progressBar.PerformStep(); FriendInfo info = new FriendInfo(); info.strUsrName = dr.GetString(1); info.strNickName = dr.GetString(2); info.strRemarkName = dr.GetString(8); info.strPinyin = dr.GetString(8); int nType = dr.GetInt16(10); string strFullPY = ""; try { strFullPY = dr.GetString(7); } catch (Exception ex) { } //info.strNickName = Microsoft.VisualBasic.Strings.StrConv(info.strNickName, // Microsoft.VisualBasic.VbStrConv.SimplifiedChinese, 0); if (info.strRemarkName.Substring(0, 2).CompareTo("\n\0") != 0) { // 获取备注名 int length = info.strRemarkName.IndexOf((char)0x12) - 2; if (length > 0) info.strRemarkName = info.strRemarkName.Substring(2, length); // 获取备注名的全拼 GetPinyinFromString(info.strPinyin, out info.strPinyin); if (info.strPinyin.Length == 0) GetPinyinFromString(strFullPY, out info.strPinyin); if (info.strPinyin.Length == 0) info.strPinyin = SpellCodeHelper.GetAllPYLetters(info.strNickName); } else { info.strRemarkName = ""; info.strPinyin = ""; } if (info.strPinyin.Length == 0) info.strPinyin = SpellCodeHelper.GetAllPYLetters(info.strNickName); #region 输出查看 //FileStream fs = new FileStream("a.txt", FileMode.OpenOrCreate | FileMode.Append); //string strFS = string.Format("{0}\t{1}\t{2}\t{3}\r\n", info.strUsrName, info.strNickName, info.strRemarkName, info.strPinyin); //byte[] bt = Encoding.UTF8.GetBytes(strFS); //fs.Write(bt, 0, bt.Length); //fs.Close(); #endregion // 若没有对应的消息记录,不列入好友列表 MD5 md5Hash = MD5.Create(); string table = "Chat_" + GetMd5Hash(md5Hash, info.strUsrName); SQLiteCommand cmd2 = new SQLiteCommand(connection); cmd2.CommandText = "select * from " + table; try { cmd2.ExecuteNonQuery(); } catch (System.Data.SQLite.SQLiteException ex) { continue; } TreeNode node = new TreeNode(); if (info.strRemarkName.Length == 0) node.Text = info.strNickName; else node.Text = info.strRemarkName; if (info.strRemarkName.Contains("<2></2>")) node.Text = info.strNickName; if (node.Text.Length == 0) node.Text = "未命名聊天群"; //node.Text = info.strNickName + "【" + info.strRemarkName + "】"; node.Tag = info; // 存储好友信息 info.strDisplayName = node.Text; m_FriendList.Add(info.strUsrName, info); //分类 string strPy = "#"; char[] arr = new char[26]; for (int i = 0; i < 26; i++) arr[i] = (char)(0x61 + i); foreach (char c in info.strPinyin.ToLower()) { bool bFound = false; foreach (char alphabet in arr) { if (c == alphabet) { strPy = c + ""; bFound = true; break; } } if (bFound) break; } strPy = strPy.ToUpper(); //if (info.strPinyin.Length == 0) // strPy = "#"; //else // strPy = info.strPinyin.Substring(0, 1).ToUpper(); //tvFriends.Nodes.Add(node); int nSel = 0; if (nType == 2) // 聊天群&已删除的服务号&其它 nSel = 1; else if (nType == 4 || // 该好友在群聊天中,但未添加好友 nType == 67 || // 语音提醒 nType == 6) // 非好友 nSel = 2; if (info.strUsrName.Contains("gh_")) nSel = 2; // 订阅号、服务号 if (info.strUsrName.Contains("@chatroom")) nSel = 1; // 群 if (tvArr[nSel].Nodes.Find(strPy, false).Length == 0) tvArr[nSel].Nodes.Add(strPy, strPy); tvArr[nSel].Nodes[strPy].Nodes.Add(node); } foreach (TreeView tv in tvArr) { tv.Sort(); for (int i = 0; i < tv.Nodes.Count; i++) tv.Nodes[i].ExpandAll(); if (tv.Nodes.Count != 0) tv.Nodes[0].EnsureVisible(); } connection.Close(); progressForm.Hide(); lbPageNumber.Text = ""; // 释放 Emoji ReleaseEmoji(); // 加载首页 StreamToFile(m_strEmojiPath, ".", "default.html"); wbHistory.WebView.Url = m_strEmojiPath + "default.html"; ; }
private void btnSearchHistory_Click(object sender, EventArgs e) { string strSearch = tbSearchHistory.Text; if (strSearch.Trim().Length == 0 || strSearch.Trim() == "搜索聊天记录") return; if (cbSearchArea.SelectedIndex == 0) // 搜索当前好友 { int nSel = tabControl.SelectedIndex; TreeView[] tvArr = new TreeView[3]; tvArr[0] = tvFriends; tvArr[1] = tvGroup; tvArr[2] = tvOthers; if (tvArr[nSel].SelectedNode == null) { MessageBox.Show("未选中任何好友,将无法搜索。"); return; } FriendInfo info = (FriendInfo)tvArr[nSel].SelectedNode.Tag; Dictionary<string, FriendInfo> friendList = new Dictionary<string, FriendInfo>(); friendList.Add(info.strUsrName, info); // 获取当前好友的消息记录数 SQLiteConnection connection = new SQLiteConnection("Data Source=" + m_strSqlFile); connection.Open(); MD5 md5Hash = MD5.Create(); string strFriendMD5 = GetMd5Hash(md5Hash, info.strUsrName); string table = "Chat_" + strFriendMD5; SQLiteCommand cmd = new SQLiteCommand(connection); SQLiteDataReader dr; try { // 开始读取数据 cmd.CommandText = "select count(*) from " + table; cmd.ExecuteNonQuery(); } catch (System.Data.SQLite.SQLiteException ex) { } dr = cmd.ExecuteReader(); dr.Read(); int nCount = dr.GetInt32(0); // 开始搜索 ProgressForm fmProgress = new ProgressForm(); fmProgress.Show(); fmProgress.progressBar.Minimum = 0; fmProgress.progressBar.Maximum = nCount; fmProgress.progressBar.Step = 1; int num = SearchHistory(strSearch, friendList, fmProgress); fmProgress.Close(); MessageBox.Show(string.Format("已搜索到{0}条消息记录。", num)); } // end of if: 搜索当前好友 else // 搜索所有好友 { ProgressForm fmProgress = new ProgressForm(); fmProgress.Show(); fmProgress.progressBar.Minimum = 0; fmProgress.progressBar.Maximum = m_FriendList.Count(); fmProgress.progressBar.Step = 1; int num = SearchHistory(strSearch, m_FriendList, fmProgress); fmProgress.Close(); MessageBox.Show(string.Format("已搜索到{0}条消息记录。", num)); } // end of else: 搜索所有好友 }