HeyCHのブログ

慢性疲労のへいちゃんです

【C#】5ちゃんねるビューアーを作ろう その3

今回の内容は前回の内容の続きとして書いていきます。
heych.hatenablog.com
前回で、スレッド一覧がListViewに表示されるところまでいきました。
今回は、スレッドを選択したときスレッドの内容をRichTextBoxに表示する方法を書いていきたいと思います。

ListViewをクリックしたときのイベント

ListVIewのアイテムを選択したときに発生するイベントはいくつかあるのですが、今回は「listView1_SelectedIndexChanged」を使ってみようと思います。
f:id:HeyCH:20200417231524p:plain
以下のようにする事で、スレッドの内容を表示するためのURLをメッセージボックスに表示することができます。

        private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
            if (listView1.SelectedItems.Count <= 0) return;
            var url = (string)treeView1.SelectedNode.Tag;
            //https://hayabusa9.5ch.net/newsの形にする
            url = url.Substring(0, url.Length - ("/subback.html").Length);
            //https://hayabusa9.5ch.net/test/read.cgi/news/の形にする
            url = url.Substring(0, url.LastIndexOf("/")) + "/test/read.cgi" + url.Substring(url.LastIndexOf("/")) + "/";
            var sub= (string)listView1.SelectedItems[0].Tag;
            sub = sub.Substring(0, sub.Length - ("150").Length);
            url = url + sub;
            MessageBox.Show(url);
        }

スレッドの内容をRichTextBoxに表示する

以下のようにする事でRichTextBoxにスレッドの内容を表示することができます。

        string html = "";
        private void listView1_SelectedIndexChanged(object sender, EventArgs e) {
            if (listView1.SelectedItems.Count <= 0) return;
            var url = (string)treeView1.SelectedNode.Tag;
            //https://hayabusa9.5ch.net/newsの形にする
            url = url.Substring(0, url.Length - ("/subback.html").Length);
            ////https://hayabusa9.5ch.net/test/read.cgi/news/の形にする
            url = url.Substring(0, url.LastIndexOf("/")) + "/test/read.cgi" + url.Substring(url.LastIndexOf("/")) + "/";
            var sub= (string)listView1.SelectedItems[0].Tag;
            sub = sub.Substring(0, sub.Length - ("150").Length);
            url = url + sub;
            //まずHTMLの取得
            try {
                HttpWebRequest req = WebRequest.CreateHttp(url);
                using (var res = req.GetResponse()) {
                    using (var r = res.GetResponseStream()) {
                        using (var sr = new StreamReader(r, Encoding.GetEncoding(932))) {
                            html = sr.ReadToEnd();
                        }
                    }
                }
            } catch (Exception ex) {
                MessageBox.Show("HTMLの取得に失敗しました。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            richTextBox1.Text = "";
            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += Bw_DoWork;
            bw.RunWorkerAsync();
        }

        private void Bw_DoWork(object sender, DoWorkEventArgs e) {
            Regex numberReg = new Regex("(<span class=\"number\">)(.*?)(</span>)");
            Regex nameReg = new Regex("(<span class=\"name\">)(.*?)(</span>)");
            Regex dateReg = new Regex("(<span class=\"date\">)(.*?)(</span>)");
            Regex uidReg = new Regex("(<span class=\"uid\">)(.*?)(</span>)");
            Regex escapedReg = new Regex("(<span class=\"escaped\">)(.*?)(</span>)");
            int index = 0;
            string tmp = "";
            while (true) {
                //numberの取得
                var m = numberReg.Match(html, index);
                if (!m.Success) break;
                var number = m.Groups[2].Value;
                index = m.Index;
                //nameの取得
                m = nameReg.Match(html, index);
                if (!m.Success) break;
                var name = m.Groups[2].Value;
                index = m.Index;
                //dateの取得
                m = dateReg.Match(html, index);
                if (!m.Success) break;
                var date = m.Groups[2].Value;
                index = m.Index;
                //uidの取得
                m = uidReg.Match(html, index);
                if (!m.Success) break;
                var uid = m.Groups[2].Value;
                index = m.Index;
                //escapedの取得
                m = escapedReg.Match(html, index);
                if (!m.Success) break;
                var escaped = m.Groups[2].Value;
                escaped = escaped.Replace("<br>", "\r\n");
                index = m.Index;

                //nameとescapedの調整
                name = Regex.Replace(name, "<[^>]*?>", "");
                escaped = Regex.Replace(escaped, "<[^>]*?>", "").Replace("&gt;", ">").Replace("&lt;", "<").Replace("&amp;", "&");

                tmp += number + " " + name + " " + date + " " + uid + "\r\n\r\n" + escaped + "\r\n\r\n\r\n";
            }
            this.Invoke((MethodInvoker)delegate () { richTextBox1.Text = tmp; });
        }

f:id:HeyCH:20200418010119p:plain
※非常に重いのでどげんかせんといかん※richTextBox1+=というのがダメでした。軽くなりました。