如何在Windows属性系统中创建IconList属性?

Ste*_*ann 5 c++ com windows-shell shell-extensions

当前,我的属性处理程序提供的属性可以显示在Windows资源管理器的type列中String。我的目标是通过(显示)类型Icon的属性扩展处​​理程序,该属性可以作为列添加到Windows资源管理器的详细信息视图中。在此列中,应该为每个文件项目显示一个图标,例如,该图标可以代表几种可能状态中文件的特定状态。

但是,我没有在Windows属性系统的基础上正确地组合创建具有这些特征的属性的必要部分。

我的方法的第一步是在.propdesc文件中为属性指定XML ,然后执行通常的PSRegisterPropertySchema注册过程。这将始终成功运行,并且该属性在Windows属性系统中列出。

<propertyDescription name="myprop.icon" formatID="{c5f47221-1053-4a75-aadc-0bfbac1c3e9c}" propID="444">
    <typeInfo type="???" isInnate="true" isViewable="true"/>
    <labelInfo label="MyProp-Icon"/>
    <displayInfo defaultColumnWidth="25" alignment="Center">
        <drawControl control="IconList"/>
    </displayInfo>
</propertyDescription>
Run Code Online (Sandbox Code Playgroud)

的存在<drawControl>drawControl)与control类型的属性"IconList"的内部<displayInfo>标签让我觉得我的想法可能是可行的。

但是如何type<typeInfo>标签(typeInfo)中设置相应的内容呢?根据概念的不同,control="IconList"它可以是一个整数,作为像图像列表一样的索引。或者它是一个"Buffer""Blob"或者"Stream"表示图像本身?

最后,在GetValue()属性处理程序外壳扩展的方法PROPVARIANT中,必须根据.propdesc文件的属性描述进行初始化:

HRESULT PropertyHandler::GetValue (REFPROPERTYKEY key, PROPVARIANT *pPropVar)
{
    HRESULT hr = ERROR_NOT_FOUND;

    if (key.pid == 444)
    {
        // How to initialize pPropVar in case of control="IconList"?
    }
    else
    {
        // String example
        hr = InitPropVariantFromString (L"Some Text", pPropVar);
    }

    return hr;
}
Run Code Online (Sandbox Code Playgroud)

同样,如何针对"IconList"属性执行此操作?

每次尝试在XML规范和PROPVARIANT初始化之间寻找正确的匹配项,Windows资源管理器中的相应列都为空白。

是否有人已经实现了<drawControl>类型为a的属性IconList

Den*_*mov 6

propsys.dll中有WINDOWSPROPERTYDESCRIPTIONS资源。此资源描述了所有系统道具。一些属性的drawcontrol等于IconList。例:

<propertyDescription name="System.StorageProviderUIStatus" formatID="{E77E90DF-6271-4F5B-834F-2DD1F245DDA4}" propID="2">
  <searchInfo reIndexPatterns="" processReIndexPatternsImmediately="true" inInvertedIndex="false" isColumn="false">
  </searchInfo>
  <typeInfo type="Blob" isInnate="true" isViewable="true">
  </typeInfo>
  <labelInfo label="@propsys.dll,-42289">
  </labelInfo>
  <displayInfo defaultColumnWidth="10">
    <drawControl control="IconList">
    </drawControl>
  </displayInfo>
</propertyDescription>
Run Code Online (Sandbox Code Playgroud)

所有此类道具的类型均等于“斑点”。所以Blob是答案。

更新资料

我的小调查。

(对我来说)唯一显示图标的处理程序是OneDrive。屏幕截图:

在此处输入图片说明

我得到了OneDrive文件之一的System.StorageProviderUIStatus属性的值。价值转储:

在此处输入图片说明

如您所见,这不是图像或图标。这是[MS-PROPSTORE]中描述的属性存储二进制文件。解码形式:

System.PropList.StatusIcons = prop:System.StorageProviderState;System.StorageProviderCustomStates
System.PropList.StatusIconsDisplayFlag = 3
StorageProviderState = 2
StorageProviderCustomStates = (binary data)
Run Code Online (Sandbox Code Playgroud)

