2006 年 6 月 27 日 19 時 27 分

複数カラム対応


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


次はリンク先を表示するカラムを作ろうと言いたい所だが、
先に、先を見据えた軽いリファクタリングをしよう。

IColumnProvider は複数のカラムを提供する能力があるので、
そのままリンク先の表示機能を追加実装してもいいのだが、
ColumnProvider が複雑になってしまう。

そこで、カラム自体を扱う IColumn インタフェースを作り、
ColumnProvider クラスから切り離すことを考えよう。
実際のカラムは、IColumn を実装してクラスを作ればいい。

では IColumn を作ってみよう。

using System;
using LoaferShellEx.Interop;

namespace LoaferShellEx.Column {

    // カラムのインタフェース
    public interface IColumn {
        bool EqualsID(ref SHCOLUMNID id);
        void GetInfo(out SHCOLUMNINFO psci);
        object GetValue(ref SHCOLUMNDATA pscd);
    }

}

インタフェースは、既定で public, オーバーライド可なので、
記述がかなりシンプルになる。
少し手抜きだが、こんな感じかな。

GetInfo と GetValue の役割は明確だと思う。
引数などに、本来構造体を使うべきではないのだが、
簡単な実装を提供するために流用することにする。
EqualsID は、カラムの識別子を比較する際に使用する。


そして、IColumn インタフェースを継承させて、
カラムの既定の実装を提供する ColumnBase クラスを作る。

using System;
using LoaferShellEx.Interop;

namespace LoaferShellEx.ColumnBase {

    // カラムの既定実装クラス
    public abstract class ColumnBase : IColumn {

        // カラムセットの ID
        protected Guid _formatID;

        // カラムの ID
        protected uint _propertyID;

        // コンストラクタで、カラムの識別子を指定する
        protected ColumnBase(Guid formatID, uint propertyID) {
            _formatID = formatID;
            _propertyID = propertyID;
        }

        // カラムの識別子の比較
        public virtual bool EqualsID(ref SHCOLUMNID id) {
            return id.fmtid == _formatID && id.pid == _propertyID;
        }

        // カラムの情報を取得
        public virtual void GetInfo(out SHCOLUMNINFO psci) {
            // 既定の実装
            psci.scid.fmtid = _formatID;
            psci.scid.pid = _propertyID;
            psci.vt = VARTYPE.BSTR;
            psci.fmt = LVCFMT.LEFT;
            psci.cChars = 16;
            psci.csFlags = SHCOLSTATE.TYPE_STR | SHCOLSTATE.SLOW;
            psci.wszTitle = string.Empty;
            psci.wszDescription = string.Empty;
        }

        // ファイルに対応した値を取得
        // これは抽象メソッドとする
        public abstract object GetValue(ref SHCOLUMNDATA pscd);

    }
}

既定の実装を用意しておくと、後で楽になる。
C# でのポイントは、virtual キーワードだ。
これは C++ から引き継いだ特別なキーワードである。

Java ではメソッドは既定でオーバーライドが可能で、
それを抑制するためには、final が必要だ。

C# では、既定でオーバーライドできない。
オーバーライドさせることが目的のメソッドには、
virtual キーワードを明記する必要がある。
これは少し面倒な気がするが、仕方あるまい。

では、明日はこれらを利用して、
現行の ColumnProvider をリファクタリングしよう。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.