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

CF204-8Aその後

 だいぶ音色の変化が落ち着いてきたので、どんな音かつらつらと書いてみようと思います。

 とても濃い音です。色が濃くて、輪郭が太いのでかなり存在感があります。生々しさを感じます。まるで目の前で歌っているようです。うるさい音はうるさく出ます。本来あるべき刺激を取り除きません。

 ソフトの荒はあまり出ません。良い音源は良く、悪い音源もそれなりに出ます。でも、その差はキッチリと描き分けます。

 音量を下げても音のバランスが変わりません。静まり返った深夜に、聞こえるか聞こえないかのギリギリまでボリュームを絞ります。それでも整ったバランスで音楽を聴かせます。

 これは、買いです。

アルテックスピーカーとりあえずは完成

HI390009.jpg

 ずっと先送りにしていたスピーカーユニットCF204-8Aの箱をこしらえました。板割を決めて買い物に出かけ、工作が終わるまで9時間のやっつけ仕事です。

 板材は3×6×12mmのラワン合板、コンパネです。これをホーマック(北海道でホームセンターといえばこれ)で買ってカットしてもらいました。しかし、丸穴は開けて貰えませんでした。

 何とか自分で安く済ませようと店内を物色しているとこんなのを見付けました。

刃の断面が丸く、どの方向にでも切れる鋸です。『NASAも使用!』ってのが素敵です。これとハンドドリルを買って丸穴を開けました。

 板の接合にはスクリュー釘を使いました。これ、釘が持つ作業の速さとネジの固定力を併せ持った素晴らしい釘です。大抵の金物屋かDIYショップに売ってると思います。

 吸音材は押入れを漁ったら出てきたので、それを使いました。ターミナルは無く、ユニットにケーブル直付けです。これは自作の特権です。

 資材、工具、板のカット代金合わせて約6千円でした。スピーカーユニットの購入代金を合わせても、ペア1.5万円のスピーカーです。ダンボールに入れても充分に鳴っていたスピーカーユニットですから、やっつけ仕事のこの箱でも当然の様に良く鳴っています。