VB.NET|フォルダパス一覧のツリー構造への変換

 多言語度を上げる為にVB.NETに書き換えました。ついでに一番乗りです。

C#|フォルダパス一覧のツリー構造への変換

 どう書く?orgのトピックフォルダパス一覧のツリー構造への変換への投稿用に書きました。

C#|TabControlのタブをドラッグ&ドロップで並び替え

 C#|TabControlでクリックされたタブが判らないのコードを手直ししました。デザイナー上でタブを切り替えると怒られるというどうしようもない失敗です。原因が良くわからなかったのでtry-catchで無理やり直しました。(こんなんでいいのか?)

 ついでにClickイベントだけじゃ物足りないと思ったのでコピペ&力技でイベントを増設しました。偉い人はもっとスマートに書けるのでしょうか?

 そして本題です。ついでにタブのD&Dに対応しちゃえ!って思ったのです。それ自体は簡単に出来ました。しかし、そこから苦労しました。と言うのも、タブが切り替わるタイミングがボタンを押して離した時ではなくて、ボタンを押し下げた瞬間なんです。つまり、ドラッグするとそのタブが選択されてしまうのです。そしてそのままドロップすると、移動したタブではなくて一番左のタブが選択されているのです。

 僕が望んだ仕様は、選択されていないタブを選択しないまま並び替えられるというものです。せめてドラッグしたときはそのタブが選択されても、ドロップが終わったときには元のタブに戻るようにしようと思いました。そこで選択されたタブの履歴を取って、そこから戻すようにしてみました。でも、選択されているタブをD&Dしたら全く関係ないタブが選択されています。

 色々試しましたが、制御仕切れなかったので諦めました。D&Dしたタブを選択するようにしました。

 ちょっと長いけど晒します。どなたか添削してくれると嬉すぃです…。

C#|TabControlでクリックされたタブが判らない

 TabControlのMouseClickイベントでどのタブがクリックされたかが判らないのがとても不満です。.NETは面白いけど、

「なんでこんなことも出来ないの?ていうか出来るようにしてくんないの?」

と思うことが時々あります。

 てことで、TabMouseClickEventArgsとかでっち上げてクリックされたタブを取得出来るようにしてみました。その名もTabMouseClickイベントです。ネーミングセンス悪くてすみません。変数とかメソッドとかクラスとか、ネーミングに非常に悩みます。

using System.Windows.Forms;

using System.Drawing;

namespace Anis.Controls {

  /// <summary>TabMouseClickイベントを処理するメソッドを表します。</summary>

  public delegate void TabMouseClickEventHandler(object sender, TabMouseClickEventArgs e);

  /// <summary>タブ部分がクリックされた際に、

  /// クリックされたタブを取得出来るTabMouseClickイベントを備えたTabControl</summary>

  public class AnisTabControl: TabControl {

    /// <summary>クリックされたタブが取得可能なMouseClickイベント/// </summary>

    public event TabMouseClickEventHandler TabMouseClick;

    /// <summary>XMLコメントが無いって警告うざい</summary>

    public AnisTabControl(){

    this.MouseClick += new MouseEventHandler(Class1_MouseClick);

    }

    void Class1_MouseClick(object sender, MouseEventArgs e) {

      for(int i = 0; i <= this.TabPages.Count - 1; i++) { //

        if(this.GetTabRect(i).Contains(e.X,e.Y)){    //この2行がキモでし。

          TabMouseClickEventArgs E = new TabMouseClickEventArgs(

            this.TabPages[i],e.Button,e.Clicks,e.X,e.Y,e.Delta);

          this.TabMouseClick(sender, E);

        }

      }

    }

  }

  /// <summary>TabMouseClickイベントのデータ</summary>

  public class TabMouseClickEventArgs:MouseEventArgs {

    private TabPage tabpage_;

    /// <param name="tabPage">クリックされたタブに対応したタブページ</param>

    public TabMouseClickEventArgs(

      TabPage tabPage,MouseButtons button,int clicks, int x, int y ,int delta):base(

        button,clicks,x,y,delta) {

      tabpage_ = tabPage;

    }

    /// <summary>クリックされたタブに対応したタブページ</summary>

    public TabPage TabPage {

      get {

        return tabpage_;

      }

    }

  }

}

アップしたらXMLコメントのタグが外れてスッキリしてます。まるでただのコメントのようです。

C#|フォルダのパスかファイルのパスか調べる

 ファイルには拡張子があって、フォルダには拡張子が無いので

if(System.IO.Path.GetExtension(“hoge”) == “”) {

//フォルダだお

} else {

//ファイルだお

}

と言うのは間違い。”hoge.moge”がフォルダ名でも”.moge”が拡張子として認識されてしまいます。フォルダ名に”.”を使えるってのは盲点でした。

if(System.IO.Directory.Exists(“hoge”)) {

//フォルダだお

} else {

//ファイルだお

}

これで上手くいきました。

if(System.IO.File.Exists(“hoge”)) {

//フォルダだお

} else {

//ファイルだお

}

は”hoge”がフォルダでもtrueが返されるのでNGでした。

以上、失敗談でした。

もっとスマートで良い方法があったら教えて下さい。

VC#2005EEでエクスプローラー風のツリービューを実装

 NetBeensとVisualC++2005EEをアンインストールして空いたスペースにVisualC#2005EEをインストールしました。VC#をインストールして最初に書いたのは、フォルダの階層を表示出来るツリービューのDLLです。

 aniscapeのお気に入りツリーをVB.NETで作ったときにちょっと大変だったので、C#で書いてDLLとして残しておこうと思いました。

 再帰処理でフォルダ階層を奥まで読んでゴリゴリとノードを追加していけば簡単なのですが、そうすると全てのノードを追加し終わるまで暫く時間が掛かります。とても実用になりません。

 それなら、ノードを開くときにその下だけ読めばもっと簡単だし、最初の待ち時間もありません。でも、それにも問題があります。ノードの頭についている+-のマークが表示されないので、フォルダの下にファイルやフォルダがあるかどうかが分かりません。

 それではどうするのかと言うと、ノードを開く度に、2階層下まで読み込みます。

 ファイルを表示するのですから、アイコンも表示させた方がいいと思います。

