【问题标题】:How to create an IconList property in the Windows Property System?如何在 Windows 属性系统中创建 IconList 属性?
【发布时间】:2018-05-27 23:46:17
【问题描述】:

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

但是,我没有设法在 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>

&lt;drawControl&gt; (drawControl) 的存在与control 类型的"IconList" 属性在&lt;displayInfo&gt; 标记内让我觉得我的想法是可行的。

但是如何在&lt;typeInfo&gt;标签(typeInfo)中设置对应的type呢?根据control="IconList" 的概念,这可能是一个整数作为索引 有点像一个图像列表。还是代表图像本身的"Buffer""Blob""Stream"

最后,在 Property Handler shell 扩展的 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;
}

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

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

是否有人已经实现了具有&lt;drawControl&gt; 类型为IconList 的属性?

【问题讨论】:

  • Denis 创建的解决方案在 Windows 7 到 Windows 10 上运行,没有任何差异。
  • 适用于 Windows 10 的相同代码不适用于我的 7。

标签: c++ com windows-shell shell-extensions


【解决方案1】:

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>

所有此类道具的类型都等于“Blob”。所以 Blob 就是答案。

更新

我的小调查。

唯一已知的(我所知道的)显示图标的处理程序是 OneDrive。截图:

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

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

System.PropList.StatusIcons = prop:System.StorageProviderState;System.StorageProviderCustomStates
System.PropList.StatusIconsDisplayFlag = 3
StorageProviderState = 2
StorageProviderCustomStates = (binary data)

嵌入式 Property Store 二进制文件中的二进制数据。其解码形式:

StorageProviderFullyQualifiedId = OneDrive!S-1-5-21-782054983-1121033576-3753986437-1001!Personal|79D9464945C2A3B2!331 

对于简单的图标描述来说,一切看起来都相当困难。也许我错了,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>

当 shell 请求 DummyUIState 时,您必须使用 Property Store Binary File 创建 blob。属性存储二进制文件必须包含以下数据:

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

就是这样。在 Windows 10 上测试。屏幕截图:

【讨论】:

  • 非常感谢,Blob 绝对正确。我仍然坚持将pPropVar-&gt;blob.pBlobData 设置为预期的数据(图像)格式。我尝试了HBITMAP 作为数据本身,GetDIBits() 从位图中提取的字节数组以及 BMP、PNG 和 ICO 文件的文件内容的字节数组。不幸的是,在所有这些组合中,图标列仍然是空白的。
  • 非常有趣和神秘。您对propsys.dll 中资源的提示将我引向System.OfflineStatus 之类的属性。它使用displayType="Enumerated"&lt;enums&gt; 中的&lt;enumeratedList&gt; 包含一个&lt;image&gt; 标记引用DLL 中的图像资源。这听起来完全合理,我建立了这样一个属性,但不幸的是图像永远不会显示。相反,该列显示同样在 &lt;enum&gt; 标记中指定的文本资源。现在我将进一步跟踪 Blob 路径并尝试了解 Property Store Binary File 格式。
  • 实际上,到目前为止,我在任何应用程序的 Windows 资源管理器列中都没有看到任何图标,除了文件图标。甚至 OneDrive 在我的系统上也没有提供图标属性。这让我怀疑实现图标属性是不可能的。非常感谢您的调查!
  • 我添加了 OneDrive 图标的屏幕截图。所以这是可能的。唯一的问题是 - 如何?
  • 恕我直言,OneDrive 中的图标是外壳的一部分。我这么认为是因为 System.StorageProviderUIStatus、System.StorageProviderState 和 System.StorageProviderCustomStates 是系统属性。无法为文件夹创建属性存储处理程序。 NSE 是唯一的解决方案。
猜你喜欢
  • 1970-01-01
  • 2015-08-17
  • 1970-01-01
  • 1970-01-01
  • 2011-07-08
  • 2011-11-03
  • 1970-01-01
  • 1970-01-01
  • 2013-05-29
相关资源
最近更新 更多