タブファイラー開発ブログ

Tablacus ExplorerやX-Finderの作者のブログ

結果フォルダに対応しました。(Tablacus Explorer)

今回のTablacus Explorerでは結果フォルダに対応しました。 結果フォルダとはX-Finderのクリップフォルダの様に一つの階層にいろいろなファイルやフォルダをまとめる機能です。 クリップフォルダのアドオンは後日にアップする予定です。とりあえず、スピードダイヤルをショートカットを作る方法から結果フォルダに変更してみました。 それから、Windows 7のコントロールパネルの不具合を調整しました。 コントロールパネルの項目を開くとTablacus Explorerの中で妙に開いてしまう問題と、64ビットWindowsで32ビット版Tablacus Explorerでコントロールパネルの64ビットの項目を開くと落ちてしまう問題を調整しました。 結果フォルダはWindows Vistaから追加された機能なのですが、XPの場合は検索結果のフォルダを同じように使っています。 Vista以降ではIExplorerBrowserからだけでなくIShellBrowserからも使いたかったので、「shell:::{2965E715-EB66-4719-B53F-1672673BBEFA}」で結果フォルダを開いています。「shell::」無しでは開けません。 XPの場合は「::{e17d4fc0-5564-11d1-83f2-00a0c90dc849}」で検索結果を開いています。 XPでは結果フォルダのインターフェイスIResultsFolder::AddIDListは使えませんが、代わりにIShellFolderView::AddObjectを使いました。 IResultsFolder::AddIDListで追加するItemIDListはフルパスですが、IShellFolderView::AddObjectの場合のItemIDListを取得する方法を見つけられなかったので、検索結果のItemIDListを調べてフルパスのItemIDListから検索結果に追加できるItemIDListを作成する方法を見つけました。ファイル名のItemIDの後ろにパスのItemIDListを繋げた様な感じでした。詳しくは以下のteILCreateResultsXPで! もうXPのサポートも一ヶ月位ですがXPで結果フォルダを使いたい場合は使って下さい。

LPITEMIDLIST teILCreateResultsXP(LPITEMIDLIST pidl) {  LPITEMIDLIST pidl2 = NULL;  LPCITEMIDLIST pidlLast;  IShellFolder *pSF;  if SUCCEEDED(SHBindToParent(pidl, IID_PPV_ARGS(&pSF), &pidlLast)) {   SFGAOF sfAttr = SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_STORAGE | SFGAO_STREAM;   if (SUCCEEDED(pSF->GetAttributesOf(1, &pidlLast, &sfAttr)) &&    (sfAttr & (SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_STORAGE | SFGAO_STREAM))) {    UINT uSize = ILGetSize(pidl) + 28;    pidl2 = (LPITEMIDLIST)::CoTaskMemAlloc(uSize + sizeof(USHORT));    ::ZeroMemory(pidl2, uSize + sizeof(USHORT));    UINT uSize2 = ILGetSize(pidlLast);    ::CopyMemory(pidl2, pidlLast, uSize2);    *(PUSHORT)pidl2 = uSize - 2;    UINT uSize3 = uSize - uSize2 - 28;    PBYTE p = (PBYTE)pidl2;    *(PUSHORT)&p[uSize2 - 2] = uSize3 + 28;    *(PDWORD)&p[uSize2 + 2] = 0xbeef0005;    ::CopyMemory(&p[uSize2 + 22], pidl, uSize3);    *(PUSHORT)&p[uSize - 4] = uSize2 - 2;    CLSID clsid;    IPersist *pPersist;    if SUCCEEDED(pSF->QueryInterface(IID_PPV_ARGS(&pPersist))) {     if SUCCEEDED(pPersist->GetClassID(&clsid)) {      if (IsEqualCLSID(clsid, CLSID_ShellFSFolder)) {       *(PUSHORT)&p[uSize2 + 24 + uSize3] = *(PUSHORT)&p[uSize2 - 4];      }     }     pPersist->Release();    }    STRRET strret;    if SUCCEEDED(pSF->GetDisplayNameOf(pidl2, SHGDN_NORMAL, &strret)) {     if (strret.uType == STRRET_WSTR) {      ::CoTaskMemFree(strret.pOleStr);     }    }    else {     ::teCoTaskMemFree(pidl2);     pidl2 = NULL;    }   }   pSF->Release();  }  return pidl2; }