最近の記事
- 9/1 - 将棋始めました
- 5/16 - サーバー引っ越し
- 4/24 - 優先順位
- 3/17 - vbNullString と 空文字列 ""
- 3/15 - InputBox 関数の戻り値
- 3/13 - 紙と Excel と VBA
- 3/9 - 未だに Visual Basic 6
- 11/14 - ぼて閉鎖
- 11/9 - 関数オブジェクトの呼び出し
- 9/7 - メソッドとしての関数オブジェクト
Entering Passive Mode
これで、通常のショートカットと、
インターネットショートカットの 2 つを読めるようになった。
LinkTargetColumn に実装してテストと行きたいところだが、
少しコードが増えてきたので、
カラムの実装の前に、リファクタリングを行おう。
クラスの設計というのは、基本的には難しい。
技術的に難しいということではなく、
考え方次第ではいくつも答えがあることが難しいのだ。
クイズのように特定の正解が存在するわけではない。
では、インターネットショートカットを読んでみよう。
まずは、適当なショートカットを用意する。
例えば、Google をお気に入りに入れたとすると、
「Google.url」というファイルが、
C:\Documents and Settings\<user>\Favorites\ にできる。
以前の、通常のショートカットを読み込む
テスト用のコードを書き換えれば速そうだ。
例によって、プロジェクトのプロパティより、
出力の種類を「コンソール アプリケーション」にしておく。
さて、では次の手を考えてみよう。
InternetShortcutClass が実装しているインタフェースは
ISellLinkW 以外にもまだまだ数多くある。
その中に、IUniformResourceLocatorW というのがある。
URL そのものを表すらしい、変な名前のインタフェースだ。
MSDN を探る。みっけ。
現在、リンク先を表示できるのは、.lnk ファイルだけだが、
リンク先を持つファイルは、.lnk ファイルだけではない。
たとえば、.url は、インターネットショートカットであり、
ファイル内部に URL を格納している。
Internet Explorer の管理するお気に入りも、
フォルダで分類されたインターネットショートカットだ。
次は、これを調べてみよう。
例によって、レジストリを探す。
拡張子「.url」
⇒ProgID「InternetShortcut」
⇒CLSID「{FBF23B40-E3F0-101B-8488-00AA003E56F8}」
⇒表示名「Internet Shortcut」
早速 ColumnPrivider に登録してみよう。
Column フォルダに LinkTargetColumn.cs を追加し、
LoaferShellEx.Column.LinkTargetColumn クラスを作る。
本来は、役割が異なるロジックは分離すべきだが、
とりあえずは動作を試してみたいので、
昨日作ったリンク先の取得のコードも、
LinkTargetColumn の中に含めてしまおう。
========== LinkTargetColumn.cs ==========
続いて、IPersistFile インタフェースだ。
C# や Java では、インタフェースを実装したクラスは、
インタフェース自身のメソッドを public として持つが、
COM では、メソッド実行は必ずインタフェース型経由となる。
理由は割愛するが、上記の制約があるため、
COM クラスに例えメソッドを定義しても直接呼び出せず、
インタフェースを全て明示してアクセスする必要がある。
さて、ShortcutClass を初期化するためには、
IPersistFile を経由してファイルを指定する必要がある。
IPersistFile は非常によく使うインタフェースなので、
.NET でも、UCOMIPersistFile と言う名前で定義されている。
まずは、Shortcut クラスを定義する。
実は外部の COM クラスを定義するのは非常に簡単だ。
クラスの定義に、ComImportAttribute 属性と、
GuidAttribute 属性を定義するだけでいいのだ。
では、Interop フォルダに ShortcutClass.cs を作る。
========== ShortcutClass.cs ==========
using System;
using System.Runtime.InteropServices;
カラムが 1 つだけなら寂しいので、
もう 1 つ、「リンク先」を表示するカラムを作ろう。
ショートカットファイルのリンク先を表示したい。
ショートカットもシェルの代表的な機能であり、
IColumnProvider と同じように COM ベースだ。
IColumnProvider と異なる点は、
ショートカット自体を扱うクラスが、
既にシェルに定義されている事である。
まず、バイトサイズのカラムの実装を、
ColumnProvider から、独立したクラスである
ByteSizeColumn に移そう。
========== ByteSizeColumn.cs ==========
using System;
using System.IO;
using LoaferShellEx.Interop;
namespace LoaferShellEx.Column {
次はリンク先を表示するカラムを作ろうと言いたい所だが、
先に、先を見据えた軽いリファクタリングをしよう。
IColumnProvider は複数のカラムを提供する能力があるので、
そのままリンク先の表示機能を追加実装してもいいのだが、
ColumnProvider が複雑になってしまう。
そこで、カラム自体を扱う IColumn インタフェースを作り、
ColumnProvider クラスから切り離すことを考えよう。
実際のカラムは、IColumn を実装してクラスを作ればいい。