2006 年 7 月 2 日 22 時 42 分

LinkTargetColumn クラス


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


[写真]


早速 ColumnPrivider に登録してみよう。

Column フォルダに LinkTargetColumn.cs を追加し、
LoaferShellEx.Column.LinkTargetColumn クラスを作る。

本来は、役割が異なるロジックは分離すべきだが、
とりあえずは動作を試してみたいので、
昨日作ったリンク先の取得のコードも、
LinkTargetColumn の中に含めてしまおう。

========== LinkTargetColumn.cs ==========

using System;
using System.Resources;
using System.Runtime.InteropServices;
using System.Text;
using LoaferShellEx.Interop;

namespace LoaferShellEx.Column {

    public class LinkTargetColumn : ColumnBase {

        // カラムセットの ID
        private static readonly Guid FORMAT_ID
                = new Guid("3D75F8D7-93CF-4cb5-B255-9D7AF7E346C5");

        // カラムの ID
        private const int PROPERTY_ID = 1;

        public LinkTargetColumn()
                : base(FORMAT_ID, PROPERTY_ID) {}

        // カラムの情報を取得
        public override void GetInfo(out SHCOLUMNINFO psci) {
           
            // まずは既定の実装を呼び、
            base.GetInfo(out psci);

            // 固有分を補正
            psci.cChars = 40;
            psci.wszTitle = "リンク先";
            psci.wszDescription = "ショートカットの示す先";
        }

        // ファイルに対応した値を取得
        public override object GetValue(ref SHCOLUMNDATA pscd) {

            // ディレクトリにはリンク先情報はない
            if ((pscd.dwFileAttributes & FILE_ATTRIBUTE.DIRECTORY) != 0) {
                throw new ComFalseException();
            }
            // 拡張子を調べる
            switch (pscd.pwszExt.ToLower()) {

            case ".lnk":
                // ショートカット
                // Shortcut オブジェクトを作成
                ShortcutClass obj = new ShortcutClass();

                try {

                    // IPersistFile インタフェースを取得し
                    UCOMIPersistFile pf = (UCOMIPersistFile)obj;

                    // ショートカットファイルを読み込み
                    pf.Load(pscd.wszFile, 0);

                    // IShellLinkW インタフェースを取得する
                    IShellLinkW link = (IShellLinkW)obj;

                    // バッファを用意し
                    StringBuilder target
                            = new StringBuilder(Constants.MAX_PATH);
                    StringBuilder arguments
                            = new StringBuilder(Constants.INFOTIPSIZE);

                    // ショートカット先と
                    link.GetPath(target, target.Capacity,
                            IntPtr.Zero, SLGP.UNCPRIORITY | SLGP.RAWPATH);

                    // 引数を取得し
                    link.GetArguments(arguments, arguments.Capacity);

                    // コマンドラインを合成する
                    string command = target.ToString();

                    // 空白を含み、クォートされてなければクォートする
                    if (command.IndexOf(' ') >= 0
                            && !command.StartsWith("\"")
                            && !command.EndsWith("\"")) {
                        command = '"' + command + '"';
                    }

                    // 引数があれば繋げる
                    if (arguments.Length > 0) {
                        command += ' ' + arguments.ToString();
                    }

                    // 完了
                    return command;

                } finally {

                    // COM オブジェクトを解放する
                    Marshal.ReleaseComObject(obj);

                }

            default:
                // 未知の形式なら S_FALSE を返す
                throw new ComFalseException();

            }

        }

    }

}

========== end of LinkTargetColumn.cs ==========

LinkTargetColumn はこんな感じとなる。

昨日のコードに手を加え、GetArguments の処理を追加した。
GetPath は実行するファイル名(またはドキュメント)だ。
コマンドに引数がある場合、GetArguments で取得できる。

例えば、「プログラムのアクセスと既定の設定」リンクは、
GetPath が、「%SystemRoot%\system32\control.exe」
GetArguments が「appwiz.cpl,,3」となる。

カラムに表示可能なのは 1 つだけなので、
これらを組み合わせてコマンドライン文字列を作っている。
GetPath が空白を含む場合はダブルクォートで囲み、
引数があれば空白をあけて後ろに続ければ完成となる。


では、ColumnProvider.cs も書き換えて、
LinkTargetColumn を公開しよう。

これは、COLUMNS 配列を変更するだけでいい。

    // カラムの定義
    private static readonly IColumn[] COLUMNS = new IColumn[] {
            new ByteSizeColumn(),
            new LinkTargetColumn(),
    };

これだけで、「リンク先」が表示されるようになった。



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