Entering Passive Mode

カテゴリ 'COM' の記事
< 1 2 3 4 5 6 7 >

仕上げ

英語表示

さて、今日で仕上げとしよう。

おさらいとして、ByteSizeColumn と同様、
LinkTargetColumn を多言語化する。手順は一緒だ。

まず、既定のリソースとして、
「LinkTargetColumn.resx」 を追加する。
内容は以下のとおりにしよう。

    title: 「Link Target」
    description: 「Target of the shortcut references.」
    size: 「40」(System.UInt32)

サテライトアセンブリ

サテライトアセンブリを使う場合、
ResourceManager は「カルチャ」に従って、
各サテライトアセンブリを検索する。

例えば、スレッドのカルチャが「ja-JP」の場合、
まずは「ja-JP」のサテライトアセンブリを探す。
見つかればそのサテライトアセンブリを読み込む。

もし見つからない場合、フォールバックが行われ、
「ja」のサテライトアセンブリが検索される。
それも見つからなかった場合は、
メインのアセンブリに含まれるリソースが読み込まれる。
つまり、メインのアセンブリは「既定のリソース」となる。

国際化・多言語化

リソースの機能は、実装とデータの分離だけではない。
一昨日、言語依存の文字列という言い方をしたが、
リソースはプログラムの国際化にも効果を発揮する。

国際化と言うと大層な話にも感じられる。
まあ、日本語さえ使えれば、別に不要といえばそうなのだが、
プログラムに英語と日本語を入れておけば、
日本語 OS では日本語、それ以外の OS では英語と、
簡単に日本語以外の OS でも利用できるようになる。

また、Windows 2000 以降には多言語版というのがあり、
UI の言語を切り替える事ができる。
この環境では言語によって表示を変えることもできる。

.resources を使う

リソースエディタ

早速 ByteSizeColumn に含まれるリソースを切り離そう。

昨日も説明したが、文字列のリソースの場合は、
.resources ファイルを使って文字列リソースをまとめ、
ResourceManager 経由で読み出した方が効率が良い。

.resources で管理する方法には色々なポリシーがあるが、
ここでは、リソースが必要なクラス毎に、
個別の .resources を作成する方法にしよう。

この方法を使った場合、ファイル数は多くなるが、
クラスとリソースをまとめて扱えるので、
独立性の点で優れていると考えられるからだ。

NET のリソース

現在、言語依存の文字列をそのままリテラルとして
ソースコードに含めている部分が何箇所かある。

一般的にこういう文字列をソースに残すのは推奨されない。
文字列は色々な場所に散らばるので、
ソースコードの保守が難しくなる。

また、ロジックを書く開発者と、
文言を書く開発者の分業が難しくなるという側面もある。
文言を変更するだけで、ソースごと
再度コンパイルを行う必要があるからだ。

レジストリ操作

シェルのカラムハンドラを登録するためには、
レジストリを操作しなければならない。

.NET にもレジストリ操作のためのクラスはある。
珍しいことに、System 名前空間の中に存在せず、
Microsoft.Win32 名前空間にある、
Registry や RegistryKey クラスである。

カラムハンドラの登録は、
HKEY_CLASSES_ROOT\Folder\shellex\ColumnHandlers の下に、
クラスの GUID の文字列表記のキーを作成することで行う。

カラム登録の自動化

一般的に、COM のライブラリ(DLL)は、
regsvr32.exe というシステム附属のツールで登録される。
regsvr32 は DLL の特定の関数を呼び出すだけなので、
COM クラスの登録等は、DLL 側が関数を用意して行う。
つまり、製作者は自由に登録処理を書くことができる。

.NET で作った場合は、純粋な COM DLL は作成できないため、
regsvr32 では登録できず、.NET Framework 附属の、
regasm.exe というツールで登録される。

しかし、regasm は regsvr32 と違い、
アセンブリが COM 用に公開しているクラスを
自動的に登録してくれるため、製作者は何もする必要がない。

実装の分割 #4: インタフェース

さて、昨日のコードを再掲しよう。

    LinkTargetHandler hander = null;

    switch (pscd.pwszExt.ToLower()) {

    case ".lnk":
        hander = new LinkTargetHandler(
                new ShortcutFile(pscd.wszFile).GetLinkTarget);
        break;

実装の分割 #3: 初期化と利用

デリゲートを使うと呼び出しを集約することができた。

昨日のコードを再掲しよう。

    LinkTargetHandler hander = null;

    switch (pscd.pwszExt.ToLower()) {

    case ".lnk":
        hander = new LinkTargetHandler(GetShortcutTarget);
        break;

実装の分割 #2: デリゲート

今日は昨日のステップをもう少し進めてみる。

switch の中が明確になり、
果たすべき役割が複数の関数に分解された。

GetValue メソッドの一部を引用する。

    switch (pscd.pwszExt.ToLower()) {

    case ".lnk":
        return GetShortcutTarget(pscd.wszFile);

< 1 2 3 4 5 6 7 >
このページのトップへ戻る
© 2008 Project Loafer/Project Fireball and all blog writers. Powered by Nucleus CMS