約 2,967,837 件
https://w.atwiki.jp/android2chbrowser/pages/21.html
■En2ch ウェブページ http //homepage1.nifty.com/salt/ ダウンロード https //market.android.com/details?id=ms.salt.en2ch2 feature=search_result 画面 設定画面 紹介記事 En2ch2ちゃんねる専用の閲覧アプリ http //pc.nikkeibp.co.jp/article/special/20091008/1019282/ En2ch (with translator func.)オフラインでも楽しめる!多機能2ちゃんねるブラウザ http //androider.jp/?p=1985 En2ch (with translator func.) ネラーの皆様、このブラウザも素敵です!Androidアプリ153 http //octoba.net/archives/20091008-en2ch-with-translator-func-android-153.html ここを編集 最近のリンク元 申し訳ありませんが、recent_page_ref プラグインは提供を終了し、ご利用いただけません。
https://w.atwiki.jp/wikiroid/pages/46.html
作者 Salt URL http //jp.androlib.com/android.application.ms-salt-en2ch2-qimE.aspx Ver 1.2.14 言語 日本語
https://w.atwiki.jp/sampleisbest/pages/181.html
開発環境 Microsoft Visual C# 2010 Express (SP1) 実行環境 Microsoft Windows XP Home Edition (SP3) プロジェクトの種類 Windows フォーム アプリケーション プロジェクト名 Jien2ch プロジェクト プロジェクトの保存 [ソリューションのディレクトリを作成]にチェックを付けておくと、 ソリューションに新しいプロジェクトを追加する時にプロジェクトの階層が整う。 フォーム 名前:Form1 プロパティ Text Jien2ch Size 800, 600 コンテナー/SplitContainerをForm1上にドロップ。 名前:splitContainer1 プロパティ FixedPanel Panel1 コモン コントロール/TreeViewをPanel1上にドロップ。 名前:treeView1 プロパティ Dock Fill コモン コントロール/TextBoxをPanel2上にドロップ。 名前:textBox1 プロパティ Dock Fill MultiLine True ScrollBars Vertical クラスライブラリ ソリューションに新しいプロジェクトを追加。 テンプレート:クラス ライブラリ 名前:Lib2ch Class1.csは削除。 Lib2chに以下の新しいフォルダーを追加。 Data IO Model 各種クラスを追加。 +Lib2ch +Data +Data.cs +IO +IO.cs +Model +BbsMenu.cs Jien2chプロジェクトの参照設定にプロジェクトLib2chを追加。 参考 C#で2ch専用ブラウザをつくろう 専ブラ開発への道 と~く2ちゃんねる Form1.cs using System.Collections.Generic; using System.Windows.Forms; using Lib2ch.Data; using Lib2ch.Model; namespace Jien2ch { public partial class Form1 Form { 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 } } } Data.cs namespace Lib2ch.Data { // ファイル結果 class FileResult { public string[] Line;// 行リスト } // 板一覧アイテム public class BbsMenuItem { public string Category;// カテゴリ public string BbsName;// 板名 public string Url;// URL } } 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; } } }
https://w.atwiki.jp/openj3/pages/6.html
open2ch板とは、おーぷん2ちゃんねるの運営板である。 おんJの植民地の一つ 正式名称は「運営@おーぷん」 運営板独自の採用バナーは存在しない(おーぷん汎用バナーになっている) 概要 スレ立てルール 野原板概要 関連リンク コメント欄 概要 不定期にさとるへの要望スレが立ったり、#おーぷんに要望スレ で要望したり、 バグ報告スレ でバグを見つけ次第おーぷん民がバグを報告するなど、運営関連の活動をしている板 また、「名無し」の表示色が、おんJのような緑ではなく青色で表示される ちなみに、野原板とは姉妹板の関係らしい 運営板不採用バナー一覧 + クリックして展開 スレ立てルール テスト投稿は野原@テスト用で行うこと。 以下は板の方向性に沿っているが現時点ではまだルールではない ここでの雑談は原則禁止 おーぷん2ちゃんねるに関する雑談は可? 名無しの名前(案) 要望名無しさん OPEN名無しさん 野原板概要 野原板とは、おーぷんのテスト板のこと。 本家5ch でいう 厨房板 の立ち位置である 板バナー一覧 + クリックして展開 主にスレ立てテストとして使われるほか、野原唯一のパートスレである雑談スレが立っている また、画像にあるとおり、3時間書き込みがないスレは削除される仕組みになっている 愚痴や暴言を吐くならここにした方がいいかもしれない また、野原板の背景が 汎用背景 ではなく、野原板にちなんで一面野原の画像が背景に使われている 関連リンク open2ch板 野原@テスト用 サイコロチェッカー コメント欄 名前 コメント すべてのコメントを見る ▽タグ一覧 板
https://w.atwiki.jp/android2chbrowser/pages/14.html
比較表 最終更新2012年04月01日10 05 05 ■ 評価の意味 ■ ◎・・・充実 ○・・・対応 △・・・一応 ×・・・駄目 -・・・無し ?・・・不明 ●・・・スキン等、専用ツールで対応 ▲・・・外部ソフトで対応 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone ログ取得 巡回機能(更新チェック) ○ ◎ ◎ ○ ◎ ○ ○ × ? ○ ? × - - ◎ 巡回機能(レス取得) ○ ○ ○ × ○ ? ? × ? × ? × - - × 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone インタフェース・操作全般 機能ボタン - - - - × ◎ ◎ × ? × × × - - × ツールバー ○ ◎ ◎ ◎ × - - × ? × ○ × - - ○ タップでスクロール ○ × × × ○ ○ - × ? × × × - - × 音量ボタンでスクロール ○ ○ ○ ○ × ◎ - × ? × ○ × - - × 傾きオートスクロール × × × × × ◎ - × ? × × × - - × 新着でオートスクロール × × × × × × × × ? × × × ◎ ◎ × スクロールタブの設定 ○ ○ ○ ○ ○ ○ - × ? × × × - - × 番号指定して移動 ○ × × ◎ × × ○ × ? × × × - - △ フリックで戻る ○ ○ ○ × ○ ○ × × ? × ○ ○ ○ - × フリックで進む ○ ○ ○ × × ○ × × ? × × ○ - - × ピンチでスレの拡大縮小 × × × ○ × × × × ? × × × - - ◎ 画面回転 ○ ○ ○ ◎ ○ ○ ○ ○ ? × △ ○ ◎ ○ ○ 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone 表示関連 赤レス抽出 ◯ × × × × × × × × × × × × × × リンク抽出 ◯ × × × × × × × × × × × × × × 画像抽出 ◯ × × × × × × × × × × × × × × 動画抽出 ◯ × × × × × × × × × × × × × × お気に入りの機能 ○ ○ ○ ○ ○ ○ ○ ? ? ? ○ × - - ◎ スレに重要度 ◎ × × × × × × × ? × × × - - × レスのスレ順表示 ○ ○ ○ ○ ○ ○ - ○ ? ○ ○ ○ ○ ○ ○ レスのツリー型表示 ◎ × × × × × ◎ × ? × × × - - × レスの逆アンカ表示 × ○ ○ × ? ? ○ ? ? ? ? × - - × レスのフロート表示 × × × × × × × × ? × × × ◎ ◎ × AA縮小表示 ◎ ◎ ◎ ◎ ◎ ◎ ○ × ? × × × - - ○ AA横スクロール表示 × ◎ ◎ × × × × × ? × × × - - × 引用のポップアップ △ △ ? ? ? ? ? ? ? ? ? × - - ◎ スレッドをタブで表示 ▲ × × × × × × × ? × × × - - × 板をタブで表示 × × × × × × × × ? × × × - - × タイトルリストのソート ○ ? ? ? ? ? ? ? ? ? ? × - - ◎ 新着ありのスレにしるし ○ ? ? ? ? ? ? ? ? ? ? × - - ○ ここまで読んだ機能 ○ ? ? ? ? ? ? ? ? ? ? × - - × 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone 非表示設定 メッセージあぼーん × ? ? ? × ? ? ? ? ? ? × - - ○ IDあぼーん ○ ? ? ? × ? ? ? ? ? ? × - - ○ NGワード設定 ○ ○ ○ ? × ? ? ? ? ? ? × - - ○ IDのNG設定 ○ ○ ○ ? ○ ? ? ? ? ? ? × - - ○ 画像のモザイク ◎ ? ? ? ? ? ◎ ? ? ? ? × - - × 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone 画像表示関連 画像サムネイル ◎ ○ ○ ◎ ◎ ◎ ○ × ? × × × - - ○ GIFアニメ ◎ × × ? ? ? ? × ? × × × - - ○ 自動画像読み込み ◎ △ △ ○ ○ ○ × × ? × × × - - ◎ ニコニコ動画サムネイル ○ × × × ? ? ? × ? × × × - - ◎ YouTubeサムネイル ○ × × × ○ ? ? × ? × × × - - ◎ 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone 他板・過去ログ まちBBS ○ ○ ○ ○ ○ ? ? ? ? ? ? × - - ○ したらば ○ ○ ○ ○ ○ ? ? ? ? ? ? × - - × 2ch互換板 ○ ○ ○ ○ × ? ? ? ? ? ? × - - × 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone 書き込み関連 スレッドに書きこむ ○ ○ ○ ○ ○ ○ ○ ○ ? ○ ○ × × × ○ 新規スレッドを立てる ○ ○ × ○ × × × × × × ○ × - - ○ このレスにレス機能 ○ ○ ○ ? ? ? ? ? ? ? ? × - - ○ コテハン・メアド記憶機能 ○ ? ? ? ? ? ? ? ? ? ? × - - ○ 書き込み履歴を読む ○ ? ? ? × ? ? ? ? ? ? × - - ◎ 書き込みプレビュー ▲ △ △ ? ? ? ? ? ? ? ? × - - × 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone 2chに関する機能 板看板を見る × × × × × × × × × × × × × × × 注意書を見る × × × × × × × × × × ○ × × × × 鯖移転時の自動追尾 ○ ? ? ? × ? ? ? ? ? ? × × × ◎ ●対応 ○ ○ ○ ○ ○ ○ × ? ? ? × × × × ◎ BE対応 × × × ○ × × × ? ? ? × × × × ◎ P2対応 ○ ○ ○ × × × × ? ? ? × × × × ◎ Proxy対応 × × ○ ▲ × ◎ × ? ? ? × × × × × 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone スキン・外観・カスタマイズ関連 スキンでカスタマイズ ○ × × ◎ × ○ × × ? × × × × × × AA用フォント使用 ○ ○ ○ ○ ○ ○ × × ? × ○ × × × × アイコン画像の変更 ○ × × ◎ - × × × ? × × × - - × 背景画像の使用 ○ × × ○ × × × × ? × × × - - × ツールボタン設定 ○ × × ◎ - ○ ○ ? ? ? × × - - × フォントサイズ設定 ◎ ◎ ◎ ◎ ◎ ◎ ◎ × ? × ○ × × ○ ◎ サムネイルサイズ設定 ○ ○ ○ × ◎ ○ × ? ? ? × × × × × 比較項目 2chmate imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (tuboroidon.png)tuboroidon 壺丼524 nora. anちゃん imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (en2ch.png)en2ch ニブロイド imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (ace2ch.png)ace2ch imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (andromona.png)andromona imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (bettiki.png)bettiki 俺2ch Gikolet imageプラグインエラー ご指定のファイルが見つかりません。ファイル名を確認して、再度指定してください。 (balloo!.png)balloo! yuz. p2iphone その他の独自機能 タブレット対応 ◎ ? ? ? ? ? ? ? ? ? ? ? ? ? ? オープンソース × ◎ ◎ × × × × × × × × × × × ◎ マーケット ◎ × × × ◎ ◎ ◎ ◎ ? ◎ ◎ × ◎ ◎ × ソフト本体の自動更新 × × × × △ △ △ △ ? △ △ × △ △ ◎ 音声検索 × × × × × × ◎ ? ? ? ? × ? ? × ウィジェット × × × × × × ◎ × × × × × × × × 他のアプリに画面を表示 × × × × × × × × ? × × × × ◎ × PCとの連携 ○ × × ▲ × × × ? ? ? ? × × × ◎ 広告 △ × × × × △ × × ? × ◎ × × × × W2ch中間鯖の使用 × × × ◎ × × × × × × × × × × × 更新頻度 ◎ ? ? ○ ○ ○ ○ ? ? ? ? × ? ○ ○ noraがスレ立て可能になりました (2011-01-10 21 52 02) ニブロイドは2010年6月からAA用フォントに対応しています。(nibroidフォルダ直下に“aafont.ttf”というファイル名でフォントファイルを格納) (2011-02-02 15 56 47) anちゃんの?を勝手に訂正 (2011-03-31 00 00 33) anちゃんですが、書き込みエラーが発生して書き込みができなくなっています。 (2011-04-30 04 01 34) anちゃんのアップデートきましたが、未だに多くの人が書き込み不具合でてます。 (2011-06-21 22 34 08) anちゃん書き込めたためしないぞ (2012-04-01 10 05 05) 評価修正内容 参考 「乱立する2ch用ブラウザの比較」 http //webmania.jp/~2browser/ 「2ちゃんねるブラウザの比較表(仮仮仮仮)」 http //browser2ch.web.fc2.com/ 「Janeシリーズの比較表(仮仮)」 http //www.geocities.jp/janecomparison/mini.html 「Janeシリーズの比較表(仮仮仮)」 http //www.geocities.jp/openjanemania/Comparison_tableNew.html 「CE/WM用2chブラウザの比較表(仮)」 http //www.geocities.jp/wm_2chbrowser_mania/Comparison_table.html ■[Android][2chMate] Android用2chブラウザ比較 http //d.hatena.ne.jp/gae+eyo/20110107 ここを編集 最近のリンク元 申し訳ありませんが、recent_page_ref プラグインは提供を終了し、ご利用いただけません。
https://w.atwiki.jp/sampleisbest/pages/185.html
開発環境 Microsoft Visual C# 2010 Express (SP1) 実行環境 Microsoft Windows XP Home Edition (SP3) プロジェクトの種類 空のプロジェクト プロジェクト名 Jien2ch Jien2chプロジェクトにクラスを追加。 テンプレート:クラス 名前:ListViewEx textBox1を削除。 Jien2ch コンポーネント/ListViewExをPanel2上にドロップ。 名前:listViewEx1 Dock Fill Lib2ch.DataをDataクラスにまとめた。 +Jien2ch +Form1.cs +Form1.Designer.cs +ListViewEx.cs +Program.cs +Lib2ch +Data +Data.cs +IO +File.cs +FileManager.cs +Model +BbsMenu.cs +Subject.cs namespace Jien2ch Program.cs using System.Windows.Forms; namespace Jien2ch { class Program { 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(); 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.Name; childNode.Tag = item; // 親ノード検索 TreeNode[] node = treeView1.Nodes.Find(item.CategoryName, false); if (node.Length == 0) { TreeNode parent = new TreeNode(); parent.Name = item.CategoryName;// 検索用 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 } } 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 CategoryName;// カテゴリ名 public string Name;// 板名 public string Url;// URL public string Directory { get { return "/" + CategoryName + "/" + Name; } } } // ファイル結果 class FileResult { public List string Line = new List string ();// 行リスト } // スレッドデータ public class SubjectData BbsMenuItem { 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.CategoryName = CategoryName; subjectData.Name = Name; subjectData.Url = Url; List.Add(subjectData); } } } } 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.CategoryName = 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.Name = 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.Name = bbsMenuItem.Name; subjectList.Url = bbsMenuItem.Url; subjectList.CategoryName = bbsMenuItem.CategoryName; FileResult fileResult = _File.StandardCheck( "./Log" + subjectList.Directory, subjectList.Url, "/subject.txt"); if (fileResult == null) return null; subjectList.Parsing(fileResult.Line); return subjectList; } } }
https://w.atwiki.jp/openjss/pages/56.html
解説 お絵描きニキの一人 その高い画力はおんj内で有名。 お題スレに現れてj民の度肝を抜くこともしばしば。 カラーイラストに入ったOPEN2chというサインからこう呼ばれる。しかしエディタで描いた線画も多くある。 本人曰く底辺ではあるがイラスト系の仕事をしているらしい(底辺の基準は定かではないが)。 通称サインニキ タグ 絵スレ 絵師ニキ コメント 名前 コメント
https://w.atwiki.jp/sampleisbest/pages/184.html
開発環境 Microsoft Visual C# 2010 Express (SP1) 実行環境 Microsoft Windows XP Home Edition (SP3) プロジェクトの種類 空のプロジェクト プロジェクト名 Jien2ch プロジェクト 新しいプロジェクト テンプレート:空のプロジェクト 名前:Jien2ch プロジェクトの保存 [ソリューションのディレクトリを作成]にチェックを付けておくと、 ソリューションに新しいプロジェクトを追加する時にプロジェクトの階層が整う。 プロジェクト/プロパティ アプリケーションタブ 出力の種類:Windows アプリケーション フォーム プロジェクトにクラスを追加 テンプレート:Windows フォーム 名前:Form1 Form1プロパティ Text Jien2ch Size 800, 600 コンテナー/SplitContainerをForm1上にドロップ 名前:splitContainer1 FixedPanel Panel1 コモン コントロール/TreeViewをPanel1上にドロップ 名前:treeView1 Dock Fill コモン コントロール/TextBoxをPanel2上にドロップ 名前:textBox1 Dock Fill MultiLine True ScrollBars Vertical クラスライブラリ ソリューションに新しいプロジェクトを追加 テンプレート:クラス ライブラリ 名前:Lib2ch Class1.csは削除 Lib2chに以下の新しいフォルダーを追加 Data IO Model 各種クラスを追加 Lib2ch +Data +BbsMenuItem +FileResult +SubjectData +SubjectList +IO +File +FileManager +Model +BbsMenu +Subject Jien2chプロジェクトの参照設定にプロジェクトLib2chを追加 イベントハンドラ Form1にLoadイベントハンドラを追加 treeView1にAfterSelectイベントハンドラを追加 namespace Jien2ch Program.cs using System.Windows.Forms; namespace Jien2ch { class Program { 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(); 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.Name; childNode.Tag = item; // 親ノード検索 TreeNode[] node = treeView1.Nodes.Find(item.ParentName, false); if (node.Length == 0) { TreeNode parent = new TreeNode(); parent.Name = item.ParentName;// 検索用 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 list = _Subject.Get(bbsMenuItem); System.Text.StringBuilder sb = new System.Text.StringBuilder(); int num = 0;// 番号 foreach (SubjectData data in list.List) { num++; sb.Append(num + " [" + data.Title + "]\r\n"); } textBox1.Text = sb.ToString(); } #endregion } } namespace Lib2ch.Data BbsMenuItem.cs namespace Lib2ch.Data { public class BbsMenuItem { public string ParentName; public string Name; public string Url; public string Directory { get { return "/" + ParentName + "/" + Name; } } } } FileResult.cs using System.Collections.Generic; namespace Lib2ch.Data { class FileResult { public List string Line = new List string (); } } SubjectData.cs namespace Lib2ch.Data { public class SubjectData BbsMenuItem { public string Title; public SubjectData(string line) { Title = line; } } } SubjectList.cs using System.Collections.Generic; namespace Lib2ch.Data { public class SubjectList BbsMenuItem { public List SubjectData List = new List SubjectData (); public void Parsing(List string list) { foreach (string line in list) { SubjectData data = new SubjectData(line); data.ParentName = ParentName; data.Name = Name; data.Url = Url; List.Add(data); } } } } 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 _HeadStart = " BR BR B "; string _HeadEnd = " /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(_HeadStart); if (index1 != -1) { int index2 = line.IndexOf(_HeadEnd); if (index2 != -1) { int start = index1 + _HeadStart.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.ParentName = 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.Name = 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 sl = new SubjectList(); sl.Name = bbsMenuItem.Name; sl.Url = bbsMenuItem.Url; sl.ParentName = bbsMenuItem.ParentName; FileResult fileResult = _File.StandardCheck( "./Log" + sl.Directory, sl.Url, "/subject.txt"); if (fileResult == null) return null; sl.Parsing(fileResult.Line); return sl; } } }
https://w.atwiki.jp/sampleisbest/pages/183.html
開発環境 Microsoft Visual C# 2010 Express (SP1) 実行環境 Microsoft Windows XP Home Edition (SP3) プロジェクトの種類 Windows フォーム アプリケーション プロジェクト名 Jien2ch プロジェクト プロジェクトの保存 [ソリューションのディレクトリを作成]にチェックを付けておくと、 ソリューションに新しいプロジェクトを追加する時にプロジェクトの階層が整う。 フォーム 名前:Form1 プロパティ Text Jien2ch Size 800, 600 メニューとツール バー/StatusStripをForm1上にドロップ。 名前:statusStrip1 statusStrip1にStatusLabelを追加。 名前:toolStripStatusLabel1 プロパティ Textをリセット(空にする) コンテナー/SplitContainerをForm1上にドロップ。 名前:splitContainer1 プロパティ FixedPanel Panel1 コンテナー/SplitContainerをsplitContainer1.Panel2上にドロップ。 名前:splitContainer2 プロパティ FixedPanel Panel1 Orientation Horizontal コモン コントロール/TreeViewをsplitContainer1.Panel1上にドロップ。 名前:treeView1 プロパティ Dock Fill Jien2chプロジェクトにクラスを追加。 テンプレート:クラス 名前:ListViewEx WebBrowserEx それぞれSystem.Windows.Forms.ListView/WebBrowserを継承した後、 ソリューションのビルド(F6)を行うとツールボックスに追加される。 Jien2ch コンポーネント/ListViewExをsplitContainer2.Panel1上にドロップ。 名前:listViewEx1 プロパティ Dock Fill Jien2ch コンポーネント/WebBrowserExをsplitContainer2.Panel2上にドロップ。 名前:webBrowserEx1 イベントハンドラ treeView1にAfterSelectイベントハンドラを追加。 listViewEx1にSelectedIndexChangedイベントハンドラを追加。 クラスライブラリ ソリューションに新しいプロジェクトを追加。 テンプレート:クラス ライブラリ 名前:Lib2ch Class1.csは削除。 Lib2chプロジェクトに以下の新しいフォルダーを追加。 Data IO Model 各種クラスを追加。 +Jien2ch\ +Form1.cs +Form1.Designer.cs +ListViewEx.cs +Program.cs +WebBrowserEx.cs +Lib2ch\ +Data\ +Data.cs +IO\ +IO.cs +Model\ +Model.cs Jien2chプロジェクトの参照設定にプロジェクトLib2chを追加。 仕様 板一覧 http;//menu.2ch.net/ bbsmenu.html スレッド一覧 http //uni.2ch.net/newsplus/ subject.txt スレッド http //uni.2ch.net/newsplus/dat/ 1234567890.dat +Logs\ +bbsmenu.html +カテゴリ\ +板名\ +subject.txt +1234567890.dat Jien2ch Form1.cs using System.Collections.Generic; using System.Windows.Forms; using Lib2ch.Data; using Lib2ch.Model; namespace Jien2ch { public partial class Form1 Form { public Form1() { InitializeComponent(); #region 板一覧 string status; List BbsMenuItem bbsMenuList = BbsMenu.GetMenuList(out status); toolStripStatusLabel1.Text = status; 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); } } #endregion } #region 板一覧アイテム選択時 private void treeView1_AfterSelect(object sender, TreeViewEventArgs e) { if (e.Node.Tag != null) { ThreadListAdd((BbsMenuItem)e.Node.Tag); } } // スレッド一覧 void ThreadListAdd(BbsMenuItem bbsMenuItem) { string status; SubjectList subjectList = Subject.Get(out status, bbsMenuItem); toolStripStatusLabel1.Text = status; listViewEx1.ItemSet(subjectList); } #endregion #region スレッド一覧アイテム選択時 private void listViewEx1_SelectedIndexChanged(object sender, System.EventArgs e) { ListViewEx listView = (ListViewEx)sender; if (listView.SelectedItems.Count == 0) return; SubjectData subjectData = (SubjectData)listView.SelectedItems[0].Tag; ThreadViewAdd(listView.bmi, subjectData); } void ThreadViewAdd(BbsMenuItem bmi, SubjectData subjectData) { string status; Dat dat = ThreadDat.Get(out status, bmi, subjectData); toolStripStatusLabel1.Text = status; webBrowserEx1.ItemSet(dat); } #endregion } } ListViewEx.cs using System.Windows.Forms; using Lib2ch.Data; namespace Jien2ch { class ListViewEx ListView { public BbsMenuItem bmi; 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) { bmi = new BbsMenuItem(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; } } } WebBrowserEx.cs using System.Text; using System.Windows.Forms; using Lib2ch.Data; namespace Jien2ch { class WebBrowserEx WebBrowser { const string crlf = "\r\n"; public void ItemSet(Dat dat) { StringBuilder sb = new StringBuilder(); sb.Append(" html " + crlf); sb.Append(" body bgcolor=#efefef style=\"font-family MS Pゴシック\" " + crlf); sb.Append(" dl " + crlf); int num = 0; foreach (DatRes datRes in dat.Res) { num++; string[] s = datRes.Data; sb.Append(" dt font color=\"blue\" u " + num.ToString() + " /u /font "); sb.Append(" 名前: font color=\"green\" b " + s[0] + " /b /font "); sb.Append("[" + s[1] + "]"); sb.Append(" 投稿日:" + s[2]); sb.Append(" dd " + s[3] + " br br " + crlf); } sb.Append(" /dl /body /html " + crlf); DocumentText = sb.ToString(); } } } Lib2ch Data.cs using System; using System.Collections.Generic; using System.IO; using System.Net; namespace Lib2ch.Data { // ファイル結果 class FileResult { public string[] Line;// 行リスト public HttpStatusCode StatusCode; public string StatusDesc; } // 索引ファイル class IdxFile { public string LastMod; // 最終修正時間 string _Path; public IdxFile(string path) { _Path = path; } public bool Load() { try { using (StreamReader sr = new StreamReader(_Path)) { LastMod = sr.ReadLine(); } return true; } catch { LastMod = null; return false; } } public void Save() { using (StreamWriter sw = new StreamWriter(_Path)) { sw.WriteLine(LastMod); } } } // 板一覧アイテム public class BbsMenuItem { public string Category;// カテゴリ public string BbsName;// 板名 public string Url; // URL public BbsMenuItem() { } public BbsMenuItem(BbsMenuItem item) { Category = item.Category; BbsName = item.BbsName; Url = item.Url; } public string Directory { get { return Category + "/" + BbsName + "/"; } } } // スレッド一覧データ public class SubjectData { public string FileName;// スレッドファイル名(X(10).dat) public string Title;// タイトル public int Count; // レス数 // [FileName.dat] [Title]([Count]) public SubjectData(string line) { if (line == "") return; FileName = line.Substring(0, 14); int start = line.LastIndexOf("("); int end = line.LastIndexOf(")"); Title = line.Substring(16, start - 16); start++; Count = Convert.ToInt32(line.Substring(start, end - start)); } } // スレッド一覧 public class SubjectList BbsMenuItem { public List SubjectData List = new List SubjectData (); public SubjectList(BbsMenuItem item) base(item) { } public void Parsing(string[] data) { foreach (string line in data) { SubjectData subjectData = new SubjectData(line); List.Add(subjectData); } } } // レス public class DatRes { public string[] Data; public void Res(string line) { Data = line.Split(new string[] { " " }, StringSplitOptions.None); } } // スレッドデータ public class Dat { public List DatRes Res = new List DatRes (); public void Parsing(string[] data) { foreach (string line in data) { DatRes datRes = new DatRes(); datRes.Res(line); Res.Add(datRes); } } } } IO.cs using System.IO; using System.Net; using System.Text; using Lib2ch.Data; namespace Lib2ch.IO { static class FileMan { static public FileResult StandardCheck(string url, string file, string dir) { FileResult fileResult = new FileResult(); // ファイル名と拡張子の分離 int index = file.LastIndexOf( . ); string fname = file.Substring(0, index); string ext = file.Substring(index); // 索引ファイルの読み込み IdxFile idxFile = new IdxFile(dir + fname + ".idx"); idxFile.Load(); // GETメソッド HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url + fname + ext); if (idxFile.LastMod != null File.Exists(dir + file)) { req.IfModifiedSince = System.DateTime.Parse(idxFile.LastMod); } HttpWebResponse res = null; try { res = (HttpWebResponse)req.GetResponse(); fileResult.StatusCode = res.StatusCode; fileResult.StatusDesc = res.StatusDescription; // ファイルのダウンロード idxFile.LastMod = res.LastModified.ToString(); Stream stream = res.GetResponseStream(); Encoding enc = Encoding.GetEncoding(res.CharacterSet);// ISO-8859-1 string buf; using (StreamReader sr = new StreamReader(stream, enc)) { buf = sr.ReadToEnd(); } stream.Close(); // ディレクトリがなければ作る if (!Directory.Exists(dir)) { Directory.CreateDirectory(dir); } using (StreamWriter sw = new StreamWriter(dir + file, false, enc)) { sw.Write(buf); } // 索引ファイルの書き込み idxFile.Save(); } catch (WebException e) { if (e.Status == WebExceptionStatus.ProtocolError) { // (304) Not Modified fileResult.StatusCode = ((HttpWebResponse)e.Response).StatusCode; fileResult.StatusDesc = ((HttpWebResponse)e.Response).StatusDescription; if (fileResult.StatusCode != HttpStatusCode.NotModified) { return fileResult; } } else { return fileResult; } } // ローカルファイルの読み込み try { fileResult.Line = File.ReadAllLines(dir + file, Encoding.Default); } catch { } return fileResult; } } } Model.cs using System.Collections.Generic; using Lib2ch.Data; using Lib2ch.IO; namespace Lib2ch.Model { // 定数 static class Com { public const string BaseDir = "./Logs/"; // 基準ディレクトリ } // 板一覧 static 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 "; static public List BbsMenuItem GetMenuList(out string status) { FileResult fileResult = FileMan.StandardCheck( "http //menu.2ch.net/", "bbsmenu.html", Com.BaseDir); status = fileResult.StatusDesc; // 解析処理 return BbsMenuParsing(fileResult.Line); } static List BbsMenuItem BbsMenuParsing(string[] data) { List BbsMenuItem list = new List BbsMenuItem (); string category = null; foreach (string line in data) { // カテゴリ // BR BR B (Category) /B 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; } // A HREF=(Url) (BbsName) /A // A HREF=(Url) TARGET=_blank (BbsName) /A static 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; } } // スレッド一覧 static public class Subject { static public SubjectList Get(out string status, BbsMenuItem bbsMenuItem) { FileResult fileResult = FileMan.StandardCheck( bbsMenuItem.Url, "subject.txt", Com.BaseDir + bbsMenuItem.Directory); status = fileResult.StatusDesc; SubjectList subjectList = new SubjectList(bbsMenuItem); subjectList.Parsing(fileResult.Line); return subjectList; } } // スレッド static public class ThreadDat { static public Dat Get(out string status, BbsMenuItem bmi, SubjectData subjectData) { FileResult fileResult = FileMan.StandardCheck( bmi.Url + "dat/", subjectData.FileName, Com.BaseDir + bmi.Directory); status = fileResult.StatusDesc; Dat dat = new Dat(); dat.Parsing(fileResult.Line); return dat; } } }
https://w.atwiki.jp/sampleisbest/pages/186.html
開発環境 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データクラス +IOIO名前空間 +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; } } }