開発環境 |
Microsoft Visual C# 2010 Express (SP1) |
実行環境 |
Microsoft Windows XP Home Edition (SP3) |
プロジェクトの種類 |
空のプロジェクト |
プロジェクト名 |
Jien2ch |
listViewEx1を削除。
コンテナー/SplitContainerをPanel2上にドロップ。
名前:splitContainer2
FixedPanel:Panel1
Jien2ch コンポーネント/ListViewExをsplitContainer2.Panel1上にドロップ。
名前:listViewEx1
Dock:Fill
コモン コントロール/TextBoxをsplitContainer2.Panel2上にドロップ。
名前:textBox1
Dock:Fill
MultiLine:True
ScrollBars:Vertical
listViewEx1にSelectedIndexChangedイベントハンドラを追加。
Lib2ch.DataにDatクラスを追加。
Lib2ch.DataにDatResクラスを追加。
Lib2ch.ModelにThreadDatクラスを追加。
+Jien2ch プロジェクト
+Form1.cs フォームクラス
+Form1.Designer.cs フォームデザイナー
+ListViewEx.cs リストビュークラス
+Program.cs プログラムクラス
+Lib2ch クラスライブラリ
+Data データ名前空間
+Data.cs データクラス
+IO IO名前空間
+File.cs ファイルクラス
+FileManager.cs ファイル管理クラス
+Model モデル名前空間
+BbsMenu.cs 板一覧クラス
+Subject.cs スレッド一覧クラス
+ThreadDat.cs スレッドdatクラス
namespace Jien2ch
Program.cs
using System;
using System.Windows.Forms;
namespace Jien2ch
{
class Program
{
[STAThread] // Single-Threaded Apartment
static void Main()
{
Application.Run(new Form1());
}
}
}
Form1.cs
using System;
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();
ThreadDat _ThreadDat = new ThreadDat();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
#region 板一覧
BbsMenu bbsMenu = new BbsMenu();
List<BbsMenuItem> bbsMenuList = bbsMenu.GetMenuList();
foreach (BbsMenuItem item in bbsMenuList)
{
TreeNode childNode = new TreeNode();
//childNode.Name = item.Name;
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 = parent.Name; // 表示用
parent.Nodes.Add(childNode);
treeView1.Nodes.Add(parent);
}
else
{
node[0].Nodes.Add(childNode);
}
}
#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
#region スレッド一覧アイテム選択時
private void listViewEx1_SelectedIndexChanged(object sender, EventArgs e)
{
ListViewEx listView = (ListViewEx)sender;
if (listView.SelectedItems.Count == 0) return;
SubjectData subjectData = (SubjectData)listView.SelectedItems[0].Tag;
// textBox1.Text = subjectData.FileName + subjectData.Title;
ThreadViewAdd(subjectData);
}
void ThreadViewAdd(SubjectData subjectData)
{
Dat dat = _ThreadDat.Get(subjectData);
// webBrowserEx1.ItemSet();
System.Text.StringBuilder sb = new System.Text.StringBuilder();
int num = 0; // 番号
foreach (DatRes datRes in dat.Res)
{
num++;
sb.Append(num + ":[" + datRes.Data + "]\r\n");
}
textBox1.Text = sb.ToString();
}
#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[0] = ;
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;
}
}
}
namespace Lib2ch.Data
Data.cs
using System;
using System.Collections.Generic;
namespace Lib2ch.Data
{
// 板一覧アイテム
public class BbsMenuItem
{
public string Category; // カテゴリ名
public string BbsName; // 板名
public string Url; // URL
public string Directory
{
get
{
return "/" + Category + "/" + BbsName;
}
}
}
// ファイル結果
class FileResult
{
public List<string> Line = new List<string>(); // 行リスト
}
// スレッドデータ
public class SubjectData : BbsMenuItem
{
public 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 void Parsing(List<string> data)
{
foreach (string line in data)
{
SubjectData subjectData = new SubjectData(line);
subjectData.Category = Category;
subjectData.BbsName = BbsName;
subjectData.Url = Url;
List.Add(subjectData);
}
}
}
// スレッドデータ
public class Dat : SubjectData
{
public List<DatRes> Res = new List<DatRes>();
public Dat() : base("")
{
}
public void Parsing(List<string> data)
{
if (data.Count > 1)
{
DatRes datRes = new DatRes();
data[0] = datRes.Title(data[0]);
datRes.Res(data[0]);
Res.Add(datRes);
}
for (int n = 1; n < data.Count; n++)
{
DatRes datRes = new DatRes();
datRes.Res(data[n]);
Res.Add(datRes);
}
}
}
public class DatRes
{
public string Data;
public void Res(string line)
{
Data = line;
}
public string Title(string line)
{
return line;
}
}
}
namespace Lib2ch.IO
File.cs
using System.IO;
using System.Collections.Generic;
using System.Net;
using System.Text;
using Lib2ch.Data;
namespace Lib2ch.IO
{
class File
{
Encoding _Type = Encoding.GetEncoding("Shift_JIS");
protected FileResult LocalReader(string path)
{
try
{
FileResult fileResult = new FileResult();
using (StreamReader sr = new StreamReader(path, _Type))
{
string line;
while ((line = sr.ReadLine()) != null)
{
fileResult.Line.Add(line);
}
}
return fileResult;
}
catch
{
return null;
}
}
protected FileResult UrlReader(string url)
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.UserAgent = "Monazilla/1.00(Jien2ch/Lib2ch)";
req.AddRange(0);
req.KeepAlive = false;
req.Headers.Add("Pragma", "no-cache");
req.Headers.Add("Cache-Control", "no-cache");
WebResponse res = null;
FileResult fileResult = new FileResult();
try
{
res = req.GetResponse();
}
catch (WebException)
{
return fileResult;
}
using (Stream stream = res.GetResponseStream())
{
using (StreamReader sr = new StreamReader(stream, _Type))
{
string line;
while ((line = sr.ReadLine()) != null)
{
fileResult.Line.Add(line);
}
}
}
return fileResult;
}
protected bool LocalWriter(string dir, string file, List<string> writeData)
{
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
try
{
using (StreamWriter sw = new StreamWriter(dir + file, false, _Type))
{
sw.NewLine = "\n";
foreach (string line in writeData)
{
sw.WriteLine(line);
}
}
return true;
}
catch
{
return false;
}
}
}
}
FileManager.cs
using Lib2ch.Data;
namespace Lib2ch.IO
{
class FileManager : File
{
public FileResult StandardCheck(string path, string host, string fileName)
{
FileResult fileResult = new FileResult();
fileResult = LocalReader(path + fileName);
if (fileResult == null)
{
// サーバーからダウンロード
fileResult = UrlReader(host + fileName);
if (fileResult == null) return null;
// ファイルの書き込み
if (!LocalWriter(path, fileName, fileResult.Line))
{
return null;
}
}
return fileResult;
}
}
}
namespace Lib2ch.Model
BbsMenu.cs
using System.Collections.Generic;
using Lib2ch.Data;
using Lib2ch.IO;
namespace Lib2ch.Model
{
// 板一覧
public class BbsMenu
{
string _Path = "./Log";
string _FileName = "/bbsmenu.html";
string _Host = "http://menu.2ch.net";
string _CateStart = "<BR><BR><B>";
string _CateEnd = "</B>";
string _BbsStart = "<A HREF=";
string _UrlEnd1 = "/>";
string _UrlEnd2 = "/ TARGET=_blank>";
string _BbsEnd = "</A>";
FileManager _File = new FileManager();
public List<BbsMenuItem> GetMenuList()
{
// ファイルの有無
FileResult fileResult = _File.StandardCheck(_Path, _Host, _FileName);
if (fileResult == null) return null;
// 解析処理
return BbsMenuParsing(fileResult.Line);
}
List<BbsMenuItem> BbsMenuParsing(List<string> data)
{
List<BbsMenuItem> list = new List<BbsMenuItem>();
string parent = null;
foreach (string line in data)
{
// カテゴリ
// <BR><BR><B>(parent)</B>
int index1 = line.IndexOf(_CateStart);
if (index1 != -1)
{
int index2 = line.IndexOf(_CateEnd);
if (index2 != -1)
{
int start = index1 + _CateStart.Length;
parent = line.Substring(start, index2 - start);
}
}
if (parent == null) continue;
BbsMenuItem item = BbsMenuFindLine(line, _BbsStart, _UrlEnd1, _BbsEnd);
if (item == null)
{
item = BbsMenuFindLine(line, _BbsStart, _UrlEnd2, _BbsEnd);
}
if (item != null)
{
item.Category = parent;
list.Add(item);
}
}
return list;
}
// 板のURLと名前を取得
// <A HREF=(Url)/>(Name)</A>
// <A HREF=(Url)/ TARGET=_blank>(Name)</A>
BbsMenuItem BbsMenuFindLine(string line, string word1, string word2, string word3)
{
int index1 = line.IndexOf(word1);
if (index1 == -1) return null;
int index2 = line.IndexOf(word2);
if (index2 == -1) return null;
int index3 = line.IndexOf(word3);
if (index3 == -1) return null;
BbsMenuItem item = new BbsMenuItem();
int start1 = index1 + word1.Length;
int start2 = index2 + word2.Length;
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)
{
SubjectList subjectList = new SubjectList();
subjectList.BbsName = bbsMenuItem.BbsName;
subjectList.Url = bbsMenuItem.Url;
subjectList.Category = bbsMenuItem.Category;
FileResult fileResult = _File.StandardCheck(
"./Log" + subjectList.Directory, subjectList.Url, "/subject.txt");
if (fileResult == null) return null;
subjectList.Parsing(fileResult.Line);
return subjectList;
}
}
}
ThreadDat.cs
using Lib2ch.Data;
using Lib2ch.IO;
namespace Lib2ch.Model
{
public class ThreadDat
{
FileManager _File = new FileManager();
public Dat Get(SubjectData subjectData)
{
Dat dat = new Dat();
dat.Category = subjectData.Category;
dat.BbsName = subjectData.BbsName;
dat.Url = subjectData.Url;
dat.FileName = "/" + subjectData.FileName;
dat.Title = subjectData.Title;
dat.Count = subjectData.Count;
FileResult fileResult = _File.StandardCheck(
"./Log" + dat.Directory, dat.Url + "/dat/", dat.FileName);
if (fileResult == null) return null;
dat.Parsing(fileResult.Line);
return dat;
}
}
}
最終更新:2012年11月13日 18:25