Icon icon = Icon.ExtractAssociatedIcon(“FileName”);

でそのファイルのアイコンを取得出来ます。これを

TreeView.ImageList.Images.Add(“FileName”, icon);

でイメージリストに追加して

TreeNode.ImageKey = “FileName”;

TreeNode.SelectedImageKey = “FileName”;

でノードにアイコンを設定します。

 ここで問題発生です。この一連の処理がとても重いのです。ノードをクリックしてから開くまでに数秒から十数秒掛かります。使い物になりません。

 そこでもう少し改造します。+-マークを表示させる為には2階層下まで読む必要がありますが、2階層下のノードについてはアイコンが無くても問題ありません。そこで、ノードは2階層下まで追加するが、アイコンは1階層下のみ追加する仕様にしました。

 これで、軽快とはいきませんが、使えるレベルまでレスポンスが良くなりました。後はもっとレスポンスが必要な場合の為に、ファイルごとにアイコンを取得しないようにするプロパティでも実装しておけば幅広く使える様になるでしょう。

以上、メモでした。

ソースコード(C#, .NET2.0)

AnisTreeView.cs

バイナリ

AnisTreeView.zip

 大量にノードを開いた時のレスポンスを改善しました。

バイナリ

AnisTreeView1_1_0_0.zip

ソースコード(C#, .NET2.0)

AnisTreeView1_1_0_0.cs

機動戦士ガンダムOO 6

 丁度今、GyaO『機動戦士ガンダムOO』の第六話を観終わったところです。

内容は、

「ソレスタルビーイングの新装備凄いんだお!」

今後も、各回お決まりのパターンで紛争に介入しながら、少しずつソレスタルビーイング云々な謎に迫るって感じの進行になるでしょう。

気になった点

・ルイスが出てこなかった。

ルイスのいないOOに価値はありません。

Java終わりました。

 と言ってもゴリゴリ書けるようになったわけじゃありません。実は気まぐれでC#触ったんです。思いの外面白くてJavaそっちのけです。VBよりも書きやすいんですね。

 ネット上の資料はVB.NETの方が多いように思いますが、テキストエディタなんか見てると、C#対応でVB.NETに対応してないのが結構あったり、C#の方が風当たりがいい感じですね。世の中、VB.NET使いよりもC#使いに有利なように出来ているようです。

 でも、VBの便利な機能のいくつかが見当たらないのは不満です。VBはWithEventsで宣言してhandlesでイベント拾えたから、プロシージャがどのイベントに対応してるか見通せたのに、C#では出来ないようです。

 With~EndWithとかも良く使ってたのですが、C#にはないのでしょうか。

 ただ、VBではOptionStrict ONでいちいち型をキャストするとゴチャゴチャとして読みにくいソースになったけど、C#だとキャストの記述が超スッキリで、これはかなりいいです。

 VB.NETはメソッドの引数のOptional指定とかが便利でしたが、まぁ…、これは無くてもそんなに変わりませんね。そうそう、VB.NETだとメソッドの引数を

[パラメータ名] : パラメータ

で指定出来て快適だったけど、C#ではどうなんでしょう。試してみようと思います。似てるけど結構違うんですね。

 実はマイPCはCドライブの容量が切迫しているのです。Dドライブは腐るほど余ってるのにです。マイドキュメントをDドライブに移したり、手動でインストールするソフトはDドライブに入れたりしているのですが、それでもデフラグするときに『容量が足りません』って怒られるくらいに余りが少ないです。面倒なくパーティションを切りなおすツールは結構高いみたいだし…、困ってます。

 そんなわけで、VB2005 EE、VC++2005 EEに加えてC#2005 EEを入れる余裕は無いわけです。NetBeansなんかも入れちゃった(使いにくいですね)ので尚更です。そこで、.NET Framework SDK + テキストエディタです。C#の予約語をググってTeraPadのC/C++モードの予約語リストにコピペでぶち込みました。拡張子も.c,.cpに加えて.csを追加設定しました。これとMSDNがあれば大抵のことは何とかなるでしょう。TeraPadの外部ツールにもcscを登録しました。こんなんでも意外と快適なもんです。

 と、ここ最近自転車ネタが全く無い本物のサボり日記になっていてすみません。だって、自転車は乗る程にお金が掛かるけど、プログラムはいくら書いてもタダなんです。こんないいおもちゃは無いですよ~。

 はぁ…、春が来て、すっと春だったらいいのに…。

java始めました

 そして終わりそうです。面白くないです。ときめかないというか、萌えません。言語にエレガントさが足りないのだと思いました、どこがとは具体的に示せませんが。

 JDK+TeraPadでやってみたのですが、IDEの威力を思い知りました。というか、インテリセンスの威力です。VB.NETの時はすらすら書けたコードも、javaだとドキュメントと睨めっこしながら、それでもいやんなっちゃうって感じです。VB.NETはインテリセンスがドキュメントの代わりみたいなところがあるから楽です。

 じゃあ、IDEに頼ってちゃ駄目じゃん?って思います。でも考えてみると、VB.NETをSDK+TeraPadで書くのは不便さは感じますがそんなに抵抗がありません。僕にとっては、強力なIDEは習得の助けになるようです。

 javaのIDEについて調べてみようと思います。VS並みの強力な機能は期待できるのでしょうか。