このアーカイブは同期化されません。 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 をリファクタリングしよう。