開発環境 |
Microsoft Visual C# 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
Windows フォーム アプリケーション |
プロジェクト名 |
Jien2ch |
Jien2chプロジェクトにクラスを追加。
テンプレート:クラス
名前:ListViewEx
textBox1を削除。
コンテナー/SplitContainerをPanel2上にドロップ。
名前:splitContainer2
プロパティ FixedPanel:Panel1 Orientation:Horizontal
Jien2ch コンポーネント/ListViewExをsplitContainer2.Panel1上にドロップ。
名前:listViewEx1
プロパティ Dock:Fill
コモン コントロール/TextBoxをsplitContainer2.Panel2上にドロップ。
名前:textBox1
プロパティ Dock:Fill MultiLine:True ScrollBars:Vertical
treeView1にAfterSelectイベントハンドラを追加。
+Jien2ch
+Form1.cs
+Form1.Designer.cs
+ListViewEx.cs
+Program.cs
+Lib2ch
+Data
+Data.cs
+IO
+IO.cs
+Model
+BbsMenu.cs
+Subject.cs
Form1.cs
using System.Collections.Generic;
using System.Windows.Forms;
using Lib2ch.Data;
using Lib2ch.Model;
namespace Jien2ch
{
public partial class Form1 : Form
{
Subject _Subject = new Subject();
public Form1()
{
InitializeComponent();
#region 板一覧
BbsMenu bbsMenu = new BbsMenu();
List<BbsMenuItem> bbsMenuList = bbsMenu.GetMenuList();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
foreach (BbsMenuItem item in bbsMenuList)
{
TreeNode childNode = new TreeNode();
childNode.Text = item.BbsName;
childNode.Tag = item;
// 親ノード検索
TreeNode[] node = treeView1.Nodes.Find(item.Category, false);
if (node.Length == 0)
{
TreeNode parent = new TreeNode();
parent.Name = item.Category; // 検索用
parent.Text = item.Category; // 表示用
parent.Nodes.Add(childNode);
treeView1.Nodes.Add(parent);
}
else
{
node[0].Nodes.Add(childNode);
}
sb.Append(item.Category + item.BbsName + item.Url + "\r\n");
}
textBox1.Text = sb.ToString();
#endregion
}
#region 板一覧アイテム選択時
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node.Tag != null)
{
ThreadListAdd((BbsMenuItem)e.Node.Tag);
}
}
// スレッド一覧
void ThreadListAdd(BbsMenuItem bbsMenuItem)
{
SubjectList subjectList = _Subject.Get(bbsMenuItem);
listViewEx1.ItemSet(subjectList);
}
#endregion
}
}
ListViewEx.cs
using System.Windows.Forms;
using Lib2ch.Data;
namespace Jien2ch
{
class ListViewEx : ListView
{
public ListViewEx()
{
// プロパティ
View = View.Details;
FullRowSelect = true;
GridLines = true;
// 列ヘッダ
Columns.Add("!", 20); // 1列目は右寄せできないのでダミー
Columns.Add("番号", 40, HorizontalAlignment.Right);
Columns.Add("タイトル", 450);
Columns.Add("レス", 40, HorizontalAlignment.Right);
}
public void ItemSet(SubjectList subjectList)
{
ListViewItem[] item = new ListViewItem[subjectList.List.Count];
int num = 0; // 番号
foreach (SubjectData data in subjectList.List)
{
string[] line = new string[4];
line[1] = (num + 1).ToString();
line[2] = data.Title;
line[3] = data.Count.ToString();
item[num] = new ListViewItem(line);
item[num].Tag = data;
num++;
}
Items.AddRange(item);
Tag = subjectList;
}
}
}
Data.cs
using System;
using System.Collections.Generic;
namespace Lib2ch.Data
{
// ファイル結果
class FileResult
{
public string[] Line; // 行リスト
}
// 板一覧アイテム
public class BbsMenuItem
{
public string Category; // カテゴリ
public string BbsName; // 板名
public string Url; // URL
public string Directory
{
get { return Category + "/" + BbsName + "/"; }
}
}
// スレッドデータ
public class SubjectData
{
string FileName; // スレッドファイル名(.dat)
public string Title; // タイトル
public int Count; // レス数
public SubjectData(string line)
{
if (line == "") return;
FileName = line.Substring(0, 14);
int start = line.LastIndexOf("(");
int end = line.LastIndexOf(")");
Count = Convert.ToInt32(line.Substring(start + 1, end - (start + 1)));
Title = line.Substring(16, start - 16);
}
}
// スレッド一覧
public class SubjectList : BbsMenuItem
{
public List<SubjectData> List = new List<SubjectData>();
public SubjectList(BbsMenuItem item)
{
Category= item.Category;
BbsName = item.BbsName;
Url = item.Url;
}
public void Parsing(string[] data)
{
foreach (string line in data)
{
SubjectData subjectData = new SubjectData(line);
List.Add(subjectData);
}
}
}
}
IO.cs
using System.IO;
using System.Net;
using System.Text;
using Lib2ch.Data;
namespace Lib2ch.IO
{
class FileManager
{
public FileResult StandardCheck(string dir, string host, string file)
{
FileResult fileResult = LocalReader(dir + file);
if (fileResult == null)
{
// サーバーからダウンロード
Download(dir, host, file);
fileResult = LocalReader(dir + file);
}
return fileResult;
}
FileResult LocalReader(string path)
{
try
{
FileResult fileResult = new FileResult();
fileResult.Line = File.ReadAllLines(path, Encoding.Default);
return fileResult;
}
catch
{
return null;
}
}
bool Download(string dir, string host, string file)
{
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
try
{
WebClient wc = new WebClient();
wc.DownloadFile(host + file, dir + file);
return true;
}
catch
{
return false;
}
}
}
}
BbsMenu.cs
using System.Collections.Generic;
using Lib2ch.Data;
using Lib2ch.IO;
namespace Lib2ch.Model
{
public class BbsMenu
{
const string _CateStart = "<BR><BR><B>";
const string _CateEnd = "</B>";
const string _BbsStart = "<A HREF=";
const string _UrlEnd1 = " TARGET=_blank>";
const string _UrlEnd2 = ">";
const string _BbsEnd = "</A>";
FileManager _File = new FileManager();
public List<BbsMenuItem> GetMenuList()
{
// ファイルの有無
FileResult fileResult = _File.StandardCheck(
"./Log/", "http://menu.2ch.net/", "bbsmenu.html");
if (fileResult == null) return null;
// 解析処理
return BbsMenuParsing(fileResult.Line);
}
List<BbsMenuItem> BbsMenuParsing(string[] data)
{
List<BbsMenuItem> list = new List<BbsMenuItem>();
string category = null;
foreach (string line in data)
{
int index1 = line.IndexOf(_CateStart);
if (index1 != -1)
{
int index2 = line.IndexOf(_CateEnd);
if (index2 != -1)
{
int start = index1 + _CateStart.Length;
category = line.Substring(start, index2 - start);
}
}
if (category == null) continue;
BbsMenuItem item = BbsMenuFindLine(line, _BbsStart, _UrlEnd1, _BbsEnd);
if (item == null)
{
item = BbsMenuFindLine(line, _BbsStart, _UrlEnd2, _BbsEnd);
}
if (item != null)
{
item.Category = category;
list.Add(item);
}
}
return list;
}
BbsMenuItem BbsMenuFindLine(string line, string word1, string word2, string word3)
{
int index1 = line.IndexOf(word1);
if (index1 == -1) return null;
int start1 = index1 + word1.Length;
int index2 = line.IndexOf(word2, start1);
if (index2 == -1) return null;
int start2 = index2 + word2.Length;
int index3 = line.IndexOf(word3, start2);
if (index3 == -1) return null;
BbsMenuItem item = new BbsMenuItem();
item.Url = line.Substring(start1, index2 - start1);
item.BbsName = line.Substring(start2, index3 - start2);
return item;
}
}
}
Subject.cs
using Lib2ch.Data;
using Lib2ch.IO;
namespace Lib2ch.Model
{
public class Subject
{
FileManager _File = new FileManager();
public SubjectList Get(BbsMenuItem bbsMenuItem)
{
FileResult fileResult = _File.StandardCheck(
"./Log/" + bbsMenuItem.Directory, bbsMenuItem.Url, "subject.txt");
if (fileResult == null) return null;
SubjectList subjectList = new SubjectList(bbsMenuItem);
subjectList.Parsing(fileResult.Line);
return subjectList;
}
}
}
最終更新:2012年11月17日 21:14