5

PIDLを比較するためにこれを行う必要があることがわかります:IShellFolder :: CompareIDs()。

特に、特定の絶対PIDL(または相対)がコントロールパネルのものであるかどうかを検出しようとしています。

ただし、実際には、IShellFolder :: CompareIDs()クレームが等しくない2つのPIDLになります(それぞれのGetDisplayName()を見ると、実際にコントロールパネルを見ていることがわかります)。 。

基本的に、私はコントロールパネルの絶対PIDLを次の方法で取得しています。

PIDL iidControlPanel = nullptr;
SHGetSpecialFolderLocation(hwnd, CSIDL_CONTROLS, &iidControlPanel);

そして、そのように着信列挙シェルオブジェクトを比較します(コンテキストについてはここを参照してください-一言で言えば、これはCMFCShellTreeCtrl内のデスクトップシェル名前空間を列挙した結果を見ています):

bool bIsControlPanel = CompareAbsolutePIDLs(iidControlPanel, pItem->pidlFQ);

参考までに、比較関数は次のとおりです。

bool CompareAbsolutePIDLs(PIDLIST_ABSOLUTE pidl1, PIDLIST_ABSOLUTE pidl2)
{
    CComPtr<IShellFolder> ishDesk;
    SHGetDesktopFolder(&ishDesk);
    HRESULT hr = ishDesk->CompareIDs(SHCIDS_CANONICALONLY, pidl1, pidl2);
    return SUCCEEDED(hr) && HRESULT_CODE(hr) == 0;
}

デバッガーでは、それぞれのGetDisplayName()が次を返すことがわかります。

"::{26EE0668-A00A-44D7-9371-BEB064C98683}\0"
"::{26EE0668-A00A-44D7-9371-BEB064C98683}"

ここで、PIDLの16進ダンプを確認できます。

1f 70 68 06 ee 26 0a a0 d7 44 93 71 be b0 64 c9 86 83 *0c* 00
1f 70 68 06 ee 26 0a a0 d7 44 93 71 be b0 64 c9 86 83 *00* 00

基になるPIDLSも、最後から2番目の値(00対0c)を除いて、バイナリで同一です。私は現在、なぜそれらが異なるのか、またはこの問題を解決するために何ができるのかについて途方に暮れていますか?!

質問

  1. その一見偽の余分なヌルバイトを含まない方法でコントロールのPIDLを取得する別の方法はありますか?
  2. あるいは、列挙アイテムのPIDLを取得するためのより良い方法はありますか(CMFCShellTreeCtrolが絶対PIDLを取得して、最後のnullバイトを含めることができないという方法で不十分なものはありますか?)
  3. コントロールパネルを相対PIDLとして取得し、それを相対列挙PIDL(私も持っています)と比較する方法はありますか?
  4. ???
4

1 に答える 1

3

これらは実際には異なるシェルオブジェクトです。取得したPIDLをSIGDN_NORMALDISPLAYオプションを使用してSHGetNameFromIDList()に渡して、読み取り可能な文字列に変換できます。長いPIDL(0x0c)は「すべてのコントロールパネル項目」に変換され、短いPIDLは「コントロールパネル」に変換されます。

この問題は、SHGetSpecialFolderLocation()を使用してコントロールパネルコントロールの仮想フォルダーを取得することから始まりました。デスクトップルートのコントロールパネルオブジェクトとは異なります。コントロールパネルのPIDLを入手してこれを修正し、仮想フォルダーを無視する必要があると思います。これを行う1つの方法は、ILCloneFirstを使用して仮想フォルダーをルートオブジェクトに変換することです。

 PITEMID_CHILD controlPanel = ILCloneFirst(iidControlPanel);

または、コントロールパネルのCLSID ":: {26EE0668-A00A-44D7-9371-BEB064C98683}"をハードコーディングし、SHParseDisplayName()を使用してPIDLに変換することもできます。

于 2013-03-01T19:04:18.710 に答える