如何在Windows 属性 系统中创建一个图标列表属性?
How to create an IconList property in the Windows Property System?
目前,我的 属性 处理程序提供的属性可以显示在类型 String
的 Windows Explorer 列中。我的目标是通过(显示)类型 Icon 的 属性 扩展处理程序,可以将其作为列添加到 Windows Explorer 的详细信息视图中。在此列中,应为每个文件项显示一个图标,例如。 G。该图标可以代表文件的几种可能状态中的特定状态。
但是,我没有设法 assemble 在 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>
在 <displayInfo>
标签中存在 <drawControl>
(drawControl) 和类型 "IconList"
的 control
属性让我觉得我的想法可以可行。
但是如何在<typeInfo>
标签中设置对应的type
(typeInfo)呢?根据 control="IconList"
的概念,这可能是一个整数作为索引
有点像图像列表。还是代表图像本身的 "Buffer"
、"Blob"
或 "Stream"
?
最后,在 属性 处理程序 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 资源管理器中的相应列留空。
是否有人已经使用 IconList
类型的 <drawControl>
实现了 属性?
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)
嵌入式二进制数据属性存储二进制文件。其解码形式:
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 时,您必须使用 属性 存储二进制文件创建 blob。 属性 存储二进制文件必须包含以下数据:
- 键 System.PropList.StatusIcons,类型 VT_LPWSTR 等于 prop:DummyState
的值
- Key System.PropList.StatusIconsDisplayFlag,类型 VT_UI4 等于 2 的值(2 - 仅图标,1 - 图标 + 文本)
- 键 DummyState,值类型 VT_UI4。此值定义图标。
就是这样。在 Windows 10 上测试。截图:
目前,我的 属性 处理程序提供的属性可以显示在类型 String
的 Windows Explorer 列中。我的目标是通过(显示)类型 Icon 的 属性 扩展处理程序,可以将其作为列添加到 Windows Explorer 的详细信息视图中。在此列中,应为每个文件项显示一个图标,例如。 G。该图标可以代表文件的几种可能状态中的特定状态。
但是,我没有设法 assemble 在 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>
在 <displayInfo>
标签中存在 <drawControl>
(drawControl) 和类型 "IconList"
的 control
属性让我觉得我的想法可以可行。
但是如何在<typeInfo>
标签中设置对应的type
(typeInfo)呢?根据 control="IconList"
的概念,这可能是一个整数作为索引
有点像图像列表。还是代表图像本身的 "Buffer"
、"Blob"
或 "Stream"
?
最后,在 属性 处理程序 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 资源管理器中的相应列留空。
是否有人已经使用 IconList
类型的 <drawControl>
实现了 属性?
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)
嵌入式二进制数据属性存储二进制文件。其解码形式:
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 时,您必须使用 属性 存储二进制文件创建 blob。 属性 存储二进制文件必须包含以下数据:
- 键 System.PropList.StatusIcons,类型 VT_LPWSTR 等于 prop:DummyState 的值
- Key System.PropList.StatusIconsDisplayFlag,类型 VT_UI4 等于 2 的值(2 - 仅图标,1 - 图标 + 文本)
- 键 DummyState,值类型 VT_UI4。此值定义图标。
就是这样。在 Windows 10 上测试。截图: