Windows API Code Pack for .NET Frameworkを使ってコモンダイアログを出してみる

Windows 7で出てきた新要素を.NET Frameworkアプリケーションが使うためのクラスライブラリ、Windows API Code Pack for .NET Frameworkを使ってみました。

コモンダイアログってどんな感じかを軽く試してみてます。
Windows API Code Pack for .NET Frameworkの入手は以下のサイトから。

http://code.msdn.microsoft.com/WindowsAPICodePack

image

このテストアプリでは、KnownFolders.Librariesを指定してコモンダイアログを開き、物理パスとなんちゃって仮想パスを取ろうとしています。
ただ、仮想パスの取り方がエレガントじゃないので、もっとほかの方法がないもんかなー。

// Windows API Code Pack 1.1のサンプルを参考に書いたものです
// (source\Samples\Shell\CommonFileDialogsDemo)

// ライブラリの取得
ShellContainer librariesFolder = (ShellContainer)KnownFolders.Libraries;

// コモンダイアログの初期化
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.AllowNonFileSystemItems = true;
// デフォルトフォルダの指定
dialog.DefaultDirectoryShellContainer = librariesFolder;

// ダイアログ表示
if (dialog.ShowDialog() != CommonFileDialogResult.Ok) return;

// 選択されたファイルの取得
// (ShellObjectでとれないことがある?サンプルではtry-catchしている)
ShellObject selectedObject = dialog.FileAsShellObject;
// 物理パスはParsingNameで得られる
absolutePathTextBox.Text = selectedObject.ParsingName;

// 仮想パスを得るきれいな手段が見当たらなかったので、親をたどってから
// 名前をつなげる方法を使ってみてます

// 親のアイテムをとれなくなるまで取ってみる
// Stackに積むことで後で根本から取り出す
Stack<ShellObject> pathStack = new Stack<ShellObject>();
ShellObject currentObject = selectedObject;
while (currentObject != null)
{
    pathStack.Push(currentObject);
    currentObject = currentObject.Parent;
}

// Stackを根本から取り出して、表示名をつなげることで仮想パスを組み立てる
string path = string.Empty;
while (0 < pathStack.Count)
{
    ShellObject currentItem = pathStack.Pop();
    path = Path.Combine(path, currentItem.Name);
}
// 仮想パス完成
// ただし、これだとデスクトップからになるので、親を探索する際にライブラリで打ち切るといったロジックがいるかも
// あと、C:\hogehoge.txtだと、ローカルディスクドライブ(C)みたいな文字列になるのがナンセンス
virtualPathTextBox.Text = path;

Code PackのMicrosoft.WindowsAPICodePack.dllとMicrosoft.WindowsAPICodePack.Shell.dllを同じフォルダに置けば、Visual Studio 2008で使えそうなアーカイブも置いておきます。

http://cid-9e1932af4be9e15d.office.live.com/self.aspx/.Public/Samples/20110105^_WinApiCodePackDialogTest.zip

 

追伸
実のところ、初期フォルダをがんばって指定しても、Windowsに覚えられちゃって、前回のフォルダで開くという挙動をするんですよね。
回避策があるかどうかは調べてません。