mirror of
https://github.com/microsoft/PowerToys.git
synced 2024-11-24 04:12:32 +08:00
[FileExplorer]Add QoiThumbnailProvider and QoiPreviewHandler (#29735)
* [FileExplorer]QoiThumbnailProvider * Corrects code documentation * Adds QoiPreviewHandler * Corrects GUIDs * Ensure returned thumbnail image is 32bit ARGB * Updates following review comments * More updates following review comments * Updates following PR comments * Fix dark theme background in QoiPreviewHandler * Updates attribution text
This commit is contained in:
parent
9d2f9bcff2
commit
0990724e44
@ -73,6 +73,12 @@
|
|||||||
"PowerToys.PdfThumbnailProviderCpp.dll",
|
"PowerToys.PdfThumbnailProviderCpp.dll",
|
||||||
"PowerToys.powerpreview.dll",
|
"PowerToys.powerpreview.dll",
|
||||||
"PowerToys.PreviewHandlerCommon.dll",
|
"PowerToys.PreviewHandlerCommon.dll",
|
||||||
|
"PowerToys.QoiPreviewHandler.dll",
|
||||||
|
"PowerToys.QoiPreviewHandler.exe",
|
||||||
|
"PowerToys.QoiPreviewHandlerCpp.dll",
|
||||||
|
"PowerToys.QoiThumbnailProvider.dll",
|
||||||
|
"PowerToys.QoiThumbnailProvider.exe",
|
||||||
|
"PowerToys.QoiThumbnailProviderCpp.dll",
|
||||||
"PowerToys.StlThumbnailProvider.dll",
|
"PowerToys.StlThumbnailProvider.dll",
|
||||||
"PowerToys.StlThumbnailProvider.exe",
|
"PowerToys.StlThumbnailProvider.exe",
|
||||||
"PowerToys.StlThumbnailProviderCpp.dll",
|
"PowerToys.StlThumbnailProviderCpp.dll",
|
||||||
|
@ -195,8 +195,10 @@ steps:
|
|||||||
**\UnitTests-GcodeThumbnailProvider.dll
|
**\UnitTests-GcodeThumbnailProvider.dll
|
||||||
**\UnitTests-StlThumbnailProvider.dll
|
**\UnitTests-StlThumbnailProvider.dll
|
||||||
**\UnitTests-PdfThumbnailProvider.dll
|
**\UnitTests-PdfThumbnailProvider.dll
|
||||||
|
**\UnitTests-QoiThumbnailProvider.dll
|
||||||
**\Settings.UI.UnitTests.dll
|
**\Settings.UI.UnitTests.dll
|
||||||
**\UnitTests-GcodePreviewHandler.dll
|
**\UnitTests-GcodePreviewHandler.dll
|
||||||
|
**\UnitTests-QoiPreviewHandler.dll
|
||||||
**\UnitTests-FancyZonesEditor.dll
|
**\UnitTests-FancyZonesEditor.dll
|
||||||
**\UnitTests-PdfPreviewHandler.dll
|
**\UnitTests-PdfPreviewHandler.dll
|
||||||
**\UnitTests-PreviewHandlerCommon.dll
|
**\UnitTests-PreviewHandlerCommon.dll
|
||||||
|
@ -538,7 +538,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CropAndLock", "src\modules\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CropAndLockModuleInterface", "src\modules\CropAndLock\CropAndLockModuleInterface\CropAndLockModuleInterface.vcxproj", "{3157FA75-86CF-4EE2-8F62-C43F776493C6}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CropAndLockModuleInterface", "src\modules\CropAndLock\CropAndLockModuleInterface\CropAndLockModuleInterface.vcxproj", "{3157FA75-86CF-4EE2-8F62-C43F776493C6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-FancyZonesEditor", "src\modules\fancyzones\UnitTests-FancyZonesEditor\UnitTests-FancyZonesEditor.csproj", "{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-FancyZonesEditor", "src\modules\fancyzones\UnitTests-FancyZonesEditor\UnitTests-FancyZonesEditor.csproj", "{FC8EB78F-F061-4BD9-A3F6-507BEA965E2B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EnvironmentVariables", "EnvironmentVariables", "{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EnvironmentVariables", "EnvironmentVariables", "{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}"
|
||||||
EndProject
|
EndProject
|
||||||
@ -546,6 +546,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvironmentVariables", "src
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EnvironmentVariablesModuleInterface", "src\modules\EnvironmentVariables\EnvironmentVariablesModuleInterface\EnvironmentVariablesModuleInterface.vcxproj", "{B9420661-B0E4-4241-ABD4-4A27A1F64250}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EnvironmentVariablesModuleInterface", "src\modules\EnvironmentVariables\EnvironmentVariablesModuleInterface\EnvironmentVariablesModuleInterface.vcxproj", "{B9420661-B0E4-4241-ABD4-4A27A1F64250}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QoiThumbnailProviderCpp", "src\modules\previewpane\QoiThumbnailProviderCpp\QoiThumbnailProviderCpp.vcxproj", "{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QoiThumbnailProvider", "src\modules\previewpane\QoiThumbnailProvider\QoiThumbnailProvider.csproj", "{D949EC7D-48A9-4279-95D5-078E7FD1F048}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QoiPreviewHandlerCpp", "src\modules\previewpane\QoiPreviewHandlerCpp\QoiPreviewHandlerCpp.vcxproj", "{3BAF9C81-A194-4925-A035-5E24A5D1E542}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "QoiPreviewHandler", "src\modules\previewpane\QoiPreviewHandler\QoiPreviewHandler.csproj", "{6B04803D-B418-4833-A67E-B0FC966636A5}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-QoiPreviewHandler", "src\modules\previewpane\UnitTests-QoiPreviewHandler\UnitTests-QoiPreviewHandler.csproj", "{3940AD4D-F748-4BE4-9083-85769CD553EF}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-QoiThumbnailProvider", "src\modules\previewpane\UnitTests-QoiThumbnailProvider\UnitTests-QoiThumbnailProvider.csproj", "{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM64 = Debug|ARM64
|
Debug|ARM64 = Debug|ARM64
|
||||||
@ -2352,6 +2364,78 @@ Global
|
|||||||
{B9420661-B0E4-4241-ABD4-4A27A1F64250}.Release|x64.Build.0 = Release|x64
|
{B9420661-B0E4-4241-ABD4-4A27A1F64250}.Release|x64.Build.0 = Release|x64
|
||||||
{B9420661-B0E4-4241-ABD4-4A27A1F64250}.Release|x86.ActiveCfg = Release|x64
|
{B9420661-B0E4-4241-ABD4-4A27A1F64250}.Release|x86.ActiveCfg = Release|x64
|
||||||
{B9420661-B0E4-4241-ABD4-4A27A1F64250}.Release|x86.Build.0 = Release|x64
|
{B9420661-B0E4-4241-ABD4-4A27A1F64250}.Release|x86.Build.0 = Release|x64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Release|x64.Build.0 = Release|x64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}.Release|x86.Build.0 = Release|x64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Release|x64.Build.0 = Release|x64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048}.Release|x86.Build.0 = Release|x64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Release|x64.Build.0 = Release|x64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542}.Release|x86.Build.0 = Release|x64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Release|x64.Build.0 = Release|x64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5}.Release|x86.Build.0 = Release|x64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Release|x64.Build.0 = Release|x64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF}.Release|x86.Build.0 = Release|x64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Debug|x86.ActiveCfg = Debug|x64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Debug|x86.Build.0 = Debug|x64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|x64.Build.0 = Release|x64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|x86.ActiveCfg = Release|x64
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}.Release|x86.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@ -2550,6 +2634,12 @@ Global
|
|||||||
{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||||
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
|
{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
|
||||||
{B9420661-B0E4-4241-ABD4-4A27A1F64250} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
|
{B9420661-B0E4-4241-ABD4-4A27A1F64250} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}
|
||||||
|
{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
|
{D949EC7D-48A9-4279-95D5-078E7FD1F048} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
|
{3BAF9C81-A194-4925-A035-5E24A5D1E542} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
|
{6B04803D-B418-4833-A67E-B0FC966636A5} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
|
{3940AD4D-F748-4BE4-9083-85769CD553EF} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
|
{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||||
|
@ -402,6 +402,15 @@
|
|||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
<File Id="Launcher_ValueGenerator_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\ValueGenerator\$(var.Language)\Community.PowerToys.Run.Plugin.ValueGenerator.resources.dll" />
|
<File Id="Launcher_ValueGenerator_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)RunPlugins\ValueGenerator\$(var.Language)\Community.PowerToys.Run.Plugin.ValueGenerator.resources.dll" />
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component
|
||||||
|
Id="QoiPreviewHandler_$(var.IdSafeLanguage)_Component"
|
||||||
|
Directory="Resource$(var.IdSafeLanguage)INSTALLFOLDER"
|
||||||
|
Guid="$(var.CompGUIDPrefix)1E">
|
||||||
|
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
|
||||||
|
<RegistryValue Type="string" Name="QoiPreviewHandler_$(var.IdSafeLanguage)_Component" Value="" KeyPath="yes"/>
|
||||||
|
</RegistryKey>
|
||||||
|
<File Id="QoiPreviewHandler_$(var.IdSafeLanguage)_File" Source="$(var.BinDir)\$(var.Language)\PowerToys.QoiPreviewHandler.resources.dll" />
|
||||||
|
</Component>
|
||||||
<?undef IdSafeLanguage?>
|
<?undef IdSafeLanguage?>
|
||||||
<?undef CompGUIDPrefix?>
|
<?undef CompGUIDPrefix?>
|
||||||
<?endforeach?>
|
<?endforeach?>
|
||||||
|
@ -1005,7 +1005,7 @@ UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall)
|
|||||||
}
|
}
|
||||||
processes.resize(bytes / sizeof(processes[0]));
|
processes.resize(bytes / sizeof(processes[0]));
|
||||||
|
|
||||||
std::array<std::wstring_view, 29> processesToTerminate = {
|
std::array<std::wstring_view, 31> processesToTerminate = {
|
||||||
L"PowerToys.PowerLauncher.exe",
|
L"PowerToys.PowerLauncher.exe",
|
||||||
L"PowerToys.Settings.exe",
|
L"PowerToys.Settings.exe",
|
||||||
L"PowerToys.Awake.exe",
|
L"PowerToys.Awake.exe",
|
||||||
@ -1026,7 +1026,9 @@ UINT __stdcall TerminateProcessesCA(MSIHANDLE hInstall)
|
|||||||
L"PowerToys.StlThumbnailProvider.exe",
|
L"PowerToys.StlThumbnailProvider.exe",
|
||||||
L"PowerToys.SvgThumbnailProvider.exe",
|
L"PowerToys.SvgThumbnailProvider.exe",
|
||||||
L"PowerToys.GcodePreviewHandler.exe",
|
L"PowerToys.GcodePreviewHandler.exe",
|
||||||
|
L"PowerToys.QoiPreviewHandler.exe",
|
||||||
L"PowerToys.PdfPreviewHandler.exe",
|
L"PowerToys.PdfPreviewHandler.exe",
|
||||||
|
L"PowerToys.QoiThumbnailProvider.exe",
|
||||||
L"PowerToys.SvgPreviewHandler.exe",
|
L"PowerToys.SvgPreviewHandler.exe",
|
||||||
L"PowerToys.Peek.UI.exe",
|
L"PowerToys.Peek.UI.exe",
|
||||||
L"PowerToys.MouseWithoutBorders.exe",
|
L"PowerToys.MouseWithoutBorders.exe",
|
||||||
|
@ -152,4 +152,12 @@ namespace winrt::PowerToys::GPOWrapper::implementation
|
|||||||
{
|
{
|
||||||
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredEnvironmentVariablesEnabledValue());
|
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredEnvironmentVariablesEnabledValue());
|
||||||
}
|
}
|
||||||
|
GpoRuleConfigured GPOWrapper::GetConfiguredQoiPreviewEnabledValue()
|
||||||
|
{
|
||||||
|
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredQoiPreviewEnabledValue());
|
||||||
|
}
|
||||||
|
GpoRuleConfigured GPOWrapper::GetConfiguredQoiThumbnailsEnabledValue()
|
||||||
|
{
|
||||||
|
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredQoiThumbnailsEnabledValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,8 @@ namespace winrt::PowerToys::GPOWrapper::implementation
|
|||||||
static GpoRuleConfigured GetAllowExperimentationValue();
|
static GpoRuleConfigured GetAllowExperimentationValue();
|
||||||
static GpoRuleConfigured GetRunPluginEnabledValue(winrt::hstring const& pluginID);
|
static GpoRuleConfigured GetRunPluginEnabledValue(winrt::hstring const& pluginID);
|
||||||
static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue();
|
static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue();
|
||||||
|
static GpoRuleConfigured GetConfiguredQoiPreviewEnabledValue();
|
||||||
|
static GpoRuleConfigured GetConfiguredQoiThumbnailsEnabledValue();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,8 @@ namespace PowerToys
|
|||||||
static GpoRuleConfigured GetAllowExperimentationValue();
|
static GpoRuleConfigured GetAllowExperimentationValue();
|
||||||
static GpoRuleConfigured GetRunPluginEnabledValue(String pluginID);
|
static GpoRuleConfigured GetRunPluginEnabledValue(String pluginID);
|
||||||
static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue();
|
static GpoRuleConfigured GetConfiguredEnvironmentVariablesEnabledValue();
|
||||||
|
static GpoRuleConfigured GetConfiguredQoiPreviewEnabledValue();
|
||||||
|
static GpoRuleConfigured GetConfiguredQoiThumbnailsEnabledValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,10 @@ public
|
|||||||
return gcnew String(CommonSharedConstants::GCODE_PREVIEW_RESIZE_EVENT);
|
return gcnew String(CommonSharedConstants::GCODE_PREVIEW_RESIZE_EVENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String ^ QoiPreviewResizeEvent() {
|
||||||
|
return gcnew String(CommonSharedConstants::QOI_PREVIEW_RESIZE_EVENT);
|
||||||
|
}
|
||||||
|
|
||||||
static String ^ DevFilesPreviewResizeEvent() {
|
static String ^ DevFilesPreviewResizeEvent() {
|
||||||
return gcnew String(CommonSharedConstants::DEV_FILES_PREVIEW_RESIZE_EVENT);
|
return gcnew String(CommonSharedConstants::DEV_FILES_PREVIEW_RESIZE_EVENT);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,9 @@ namespace CommonSharedConstants
|
|||||||
// Path to the event used by GcodePreviewHandler
|
// Path to the event used by GcodePreviewHandler
|
||||||
const wchar_t GCODE_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysGcodePreviewResizeEvent-6ff1f9bd-ccbd-4b24-a79f-40a34fb0317d";
|
const wchar_t GCODE_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysGcodePreviewResizeEvent-6ff1f9bd-ccbd-4b24-a79f-40a34fb0317d";
|
||||||
|
|
||||||
|
// Path to the event used by QoiPreviewHandler
|
||||||
|
const wchar_t QOI_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysQoiPreviewResizeEvent-579518d1-8c8b-494f-8143-04f43d761ead";
|
||||||
|
|
||||||
// Path to the event used by DevFilesPreviewHandler
|
// Path to the event used by DevFilesPreviewHandler
|
||||||
const wchar_t DEV_FILES_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysDevFilesPreviewResizeEvent-5707a22c-2cac-4ea2-82f0-27c03ef0b5f3";
|
const wchar_t DEV_FILES_PREVIEW_RESIZE_EVENT[] = L"Local\\PowerToysDevFilesPreviewResizeEvent-5707a22c-2cac-4ea2-82f0-27c03ef0b5f3";
|
||||||
|
|
||||||
|
@ -27,6 +27,10 @@ struct LogSettings
|
|||||||
inline const static std::wstring pdfPrevLogPath = L"logs\\FileExplorer_localLow\\PdfPrevHandler\\pdf-prev-handler-log.txt";
|
inline const static std::wstring pdfPrevLogPath = L"logs\\FileExplorer_localLow\\PdfPrevHandler\\pdf-prev-handler-log.txt";
|
||||||
inline const static std::string pdfThumbLoggerName = "PdfThumbnailProvider";
|
inline const static std::string pdfThumbLoggerName = "PdfThumbnailProvider";
|
||||||
inline const static std::wstring pdfThumbLogPath = L"logs\\FileExplorer_localLow\\PdfThumbnailProvider\\pdf-thumbnail-provider-log.txt";
|
inline const static std::wstring pdfThumbLogPath = L"logs\\FileExplorer_localLow\\PdfThumbnailProvider\\pdf-thumbnail-provider-log.txt";
|
||||||
|
inline const static std::string qoiPrevLoggerName = "QoiPrevHandler";
|
||||||
|
inline const static std::wstring qoiPrevLogPath = L"logs\\FileExplorer_localLow\\QoiPreviewHandler\\qoi-prev-handler-log.txt";
|
||||||
|
inline const static std::string qoiThumbLoggerName = "QoiThumbnailProvider";
|
||||||
|
inline const static std::wstring qoiThumbLogPath = L"logs\\FileExplorer_localLow\\QoiThumbnailProvider\\qoi-thumbnail-provider-log.txt";
|
||||||
inline const static std::string stlThumbLoggerName = "StlThumbnailProvider";
|
inline const static std::string stlThumbLoggerName = "StlThumbnailProvider";
|
||||||
inline const static std::wstring stlThumbLogPath = L"logs\\FileExplorer_localLow\\StlThumbnailProvider\\stl-thumbnail-provider-log.txt";
|
inline const static std::wstring stlThumbLogPath = L"logs\\FileExplorer_localLow\\StlThumbnailProvider\\stl-thumbnail-provider-log.txt";
|
||||||
inline const static std::string svgPrevLoggerName = "SvgPrevHandler";
|
inline const static std::string svgPrevLoggerName = "SvgPrevHandler";
|
||||||
|
@ -56,6 +56,8 @@ namespace powertoys_gpo {
|
|||||||
const std::wstring POLICY_CONFIGURE_ENABLED_MOUSE_WITHOUT_BORDERS = L"ConfigureEnabledUtilityMouseWithoutBorders";
|
const std::wstring POLICY_CONFIGURE_ENABLED_MOUSE_WITHOUT_BORDERS = L"ConfigureEnabledUtilityMouseWithoutBorders";
|
||||||
const std::wstring POLICY_CONFIGURE_ENABLED_PEEK = L"ConfigureEnabledUtilityPeek";
|
const std::wstring POLICY_CONFIGURE_ENABLED_PEEK = L"ConfigureEnabledUtilityPeek";
|
||||||
const std::wstring POLICY_CONFIGURE_ENABLED_ENVIRONMENT_VARIABLES = L"ConfigureEnabledUtilityEnvironmentVariables";
|
const std::wstring POLICY_CONFIGURE_ENABLED_ENVIRONMENT_VARIABLES = L"ConfigureEnabledUtilityEnvironmentVariables";
|
||||||
|
const std::wstring POLICY_CONFIGURE_ENABLED_QOI_PREVIEW = L"ConfigureEnabledUtilityFileExplorerQOIPreview";
|
||||||
|
const std::wstring POLICY_CONFIGURE_ENABLED_QOI_THUMBNAILS = L"ConfigureEnabledUtilityFileExplorerQOIThumbnails";
|
||||||
|
|
||||||
// The registry value names for PowerToys installer and update policies.
|
// The registry value names for PowerToys installer and update policies.
|
||||||
const std::wstring POLICY_DISABLE_PER_USER_INSTALLATION = L"PerUserInstallationDisabled";
|
const std::wstring POLICY_DISABLE_PER_USER_INSTALLATION = L"PerUserInstallationDisabled";
|
||||||
@ -446,4 +448,14 @@ namespace powertoys_gpo {
|
|||||||
return getConfiguredValue(POLICY_CONFIGURE_ENABLED_POWER_LAUNCHER_ALL_PLUGINS);
|
return getConfiguredValue(POLICY_CONFIGURE_ENABLED_POWER_LAUNCHER_ALL_PLUGINS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline gpo_rule_configured_t getConfiguredQoiPreviewEnabledValue()
|
||||||
|
{
|
||||||
|
return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_QOI_PREVIEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline gpo_rule_configured_t getConfiguredQoiThumbnailsEnabledValue()
|
||||||
|
{
|
||||||
|
return getUtilityEnabledValue(POLICY_CONFIGURE_ENABLED_QOI_THUMBNAILS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ namespace NonLocalizable
|
|||||||
const static std::vector<std::wstring> ExtPDF = { L".pdf" };
|
const static std::vector<std::wstring> ExtPDF = { L".pdf" };
|
||||||
const static std::vector<std::wstring> ExtGCode = { L".gcode" };
|
const static std::vector<std::wstring> ExtGCode = { L".gcode" };
|
||||||
const static std::vector<std::wstring> ExtSTL = { L".stl" };
|
const static std::vector<std::wstring> ExtSTL = { L".stl" };
|
||||||
|
const static std::vector<std::wstring> ExtQOI = { L".qoi" };
|
||||||
const static std::vector<std::wstring> ExtNoNoNo = {
|
const static std::vector<std::wstring> ExtNoNoNo = {
|
||||||
L".svgz" //Monaco cannot handle this file type at all; it's a binary file.
|
L".svgz" //Monaco cannot handle this file type at all; it's a binary file.
|
||||||
};
|
};
|
||||||
@ -145,6 +146,19 @@ inline registry::ChangeSet getGcodePreviewHandlerChangeSet(const std::wstring in
|
|||||||
NonLocalizable::ExtGCode);
|
NonLocalizable::ExtGCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline registry::ChangeSet getQoiPreviewHandlerChangeSet(const std::wstring installationDir, const bool perUser)
|
||||||
|
{
|
||||||
|
using namespace registry::shellex;
|
||||||
|
return generatePreviewHandler(PreviewHandlerType::preview,
|
||||||
|
perUser,
|
||||||
|
L"{729B72CD-B72E-4FE9-BCBF-E954B33FE699}",
|
||||||
|
get_std_product_version(),
|
||||||
|
(fs::path{ installationDir } / LR"d(PowerToys.QoiPreviewHandlerCpp.dll)d").wstring(),
|
||||||
|
L"QoiPreviewHandler",
|
||||||
|
L"Qoi Preview Handler",
|
||||||
|
NonLocalizable::ExtQOI);
|
||||||
|
}
|
||||||
|
|
||||||
inline registry::ChangeSet getSvgThumbnailHandlerChangeSet(const std::wstring installationDir, const bool perUser)
|
inline registry::ChangeSet getSvgThumbnailHandlerChangeSet(const std::wstring installationDir, const bool perUser)
|
||||||
{
|
{
|
||||||
using namespace registry::shellex;
|
using namespace registry::shellex;
|
||||||
@ -198,6 +212,19 @@ inline registry::ChangeSet getStlThumbnailHandlerChangeSet(const std::wstring in
|
|||||||
NonLocalizable::ExtSTL);
|
NonLocalizable::ExtSTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline registry::ChangeSet getQoiThumbnailHandlerChangeSet(const std::wstring installationDir, const bool perUser)
|
||||||
|
{
|
||||||
|
using namespace registry::shellex;
|
||||||
|
return generatePreviewHandler(PreviewHandlerType::thumbnail,
|
||||||
|
perUser,
|
||||||
|
L"{AD856B15-D25E-4008-AFB7-AFAA55586188}",
|
||||||
|
get_std_product_version(),
|
||||||
|
(fs::path{ installationDir } / LR"d(PowerToys.QoiThumbnailProviderCpp.dll)d").wstring(),
|
||||||
|
L"QoiThumbnailProvider",
|
||||||
|
L"Qoi Thumbnail Provider",
|
||||||
|
NonLocalizable::ExtQOI);
|
||||||
|
}
|
||||||
|
|
||||||
inline registry::ChangeSet getRegistryPreviewSetDefaultAppChangeSet(const std::wstring installationDir, const bool perUser)
|
inline registry::ChangeSet getRegistryPreviewSetDefaultAppChangeSet(const std::wstring installationDir, const bool perUser)
|
||||||
{
|
{
|
||||||
const HKEY scope = perUser ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
|
const HKEY scope = perUser ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
|
||||||
@ -245,9 +272,11 @@ inline std::vector<registry::ChangeSet> getAllOnByDefaultModulesChangeSets(const
|
|||||||
getMdPreviewHandlerChangeSet(installationDir, PER_USER),
|
getMdPreviewHandlerChangeSet(installationDir, PER_USER),
|
||||||
getMonacoPreviewHandlerChangeSet(installationDir, PER_USER),
|
getMonacoPreviewHandlerChangeSet(installationDir, PER_USER),
|
||||||
getGcodePreviewHandlerChangeSet(installationDir, PER_USER),
|
getGcodePreviewHandlerChangeSet(installationDir, PER_USER),
|
||||||
|
getQoiPreviewHandlerChangeSet(installationDir, PER_USER),
|
||||||
getSvgThumbnailHandlerChangeSet(installationDir, PER_USER),
|
getSvgThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
getGcodeThumbnailHandlerChangeSet(installationDir, PER_USER),
|
getGcodeThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
getStlThumbnailHandlerChangeSet(installationDir, PER_USER),
|
getStlThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
|
getQoiThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
getRegistryPreviewChangeSet(installationDir, PER_USER) };
|
getRegistryPreviewChangeSet(installationDir, PER_USER) };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,10 +288,12 @@ inline std::vector<registry::ChangeSet> getAllModulesChangeSets(const std::wstri
|
|||||||
getMonacoPreviewHandlerChangeSet(installationDir, PER_USER),
|
getMonacoPreviewHandlerChangeSet(installationDir, PER_USER),
|
||||||
getPdfPreviewHandlerChangeSet(installationDir, PER_USER),
|
getPdfPreviewHandlerChangeSet(installationDir, PER_USER),
|
||||||
getGcodePreviewHandlerChangeSet(installationDir, PER_USER),
|
getGcodePreviewHandlerChangeSet(installationDir, PER_USER),
|
||||||
|
getQoiPreviewHandlerChangeSet(installationDir, PER_USER),
|
||||||
getSvgThumbnailHandlerChangeSet(installationDir, PER_USER),
|
getSvgThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
getPdfThumbnailHandlerChangeSet(installationDir, PER_USER),
|
getPdfThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
getGcodeThumbnailHandlerChangeSet(installationDir, PER_USER),
|
getGcodeThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
getStlThumbnailHandlerChangeSet(installationDir, PER_USER),
|
getStlThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
|
getQoiThumbnailHandlerChangeSet(installationDir, PER_USER),
|
||||||
getRegistryPreviewChangeSet(installationDir, PER_USER),
|
getRegistryPreviewChangeSet(installationDir, PER_USER),
|
||||||
getRegistryPreviewSetDefaultAppChangeSet(installationDir, PER_USER) };
|
getRegistryPreviewSetDefaultAppChangeSet(installationDir, PER_USER) };
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<policyNamespaces>
|
<policyNamespaces>
|
||||||
<target prefix="powertoys" namespace="Microsoft.Policies.PowerToys" />
|
<target prefix="powertoys" namespace="Microsoft.Policies.PowerToys" />
|
||||||
</policyNamespaces>
|
</policyNamespaces>
|
||||||
<resources minRequiredRevision="1.5"/><!-- Last changed with PowerToys v0.75.1 -->
|
<resources minRequiredRevision="1.6"/><!-- Last changed with PowerToys v0.76.0 -->
|
||||||
<supportedOn>
|
<supportedOn>
|
||||||
<definitions>
|
<definitions>
|
||||||
<definition name="SUPPORTED_POWERTOYS_0_64_0" displayName="$(string.SUPPORTED_POWERTOYS_0_64_0)"/>
|
<definition name="SUPPORTED_POWERTOYS_0_64_0" displayName="$(string.SUPPORTED_POWERTOYS_0_64_0)"/>
|
||||||
@ -14,6 +14,7 @@
|
|||||||
<definition name="SUPPORTED_POWERTOYS_0_70_0" displayName="$(string.SUPPORTED_POWERTOYS_0_70_0)"/>
|
<definition name="SUPPORTED_POWERTOYS_0_70_0" displayName="$(string.SUPPORTED_POWERTOYS_0_70_0)"/>
|
||||||
<definition name="SUPPORTED_POWERTOYS_0_73_0" displayName="$(string.SUPPORTED_POWERTOYS_0_73_0)"/>
|
<definition name="SUPPORTED_POWERTOYS_0_73_0" displayName="$(string.SUPPORTED_POWERTOYS_0_73_0)"/>
|
||||||
<definition name="SUPPORTED_POWERTOYS_0_75_0" displayName="$(string.SUPPORTED_POWERTOYS_0_75_0)"/>
|
<definition name="SUPPORTED_POWERTOYS_0_75_0" displayName="$(string.SUPPORTED_POWERTOYS_0_75_0)"/>
|
||||||
|
<definition name="SUPPORTED_POWERTOYS_0_76_0" displayName="$(string.SUPPORTED_POWERTOYS_0_76_0)"/>
|
||||||
</definitions>
|
</definitions>
|
||||||
</supportedOn>
|
</supportedOn>
|
||||||
<categories>
|
<categories>
|
||||||
@ -188,6 +189,26 @@
|
|||||||
<decimal value="0" />
|
<decimal value="0" />
|
||||||
</disabledValue>
|
</disabledValue>
|
||||||
</policy>
|
</policy>
|
||||||
|
<policy name="ConfigureEnabledUtilityFileExplorerQOIPreview" class="Both" displayName="$(string.ConfigureEnabledUtilityFileExplorerQOIPreview)" explainText="$(string.ConfigureEnabledUtilityDescription)" key="Software\Policies\PowerToys" valueName="ConfigureEnabledUtilityFileExplorerQOIPreview">
|
||||||
|
<parentCategory ref="PowerToys" />
|
||||||
|
<supportedOn ref="SUPPORTED_POWERTOYS_0_76_0" />
|
||||||
|
<enabledValue>
|
||||||
|
<decimal value="1" />
|
||||||
|
</enabledValue>
|
||||||
|
<disabledValue>
|
||||||
|
<decimal value="0" />
|
||||||
|
</disabledValue>
|
||||||
|
</policy>
|
||||||
|
<policy name="ConfigureEnabledUtilityFileExplorerQOIThumbnails" class="Both" displayName="$(string.ConfigureEnabledUtilityFileExplorerQOIThumbnails)" explainText="$(string.ConfigureEnabledUtilityDescription)" key="Software\Policies\PowerToys" valueName="ConfigureEnabledUtilityFileExplorerQOIThumbnails">
|
||||||
|
<parentCategory ref="PowerToys" />
|
||||||
|
<supportedOn ref="SUPPORTED_POWERTOYS_0_76_0" />
|
||||||
|
<enabledValue>
|
||||||
|
<decimal value="1" />
|
||||||
|
</enabledValue>
|
||||||
|
<disabledValue>
|
||||||
|
<decimal value="0" />
|
||||||
|
</disabledValue>
|
||||||
|
</policy>
|
||||||
<policy name="ConfigureEnabledUtilityFileExplorerSTLThumbnails" class="Both" displayName="$(string.ConfigureEnabledUtilityFileExplorerSTLThumbnails)" explainText="$(string.ConfigureEnabledUtilityDescription)" key="Software\Policies\PowerToys" valueName="ConfigureEnabledUtilityFileExplorerSTLThumbnails">
|
<policy name="ConfigureEnabledUtilityFileExplorerSTLThumbnails" class="Both" displayName="$(string.ConfigureEnabledUtilityFileExplorerSTLThumbnails)" explainText="$(string.ConfigureEnabledUtilityDescription)" key="Software\Policies\PowerToys" valueName="ConfigureEnabledUtilityFileExplorerSTLThumbnails">
|
||||||
<parentCategory ref="PowerToys" />
|
<parentCategory ref="PowerToys" />
|
||||||
<supportedOn ref="SUPPORTED_POWERTOYS_0_64_0" />
|
<supportedOn ref="SUPPORTED_POWERTOYS_0_64_0" />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Copyright (c) Microsoft Corporation.
|
<!-- Copyright (c) Microsoft Corporation.
|
||||||
Licensed under the MIT License. -->
|
Licensed under the MIT License. -->
|
||||||
<policyDefinitionResources xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.5" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
|
<policyDefinitionResources xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" revision="1.6" schemaVersion="1.0" xmlns="http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions">
|
||||||
<displayName>PowerToys</displayName>
|
<displayName>PowerToys</displayName>
|
||||||
<description>PowerToys</description>
|
<description>PowerToys</description>
|
||||||
<resources>
|
<resources>
|
||||||
@ -16,6 +16,7 @@
|
|||||||
<string id="SUPPORTED_POWERTOYS_0_70_0">PowerToys version 0.70.0 or later</string>
|
<string id="SUPPORTED_POWERTOYS_0_70_0">PowerToys version 0.70.0 or later</string>
|
||||||
<string id="SUPPORTED_POWERTOYS_0_73_0">PowerToys version 0.73.0 or later</string>
|
<string id="SUPPORTED_POWERTOYS_0_73_0">PowerToys version 0.73.0 or later</string>
|
||||||
<string id="SUPPORTED_POWERTOYS_0_75_0">PowerToys version 0.75.0 or later</string>
|
<string id="SUPPORTED_POWERTOYS_0_75_0">PowerToys version 0.75.0 or later</string>
|
||||||
|
<string id="SUPPORTED_POWERTOYS_0_76_0">PowerToys version 0.76.0 or later</string>
|
||||||
|
|
||||||
<string id="ConfigureGlobalUtilityEnabledStateDescription">This policy configures the enabled state for all PowerToys utilities.
|
<string id="ConfigureGlobalUtilityEnabledStateDescription">This policy configures the enabled state for all PowerToys utilities.
|
||||||
|
|
||||||
@ -149,6 +150,8 @@ Note: Changes require a restart of PowerToys Run.
|
|||||||
<string id="AllowExperimentation">Allow Experimentation</string>
|
<string id="AllowExperimentation">Allow Experimentation</string>
|
||||||
<string id="PowerToysRunAllPluginsEnabledState">Configure enabled state for all plugins</string>
|
<string id="PowerToysRunAllPluginsEnabledState">Configure enabled state for all plugins</string>
|
||||||
<string id="PowerToysRunIndividualPluginEnabledState">Configure enabled state for individual plugins</string>
|
<string id="PowerToysRunIndividualPluginEnabledState">Configure enabled state for individual plugins</string>
|
||||||
|
<string id="ConfigureEnabledUtilityFileExplorerQOIPreview">QOI file preview: Configure enabled state</string>
|
||||||
|
<string id="ConfigureEnabledUtilityFileExplorerQOIThumbnails">QOI file thumbnail: Configure enabled state</string>
|
||||||
</stringTable>
|
</stringTable>
|
||||||
|
|
||||||
<presentationTable>
|
<presentationTable>
|
||||||
|
63
src/modules/previewpane/QoiPreviewHandler/Program.cs
Normal file
63
src/modules/previewpane/QoiPreviewHandler/Program.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
using Common.UI;
|
||||||
|
using interop;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.PreviewHandler.Qoi
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
private static QoiPreviewHandlerControl _previewHandlerControl;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
ApplicationConfiguration.Initialize();
|
||||||
|
if (args != null)
|
||||||
|
{
|
||||||
|
if (args.Length == 6)
|
||||||
|
{
|
||||||
|
string filePath = args[0];
|
||||||
|
int hwnd = Convert.ToInt32(args[1], 16);
|
||||||
|
|
||||||
|
Rectangle s = default(Rectangle);
|
||||||
|
int left = Convert.ToInt32(args[2], 10);
|
||||||
|
int right = Convert.ToInt32(args[3], 10);
|
||||||
|
int top = Convert.ToInt32(args[4], 10);
|
||||||
|
int bottom = Convert.ToInt32(args[5], 10);
|
||||||
|
|
||||||
|
_previewHandlerControl = new QoiPreviewHandlerControl();
|
||||||
|
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
|
||||||
|
_previewHandlerControl.DoPreview(filePath);
|
||||||
|
|
||||||
|
NativeEventWaiter.WaitForEventLoop(
|
||||||
|
Constants.QoiPreviewResizeEvent(),
|
||||||
|
() =>
|
||||||
|
{
|
||||||
|
Rectangle s = default(Rectangle);
|
||||||
|
_previewHandlerControl.SetRect(s);
|
||||||
|
},
|
||||||
|
Dispatcher.CurrentDispatcher,
|
||||||
|
_tokenSource.Token);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Wrong number of args: " + args.Length.ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// To customize application configuration such as set high DPI settings or default font,
|
||||||
|
// see https://aka.ms/applicationconfiguration.
|
||||||
|
Application.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
81
src/modules/previewpane/QoiPreviewHandler/Properties/Resource.Designer.cs
generated
Normal file
81
src/modules/previewpane/QoiPreviewHandler/Properties/Resource.Designer.cs
generated
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.PreviewHandler.Qoi.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resource {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resource() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.PowerToys.PreviewHandler.Qoi.Properties.Resource", typeof(Resource).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to This Qoi could not be previewed due to an internal error..
|
||||||
|
/// </summary>
|
||||||
|
internal static string QoiNotPreviewedError {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("QoiNotPreviewedError", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string for an error when Gpo has the utility disabled.
|
||||||
|
/// </summary>
|
||||||
|
internal static string GpoDisabledErrorText {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("GpoDisabledErrorText", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="QoiNotPreviewedError" xml:space="preserve">
|
||||||
|
<value>This Qoi could not be previewed due to an internal error.</value>
|
||||||
|
<comment>This text is displayed if Qoi fails to preview</comment>
|
||||||
|
</data>
|
||||||
|
<data name="GpoDisabledErrorText" xml:space="preserve">
|
||||||
|
<value>Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.</value>
|
||||||
|
<comment>GPO stands for the Windows Group Policy Object feature.</comment>
|
||||||
|
</data>
|
||||||
|
</root>
|
@ -0,0 +1,77 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<AssemblyTitle>PowerToys.QoiPreviewHandler</AssemblyTitle>
|
||||||
|
<AssemblyDescription>PowerToys QoiPreviewHandler</AssemblyDescription>
|
||||||
|
<Description>PowerToys QoiPreviewHandler</Description>
|
||||||
|
<DocumentationFile>..\..\..\..\$(Platform)\$(Configuration)\QoiPreviewPaneDocumentation.xml</DocumentationFile>
|
||||||
|
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)</OutputPath>
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
|
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||||
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||||
|
<AssemblyName>PowerToys.QoiPreviewHandler</AssemblyName>
|
||||||
|
<SelfContained>true</SelfContained>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
|
||||||
|
<PropertyGroup Condition="'$(Platform)'=='x64'">
|
||||||
|
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
|
||||||
|
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<ProjectGuid>{6B04803D-B418-4833-A67E-B0FC966636A5}</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Qoi</RootNamespace>
|
||||||
|
<TargetFramework>net7.0-windows10.0.20348.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||||
|
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="..\..\..\Version.props" />
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Update="QoiPreviewHandlerControl.cs" />
|
||||||
|
<Compile Update="Properties\Resource.Designer.cs">
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Resource.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||||
|
<PropertyGroup>
|
||||||
|
<CsWinRTIncludes>PowerToys.GPOWrapper</CsWinRTIncludes>
|
||||||
|
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||||
|
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<!-- Disable missing comment warning. WinRT/C++ libraries added won't have comments on their reflections. -->
|
||||||
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Windows.CsWinRT" />
|
||||||
|
<PackageReference Include="System.IO.Abstractions" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||||
|
<ProjectReference Include="..\..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||||
|
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||||
|
<ProjectReference Include="..\common\PreviewHandlerCommon.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Update="Properties\Resource.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -0,0 +1,166 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using Common;
|
||||||
|
using Microsoft.PowerToys.PreviewHandler.Qoi.Telemetry.Events;
|
||||||
|
using Microsoft.PowerToys.Telemetry;
|
||||||
|
using PreviewHandlerCommon.Utilities;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.PreviewHandler.Qoi
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Implementation of Control for Qoi Preview Handler.
|
||||||
|
/// </summary>
|
||||||
|
public class QoiPreviewHandlerControl : FormHandlerControl
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Picture box control to display the Qoi thumbnail.
|
||||||
|
/// </summary>
|
||||||
|
private PictureBox _pictureBox;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Text box to display errors.
|
||||||
|
/// </summary>
|
||||||
|
private RichTextBox _textBox;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represent if an text box info bar is added for showing message.
|
||||||
|
/// </summary>
|
||||||
|
private bool _infoBarAdded;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="QoiPreviewHandlerControl"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public QoiPreviewHandlerControl()
|
||||||
|
{
|
||||||
|
SetBackgroundColor(Settings.BackgroundColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start the preview on the Control.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dataSource">Stream reference to access source file.</param>
|
||||||
|
public override void DoPreview<T>(T dataSource)
|
||||||
|
{
|
||||||
|
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredQoiPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
|
||||||
|
{
|
||||||
|
// GPO is disabling this utility. Show an error message instead.
|
||||||
|
_infoBarAdded = true;
|
||||||
|
AddTextBoxControl(Properties.Resource.GpoDisabledErrorText);
|
||||||
|
Resize += FormResized;
|
||||||
|
base.DoPreview(dataSource);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Bitmap thumbnail = null;
|
||||||
|
|
||||||
|
if (!(dataSource is string filePath))
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"{nameof(dataSource)} for {nameof(QoiPreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||||
|
|
||||||
|
thumbnail = QoiImage.FromStream(fs);
|
||||||
|
|
||||||
|
_infoBarAdded = false;
|
||||||
|
|
||||||
|
AddPictureBoxControl(thumbnail);
|
||||||
|
|
||||||
|
Resize += FormResized;
|
||||||
|
base.DoPreview(fs);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PowerToysTelemetry.Log.WriteEvent(new QoiFilePreviewed());
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{ // Should not crash if sending telemetry is failing. Ignore the exception.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
PreviewError(ex, dataSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when RichtextBox is resized.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">Reference to resized control.</param>
|
||||||
|
/// <param name="e">Provides data for the ContentsResized event.</param>
|
||||||
|
private void RTBContentsResized(object sender, ContentsResizedEventArgs e)
|
||||||
|
{
|
||||||
|
var richTextBox = sender as RichTextBox;
|
||||||
|
richTextBox.Height = e.NewRectangle.Height + 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Occurs when form is resized.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender">Reference to resized control.</param>
|
||||||
|
/// <param name="e">Provides data for the resize event.</param>
|
||||||
|
private void FormResized(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
if (_infoBarAdded)
|
||||||
|
{
|
||||||
|
_textBox.Width = Width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a PictureBox Control to Control Collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">Image to display on PictureBox Control.</param>
|
||||||
|
private void AddPictureBoxControl(Image image)
|
||||||
|
{
|
||||||
|
_pictureBox = new PictureBox();
|
||||||
|
_pictureBox.BackgroundImage = image;
|
||||||
|
_pictureBox.BackgroundImageLayout = Width >= image.Width && Height >= image.Height ? ImageLayout.Center : ImageLayout.Zoom;
|
||||||
|
_pictureBox.Dock = DockStyle.Fill;
|
||||||
|
Controls.Add(_pictureBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a Text Box to display errors.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">Message to be displayed in textbox.</param>
|
||||||
|
private void AddTextBoxControl(string message)
|
||||||
|
{
|
||||||
|
_textBox = new RichTextBox();
|
||||||
|
_textBox.Text = message;
|
||||||
|
_textBox.BackColor = Color.LightYellow;
|
||||||
|
_textBox.Multiline = true;
|
||||||
|
_textBox.Dock = DockStyle.Top;
|
||||||
|
_textBox.ReadOnly = true;
|
||||||
|
_textBox.ContentsResized += RTBContentsResized;
|
||||||
|
_textBox.ScrollBars = RichTextBoxScrollBars.None;
|
||||||
|
_textBox.BorderStyle = BorderStyle.None;
|
||||||
|
Controls.Add(_textBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when an error occurs during preview.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exception">The exception which occurred.</param>
|
||||||
|
/// <param name="dataSource">Stream reference to access source file.</param>
|
||||||
|
private void PreviewError<T>(Exception exception, T dataSource)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PowerToysTelemetry.Log.WriteEvent(new QoiFilePreviewError { Message = exception.Message });
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{ // Should not crash if sending telemetry is failing. Ignore the exception.
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls.Clear();
|
||||||
|
_infoBarAdded = true;
|
||||||
|
AddTextBoxControl(Properties.Resource.QoiNotPreviewedError);
|
||||||
|
base.DoPreview(dataSource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
38
src/modules/previewpane/QoiPreviewHandler/Settings.cs
Normal file
38
src/modules/previewpane/QoiPreviewHandler/Settings.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.PreviewHandler.Qoi
|
||||||
|
{
|
||||||
|
internal sealed class Settings
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the color of the window background.
|
||||||
|
/// Even though this is not a setting yet, it's retrieved from a "Settings" class to be aligned with other preview handlers that contain this setting.
|
||||||
|
/// It's possible it can be converted into a setting in the future.
|
||||||
|
/// </summary>
|
||||||
|
public static Color BackgroundColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (GetTheme() == "dark")
|
||||||
|
{
|
||||||
|
return Color.FromArgb(30, 30, 30); // #1e1e1e
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Color.White;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the theme.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Theme that should be used.</returns>
|
||||||
|
public static string GetTheme()
|
||||||
|
{
|
||||||
|
return Common.UI.ThemeManager.GetWindowsBaseColor().ToLowerInvariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.Diagnostics.Tracing;
|
||||||
|
using Microsoft.PowerToys.Telemetry;
|
||||||
|
using Microsoft.PowerToys.Telemetry.Events;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.PreviewHandler.Qoi.Telemetry.Events
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A telemetry event to be raised when an error has occurred in the preview pane.
|
||||||
|
/// </summary>
|
||||||
|
[EventData]
|
||||||
|
public class QoiFilePreviewError : EventBase, IEvent
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the error message to log as part of the telemetry event.
|
||||||
|
/// </summary>
|
||||||
|
public string Message { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.Diagnostics.Tracing;
|
||||||
|
using Microsoft.PowerToys.Telemetry;
|
||||||
|
using Microsoft.PowerToys.Telemetry.Events;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.PreviewHandler.Qoi.Telemetry.Events
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A telemetry event to be raised when a Qoi file has been viewed in the preview pane.
|
||||||
|
/// </summary>
|
||||||
|
[EventData]
|
||||||
|
public class QoiFilePreviewed : EventBase, IEvent
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServiceUsage;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "ClassFactory.h"
|
||||||
|
#include "QoiPreviewHandler.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
|
extern long g_cDllRef;
|
||||||
|
|
||||||
|
ClassFactory::ClassFactory() :
|
||||||
|
m_cRef(1)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassFactory::~ClassFactory()
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// IUnknown
|
||||||
|
//
|
||||||
|
|
||||||
|
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
static const QITAB qit[] = {
|
||||||
|
QITABENT(ClassFactory, IClassFactory),
|
||||||
|
{ 0 },
|
||||||
|
};
|
||||||
|
return QISearch(this, qit, riid, ppv);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
|
||||||
|
{
|
||||||
|
return InterlockedIncrement(&m_cRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
|
||||||
|
{
|
||||||
|
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||||
|
if (0 == cRef)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
return cRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// IClassFactory
|
||||||
|
//
|
||||||
|
|
||||||
|
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
HRESULT hr = CLASS_E_NOAGGREGATION;
|
||||||
|
|
||||||
|
if (pUnkOuter == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
QoiPreviewHandler* pExt = new (std::nothrow) QoiPreviewHandler();
|
||||||
|
if (pExt)
|
||||||
|
{
|
||||||
|
hr = pExt->QueryInterface(riid, ppv);
|
||||||
|
pExt->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP ClassFactory::LockServer(BOOL fLock)
|
||||||
|
{
|
||||||
|
if (fLock)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
24
src/modules/previewpane/QoiPreviewHandlerCpp/ClassFactory.h
Normal file
24
src/modules/previewpane/QoiPreviewHandlerCpp/ClassFactory.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Unknwn.h>
|
||||||
|
|
||||||
|
class ClassFactory : public IClassFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// IUnknown
|
||||||
|
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
|
||||||
|
IFACEMETHODIMP_(ULONG) AddRef();
|
||||||
|
IFACEMETHODIMP_(ULONG) Release();
|
||||||
|
|
||||||
|
// IClassFactory
|
||||||
|
IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv);
|
||||||
|
IFACEMETHODIMP LockServer(BOOL fLock);
|
||||||
|
|
||||||
|
ClassFactory();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~ClassFactory();
|
||||||
|
|
||||||
|
private:
|
||||||
|
long m_cRef;
|
||||||
|
};
|
@ -0,0 +1,3 @@
|
|||||||
|
EXPORTS
|
||||||
|
DllGetClassObject PRIVATE
|
||||||
|
DllCanUnloadNow PRIVATE
|
@ -0,0 +1,266 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "QoiPreviewHandler.h"
|
||||||
|
#include "../powerpreview/powerpreviewConstants.h"
|
||||||
|
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <common/interop/shared_constants.h>
|
||||||
|
#include <common/logger/logger.h>
|
||||||
|
#include <common/SettingsAPI/settings_helpers.h>
|
||||||
|
#include <common/utils/process_path.h>
|
||||||
|
#include <common/Themes/windows_colors.h>
|
||||||
|
|
||||||
|
extern HINSTANCE g_hInst;
|
||||||
|
extern long g_cDllRef;
|
||||||
|
|
||||||
|
QoiPreviewHandler::QoiPreviewHandler() :
|
||||||
|
m_cRef(1), m_hwndParent(NULL), m_rcParent(), m_punkSite(NULL), m_process(NULL)
|
||||||
|
{
|
||||||
|
m_resizeEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::QOI_PREVIEW_RESIZE_EVENT);
|
||||||
|
|
||||||
|
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
|
||||||
|
logFilePath.append(LogSettings::qoiPrevLogPath);
|
||||||
|
Logger::init(LogSettings::qoiPrevLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||||
|
|
||||||
|
InterlockedIncrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
QoiPreviewHandler::~QoiPreviewHandler()
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma region IUnknown
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::QueryInterface(REFIID riid, void** ppv)
|
||||||
|
{
|
||||||
|
static const QITAB qit[] = {
|
||||||
|
QITABENT(QoiPreviewHandler, IPreviewHandler),
|
||||||
|
QITABENT(QoiPreviewHandler, IInitializeWithFile),
|
||||||
|
QITABENT(QoiPreviewHandler, IPreviewHandlerVisuals),
|
||||||
|
QITABENT(QoiPreviewHandler, IOleWindow),
|
||||||
|
QITABENT(QoiPreviewHandler, IObjectWithSite),
|
||||||
|
{ 0 },
|
||||||
|
};
|
||||||
|
return QISearch(this, qit, riid, ppv);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(ULONG)
|
||||||
|
QoiPreviewHandler::AddRef()
|
||||||
|
{
|
||||||
|
return InterlockedIncrement(&m_cRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(ULONG)
|
||||||
|
QoiPreviewHandler::Release()
|
||||||
|
{
|
||||||
|
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||||
|
if (0 == cRef)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
return cRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region IInitializationWithFile
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::Initialize(LPCWSTR pszFilePath, DWORD grfMode)
|
||||||
|
{
|
||||||
|
m_filePath = pszFilePath;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region IPreviewHandler
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::SetWindow(HWND hwnd, const RECT* prc)
|
||||||
|
{
|
||||||
|
if (hwnd && prc)
|
||||||
|
{
|
||||||
|
m_hwndParent = hwnd;
|
||||||
|
m_rcParent = *prc;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::SetFocus()
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::QueryFocus(HWND* phwnd)
|
||||||
|
{
|
||||||
|
HRESULT hr = E_INVALIDARG;
|
||||||
|
if (phwnd)
|
||||||
|
{
|
||||||
|
*phwnd = ::GetFocus();
|
||||||
|
if (*phwnd)
|
||||||
|
{
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::TranslateAccelerator(MSG* pmsg)
|
||||||
|
{
|
||||||
|
HRESULT hr = S_FALSE;
|
||||||
|
IPreviewHandlerFrame* pFrame = NULL;
|
||||||
|
if (m_punkSite && SUCCEEDED(m_punkSite->QueryInterface(&pFrame)))
|
||||||
|
{
|
||||||
|
hr = pFrame->TranslateAccelerator(pmsg);
|
||||||
|
|
||||||
|
pFrame->Release();
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::SetRect(const RECT* prc)
|
||||||
|
{
|
||||||
|
HRESULT hr = E_INVALIDARG;
|
||||||
|
if (prc != NULL)
|
||||||
|
{
|
||||||
|
if (!m_resizeEvent)
|
||||||
|
{
|
||||||
|
Logger::error(L"Failed to create resize event for QoiPreviewHandler");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_rcParent.right != prc->right || m_rcParent.left != prc->left || m_rcParent.top != prc->top || m_rcParent.bottom != prc->bottom)
|
||||||
|
{
|
||||||
|
if (!SetEvent(m_resizeEvent))
|
||||||
|
{
|
||||||
|
Logger::error(L"Failed to signal resize event for QoiPreviewHandler");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_rcParent = *prc;
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::DoPreview()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Logger::info(L"Starting QoiPreviewHandler.exe");
|
||||||
|
|
||||||
|
STARTUPINFO info = { sizeof(info) };
|
||||||
|
std::wstring cmdLine{ L"\"" + m_filePath + L"\"" };
|
||||||
|
cmdLine += L" ";
|
||||||
|
std::wostringstream ss;
|
||||||
|
ss << std::hex << m_hwndParent;
|
||||||
|
|
||||||
|
cmdLine += ss.str();
|
||||||
|
cmdLine += L" ";
|
||||||
|
cmdLine += std::to_wstring(m_rcParent.left);
|
||||||
|
cmdLine += L" ";
|
||||||
|
cmdLine += std::to_wstring(m_rcParent.right);
|
||||||
|
cmdLine += L" ";
|
||||||
|
cmdLine += std::to_wstring(m_rcParent.top);
|
||||||
|
cmdLine += L" ";
|
||||||
|
cmdLine += std::to_wstring(m_rcParent.bottom);
|
||||||
|
std::wstring appPath = get_module_folderpath(g_hInst) + L"\\PowerToys.QoiPreviewHandler.exe";
|
||||||
|
|
||||||
|
SHELLEXECUTEINFO sei{ sizeof(sei) };
|
||||||
|
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
||||||
|
sei.lpFile = appPath.c_str();
|
||||||
|
sei.lpParameters = cmdLine.c_str();
|
||||||
|
sei.nShow = SW_SHOWDEFAULT;
|
||||||
|
ShellExecuteEx(&sei);
|
||||||
|
m_process = sei.hProcess;
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::wstring errorMessage = std::wstring{ winrt::to_hstring(e.what()) };
|
||||||
|
Logger::error(L"Failed to start QoiPreviewHandler.exe. Error: {}", errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::Unload()
|
||||||
|
{
|
||||||
|
Logger::info(L"Unload and terminate .exe");
|
||||||
|
|
||||||
|
m_hwndParent = NULL;
|
||||||
|
TerminateProcess(m_process, 0);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region IPreviewHandlerVisuals
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::SetBackgroundColor(COLORREF color)
|
||||||
|
{
|
||||||
|
HBRUSH brush = CreateSolidBrush(WindowsColors::is_dark_mode() ? powerpreviewConstants::DARK_THEME_COLOR : powerpreviewConstants::LIGHT_THEME_COLOR);
|
||||||
|
SetClassLongPtr(m_hwndParent, GCLP_HBRBACKGROUND, reinterpret_cast<LONG_PTR>(brush));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::SetFont(const LOGFONTW* plf)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::SetTextColor(COLORREF color)
|
||||||
|
{
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region IOleWindow
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::GetWindow(HWND* phwnd)
|
||||||
|
{
|
||||||
|
HRESULT hr = E_INVALIDARG;
|
||||||
|
if (phwnd)
|
||||||
|
{
|
||||||
|
*phwnd = m_hwndParent;
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::ContextSensitiveHelp(BOOL fEnterMode)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region IObjectWithSite
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::SetSite(IUnknown* punkSite)
|
||||||
|
{
|
||||||
|
if (m_punkSite)
|
||||||
|
{
|
||||||
|
m_punkSite->Release();
|
||||||
|
m_punkSite = NULL;
|
||||||
|
}
|
||||||
|
return punkSite ? punkSite->QueryInterface(&m_punkSite) : S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiPreviewHandler::GetSite(REFIID riid, void** ppv)
|
||||||
|
{
|
||||||
|
*ppv = NULL;
|
||||||
|
return m_punkSite ? m_punkSite->QueryInterface(riid, ppv) : E_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Helper Functions
|
||||||
|
|
||||||
|
#pragma endregion
|
@ -0,0 +1,69 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <ShlObj.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class QoiPreviewHandler :
|
||||||
|
public IInitializeWithFile,
|
||||||
|
public IPreviewHandler,
|
||||||
|
public IPreviewHandlerVisuals,
|
||||||
|
public IOleWindow,
|
||||||
|
public IObjectWithSite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// IUnknown
|
||||||
|
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
|
||||||
|
IFACEMETHODIMP_(ULONG) AddRef();
|
||||||
|
IFACEMETHODIMP_(ULONG) Release();
|
||||||
|
|
||||||
|
// IInitializeWithFile
|
||||||
|
IFACEMETHODIMP Initialize(LPCWSTR pszFilePath, DWORD grfMode);
|
||||||
|
|
||||||
|
// IPreviewHandler
|
||||||
|
IFACEMETHODIMP SetWindow(HWND hwnd, const RECT* prc);
|
||||||
|
IFACEMETHODIMP SetFocus();
|
||||||
|
IFACEMETHODIMP QueryFocus(HWND* phwnd);
|
||||||
|
IFACEMETHODIMP TranslateAccelerator(MSG* pmsg);
|
||||||
|
IFACEMETHODIMP SetRect(const RECT* prc);
|
||||||
|
IFACEMETHODIMP DoPreview();
|
||||||
|
IFACEMETHODIMP Unload();
|
||||||
|
|
||||||
|
// IPreviewHandlerVisuals
|
||||||
|
IFACEMETHODIMP SetBackgroundColor(COLORREF color);
|
||||||
|
IFACEMETHODIMP SetFont(const LOGFONTW* plf);
|
||||||
|
IFACEMETHODIMP SetTextColor(COLORREF color);
|
||||||
|
|
||||||
|
// IOleWindow
|
||||||
|
IFACEMETHODIMP GetWindow(HWND* phwnd);
|
||||||
|
IFACEMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
|
||||||
|
|
||||||
|
// IObjectWithSite
|
||||||
|
IFACEMETHODIMP SetSite(IUnknown* punkSite);
|
||||||
|
IFACEMETHODIMP GetSite(REFIID riid, void** ppv);
|
||||||
|
|
||||||
|
QoiPreviewHandler();
|
||||||
|
protected:
|
||||||
|
~QoiPreviewHandler();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Reference count of component.
|
||||||
|
long m_cRef;
|
||||||
|
|
||||||
|
// Provided during initialization.
|
||||||
|
std::wstring m_filePath;
|
||||||
|
|
||||||
|
// Parent window that hosts the previewer window.
|
||||||
|
// Note: do NOT DestroyWindow this.
|
||||||
|
HWND m_hwndParent;
|
||||||
|
// Bounding rect of the parent window.
|
||||||
|
RECT m_rcParent;
|
||||||
|
|
||||||
|
// Site pointer from host, used to get IPreviewHandlerFrame.
|
||||||
|
IUnknown* m_punkSite;
|
||||||
|
|
||||||
|
HANDLE m_process;
|
||||||
|
HANDLE m_resizeEvent;
|
||||||
|
};
|
@ -0,0 +1,40 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include "resource.h"
|
||||||
|
#include "../../../common/version/version.h"
|
||||||
|
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#include "winres.h"
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
1 VERSIONINFO
|
||||||
|
FILEVERSION FILE_VERSION
|
||||||
|
PRODUCTVERSION PRODUCT_VERSION
|
||||||
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS VS_FF_DEBUG
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS VOS_NT_WINDOWS32
|
||||||
|
FILETYPE VFT_DLL
|
||||||
|
FILESUBTYPE VFT2_UNKNOWN
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", COMPANY_NAME
|
||||||
|
VALUE "FileDescription", FILE_DESCRIPTION
|
||||||
|
VALUE "FileVersion", FILE_VERSION_STRING
|
||||||
|
VALUE "InternalName", INTERNAL_NAME
|
||||||
|
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
||||||
|
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
||||||
|
VALUE "ProductName", PRODUCT_NAME
|
||||||
|
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
||||||
|
END
|
||||||
|
END
|
@ -0,0 +1,121 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{3BAF9C81-A194-4925-A035-5E24A5D1E542}</ProjectGuid>
|
||||||
|
<RootNamespace>QoiPreviewHandlerCpp</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutDir>..\..\..\..\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetName>PowerToys.$(ProjectName)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
|
||||||
|
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
|
||||||
|
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="ClassFactory.h" />
|
||||||
|
<ClInclude Include="QoiPreviewHandler.h" />
|
||||||
|
<ClInclude Include="pch.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="ClassFactory.cpp" />
|
||||||
|
<ClCompile Include="dllmain.cpp" />
|
||||||
|
<ClCompile Include="QoiPreviewHandler.cpp" />
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="GlobalExportFunctions.def" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="QoiPreviewHandlerCpp.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
|
||||||
|
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
|
||||||
|
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\..\common\Themes\Themes.vcxproj">
|
||||||
|
<Project>{98537082-0fdb-40de-abd8-0dc5a4269bab}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||||
|
</ImportGroup>
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||||
|
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="pch.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ClassFactory.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="QoiPreviewHandler.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="resource.h">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="dllmain.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ClassFactory.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="QoiPreviewHandler.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="GlobalExportFunctions.def">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="QoiPreviewHandlerCpp.rc">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
73
src/modules/previewpane/QoiPreviewHandlerCpp/dllmain.cpp
Normal file
73
src/modules/previewpane/QoiPreviewHandlerCpp/dllmain.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||||
|
#include "pch.h"
|
||||||
|
#include "ClassFactory.h"
|
||||||
|
|
||||||
|
HINSTANCE g_hInst = NULL;
|
||||||
|
long g_cDllRef = 0;
|
||||||
|
|
||||||
|
// {729B72CD-B72E-4FE9-BCBF-E954B33FE699}
|
||||||
|
static const GUID CLSID_QoiPreviewHandler = { 0x729b72cd, 0xb72e, 0x4fe9, { 0xbc, 0xbf, 0xe9, 0x54, 0xb3, 0x3f, 0xe6, 0x99 } };
|
||||||
|
|
||||||
|
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||||
|
DWORD ul_reason_for_call,
|
||||||
|
LPVOID lpReserved)
|
||||||
|
{
|
||||||
|
switch (ul_reason_for_call)
|
||||||
|
{
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
g_hInst = hModule;
|
||||||
|
DisableThreadLibraryCalls(hModule);
|
||||||
|
break;
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FUNCTION: DllGetClassObject
|
||||||
|
//
|
||||||
|
// PURPOSE: Create the class factory and query to the specific interface.
|
||||||
|
//
|
||||||
|
// PARAMETERS:
|
||||||
|
// * rclsid - The CLSID that will associate the correct data and code.
|
||||||
|
// * riid - A reference to the identifier of the interface that the caller
|
||||||
|
// is to use to communicate with the class object.
|
||||||
|
// * ppv - The address of a pointer variable that receives the interface
|
||||||
|
// pointer requested in riid. Upon successful return, *ppv contains the
|
||||||
|
// requested interface pointer. If an error occurs, the interface pointer
|
||||||
|
// is NULL.
|
||||||
|
//
|
||||||
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
|
||||||
|
{
|
||||||
|
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
|
||||||
|
|
||||||
|
if (IsEqualCLSID(CLSID_QoiPreviewHandler, rclsid))
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
ClassFactory* pClassFactory = new ClassFactory();
|
||||||
|
if (pClassFactory)
|
||||||
|
{
|
||||||
|
hr = pClassFactory->QueryInterface(riid, ppv);
|
||||||
|
pClassFactory->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FUNCTION: DllCanUnloadNow
|
||||||
|
//
|
||||||
|
// PURPOSE: Check if we can unload the component from the memory.
|
||||||
|
//
|
||||||
|
// NOTE: The component can be unloaded from the memory when its reference
|
||||||
|
// count is zero (i.e. nobody is still using the component).
|
||||||
|
//
|
||||||
|
STDAPI DllCanUnloadNow(void)
|
||||||
|
{
|
||||||
|
return g_cDllRef > 0 ? S_FALSE : S_OK;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Microsoft.Windows.CppWinRT" version="2.0.221104.6" targetFramework="native" />
|
||||||
|
</packages>
|
5
src/modules/previewpane/QoiPreviewHandlerCpp/pch.cpp
Normal file
5
src/modules/previewpane/QoiPreviewHandlerCpp/pch.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// pch.cpp: source file corresponding to the pre-compiled header
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
14
src/modules/previewpane/QoiPreviewHandlerCpp/pch.h
Normal file
14
src/modules/previewpane/QoiPreviewHandlerCpp/pch.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// pch.h: This is a precompiled header file.
|
||||||
|
// Files listed below are compiled only once, improving build performance for future builds.
|
||||||
|
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
||||||
|
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
||||||
|
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
||||||
|
|
||||||
|
#ifndef PCH_H
|
||||||
|
#define PCH_H
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
|
// Windows Header Files
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#endif //PCH_H
|
13
src/modules/previewpane/QoiPreviewHandlerCpp/resource.h
Normal file
13
src/modules/previewpane/QoiPreviewHandlerCpp/resource.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by AlwaysOnTopModuleInterface.rc
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Non-localizable
|
||||||
|
|
||||||
|
#define FILE_DESCRIPTION "PowerToys Qoi Preview Handler Module"
|
||||||
|
#define INTERNAL_NAME "PowerToys.QoiPreviewHandlerCpp"
|
||||||
|
#define ORIGINAL_FILENAME "PowerToys.QoiPreviewHandlerCpp.dll"
|
||||||
|
|
||||||
|
// Non-localizable
|
||||||
|
//////////////////////////////
|
42
src/modules/previewpane/QoiThumbnailProvider/Program.cs
Normal file
42
src/modules/previewpane/QoiThumbnailProvider/Program.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.ThumbnailHandler.Qoi
|
||||||
|
{
|
||||||
|
internal static class Program
|
||||||
|
{
|
||||||
|
private static QoiThumbnailProvider _thumbnailProvider;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The main entry point for the application.
|
||||||
|
/// </summary>
|
||||||
|
[STAThread]
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
ApplicationConfiguration.Initialize();
|
||||||
|
if (args != null)
|
||||||
|
{
|
||||||
|
if (args.Length == 2)
|
||||||
|
{
|
||||||
|
string filePath = args[0];
|
||||||
|
uint cx = Convert.ToUInt32(args[1], 10);
|
||||||
|
|
||||||
|
_thumbnailProvider = new QoiThumbnailProvider(filePath);
|
||||||
|
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
||||||
|
if (thumbnail != null)
|
||||||
|
{
|
||||||
|
filePath = filePath.Replace(".qoi", ".bmp");
|
||||||
|
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MessageBox.Show("Qoi thumbnail - wrong number of args: " + args.Length.ToString(CultureInfo.InvariantCulture));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,139 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using PreviewHandlerCommon.Utilities;
|
||||||
|
|
||||||
|
namespace Microsoft.PowerToys.ThumbnailHandler.Qoi
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Qoi Thumbnail Provider.
|
||||||
|
/// </summary>
|
||||||
|
public class QoiThumbnailProvider
|
||||||
|
{
|
||||||
|
public QoiThumbnailProvider(string filePath)
|
||||||
|
{
|
||||||
|
FilePath = filePath;
|
||||||
|
Stream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the file path to the file creating thumbnail for.
|
||||||
|
/// </summary>
|
||||||
|
public string FilePath { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the stream object to access file.
|
||||||
|
/// </summary>
|
||||||
|
public Stream Stream { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maximum dimension (width or height) thumbnail we will generate.
|
||||||
|
/// </summary>
|
||||||
|
private const uint MaxThumbnailSize = 10000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate thumbnail bitmap for provided Qoi stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">The Stream instance for the Qoi bitmap.</param>
|
||||||
|
/// <param name="cx">The maximum thumbnail size, in pixels.</param>
|
||||||
|
/// <returns>A thumbnail rendered from the Qoi bitmap.</returns>
|
||||||
|
public static Bitmap GetThumbnail(Stream stream, uint cx)
|
||||||
|
{
|
||||||
|
if (cx > MaxThumbnailSize || stream == null || stream.Length == 0)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap thumbnail = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
thumbnail = QoiImage.FromStream(stream);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// TODO: add logger
|
||||||
|
}
|
||||||
|
|
||||||
|
if (thumbnail != null && (
|
||||||
|
((thumbnail.Width != cx || thumbnail.Height > cx) && (thumbnail.Height != cx || thumbnail.Width > cx)) ||
|
||||||
|
thumbnail.PixelFormat != PixelFormat.Format32bppArgb))
|
||||||
|
{
|
||||||
|
// We are not the appropriate size for caller. Resize now while
|
||||||
|
// respecting the aspect ratio.
|
||||||
|
float scale = Math.Min((float)cx / thumbnail.Width, (float)cx / thumbnail.Height);
|
||||||
|
int scaleWidth = (int)(thumbnail.Width * scale);
|
||||||
|
int scaleHeight = (int)(thumbnail.Height * scale);
|
||||||
|
thumbnail = ResizeImage(thumbnail, scaleWidth, scaleHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
return thumbnail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Resize the image with high quality to the specified width and height.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The image to resize.</param>
|
||||||
|
/// <param name="width">The width to resize to.</param>
|
||||||
|
/// <param name="height">The height to resize to.</param>
|
||||||
|
/// <returns>The resized image.</returns>
|
||||||
|
public static Bitmap ResizeImage(Image image, int width, int height)
|
||||||
|
{
|
||||||
|
if (width <= 0 ||
|
||||||
|
height <= 0 ||
|
||||||
|
width > MaxThumbnailSize ||
|
||||||
|
height > MaxThumbnailSize ||
|
||||||
|
image == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap destImage = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||||
|
|
||||||
|
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
|
||||||
|
|
||||||
|
using (var graphics = Graphics.FromImage(destImage))
|
||||||
|
{
|
||||||
|
graphics.CompositingMode = CompositingMode.SourceCopy;
|
||||||
|
graphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
graphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||||
|
|
||||||
|
graphics.DrawImage(image, 0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
image.Dispose();
|
||||||
|
|
||||||
|
return destImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Generate thumbnail bitmap for provided Qoi file/stream.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cx">Maximum thumbnail size, in pixels.</param>
|
||||||
|
/// <returns>Generated bitmap</returns>
|
||||||
|
public Bitmap GetThumbnail(uint cx)
|
||||||
|
{
|
||||||
|
if (cx == 0 || cx > MaxThumbnailSize)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredQoiThumbnailsEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
|
||||||
|
{
|
||||||
|
// GPO is disabling this utility.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap thumbnail = GetThumbnail(this.Stream, cx);
|
||||||
|
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
|
||||||
|
{
|
||||||
|
return thumbnail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
<ProjectGuid>{D949EC7D-48A9-4279-95D5-078E7FD1F048}</ProjectGuid>
|
||||||
|
<RootNamespace>Microsoft.PowerToys.ThumbnailHandler.Qoi</RootNamespace>
|
||||||
|
<AssemblyName>PowerToys.QoiThumbnailProvider</AssemblyName>
|
||||||
|
<AssemblyTitle>PowerToys.QoiThumbnailProvider</AssemblyTitle>
|
||||||
|
<AssemblyDescription>PowerToys QoiPreviewHandler</AssemblyDescription>
|
||||||
|
<TargetFramework>net7.0-windows10.0.20348.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||||
|
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Description>PowerToys QoiPreviewHandler</Description>
|
||||||
|
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)</OutputPath>
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
|
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||||
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
<SelfContained>true</SelfContained>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
|
||||||
|
<PropertyGroup Condition="'$(Platform)'=='x64'">
|
||||||
|
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
|
||||||
|
<RuntimeIdentifier>win10-arm64</RuntimeIdentifier>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="..\..\..\Version.props" />
|
||||||
|
|
||||||
|
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||||
|
<PropertyGroup>
|
||||||
|
<CsWinRTIncludes>PowerToys.GPOWrapper</CsWinRTIncludes>
|
||||||
|
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||||
|
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<!-- Disable missing comment warning. WinRT/C++ libraries added won't have comments on their reflections. -->
|
||||||
|
<NoWarn>$(NoWarn);1591</NoWarn>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Windows.CsWinRT" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||||
|
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||||
|
<ProjectReference Include="..\Common\PreviewHandlerCommon.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -0,0 +1,84 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "ClassFactory.h"
|
||||||
|
#include "QoiThumbnailProvider.h"
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
|
||||||
|
extern long g_cDllRef;
|
||||||
|
|
||||||
|
ClassFactory::ClassFactory() :
|
||||||
|
m_cRef(1)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
ClassFactory::~ClassFactory()
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// IUnknown
|
||||||
|
//
|
||||||
|
|
||||||
|
IFACEMETHODIMP ClassFactory::QueryInterface(REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
static const QITAB qit[] = {
|
||||||
|
QITABENT(ClassFactory, IClassFactory),
|
||||||
|
{ 0 },
|
||||||
|
};
|
||||||
|
return QISearch(this, qit, riid, ppv);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(ULONG) ClassFactory::AddRef()
|
||||||
|
{
|
||||||
|
return InterlockedIncrement(&m_cRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(ULONG) ClassFactory::Release()
|
||||||
|
{
|
||||||
|
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||||
|
if (0 == cRef)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
return cRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// IClassFactory
|
||||||
|
//
|
||||||
|
|
||||||
|
IFACEMETHODIMP ClassFactory::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppv)
|
||||||
|
{
|
||||||
|
HRESULT hr = CLASS_E_NOAGGREGATION;
|
||||||
|
|
||||||
|
if (pUnkOuter == NULL)
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
QoiThumbnailProvider* pExt = new (std::nothrow) QoiThumbnailProvider();
|
||||||
|
if (pExt)
|
||||||
|
{
|
||||||
|
hr = pExt->QueryInterface(riid, ppv);
|
||||||
|
pExt->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP ClassFactory::LockServer(BOOL fLock)
|
||||||
|
{
|
||||||
|
if (fLock)
|
||||||
|
{
|
||||||
|
InterlockedIncrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Unknwn.h>
|
||||||
|
|
||||||
|
class ClassFactory : public IClassFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// IUnknown
|
||||||
|
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
|
||||||
|
IFACEMETHODIMP_(ULONG) AddRef();
|
||||||
|
IFACEMETHODIMP_(ULONG) Release();
|
||||||
|
|
||||||
|
// IClassFactory
|
||||||
|
IFACEMETHODIMP CreateInstance(IUnknown* pUnkOuter, REFIID riid, void** ppv);
|
||||||
|
IFACEMETHODIMP LockServer(BOOL fLock);
|
||||||
|
|
||||||
|
ClassFactory();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
~ClassFactory();
|
||||||
|
|
||||||
|
private:
|
||||||
|
long m_cRef;
|
||||||
|
};
|
@ -0,0 +1,3 @@
|
|||||||
|
EXPORTS
|
||||||
|
DllGetClassObject PRIVATE
|
||||||
|
DllCanUnloadNow PRIVATE
|
@ -0,0 +1,195 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "QoiThumbnailProvider.h"
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <shellapi.h>
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <wil/com.h>
|
||||||
|
|
||||||
|
#include <common/utils/process_path.h>
|
||||||
|
#include <common/interop/shared_constants.h>
|
||||||
|
#include <common/logger/logger.h>
|
||||||
|
#include <common/SettingsAPI/settings_helpers.h>
|
||||||
|
#include <common/utils/process_path.h>
|
||||||
|
|
||||||
|
extern HINSTANCE g_hInst;
|
||||||
|
extern long g_cDllRef;
|
||||||
|
|
||||||
|
QoiThumbnailProvider::QoiThumbnailProvider() :
|
||||||
|
m_cRef(1), m_pStream(NULL), m_process(NULL)
|
||||||
|
{
|
||||||
|
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
|
||||||
|
logFilePath.append(LogSettings::qoiThumbLogPath);
|
||||||
|
Logger::init(LogSettings::qoiThumbLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||||
|
|
||||||
|
InterlockedIncrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
QoiThumbnailProvider::~QoiThumbnailProvider()
|
||||||
|
{
|
||||||
|
InterlockedDecrement(&g_cDllRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma region IUnknown
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiThumbnailProvider::QueryInterface(REFIID riid, void** ppv)
|
||||||
|
{
|
||||||
|
static const QITAB qit[] = {
|
||||||
|
QITABENT(QoiThumbnailProvider, IThumbnailProvider),
|
||||||
|
QITABENT(QoiThumbnailProvider, IInitializeWithStream),
|
||||||
|
{ 0 },
|
||||||
|
};
|
||||||
|
return QISearch(this, qit, riid, ppv);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(ULONG)
|
||||||
|
QoiThumbnailProvider::AddRef()
|
||||||
|
{
|
||||||
|
return InterlockedIncrement(&m_cRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
IFACEMETHODIMP_(ULONG)
|
||||||
|
QoiThumbnailProvider::Release()
|
||||||
|
{
|
||||||
|
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||||
|
if (0 == cRef)
|
||||||
|
{
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
return cRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region IInitializationWithStream
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiThumbnailProvider::Initialize(IStream* pStream, DWORD grfMode)
|
||||||
|
{
|
||||||
|
HRESULT hr = E_INVALIDARG;
|
||||||
|
if (pStream)
|
||||||
|
{
|
||||||
|
// Initialize can be called more than once, so release existing valid
|
||||||
|
// m_pStream.
|
||||||
|
if (m_pStream)
|
||||||
|
{
|
||||||
|
m_pStream->Release();
|
||||||
|
m_pStream = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pStream = pStream;
|
||||||
|
m_pStream->AddRef();
|
||||||
|
hr = S_OK;
|
||||||
|
}
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region IThumbnailProvider
|
||||||
|
|
||||||
|
IFACEMETHODIMP QoiThumbnailProvider::GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha)
|
||||||
|
{
|
||||||
|
// Read stream into the buffer
|
||||||
|
char buffer[4096];
|
||||||
|
ULONG cbRead;
|
||||||
|
|
||||||
|
Logger::trace(L"Begin");
|
||||||
|
|
||||||
|
GUID guid;
|
||||||
|
if (CoCreateGuid(&guid) == S_OK)
|
||||||
|
{
|
||||||
|
wil::unique_cotaskmem_string guidString;
|
||||||
|
if (SUCCEEDED(StringFromCLSID(guid, &guidString)))
|
||||||
|
{
|
||||||
|
Logger::info(L"Read stream and save to tmp file.");
|
||||||
|
|
||||||
|
// {CLSID} -> CLSID
|
||||||
|
std::wstring guid = std::wstring(guidString.get()).substr(1, std::wstring(guidString.get()).size() - 2);
|
||||||
|
std::wstring filePath = PTSettingsHelper::get_local_low_folder_location() + L"\\QoiThumbnail-Temp\\";
|
||||||
|
if (!std::filesystem::exists(filePath))
|
||||||
|
{
|
||||||
|
std::filesystem::create_directories(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring fileName = filePath + guid + L".qoi";
|
||||||
|
|
||||||
|
// Write data to tmp file
|
||||||
|
std::fstream file;
|
||||||
|
file.open(fileName, std::ios_base::out | std::ios_base::binary);
|
||||||
|
|
||||||
|
if (!file.is_open())
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
auto result = m_pStream->Read(buffer, 4096, &cbRead);
|
||||||
|
|
||||||
|
file.write(buffer, cbRead);
|
||||||
|
if (result == S_FALSE)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
m_pStream->Release();
|
||||||
|
m_pStream = NULL;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Logger::info(L"Start QoiThumbnailProvider.exe");
|
||||||
|
|
||||||
|
STARTUPINFO info = { sizeof(info) };
|
||||||
|
std::wstring cmdLine{ L"\"" + fileName + L"\"" };
|
||||||
|
cmdLine += L" ";
|
||||||
|
cmdLine += std::to_wstring(cx);
|
||||||
|
|
||||||
|
std::wstring appPath = get_module_folderpath(g_hInst) + L"\\PowerToys.QoiThumbnailProvider.exe";
|
||||||
|
|
||||||
|
SHELLEXECUTEINFO sei{ sizeof(sei) };
|
||||||
|
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
||||||
|
sei.lpFile = appPath.c_str();
|
||||||
|
sei.lpParameters = cmdLine.c_str();
|
||||||
|
sei.nShow = SW_SHOWDEFAULT;
|
||||||
|
ShellExecuteEx(&sei);
|
||||||
|
m_process = sei.hProcess;
|
||||||
|
WaitForSingleObject(m_process, INFINITE);
|
||||||
|
std::filesystem::remove(fileName);
|
||||||
|
|
||||||
|
|
||||||
|
std::wstring fileNameBmp = filePath + guid + L".bmp";
|
||||||
|
if (std::filesystem::exists(fileNameBmp))
|
||||||
|
{
|
||||||
|
*phbmp = static_cast<HBITMAP>(LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE));
|
||||||
|
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
||||||
|
std::filesystem::remove(fileNameBmp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger::info(L"Bmp file not generated.");
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::wstring errorMessage = std::wstring{ winrt::to_hstring(e.what()) };
|
||||||
|
Logger::error(L"Failed to start QoiThumbnailProvider.exe. Error: {}", errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region Helper Functions
|
||||||
|
|
||||||
|
#pragma endregion
|
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
#include <ShlObj.h>
|
||||||
|
#include <string>
|
||||||
|
#include <thumbcache.h>
|
||||||
|
|
||||||
|
class QoiThumbnailProvider :
|
||||||
|
public IInitializeWithStream,
|
||||||
|
public IThumbnailProvider
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// IUnknown
|
||||||
|
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv);
|
||||||
|
IFACEMETHODIMP_(ULONG) AddRef();
|
||||||
|
IFACEMETHODIMP_(ULONG) Release();
|
||||||
|
|
||||||
|
// IInitializeWithStream
|
||||||
|
IFACEMETHODIMP Initialize(IStream* pstream, DWORD grfMode);
|
||||||
|
|
||||||
|
// IThumbnailProvider
|
||||||
|
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
||||||
|
|
||||||
|
QoiThumbnailProvider();
|
||||||
|
protected:
|
||||||
|
~QoiThumbnailProvider();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Reference count of component.
|
||||||
|
long m_cRef;
|
||||||
|
|
||||||
|
// Provided during initialization.
|
||||||
|
IStream* m_pStream;
|
||||||
|
|
||||||
|
HANDLE m_process;
|
||||||
|
};
|
@ -0,0 +1,40 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
#include "resource.h"
|
||||||
|
#include "../../../common/version/version.h"
|
||||||
|
|
||||||
|
#define APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#include "winres.h"
|
||||||
|
#undef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
|
||||||
|
1 VERSIONINFO
|
||||||
|
FILEVERSION FILE_VERSION
|
||||||
|
PRODUCTVERSION PRODUCT_VERSION
|
||||||
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FILEFLAGS VS_FF_DEBUG
|
||||||
|
#else
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
#endif
|
||||||
|
FILEOS VOS_NT_WINDOWS32
|
||||||
|
FILETYPE VFT_DLL
|
||||||
|
FILESUBTYPE VFT2_UNKNOWN
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", COMPANY_NAME
|
||||||
|
VALUE "FileDescription", FILE_DESCRIPTION
|
||||||
|
VALUE "FileVersion", FILE_VERSION_STRING
|
||||||
|
VALUE "InternalName", INTERNAL_NAME
|
||||||
|
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
||||||
|
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
||||||
|
VALUE "ProductName", PRODUCT_NAME
|
||||||
|
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
||||||
|
END
|
||||||
|
END
|
@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<ProjectGuid>{CCB5E44F-84D9-4203-83C6-1C9EC9302BC7}</ProjectGuid>
|
||||||
|
<RootNamespace>QoiThumbnailProviderCpp</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutDir>..\..\..\..\$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetName>PowerToys.$(ProjectName)</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
|
||||||
|
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;MARKDOWNPREVIEWHANDLERCPP_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||||
|
<AdditionalIncludeDirectories>../../..</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<EnableUAC>false</EnableUAC>
|
||||||
|
<ModuleDefinitionFile>GlobalExportFunctions.def</ModuleDefinitionFile>
|
||||||
|
<AdditionalDependencies>Shlwapi.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="ClassFactory.h" />
|
||||||
|
<ClInclude Include="QoiThumbnailProvider.h" />
|
||||||
|
<ClInclude Include="pch.h" />
|
||||||
|
<ClInclude Include="resource.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="ClassFactory.cpp" />
|
||||||
|
<ClCompile Include="dllmain.cpp" />
|
||||||
|
<ClCompile Include="QoiThumbnailProvider.cpp" />
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="GlobalExportFunctions.def" />
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
|
||||||
|
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
|
||||||
|
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="QoiThumbnailProviderCpp.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||||
|
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
||||||
|
</ImportGroup>
|
||||||
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
|
<PropertyGroup>
|
||||||
|
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||||
|
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.221104.6\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||||
|
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.220914.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
||||||
|
</Target>
|
||||||
|
</Project>
|
@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="pch.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ClassFactory.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="QoiThumbnailProvider.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="resource.h">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="dllmain.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="pch.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ClassFactory.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="QoiThumbnailProvider.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="GlobalExportFunctions.def">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="QoiThumbnailProviderCpp.rc">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
73
src/modules/previewpane/QoiThumbnailProviderCpp/dllmain.cpp
Normal file
73
src/modules/previewpane/QoiThumbnailProviderCpp/dllmain.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||||
|
#include "pch.h"
|
||||||
|
#include "ClassFactory.h"
|
||||||
|
|
||||||
|
HINSTANCE g_hInst = NULL;
|
||||||
|
long g_cDllRef = 0;
|
||||||
|
|
||||||
|
// {AD856B15-D25E-4008-AFB7-AFAA55586188}
|
||||||
|
static const GUID CLSID_QoiThumbnailProvider = { 0xad856b15, 0xd25e, 0x4008, { 0xaf, 0xb7, 0xaf, 0xaa, 0x55, 0x58, 0x61, 0x88 } };
|
||||||
|
|
||||||
|
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||||
|
DWORD ul_reason_for_call,
|
||||||
|
LPVOID lpReserved)
|
||||||
|
{
|
||||||
|
switch (ul_reason_for_call)
|
||||||
|
{
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
g_hInst = hModule;
|
||||||
|
DisableThreadLibraryCalls(hModule);
|
||||||
|
break;
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FUNCTION: DllGetClassObject
|
||||||
|
//
|
||||||
|
// PURPOSE: Create the class factory and query to the specific interface.
|
||||||
|
//
|
||||||
|
// PARAMETERS:
|
||||||
|
// * rclsid - The CLSID that will associate the correct data and code.
|
||||||
|
// * riid - A reference to the identifier of the interface that the caller
|
||||||
|
// is to use to communicate with the class object.
|
||||||
|
// * ppv - The address of a pointer variable that receives the interface
|
||||||
|
// pointer requested in riid. Upon successful return, *ppv contains the
|
||||||
|
// requested interface pointer. If an error occurs, the interface pointer
|
||||||
|
// is NULL.
|
||||||
|
//
|
||||||
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void** ppv)
|
||||||
|
{
|
||||||
|
HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
|
||||||
|
|
||||||
|
if (IsEqualCLSID(CLSID_QoiThumbnailProvider, rclsid))
|
||||||
|
{
|
||||||
|
hr = E_OUTOFMEMORY;
|
||||||
|
|
||||||
|
ClassFactory* pClassFactory = new ClassFactory();
|
||||||
|
if (pClassFactory)
|
||||||
|
{
|
||||||
|
hr = pClassFactory->QueryInterface(riid, ppv);
|
||||||
|
pClassFactory->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// FUNCTION: DllCanUnloadNow
|
||||||
|
//
|
||||||
|
// PURPOSE: Check if we can unload the component from the memory.
|
||||||
|
//
|
||||||
|
// NOTE: The component can be unloaded from the memory when its reference
|
||||||
|
// count is zero (i.e. nobody is still using the component).
|
||||||
|
//
|
||||||
|
STDAPI DllCanUnloadNow(void)
|
||||||
|
{
|
||||||
|
return g_cDllRef > 0 ? S_FALSE : S_OK;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Microsoft.Windows.CppWinRT" version="2.0.221104.6" targetFramework="native" />
|
||||||
|
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220914.1" targetFramework="native" />
|
||||||
|
</packages>
|
5
src/modules/previewpane/QoiThumbnailProviderCpp/pch.cpp
Normal file
5
src/modules/previewpane/QoiThumbnailProviderCpp/pch.cpp
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
// pch.cpp: source file corresponding to the pre-compiled header
|
||||||
|
|
||||||
|
#include "pch.h"
|
||||||
|
|
||||||
|
// When you are using pre-compiled headers, this source file is necessary for compilation to succeed.
|
15
src/modules/previewpane/QoiThumbnailProviderCpp/pch.h
Normal file
15
src/modules/previewpane/QoiThumbnailProviderCpp/pch.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// pch.h: This is a precompiled header file.
|
||||||
|
// Files listed below are compiled only once, improving build performance for future builds.
|
||||||
|
// This also affects IntelliSense performance, including code completion and many code browsing features.
|
||||||
|
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
|
||||||
|
// Do not add files here that you will be updating frequently as this negates the performance advantage.
|
||||||
|
|
||||||
|
#ifndef PCH_H
|
||||||
|
#define PCH_H
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
|
// Windows Header Files
|
||||||
|
#include <windows.h>
|
||||||
|
#include <winrt/base.h>
|
||||||
|
|
||||||
|
#endif //PCH_H
|
13
src/modules/previewpane/QoiThumbnailProviderCpp/resource.h
Normal file
13
src/modules/previewpane/QoiThumbnailProviderCpp/resource.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//{{NO_DEPENDENCIES}}
|
||||||
|
// Microsoft Visual C++ generated include file.
|
||||||
|
// Used by AlwaysOnTopModuleInterface.rc
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
// Non-localizable
|
||||||
|
|
||||||
|
#define FILE_DESCRIPTION "PowerToys Qoi Thumbnail Provider Module"
|
||||||
|
#define INTERNAL_NAME "PowerToys.QoiThumbnailProviderCpp"
|
||||||
|
#define ORIGINAL_FILENAME "PowerToys.QoiThumbnailProviderCpp.dll"
|
||||||
|
|
||||||
|
// Non-localizable
|
||||||
|
//////////////////////////////
|
Binary file not shown.
@ -0,0 +1,92 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Microsoft.PowerToys.PreviewHandler.Qoi;
|
||||||
|
using Microsoft.PowerToys.STATestExtension;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Moq;
|
||||||
|
|
||||||
|
namespace QoiPreviewHandlerUnitTests
|
||||||
|
{
|
||||||
|
[STATestClass]
|
||||||
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2201:Do not raise reserved exception types", Justification = "new Exception() is fine in test projects.")]
|
||||||
|
public class QoiPreviewHandlerTest
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void QoiPreviewHandlerControlAddsControlsToFormWhenDoPreviewIsCalled()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
using (var qoiPreviewHandlerControl = new QoiPreviewHandlerControl())
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var file = File.ReadAllBytes("HelperFiles/sample.qoi");
|
||||||
|
|
||||||
|
qoiPreviewHandlerControl.DoPreview<IStream>(GetMockStream(file));
|
||||||
|
|
||||||
|
var flowLayoutPanel = qoiPreviewHandlerControl.Controls[0] as FlowLayoutPanel;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.AreEqual(1, qoiPreviewHandlerControl.Controls.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void QoiPreviewHandlerControlShouldAddValidInfoBarIfQoiPreviewThrows()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
using (var qoiPreviewHandlerControl = new QoiPreviewHandlerControl())
|
||||||
|
{
|
||||||
|
var mockStream = new Mock<IStream>();
|
||||||
|
mockStream
|
||||||
|
.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<IntPtr>()))
|
||||||
|
.Throws(new Exception());
|
||||||
|
|
||||||
|
// Act
|
||||||
|
qoiPreviewHandlerControl.DoPreview(mockStream.Object);
|
||||||
|
var textBox = qoiPreviewHandlerControl.Controls[0] as RichTextBox;
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsFalse(string.IsNullOrWhiteSpace(textBox.Text));
|
||||||
|
Assert.AreEqual(1, qoiPreviewHandlerControl.Controls.Count);
|
||||||
|
Assert.AreEqual(DockStyle.Top, textBox.Dock);
|
||||||
|
Assert.AreEqual(Color.LightYellow, textBox.BackColor);
|
||||||
|
Assert.IsTrue(textBox.Multiline);
|
||||||
|
Assert.IsTrue(textBox.ReadOnly);
|
||||||
|
Assert.AreEqual(RichTextBoxScrollBars.None, textBox.ScrollBars);
|
||||||
|
Assert.AreEqual(BorderStyle.None, textBox.BorderStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IStream GetMockStream(byte[] sourceArray)
|
||||||
|
{
|
||||||
|
var streamMock = new Mock<IStream>();
|
||||||
|
int bytesRead = 0;
|
||||||
|
|
||||||
|
streamMock
|
||||||
|
.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<IntPtr>()))
|
||||||
|
.Callback<byte[], int, IntPtr>((buffer, countToRead, bytesReadPtr) =>
|
||||||
|
{
|
||||||
|
int actualCountToRead = Math.Min(sourceArray.Length - bytesRead, countToRead);
|
||||||
|
if (actualCountToRead > 0)
|
||||||
|
{
|
||||||
|
Array.Copy(sourceArray, bytesRead, buffer, 0, actualCountToRead);
|
||||||
|
Marshal.WriteInt32(bytesReadPtr, actualCountToRead);
|
||||||
|
bytesRead += actualCountToRead;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Marshal.WriteInt32(bytesReadPtr, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return streamMock.Object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblyTitle>UnitTests-QoiPreviewHandler</AssemblyTitle>
|
||||||
|
<AssemblyDescription>PowerToys UnitTests-QoiPreviewHandler</AssemblyDescription>
|
||||||
|
<AssemblyTitle>UnitTests-QoiPreviewHandler</AssemblyTitle>
|
||||||
|
<Description>PowerToys UnitTests-QoiPreviewHandler</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<ProjectGuid>{3940AD4D-F748-4BE4-9083-85769CD553EF}</ProjectGuid>
|
||||||
|
<RootNamespace>PdfPreviewHandlerUnitTests</RootNamespace>
|
||||||
|
<TargetFramework>net7.0-windows10.0.20348.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||||
|
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||||
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||||
|
<IsCodedUITest>False</IsCodedUITest>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="..\..\..\Version.props" />
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="HelperFiles\sample.qoi" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Windows.CsWinRT" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Moq" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\common\PreviewHandlerCommon.csproj" />
|
||||||
|
<ProjectReference Include="..\QoiPreviewHandler\QoiPreviewHandler.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="HelperFiles\sample.qoi">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Compile Include="..\STATestClassAttribute.cs" Link="STATestClassAttribute.cs" />
|
||||||
|
<Compile Include="..\STATestMethodAttribute.cs" Link="STATestMethodAttribute.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
Binary file not shown.
@ -0,0 +1,61 @@
|
|||||||
|
// Copyright (c) Microsoft Corporation
|
||||||
|
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||||
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
using System.Drawing;
|
||||||
|
using Microsoft.PowerToys.STATestExtension;
|
||||||
|
using Microsoft.PowerToys.ThumbnailHandler.Qoi;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
|
||||||
|
namespace QoiThumbnailProviderUnitTests
|
||||||
|
{
|
||||||
|
[STATestClass]
|
||||||
|
public class QoiThumbnailProviderTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void GetThumbnailValidStreamQoi()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var filePath = "HelperFiles/sample.qoi";
|
||||||
|
|
||||||
|
QoiThumbnailProvider provider = new QoiThumbnailProvider(filePath);
|
||||||
|
|
||||||
|
Bitmap bitmap = provider.GetThumbnail(256);
|
||||||
|
|
||||||
|
Assert.IsTrue(bitmap != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetThumbnailInValidSizeQoi()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var filePath = "HelperFiles/sample.qoi";
|
||||||
|
|
||||||
|
QoiThumbnailProvider provider = new QoiThumbnailProvider(filePath);
|
||||||
|
|
||||||
|
Bitmap bitmap = provider.GetThumbnail(0);
|
||||||
|
|
||||||
|
Assert.IsTrue(bitmap == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetThumbnailToBigQoi()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var filePath = "HelperFiles/sample.qoi";
|
||||||
|
|
||||||
|
QoiThumbnailProvider provider = new QoiThumbnailProvider(filePath);
|
||||||
|
|
||||||
|
Bitmap bitmap = provider.GetThumbnail(10001);
|
||||||
|
|
||||||
|
Assert.IsTrue(bitmap == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CheckNoQoiNullStringShouldReturnNullBitmap()
|
||||||
|
{
|
||||||
|
Bitmap thumbnail = QoiThumbnailProvider.GetThumbnail(null, 256);
|
||||||
|
Assert.IsTrue(thumbnail == null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<AssemblyTitle>UnitTests-QoiThumbnailProvider</AssemblyTitle>
|
||||||
|
<AssemblyDescription>PowerToys UnitTests-QoiThumbnailProvider</AssemblyDescription>
|
||||||
|
<AssemblyTitle>UnitTests-QoiThumbnailProvider</AssemblyTitle>
|
||||||
|
<Description>PowerToys UnitTests-QoiThumbnailProvider</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<ProjectGuid>{F8FFFC12-A31A-4AFA-B3DF-14DCF42B5E38}</ProjectGuid>
|
||||||
|
<RootNamespace>QoiThumbnailProviderUnitTests</RootNamespace>
|
||||||
|
<TargetFramework>net7.0-windows10.0.20348.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||||
|
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||||
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||||
|
<IsCodedUITest>False</IsCodedUITest>
|
||||||
|
<TestProjectType>UnitTest</TestProjectType>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="..\..\..\Version.props" />
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="HelperFiles\sample.qoi" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Windows.CsWinRT" />
|
||||||
|
<PackageReference Include="Moq" />
|
||||||
|
<PackageReference Include="MSTest.TestAdapter" />
|
||||||
|
<PackageReference Include="MSTest.TestFramework" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Common\PreviewHandlerCommon.csproj" />
|
||||||
|
<ProjectReference Include="..\QoiThumbnailProvider\QoiThumbnailProvider.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="..\STATestClassAttribute.cs" Link="STATestClassAttribute.cs" />
|
||||||
|
<Compile Include="..\STATestMethodAttribute.cs" Link="STATestMethodAttribute.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="HelperFiles\sample.qoi">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
@ -37,17 +37,27 @@ const CLSID CLSID_SHIMActivateGcodePreviewHandler = { 0x516cb24f, 0x562f, 0x422f
|
|||||||
// ec52dea8-7c9f-4130-a77b-1737d0418507
|
// ec52dea8-7c9f-4130-a77b-1737d0418507
|
||||||
const CLSID CLSID_GcodePreviewHandler = { 0xec52dea8, 0x7c9f, 0x4130, { 0xa7, 0x7b, 0x17, 0x37, 0xd0, 0x41, 0x85, 0x07 } };
|
const CLSID CLSID_GcodePreviewHandler = { 0xec52dea8, 0x7c9f, 0x4130, { 0xa7, 0x7b, 0x17, 0x37, 0xd0, 0x41, 0x85, 0x07 } };
|
||||||
|
|
||||||
|
// F498BE36-5C94-4EC9-A65A-AD1CF4C38271
|
||||||
|
const GUID CLSID_SHIMActivateQoiPreviewHandler = { 0xf498be36, 0x5c94, 0x4ec9, { 0xa6, 0x5a, 0xad, 0x1c, 0xf4, 0xc3, 0x82, 0x71 } };
|
||||||
|
|
||||||
|
// 8AA07897-C30B-4543-865B-00A0E5A1B32D
|
||||||
|
const GUID CLSID_QoiPreviewHandler = { 0x8aa07897, 0xc30b, 0x4543, { 0x86, 0x5b, 0x0, 0xa0, 0xe5, 0xa1, 0xb3, 0x2d } };
|
||||||
|
|
||||||
// BFEE99B4-B74D-4348-BCA5-E757029647FF
|
// BFEE99B4-B74D-4348-BCA5-E757029647FF
|
||||||
const GUID CLSID_GcodeThumbnailProvider = { 0xbfee99b4, 0xb74d, 0x4348, { 0xbc, 0xa5, 0xe7, 0x57, 0x02, 0x96, 0x47, 0xff } };
|
const GUID CLSID_GcodeThumbnailProvider = { 0xbfee99b4, 0xb74d, 0x4348, { 0xbc, 0xa5, 0xe7, 0x57, 0x02, 0x96, 0x47, 0xff } };
|
||||||
|
|
||||||
// 8BC8AFC2-4E7C-4695-818E-8C1FFDCEA2AF
|
// 8BC8AFC2-4E7C-4695-818E-8C1FFDCEA2AF
|
||||||
const GUID CLSID_StlThumbnailProvider = { 0x8bc8afc2, 0x4e7c, 0x4695, { 0x81, 0x8e, 0x8c, 0x1f, 0xfd, 0xce, 0xa2, 0xaf } };
|
const GUID CLSID_StlThumbnailProvider = { 0x8bc8afc2, 0x4e7c, 0x4695, { 0x81, 0x8e, 0x8c, 0x1f, 0xfd, 0xce, 0xa2, 0xaf } };
|
||||||
|
|
||||||
|
// 907B7E38-38ED-42E7-A276-9EF0ECABB003
|
||||||
|
const GUID CLSID_QoiThumbnailProvider = { 0x907b7e38, 0x38ed, 0x42e7, { 0xa2, 0x76, 0x9e, 0xf0, 0xec, 0xab, 0xb0, 0x3 } };
|
||||||
|
|
||||||
// Pairs of NativeClsid vs ManagedClsid used for preview handlers.
|
// Pairs of NativeClsid vs ManagedClsid used for preview handlers.
|
||||||
const std::vector<std::pair<CLSID, CLSID>> NativeToManagedClsid({
|
const std::vector<std::pair<CLSID, CLSID>> NativeToManagedClsid({
|
||||||
{ CLSID_SHIMActivateMdPreviewHandler, CLSID_MdPreviewHandler },
|
{ CLSID_SHIMActivateMdPreviewHandler, CLSID_MdPreviewHandler },
|
||||||
{ CLSID_SHIMActivatePdfPreviewHandler, CLSID_PdfPreviewHandler },
|
{ CLSID_SHIMActivatePdfPreviewHandler, CLSID_PdfPreviewHandler },
|
||||||
{ CLSID_SHIMActivateGcodePreviewHandler, CLSID_GcodePreviewHandler },
|
{ CLSID_SHIMActivateGcodePreviewHandler, CLSID_GcodePreviewHandler },
|
||||||
|
{ CLSID_SHIMActivateQoiPreviewHandler, CLSID_QoiPreviewHandler },
|
||||||
{ CLSID_SHIMActivateSvgPreviewHandler, CLSID_SvgPreviewHandler },
|
{ CLSID_SHIMActivateSvgPreviewHandler, CLSID_SvgPreviewHandler },
|
||||||
{ CLSID_SHIMActivateSvgThumbnailProvider, CLSID_SvgThumbnailProvider }
|
{ CLSID_SHIMActivateSvgThumbnailProvider, CLSID_SvgThumbnailProvider }
|
||||||
});
|
});
|
||||||
|
@ -192,4 +192,10 @@
|
|||||||
<data name="Stl_Thumbnail_Provider_Settings_Description" xml:space="preserve">
|
<data name="Stl_Thumbnail_Provider_Settings_Description" xml:space="preserve">
|
||||||
<value>Stl Thumbnail Provider</value>
|
<value>Stl Thumbnail Provider</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Prevpane_Qoi_Settings_Description" xml:space="preserve">
|
||||||
|
<value>Qoi Previewer</value>
|
||||||
|
</data>
|
||||||
|
<data name="Qoi_Thumbnail_Provider_Settings_Description" xml:space="preserve">
|
||||||
|
<value>Qoi Thumbnail Provider</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -71,6 +71,16 @@ PowerPreviewModule::PowerPreviewModule() :
|
|||||||
.checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredStlThumbnailsEnabledValue,
|
.checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredStlThumbnailsEnabledValue,
|
||||||
.registryChanges = getStlThumbnailHandlerChangeSet(installationDir, installPerUser) });
|
.registryChanges = getStlThumbnailHandlerChangeSet(installationDir, installPerUser) });
|
||||||
|
|
||||||
|
m_fileExplorerModules.push_back({ .settingName = L"qoi-previewer-toggle-setting",
|
||||||
|
.settingDescription = GET_RESOURCE_STRING(IDS_PREVPANE_QOI_SETTINGS_DESCRIPTION),
|
||||||
|
.checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredQoiPreviewEnabledValue,
|
||||||
|
.registryChanges = getQoiPreviewHandlerChangeSet(installationDir, installPerUser) });
|
||||||
|
|
||||||
|
m_fileExplorerModules.push_back({ .settingName = L"qoi-thumbnail-toggle-setting",
|
||||||
|
.settingDescription = GET_RESOURCE_STRING(IDS_QOI_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION),
|
||||||
|
.checkModuleGPOEnabledRuleFunction = powertoys_gpo::getConfiguredQoiThumbnailsEnabledValue,
|
||||||
|
.registryChanges = getQoiThumbnailHandlerChangeSet(installationDir, installPerUser) });
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PowerToysSettings::PowerToyValues settings =
|
PowerToysSettings::PowerToyValues settings =
|
||||||
|
@ -221,6 +221,40 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
|||||||
[JsonPropertyName("stl-thumbnail-color-setting")]
|
[JsonPropertyName("stl-thumbnail-color-setting")]
|
||||||
public StringProperty StlThumbnailColor { get; set; }
|
public StringProperty StlThumbnailColor { get; set; }
|
||||||
|
|
||||||
|
private bool enableQoiPreview = true;
|
||||||
|
|
||||||
|
[JsonPropertyName("qoi-previewer-toggle-setting")]
|
||||||
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||||
|
public bool EnableQoiPreview
|
||||||
|
{
|
||||||
|
get => enableQoiPreview;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != enableQoiPreview)
|
||||||
|
{
|
||||||
|
LogTelemetryEvent(value);
|
||||||
|
enableQoiPreview = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool enableQoiThumbnail = true;
|
||||||
|
|
||||||
|
[JsonPropertyName("qoi-thumbnail-toggle-setting")]
|
||||||
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||||
|
public bool EnableQoiThumbnail
|
||||||
|
{
|
||||||
|
get => enableQoiThumbnail;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != enableQoiThumbnail)
|
||||||
|
{
|
||||||
|
LogTelemetryEvent(value);
|
||||||
|
enableQoiThumbnail = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PowerPreviewProperties()
|
public PowerPreviewProperties()
|
||||||
{
|
{
|
||||||
SvgBackgroundColorMode = new IntProperty(DefaultSvgBackgroundColorMode);
|
SvgBackgroundColorMode = new IntProperty(DefaultSvgBackgroundColorMode);
|
||||||
|
@ -60,11 +60,13 @@ namespace ViewModelTests
|
|||||||
Assert.AreEqual(originalSettings.Properties.EnableMonacoPreview, viewModel.MonacoRenderIsEnabled);
|
Assert.AreEqual(originalSettings.Properties.EnableMonacoPreview, viewModel.MonacoRenderIsEnabled);
|
||||||
Assert.AreEqual(originalSettings.Properties.EnablePdfPreview, viewModel.PDFRenderIsEnabled);
|
Assert.AreEqual(originalSettings.Properties.EnablePdfPreview, viewModel.PDFRenderIsEnabled);
|
||||||
Assert.AreEqual(originalSettings.Properties.EnableGcodePreview, viewModel.GCODERenderIsEnabled);
|
Assert.AreEqual(originalSettings.Properties.EnableGcodePreview, viewModel.GCODERenderIsEnabled);
|
||||||
|
Assert.AreEqual(originalSettings.Properties.EnableQoiPreview, viewModel.QOIRenderIsEnabled);
|
||||||
Assert.AreEqual(originalSettings.Properties.EnableSvgPreview, viewModel.SVGRenderIsEnabled);
|
Assert.AreEqual(originalSettings.Properties.EnableSvgPreview, viewModel.SVGRenderIsEnabled);
|
||||||
Assert.AreEqual(originalSettings.Properties.EnableSvgThumbnail, viewModel.SVGThumbnailIsEnabled);
|
Assert.AreEqual(originalSettings.Properties.EnableSvgThumbnail, viewModel.SVGThumbnailIsEnabled);
|
||||||
Assert.AreEqual(originalSettings.Properties.EnablePdfThumbnail, viewModel.PDFThumbnailIsEnabled);
|
Assert.AreEqual(originalSettings.Properties.EnablePdfThumbnail, viewModel.PDFThumbnailIsEnabled);
|
||||||
Assert.AreEqual(originalSettings.Properties.EnableGcodeThumbnail, viewModel.GCODEThumbnailIsEnabled);
|
Assert.AreEqual(originalSettings.Properties.EnableGcodeThumbnail, viewModel.GCODEThumbnailIsEnabled);
|
||||||
Assert.AreEqual(originalSettings.Properties.EnableStlThumbnail, viewModel.STLThumbnailIsEnabled);
|
Assert.AreEqual(originalSettings.Properties.EnableStlThumbnail, viewModel.STLThumbnailIsEnabled);
|
||||||
|
Assert.AreEqual(originalSettings.Properties.EnableQoiThumbnail, viewModel.QOIThumbnailIsEnabled);
|
||||||
|
|
||||||
// Verify that the stub file was used
|
// Verify that the stub file was used
|
||||||
var expectedCallCount = 2; // once via the view model, and once by the test (GetSettings<T>)
|
var expectedCallCount = 2; // once via the view model, and once by the test (GetSettings<T>)
|
||||||
@ -161,6 +163,24 @@ namespace ViewModelTests
|
|||||||
viewModel.STLThumbnailIsEnabled = true;
|
viewModel.STLThumbnailIsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void QOIThumbnailIsEnabledShouldPrevHandlerWhenSuccessful()
|
||||||
|
{
|
||||||
|
// Assert
|
||||||
|
Func<string, int> sendMockIPCConfigMSG = msg =>
|
||||||
|
{
|
||||||
|
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
|
||||||
|
Assert.IsTrue(snd.PowertoysSetting.FileExplorerPreviewSettings.Properties.EnableQoiThumbnail);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// arrange
|
||||||
|
PowerPreviewViewModel viewModel = new PowerPreviewViewModel(SettingsRepository<PowerPreviewSettings>.GetInstance(mockPowerPreviewSettingsUtils.Object), SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), sendMockIPCConfigMSG, PowerPreviewSettings.ModuleName);
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.QOIThumbnailIsEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MDRenderIsEnabledShouldPrevHandlerWhenSuccessful()
|
public void MDRenderIsEnabledShouldPrevHandlerWhenSuccessful()
|
||||||
{
|
{
|
||||||
@ -232,5 +252,23 @@ namespace ViewModelTests
|
|||||||
// act
|
// act
|
||||||
viewModel.GCODERenderIsEnabled = true;
|
viewModel.GCODERenderIsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void QOIRenderIsEnabledShouldPrevHandlerWhenSuccessful()
|
||||||
|
{
|
||||||
|
// Assert
|
||||||
|
Func<string, int> sendMockIPCConfigMSG = msg =>
|
||||||
|
{
|
||||||
|
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
|
||||||
|
Assert.IsTrue(snd.PowertoysSetting.FileExplorerPreviewSettings.Properties.EnableQoiPreview);
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// arrange
|
||||||
|
PowerPreviewViewModel viewModel = new PowerPreviewViewModel(SettingsRepository<PowerPreviewSettings>.GetInstance(mockPowerPreviewSettingsUtils.Object), SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object), sendMockIPCConfigMSG, PowerPreviewSettings.ModuleName);
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.QOIRenderIsEnabled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,18 @@
|
|||||||
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODERenderEnabledGpoConfigured}"
|
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODERenderEnabledGpoConfigured}"
|
||||||
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODERenderEnabledGpoConfigured}"
|
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsGCODERenderEnabledGpoConfigured}"
|
||||||
Severity="Informational" />
|
Severity="Informational" />
|
||||||
|
<controls:SettingsCard
|
||||||
|
x:Uid="FileExplorerPreview_ToggleSwitch_Preview_QOI"
|
||||||
|
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||||
|
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsQOIRenderEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
|
||||||
|
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.QOIRenderIsEnabled}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<InfoBar
|
||||||
|
x:Uid="GPO_IsSettingForced"
|
||||||
|
IsClosable="False"
|
||||||
|
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsQOIRenderEnabledGpoConfigured}"
|
||||||
|
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsQOIRenderEnabledGpoConfigured}"
|
||||||
|
Severity="Informational" />
|
||||||
</custom:SettingsGroup>
|
</custom:SettingsGroup>
|
||||||
|
|
||||||
<custom:SettingsGroup x:Uid="FileExplorerPreview_IconThumbnail_GroupSettings">
|
<custom:SettingsGroup x:Uid="FileExplorerPreview_IconThumbnail_GroupSettings">
|
||||||
@ -201,6 +213,19 @@
|
|||||||
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsSTLThumbnailEnabledGpoConfigured}"
|
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsSTLThumbnailEnabledGpoConfigured}"
|
||||||
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsSTLThumbnailEnabledGpoConfigured}"
|
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsSTLThumbnailEnabledGpoConfigured}"
|
||||||
Severity="Informational" />
|
Severity="Informational" />
|
||||||
|
|
||||||
|
<controls:SettingsCard
|
||||||
|
x:Uid="FileExplorerPreview_ToggleSwitch_Thumbnail_QOI"
|
||||||
|
HeaderIcon="{ui:FontIcon Glyph=}"
|
||||||
|
IsEnabled="{x:Bind Mode=OneWay, Path=ViewModel.IsQOIThumbnailEnabledGpoConfigured, Converter={StaticResource BoolNegationConverter}}">
|
||||||
|
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind Mode=TwoWay, Path=ViewModel.QOIThumbnailIsEnabled}" />
|
||||||
|
</controls:SettingsCard>
|
||||||
|
<InfoBar
|
||||||
|
x:Uid="GPO_IsSettingForced"
|
||||||
|
IsClosable="False"
|
||||||
|
IsOpen="{x:Bind Mode=OneWay, Path=ViewModel.IsQOIThumbnailEnabledGpoConfigured}"
|
||||||
|
IsTabStop="{x:Bind Mode=OneWay, Path=ViewModel.IsQOIThumbnailEnabledGpoConfigured}"
|
||||||
|
Severity="Informational" />
|
||||||
</custom:SettingsGroup>
|
</custom:SettingsGroup>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</custom:SettingsPageControl.ModuleContent>
|
</custom:SettingsPageControl.ModuleContent>
|
||||||
@ -210,7 +235,7 @@
|
|||||||
</custom:SettingsPageControl.PrimaryLinks>
|
</custom:SettingsPageControl.PrimaryLinks>
|
||||||
<custom:SettingsPageControl.SecondaryLinks>
|
<custom:SettingsPageControl.SecondaryLinks>
|
||||||
<custom:PageLink Link="https://blog.aaron-junker.ch" Text="Aaron Junker's work on developer file preview" />
|
<custom:PageLink Link="https://blog.aaron-junker.ch" Text="Aaron Junker's work on developer file preview" />
|
||||||
<custom:PageLink Link="https://www.pedrolamas.com" Text="Pedro Lamas's work on G-Code and STL" />
|
<custom:PageLink Link="https://www.pedrolamas.com" Text="Pedro Lamas's work on G-Code, STL, and QOI" />
|
||||||
</custom:SettingsPageControl.SecondaryLinks>
|
</custom:SettingsPageControl.SecondaryLinks>
|
||||||
</custom:SettingsPageControl>
|
</custom:SettingsPageControl>
|
||||||
</Page>
|
</Page>
|
||||||
|
@ -1135,6 +1135,21 @@
|
|||||||
<data name="FileExplorerPreview_Color_Thumbnail_STL.Header" xml:space="preserve">
|
<data name="FileExplorerPreview_Color_Thumbnail_STL.Header" xml:space="preserve">
|
||||||
<value>Color</value>
|
<value>Color</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="FileExplorerPreview_ToggleSwitch_Preview_QOI.Header" xml:space="preserve">
|
||||||
|
<value>Quite Ok Image</value>
|
||||||
|
<comment>File type, do not translate</comment>
|
||||||
|
</data>
|
||||||
|
<data name="FileExplorerPreview_ToggleSwitch_Preview_QOI.Description" xml:space="preserve">
|
||||||
|
<value>.qoi</value>
|
||||||
|
</data>
|
||||||
|
<data name="FileExplorerPreview_ToggleSwitch_Thumbnail_QOI.Header" xml:space="preserve">
|
||||||
|
<value>Quite OK Image</value>
|
||||||
|
<comment>File type, do not translate</comment>
|
||||||
|
</data>
|
||||||
|
<data name="FileExplorerPreview_ToggleSwitch_Thumbnail_QOI.Description" xml:space="preserve">
|
||||||
|
<value>.qoi</value>
|
||||||
|
<comment>File extension, should not be altered</comment>
|
||||||
|
</data>
|
||||||
<data name="FileExplorerPreview_ToggleSwitch_Thumbnail_PDF.Header" xml:space="preserve">
|
<data name="FileExplorerPreview_ToggleSwitch_Thumbnail_PDF.Header" xml:space="preserve">
|
||||||
<value>Portable Document Format</value>
|
<value>Portable Document Format</value>
|
||||||
<comment>File type, do not translate</comment>
|
<comment>File type, do not translate</comment>
|
||||||
|
@ -129,6 +129,18 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
_gcodeRenderIsEnabled = Settings.Properties.EnableGcodePreview;
|
_gcodeRenderIsEnabled = Settings.Properties.EnableGcodePreview;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_qoiRenderEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredQoiPreviewEnabledValue();
|
||||||
|
if (_qoiRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _qoiRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
||||||
|
{
|
||||||
|
// Get the enabled state from GPO.
|
||||||
|
_qoiRenderEnabledStateIsGPOConfigured = true;
|
||||||
|
_qoiRenderIsEnabled = _qoiRenderEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_qoiRenderIsEnabled = Settings.Properties.EnableQoiPreview;
|
||||||
|
}
|
||||||
|
|
||||||
_pdfThumbnailEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredPdfThumbnailsEnabledValue();
|
_pdfThumbnailEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredPdfThumbnailsEnabledValue();
|
||||||
if (_pdfThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _pdfThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
if (_pdfThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _pdfThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
||||||
{
|
{
|
||||||
@ -166,6 +178,18 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
}
|
}
|
||||||
|
|
||||||
_stlThumbnailColor = Settings.Properties.StlThumbnailColor.Value;
|
_stlThumbnailColor = Settings.Properties.StlThumbnailColor.Value;
|
||||||
|
|
||||||
|
_qoiThumbnailEnabledGpoRuleConfiguration = GPOWrapper.GetConfiguredQoiThumbnailsEnabledValue();
|
||||||
|
if (_qoiThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _qoiThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
|
||||||
|
{
|
||||||
|
// Get the enabled state from GPO.
|
||||||
|
_qoiThumbnailEnabledStateIsGPOConfigured = true;
|
||||||
|
_qoiThumbnailIsEnabled = _qoiThumbnailEnabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_qoiThumbnailIsEnabled = Settings.Properties.EnableQoiThumbnail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private GpoRuleConfigured _svgRenderEnabledGpoRuleConfiguration;
|
private GpoRuleConfigured _svgRenderEnabledGpoRuleConfiguration;
|
||||||
@ -194,6 +218,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
private bool _gcodeRenderEnabledStateIsGPOConfigured;
|
private bool _gcodeRenderEnabledStateIsGPOConfigured;
|
||||||
private bool _gcodeRenderIsEnabled;
|
private bool _gcodeRenderIsEnabled;
|
||||||
|
|
||||||
|
private GpoRuleConfigured _qoiRenderEnabledGpoRuleConfiguration;
|
||||||
|
private bool _qoiRenderEnabledStateIsGPOConfigured;
|
||||||
|
private bool _qoiRenderIsEnabled;
|
||||||
|
|
||||||
private GpoRuleConfigured _svgThumbnailEnabledGpoRuleConfiguration;
|
private GpoRuleConfigured _svgThumbnailEnabledGpoRuleConfiguration;
|
||||||
private bool _svgThumbnailEnabledStateIsGPOConfigured;
|
private bool _svgThumbnailEnabledStateIsGPOConfigured;
|
||||||
private bool _svgThumbnailIsEnabled;
|
private bool _svgThumbnailIsEnabled;
|
||||||
@ -211,6 +239,10 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
private bool _stlThumbnailIsEnabled;
|
private bool _stlThumbnailIsEnabled;
|
||||||
private string _stlThumbnailColor;
|
private string _stlThumbnailColor;
|
||||||
|
|
||||||
|
private GpoRuleConfigured _qoiThumbnailEnabledGpoRuleConfiguration;
|
||||||
|
private bool _qoiThumbnailEnabledStateIsGPOConfigured;
|
||||||
|
private bool _qoiThumbnailIsEnabled;
|
||||||
|
|
||||||
public bool SVGRenderIsEnabled
|
public bool SVGRenderIsEnabled
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -616,6 +648,64 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool QOIRenderIsEnabled
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _qoiRenderIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_qoiRenderEnabledStateIsGPOConfigured)
|
||||||
|
{
|
||||||
|
// If it's GPO configured, shouldn't be able to change this state.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != _qoiRenderIsEnabled)
|
||||||
|
{
|
||||||
|
_qoiRenderIsEnabled = value;
|
||||||
|
Settings.Properties.EnableQoiPreview = value;
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsQOIRenderEnabledGpoConfigured
|
||||||
|
{
|
||||||
|
get => _qoiRenderEnabledStateIsGPOConfigured;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool QOIThumbnailIsEnabled
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _qoiThumbnailIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_qoiThumbnailEnabledStateIsGPOConfigured)
|
||||||
|
{
|
||||||
|
// If it's GPO configured, shouldn't be able to change this state.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value != _qoiThumbnailIsEnabled)
|
||||||
|
{
|
||||||
|
_qoiThumbnailIsEnabled = value;
|
||||||
|
Settings.Properties.EnableQoiThumbnail = value;
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsQOIThumbnailEnabledGpoConfigured
|
||||||
|
{
|
||||||
|
get => _qoiThumbnailEnabledStateIsGPOConfigured;
|
||||||
|
}
|
||||||
|
|
||||||
public string GetSettingsSubPath()
|
public string GetSettingsSubPath()
|
||||||
{
|
{
|
||||||
return _settingsConfigFileFolder + "\\" + ModuleName;
|
return _settingsConfigFileFolder + "\\" + ModuleName;
|
||||||
|
@ -30,6 +30,8 @@ std::vector<std::wstring> processes =
|
|||||||
L"PowerToys.MonacoPreviewHandler.exe",
|
L"PowerToys.MonacoPreviewHandler.exe",
|
||||||
L"PowerToys.PdfPreviewHandler.exe",
|
L"PowerToys.PdfPreviewHandler.exe",
|
||||||
L"PowerToys.PdfThumbnailProvider.exe",
|
L"PowerToys.PdfThumbnailProvider.exe",
|
||||||
|
L"PowerToys.QoiPreviewHandler.exe",
|
||||||
|
L"PowerToys.QoiThumbnailProvider.exe",
|
||||||
L"PowerToys.StlThumbnailProvider.exe",
|
L"PowerToys.StlThumbnailProvider.exe",
|
||||||
L"PowerToys.SvgPreviewHandler.exe",
|
L"PowerToys.SvgPreviewHandler.exe",
|
||||||
L"PowerToys.SvgThumbnailProvider.exe",
|
L"PowerToys.SvgThumbnailProvider.exe",
|
||||||
|
@ -17,6 +17,7 @@ namespace
|
|||||||
{ HKEY_CLASSES_ROOT, L"AppID\\{CF142243-F059-45AF-8842-DBBE9783DB14}" },
|
{ HKEY_CLASSES_ROOT, L"AppID\\{CF142243-F059-45AF-8842-DBBE9783DB14}" },
|
||||||
{ HKEY_CLASSES_ROOT, L"CLSID\\{07665729-6243-4746-95b7-79579308d1b2}" },
|
{ HKEY_CLASSES_ROOT, L"CLSID\\{07665729-6243-4746-95b7-79579308d1b2}" },
|
||||||
{ HKEY_CLASSES_ROOT, L"CLSID\\{ec52dea8-7c9f-4130-a77b-1737d0418507}" },
|
{ HKEY_CLASSES_ROOT, L"CLSID\\{ec52dea8-7c9f-4130-a77b-1737d0418507}" },
|
||||||
|
{ HKEY_CLASSES_ROOT, L"CLSID\\{8AA07897-C30B-4543-865B-00A0E5A1B32D}" },
|
||||||
{ HKEY_CLASSES_ROOT, L"CLSID\\{BCC13D15-9720-4CC4-8371-EA74A274741E}" },
|
{ HKEY_CLASSES_ROOT, L"CLSID\\{BCC13D15-9720-4CC4-8371-EA74A274741E}" },
|
||||||
{ HKEY_CLASSES_ROOT, L"CLSID\\{BFEE99B4-B74D-4348-BCA5-E757029647FF}" },
|
{ HKEY_CLASSES_ROOT, L"CLSID\\{BFEE99B4-B74D-4348-BCA5-E757029647FF}" },
|
||||||
{ HKEY_CLASSES_ROOT, L"CLSID\\{8BC8AFC2-4E7C-4695-818E-8C1FFDCEA2AF}" },
|
{ HKEY_CLASSES_ROOT, L"CLSID\\{8BC8AFC2-4E7C-4695-818E-8C1FFDCEA2AF}" },
|
||||||
@ -28,6 +29,8 @@ namespace
|
|||||||
{ HKEY_CLASSES_ROOT, L".md\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
{ HKEY_CLASSES_ROOT, L".md\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
||||||
{ HKEY_CLASSES_ROOT, L".pdf\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
{ HKEY_CLASSES_ROOT, L".pdf\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
||||||
{ HKEY_CLASSES_ROOT, L".pdf\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" },
|
{ HKEY_CLASSES_ROOT, L".pdf\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" },
|
||||||
|
{ HKEY_CLASSES_ROOT, L".qoi\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
||||||
|
{ HKEY_CLASSES_ROOT, L".qoi\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" },
|
||||||
{ HKEY_CLASSES_ROOT, L".gcode\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
{ HKEY_CLASSES_ROOT, L".gcode\\shellex\\{8895b1c6-b41f-4c1c-a562-0d564250836f}" },
|
||||||
{ HKEY_CLASSES_ROOT, L".gcode\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" },
|
{ HKEY_CLASSES_ROOT, L".gcode\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" },
|
||||||
{ HKEY_CLASSES_ROOT, L".stl\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" }
|
{ HKEY_CLASSES_ROOT, L".stl\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}" }
|
||||||
@ -38,6 +41,7 @@ namespace
|
|||||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}" },
|
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}" },
|
||||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{07665729-6243-4746-95b7-79579308d1b2}" },
|
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{07665729-6243-4746-95b7-79579308d1b2}" },
|
||||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{ec52dea8-7c9f-4130-a77b-1737d0418507}" },
|
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{ec52dea8-7c9f-4130-a77b-1737d0418507}" },
|
||||||
|
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers", L"{8AA07897-C30B-4543-865B-00A0E5A1B32D}" },
|
||||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", L"prevhost.exe" },
|
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", L"prevhost.exe" },
|
||||||
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", L"dllhost.exe" }
|
{ HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", L"dllhost.exe" }
|
||||||
};
|
};
|
||||||
|
@ -64,5 +64,7 @@ void ReportGPOValues(const std::filesystem::path& tmpDir)
|
|||||||
report << "getSuspendNewUpdateToastValue: " << gpo_rule_configured_to_string(powertoys_gpo::getSuspendNewUpdateToastValue()) << std::endl;
|
report << "getSuspendNewUpdateToastValue: " << gpo_rule_configured_to_string(powertoys_gpo::getSuspendNewUpdateToastValue()) << std::endl;
|
||||||
report << "getDisablePeriodicUpdateCheckValue: " << gpo_rule_configured_to_string(powertoys_gpo::getDisablePeriodicUpdateCheckValue()) << std::endl;
|
report << "getDisablePeriodicUpdateCheckValue: " << gpo_rule_configured_to_string(powertoys_gpo::getDisablePeriodicUpdateCheckValue()) << std::endl;
|
||||||
report << "getAllowExperimentationValue: " << gpo_rule_configured_to_string(powertoys_gpo::getAllowExperimentationValue()) << std::endl;
|
report << "getAllowExperimentationValue: " << gpo_rule_configured_to_string(powertoys_gpo::getAllowExperimentationValue()) << std::endl;
|
||||||
|
report << "getConfiguredQoiPreviewEnabledValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredQoiPreviewEnabledValue()) << std::endl;
|
||||||
|
report << "getConfiguredQoiThumbnailsEnabledValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredQoiThumbnailsEnabledValue()) << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,12 +15,13 @@ function PublicStaticVoidMain {
|
|||||||
[String] $MachineWideHandler
|
[String] $MachineWideHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
[String[]]$TypesToCheck = @(".markdown", ".mdtext", ".mdtxt", ".mdown", ".mkdn", ".mdwn", ".mkd", ".md", ".svg", ".svgz", ".pdf", ".gcode", ".stl", ".txt", ".ini")
|
[String[]]$TypesToCheck = @(".markdown", ".mdtext", ".mdtxt", ".mdown", ".mkdn", ".mdwn", ".mkd", ".md", ".svg", ".svgz", ".pdf", ".gcode", ".stl", ".txt", ".ini", ".qoi")
|
||||||
$IPREVIEW_HANDLER_CLSID = '{8895b1c6-b41f-4c1c-a562-0d564250836f}'
|
$IPREVIEW_HANDLER_CLSID = '{8895b1c6-b41f-4c1c-a562-0d564250836f}'
|
||||||
$PowerToysHandlers = @{
|
$PowerToysHandlers = @{
|
||||||
'{07665729-6243-4746-95b7-79579308d1b2}' = "PowerToys PDF handler"
|
'{07665729-6243-4746-95b7-79579308d1b2}' = "PowerToys PDF handler"
|
||||||
'{ddee2b8a-6807-48a6-bb20-2338174ff779}' = "PowerToys SVG handler"
|
'{ddee2b8a-6807-48a6-bb20-2338174ff779}' = "PowerToys SVG handler"
|
||||||
'{ec52dea8-7c9f-4130-a77b-1737d0418507}' = "PowerToys GCode handler"
|
'{ec52dea8-7c9f-4130-a77b-1737d0418507}' = "PowerToys GCode handler"
|
||||||
|
'{8AA07897-C30B-4543-865B-00A0E5A1B32D}' = "PowerToys QOI handler"
|
||||||
'{45769bcc-e8fd-42d0-947e-02beef77a1f5}' = "PowerToys Markdown handler"
|
'{45769bcc-e8fd-42d0-947e-02beef77a1f5}' = "PowerToys Markdown handler"
|
||||||
'{afbd5a44-2520-4ae0-9224-6cfce8fe4400}' = "PowerToys Monaco fallback handler"
|
'{afbd5a44-2520-4ae0-9224-6cfce8fe4400}' = "PowerToys Monaco fallback handler"
|
||||||
'{DC6EFB56-9CFA-464D-8880-44885D7DC193}' = "Adobe Acrobat DC"
|
'{DC6EFB56-9CFA-464D-8880-44885D7DC193}' = "Adobe Acrobat DC"
|
||||||
|
Loading…
Reference in New Issue
Block a user