예제 #1
0
        /// <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;
        }
예제 #2
0
        /// <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;
        }
예제 #3
0
        /// <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"; ;
        }
예제 #4
0
        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: 搜索所有好友
        }