嵌入式属性存储二进制文件中的二进制数据。其解码形式:

StorageProviderFullyQualifiedId = OneDrive!S-1-5-21-782054983-1121033576-3753986437-1001!Personal|79D9464945C2A3B2!331 
Run Code Online (Sandbox Code Playgroud)

对于简单的图标描述,一切看起来都很困难。也许我错了,但Blob类型不是唯一的答案。

propdesc文件的内容:

<propertyDescription name="DummyUIState" formatID="{8A560909-320E-4E6A-A6C4-A95C50B77084}" propID="5001">
  <searchInfo columnIndexType="NotIndexed"/>
  <labelInfo label="DummyUIState"/>
  <typeInfo type="Blob" isInnate="true" isViewable="true"/>
  <displayInfo defaultColumnWidth="10">
    <drawControl control="IconList"/>
  </displayInfo>
</propertyDescription>

<propertyDescription name="DummyState" formatID="{8A560909-320E-4E6A-A6C4-A95C50B77084}" propID="5000">
  <searchInfo columnIndexType="NotIndexed"/>
  <labelInfo label="DummyState"/>
  <typeInfo type="UInt32" isInnate="true" isViewable="true"/>
  <displayInfo displayType="Enumerated">
    <enumeratedList>
      <enum name="None" value="0" text="@propsys.dll,-42290"/>
      <enum name="Sparse" value="1" text="@propsys.dll,-42291">
        <image res="%systemroot%\system32\imageres.dll,-1404"/>
      </enum>
      <enum name="InSync" value="2" text="@propsys.dll,-42292">
        <image res="%systemroot%\system32\imageres.dll,-1400"/>
      </enum>
      <enum name="Pinned" value="3" text="@propsys.dll,-42293">
        <image res="%systemroot%\system32\imageres.dll,-1405"/>
      </enum>
      <enum name="PendingUpload" value="4" text="@propsys.dll,-42294">
        <image res="%systemroot%\system32\imageres.dll,-1401"/>
      </enum>
      <enum name="PendingDownload" value="5" text="@propsys.dll,-42303">
        <image res="%systemroot%\system32\imageres.dll,-1401"/>
      </enum>
      <enum name="Transferring" value="6" text="@propsys.dll,-42296">
        <image res="%systemroot%\system32\imageres.dll,-1401"/>
      </enum>
      <enum name="Error" value="7" text="@propsys.dll,-42315">
        <image res="%systemroot%\system32\imageres.dll,-1402"/>
      </enum>
      <enum name="Warning" value="8" text="@propsys.dll,-42316">
        <image res="%systemroot%\system32\imageres.dll,-1403"/>
      </enum>
      <enum name="Excluded" value="9" text="@propsys.dll,-42319"/>
      <enum name="Pending" value="10" text="@propsys.dll,-42324">
        <image res="%systemroot%\system32\imageres.dll,-1401"/>
      </enum>
    </enumeratedList>
  </displayInfo>
</propertyDescription>
Run Code Online (Sandbox Code Playgroud)

当外壳程序请求DummyUIState时,必须使用属性存储二进制文件创建blob。属性存储二进制文件必须包含以下数据:

  1. 密钥System.PropList.StatusIcons,类型为VT_LPWSTR的值等于prop:DummyState
  2. 密钥System.PropList.StatusIconsDisplayFlag,类型VT_UI4的值等于2(2-仅图标,1-图标+文本)
  3. 密钥DummyState,值类型VT_UI4。此值定义图标。

就这样。在Windows 10上进行了测试。屏幕截图:

在此处输入图片说明

  • 我添加了OneDrive图标的屏幕截图。因此有可能。唯一的问题是-怎么样? (2认同)
  • 恕我直言,OneDrive中的图标是外壳的一部分。我认为是因为System.StorageProviderUIStatus,System.StorageProviderState和System.StorageProviderCustomStates是系统属性。无法为文件夹创建属性存储处理程序。NSE是唯一的解决方案。 (2认同)