mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
Add SVG Thumbnail Provider for Windows Explorer (#5048)
* Add SVG Thumbnail Provider * Some cleanup * Small settings changes * Update PowerToys.sln Remove Any CPU entries * Fix project configuration issues * Fix bad merge * Update output path for SVG thumbnail provider * Sync with latest
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -341,3 +341,4 @@ src/common/Telemetry/*.etl
|
|||||||
# Don't ignore MergeModules
|
# Don't ignore MergeModules
|
||||||
!**/MergeModules/Release/
|
!**/MergeModules/Release/
|
||||||
!**/MergeModules/Debug/
|
!**/MergeModules/Debug/
|
||||||
|
/src/modules/previewpane/SvgThumbnailProvider/$(SolutionDir)$(Platform)/$(Configuration)/modules/FileExplorerPreview/SvgThumbnailProvider.xml
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 16
|
||||||
VisualStudioVersion = 16.0.28803.452
|
VisualStudioVersion = 16.0.28803.452
|
||||||
@@ -254,6 +253,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManagedCommon", "src\common
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Program.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Program.UnitTests\Microsoft.Plugin.Program.UnitTests.csproj", "{42851751-CBC8-45A6-97F5-7A0753F7B4D1}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Plugin.Program.UnitTests", "src\modules\launcher\Plugins\Microsoft.Plugin.Program.UnitTests\Microsoft.Plugin.Program.UnitTests.csproj", "{42851751-CBC8-45A6-97F5-7A0753F7B4D1}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests-SvgThumbnailProvider", "src\modules\previewpane\UnitTests-SvgThumbnailProvider\UnitTests-SvgThumbnailProvider.csproj", "{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SvgThumbnailProvider", "src\modules\previewpane\SvgThumbnailProvider\SvgThumbnailProvider.csproj", "{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}"
|
||||||
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ColorPicker", "src\modules\colorPicker\ColorPicker\ColorPicker.vcxproj", "{655C9AF2-18D3-4DA6-80E4-85504A7722BA}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ColorPicker", "src\modules\colorPicker\ColorPicker\ColorPicker.vcxproj", "{655C9AF2-18D3-4DA6-80E4-85504A7722BA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorPickerUI", "src\modules\colorPicker\ColorPickerUI\ColorPickerUI.csproj", "{BA58206B-1493-4C75-BFEA-A85768A1E156}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorPickerUI", "src\modules\colorPicker\ColorPickerUI\ColorPickerUI.csproj", "{BA58206B-1493-4C75-BFEA-A85768A1E156}"
|
||||||
@@ -502,6 +505,14 @@ Global
|
|||||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Debug|x64.Build.0 = Debug|x64
|
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Debug|x64.Build.0 = Debug|x64
|
||||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Release|x64.ActiveCfg = Release|x64
|
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Release|x64.ActiveCfg = Release|x64
|
||||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Release|x64.Build.0 = Release|x64
|
{42851751-CBC8-45A6-97F5-7A0753F7B4D1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}.Release|x64.Build.0 = Release|x64
|
||||||
|
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}.Release|x64.Build.0 = Release|x64
|
||||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Debug|x64.ActiveCfg = Debug|x64
|
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Debug|x64.Build.0 = Debug|x64
|
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Debug|x64.Build.0 = Debug|x64
|
||||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Release|x64.ActiveCfg = Release|x64
|
{655C9AF2-18D3-4DA6-80E4-85504A7722BA}.Release|x64.ActiveCfg = Release|x64
|
||||||
@@ -579,6 +590,8 @@ Global
|
|||||||
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
{62173D9A-6724-4C00-A1C8-FB646480A9EC} = {38BDB927-829B-4C65-9CD9-93FB05D66D65}
|
||||||
{4AED67B6-55FD-486F-B917-E543DEE2CB3C} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
{4AED67B6-55FD-486F-B917-E543DEE2CB3C} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||||
{42851751-CBC8-45A6-97F5-7A0753F7B4D1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
{42851751-CBC8-45A6-97F5-7A0753F7B4D1} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||||
|
{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
|
{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
{655C9AF2-18D3-4DA6-80E4-85504A7722BA} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
{655C9AF2-18D3-4DA6-80E4-85504A7722BA} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||||
{BA58206B-1493-4C75-BFEA-A85768A1E156} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
{BA58206B-1493-4C75-BFEA-A85768A1E156} = {1D78B84B-CA39-406C-98F4-71F7EC266CC0}
|
||||||
{1D78B84B-CA39-406C-98F4-71F7EC266CC0} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
{1D78B84B-CA39-406C-98F4-71F7EC266CC0} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||||
|
|||||||
@@ -428,6 +428,23 @@
|
|||||||
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="RuntimeVersion" Value="v4.0.30319" />
|
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="RuntimeVersion" Value="v4.0.30319" />
|
||||||
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="CodeBase" Value="file:///[FileExplorerPreviewInstallFolder]SvgPreviewHandler.dll" />
|
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="CodeBase" Value="file:///[FileExplorerPreviewInstallFolder]SvgPreviewHandler.dll" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
|
<!-- Registry Key for Class Registration of Svg Thumbnail Provider -->
|
||||||
|
<RegistryKey Root="HKCR" Key="CLSID\{36B27788-A8BB-4698-A756-DF9F11F64F84}">
|
||||||
|
<RegistryValue Type="string" Value="SvgThumbnailProvider.SvgThumbnailProvider" />
|
||||||
|
<RegistryValue Type="string" Name="DisplayName" Value="Svg Thumbnail Provider" />
|
||||||
|
<RegistryValue Type="string" Name="AppID" Value="{CF142243-F059-45AF-8842-DBBE9783DB14}" />
|
||||||
|
<RegistryValue Type="string" Key="Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value=""/>
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32" Value="mscoree.dll" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32" Name="Assembly" Value="SvgThumbnailProvider, Version=$(var.Version).0, Culture=neutral" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32" Name="Class" Value="SvgThumbnailProvider.SvgThumbnailProvider" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Both" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32" Name="CodeBase" Value="file:///[FileExplorerPreviewInstallFolder]SvgThumbnailProvider.dll" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Assembly" Value="SvgThumbnailProvider, Version=$(var.Version).0, Culture=neutral" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Class" Value="SvgThumbnailProvider.SvgThumbnailProvider" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="RuntimeVersion" Value="v4.0.30319" />
|
||||||
|
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="CodeBase" Value="file:///[FileExplorerPreviewInstallFolder]SvgThumbnailProvider.dll" />
|
||||||
|
</RegistryKey>
|
||||||
<!-- Registry Key for Class Registration of Markdown Preview Handler -->
|
<!-- Registry Key for Class Registration of Markdown Preview Handler -->
|
||||||
<RegistryKey Root="HKCR" Key="CLSID\{45769bcc-e8fd-42d0-947e-02beef77a1f5}">
|
<RegistryKey Root="HKCR" Key="CLSID\{45769bcc-e8fd-42d0-947e-02beef77a1f5}">
|
||||||
<RegistryValue Type="string" Value="MarkdownPreviewHandler.MarkdownPreviewHandler" />
|
<RegistryValue Type="string" Value="MarkdownPreviewHandler.MarkdownPreviewHandler" />
|
||||||
@@ -461,6 +478,10 @@
|
|||||||
<RegistryKey Root="HKCR" Key=".svg\shellex">
|
<RegistryKey Root="HKCR" Key=".svg\shellex">
|
||||||
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{ddee2b8a-6807-48a6-bb20-2338174ff779}" />
|
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{ddee2b8a-6807-48a6-bb20-2338174ff779}" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
|
<!-- Add file type association for Svg Thumbnail Provider -->
|
||||||
|
<RegistryKey Root="HKCR" Key=".svg\shellex">
|
||||||
|
<RegistryValue Type="string" Key="{E357FCCD-A995-4576-B01F-234630154E96}" Value="{36B27788-A8BB-4698-A756-DF9F11F64F84}" />
|
||||||
|
</RegistryKey>
|
||||||
<!-- Add file type association for Markdown Preview Handler -->
|
<!-- Add file type association for Markdown Preview Handler -->
|
||||||
<RegistryKey Root="HKCR" Key=".md\shellex">
|
<RegistryKey Root="HKCR" Key=".md\shellex">
|
||||||
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{45769bcc-e8fd-42d0-947e-02beef77a1f5}" />
|
<RegistryValue Type="string" Key="{8895b1c6-b41f-4c1c-a562-0d564250836f}" Value="{45769bcc-e8fd-42d0-947e-02beef77a1f5}" />
|
||||||
@@ -469,6 +490,10 @@
|
|||||||
<RegistryKey Root="HKLM" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
<RegistryKey Root="HKLM" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
||||||
<RegistryValue Type="integer" Name="prevhost.exe" Value="11000" />
|
<RegistryValue Type="integer" Name="prevhost.exe" Value="11000" />
|
||||||
</RegistryKey>
|
</RegistryKey>
|
||||||
|
<!-- Update Key to use IE11 for dllhost.exe -->
|
||||||
|
<RegistryKey Root="HKLM" Key="Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION">
|
||||||
|
<RegistryValue Type="integer" Name="dllhost.exe" Value="11000" />
|
||||||
|
</RegistryKey>
|
||||||
</Component>
|
</Component>
|
||||||
</DirectoryRef>
|
</DirectoryRef>
|
||||||
|
|
||||||
@@ -611,6 +636,8 @@
|
|||||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\Telemetry.dll" />
|
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\Telemetry.dll" />
|
||||||
<!-- File to include dll for Svg Preview Handler -->
|
<!-- File to include dll for Svg Preview Handler -->
|
||||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\SvgPreviewHandler.dll" />
|
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\SvgPreviewHandler.dll" />
|
||||||
|
<!-- File to include dll for Svg Preview Handler -->
|
||||||
|
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\SvgThumbnailProvider.dll" />
|
||||||
<!-- Files to include dll's for Markdown Preview Handler and it's dependencies -->
|
<!-- Files to include dll's for Markdown Preview Handler and it's dependencies -->
|
||||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\MarkdownPreviewHandler.dll" />
|
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\MarkdownPreviewHandler.dll" />
|
||||||
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\Markdig.Signed.dll" />
|
<File Source="$(var.BinX64Dir)modules\FileExplorerPreview\Markdig.Signed.dll" />
|
||||||
|
|||||||
@@ -12,36 +12,53 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
|
|||||||
{
|
{
|
||||||
public class PowerPreviewProperties
|
public class PowerPreviewProperties
|
||||||
{
|
{
|
||||||
private bool enableSvg = true;
|
private bool enableSvgPreview = true;
|
||||||
|
|
||||||
[JsonPropertyName("svg-previewer-toggle-setting")]
|
[JsonPropertyName("svg-previewer-toggle-setting")]
|
||||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||||
public bool EnableSvg
|
public bool EnableSvgPreview
|
||||||
{
|
{
|
||||||
get => this.enableSvg;
|
get => this.enableSvgPreview;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value != this.enableSvg)
|
if (value != this.enableSvgPreview)
|
||||||
{
|
{
|
||||||
LogTelemetryEvent(value);
|
LogTelemetryEvent(value);
|
||||||
this.enableSvg = value;
|
this.enableSvgPreview = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool enableMd = true;
|
private bool enableSvgThumbnail = true;
|
||||||
|
|
||||||
|
[JsonPropertyName("svg-thumbnail-toggle-setting")]
|
||||||
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||||
|
public bool EnableSvgThumbnail
|
||||||
|
{
|
||||||
|
get => this.enableSvgThumbnail;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != this.enableSvgThumbnail)
|
||||||
|
{
|
||||||
|
LogTelemetryEvent(value);
|
||||||
|
this.enableSvgThumbnail = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool enableMdPreview = true;
|
||||||
|
|
||||||
[JsonPropertyName("md-previewer-toggle-setting")]
|
[JsonPropertyName("md-previewer-toggle-setting")]
|
||||||
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
[JsonConverter(typeof(BoolPropertyJsonConverter))]
|
||||||
public bool EnableMd
|
public bool EnableMdPreview
|
||||||
{
|
{
|
||||||
get => this.enableMd;
|
get => this.enableMdPreview;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value != this.enableMd)
|
if (value != this.enableMdPreview)
|
||||||
{
|
{
|
||||||
LogTelemetryEvent(value);
|
LogTelemetryEvent(value);
|
||||||
this.enableMd = value;
|
this.enableMdPreview = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -422,6 +422,9 @@
|
|||||||
</data>
|
</data>
|
||||||
<data name="FileExplorerPreview_ToggleSwitch_Preview_SVG.Header" xml:space="preserve">
|
<data name="FileExplorerPreview_ToggleSwitch_Preview_SVG.Header" xml:space="preserve">
|
||||||
<value>Enable SVG (.svg) preview</value>
|
<value>Enable SVG (.svg) preview</value>
|
||||||
|
</data>
|
||||||
|
<data name="FileExplorerPreview_ToggleSwitch_SVG_Thumbnail.Header" xml:space="preserve">
|
||||||
|
<value>Enable SVG (.svg) thumbnails</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FileExplorerPreview_Description.Text" xml:space="preserve">
|
<data name="FileExplorerPreview_Description.Text" xml:space="preserve">
|
||||||
<value>These settings allow you to manage your Windows File Explorer custom preview handlers.</value>
|
<value>These settings allow you to manage your Windows File Explorer custom preview handlers.</value>
|
||||||
|
|||||||
@@ -27,12 +27,14 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._svgRenderIsEnabled = Settings.properties.EnableSvg;
|
this._svgRenderIsEnabled = Settings.properties.EnableSvgPreview;
|
||||||
this._mdRenderIsEnabled = Settings.properties.EnableMd;
|
this._svgThumbnailIsEnabled = Settings.properties.EnableSvgThumbnail;
|
||||||
|
this._mdRenderIsEnabled = Settings.properties.EnableMdPreview;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _svgRenderIsEnabled = false;
|
private bool _svgRenderIsEnabled = false;
|
||||||
private bool _mdRenderIsEnabled = false;
|
private bool _mdRenderIsEnabled = false;
|
||||||
|
private bool _svgThumbnailIsEnabled = false;
|
||||||
|
|
||||||
public bool SVGRenderIsEnabled
|
public bool SVGRenderIsEnabled
|
||||||
{
|
{
|
||||||
@@ -46,7 +48,25 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
if (value != _svgRenderIsEnabled)
|
if (value != _svgRenderIsEnabled)
|
||||||
{
|
{
|
||||||
_svgRenderIsEnabled = value;
|
_svgRenderIsEnabled = value;
|
||||||
Settings.properties.EnableSvg = value;
|
Settings.properties.EnableSvgPreview = value;
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool SVGThumbnailIsEnabled
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _svgThumbnailIsEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value != _svgThumbnailIsEnabled)
|
||||||
|
{
|
||||||
|
_svgThumbnailIsEnabled = value;
|
||||||
|
Settings.properties.EnableSvgThumbnail = value;
|
||||||
RaisePropertyChanged();
|
RaisePropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +84,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
|||||||
if (value != _mdRenderIsEnabled)
|
if (value != _mdRenderIsEnabled)
|
||||||
{
|
{
|
||||||
_mdRenderIsEnabled = value;
|
_mdRenderIsEnabled = value;
|
||||||
Settings.properties.EnableMd = value;
|
Settings.properties.EnableMdPreview = value;
|
||||||
RaisePropertyChanged();
|
RaisePropertyChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,10 @@
|
|||||||
Margin="{StaticResource MediumTopMargin}"
|
Margin="{StaticResource MediumTopMargin}"
|
||||||
IsOn="{Binding Mode=TwoWay, Path=SVGRenderIsEnabled}" />
|
IsOn="{Binding Mode=TwoWay, Path=SVGRenderIsEnabled}" />
|
||||||
|
|
||||||
|
<ToggleSwitch x:Uid="FileExplorerPreview_ToggleSwitch_SVG_Thumbnail"
|
||||||
|
Margin="{StaticResource SmallTopMargin}"
|
||||||
|
IsOn="{Binding Mode=TwoWay, Path=SVGThumbnailIsEnabled}" />
|
||||||
|
|
||||||
<ToggleSwitch x:Uid="FileExplorerPreview_ToggleSwitch_Preview_MD"
|
<ToggleSwitch x:Uid="FileExplorerPreview_ToggleSwitch_Preview_MD"
|
||||||
Margin="{StaticResource SmallTopMargin}"
|
Margin="{StaticResource SmallTopMargin}"
|
||||||
IsOn="{Binding Mode=TwoWay, Path=MDRenderIsEnabled}" />
|
IsOn="{Binding Mode=TwoWay, Path=MDRenderIsEnabled}" />
|
||||||
|
|||||||
@@ -59,13 +59,30 @@ namespace ViewModelTests
|
|||||||
ShellPage.DefaultSndMSGCallback = msg =>
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
{
|
{
|
||||||
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
|
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
|
||||||
Assert.IsTrue(snd.powertoys.FileExplorerPreviewSettings.properties.EnableSvg);
|
Assert.IsTrue(snd.powertoys.FileExplorerPreviewSettings.properties.EnableSvgPreview);
|
||||||
};
|
};
|
||||||
|
|
||||||
// act
|
// act
|
||||||
viewModel.SVGRenderIsEnabled = true;
|
viewModel.SVGRenderIsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void SVGThumbnailIsEnabled_ShouldPrevHandler_WhenSuccessful()
|
||||||
|
{
|
||||||
|
// arrange
|
||||||
|
PowerPreviewViewModel viewModel = new PowerPreviewViewModel();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
|
{
|
||||||
|
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
|
||||||
|
Assert.IsTrue(snd.powertoys.FileExplorerPreviewSettings.properties.EnableSvgThumbnail);
|
||||||
|
};
|
||||||
|
|
||||||
|
// act
|
||||||
|
viewModel.SVGThumbnailIsEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MDRenderIsEnabled_ShouldPrevHandler_WhenSuccessful()
|
public void MDRenderIsEnabled_ShouldPrevHandler_WhenSuccessful()
|
||||||
{
|
{
|
||||||
@@ -76,7 +93,7 @@ namespace ViewModelTests
|
|||||||
ShellPage.DefaultSndMSGCallback = msg =>
|
ShellPage.DefaultSndMSGCallback = msg =>
|
||||||
{
|
{
|
||||||
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
|
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
|
||||||
Assert.IsTrue(snd.powertoys.FileExplorerPreviewSettings.properties.EnableMd);
|
Assert.IsTrue(snd.powertoys.FileExplorerPreviewSettings.properties.EnableMdPreview);
|
||||||
};
|
};
|
||||||
|
|
||||||
// act
|
// act
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ using Common.Utilities;
|
|||||||
using Microsoft.PowerToys.Telemetry;
|
using Microsoft.PowerToys.Telemetry;
|
||||||
using PreviewHandlerCommon;
|
using PreviewHandlerCommon;
|
||||||
using SvgPreviewHandler.Telemetry.Events;
|
using SvgPreviewHandler.Telemetry.Events;
|
||||||
using SvgPreviewHandler.Utilities;
|
|
||||||
|
|
||||||
namespace SvgPreviewHandler
|
namespace SvgPreviewHandler
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -112,7 +112,6 @@
|
|||||||
<Compile Include="Telemetry\Events\SvgFileHandlerLoaded.cs" />
|
<Compile Include="Telemetry\Events\SvgFileHandlerLoaded.cs" />
|
||||||
<Compile Include="Telemetry\Events\SvgFilePreviewed.cs" />
|
<Compile Include="Telemetry\Events\SvgFilePreviewed.cs" />
|
||||||
<Compile Include="Telemetry\Events\SvgFilePreviewError.cs" />
|
<Compile Include="Telemetry\Events\SvgFilePreviewError.cs" />
|
||||||
<Compile Include="Utilities\SvgPreviewHandlerHelper.cs" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\Telemetry.csproj">
|
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\Telemetry.csproj">
|
||||||
|
|||||||
21
src/modules/previewpane/SvgThumbnailProvider/StyleCop.json
Normal file
21
src/modules/previewpane/SvgThumbnailProvider/StyleCop.json
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
|
||||||
|
"settings": {
|
||||||
|
"documentationRules": {
|
||||||
|
"companyName": "Microsoft Corporation",
|
||||||
|
"copyrightText": "Copyright (c) {companyName}\r\nThe {companyName} licenses this file to you under the MIT license.\r\nSee the LICENSE file in the project root for more information.",
|
||||||
|
"xmlHeader": false,
|
||||||
|
"headerDecoration": "",
|
||||||
|
"fileNamingConvention": "metadata",
|
||||||
|
"documentInterfaces": false,
|
||||||
|
"documentExposedElements": false,
|
||||||
|
"documentInternalElements": false
|
||||||
|
},
|
||||||
|
"layoutRules": {
|
||||||
|
"newlineAtEndOfFile": "require"
|
||||||
|
},
|
||||||
|
"orderingRules": {
|
||||||
|
"usingDirectivesPlacement": "outsideNamespace"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
// 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 SvgThumbnailProvider
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Drawing.Drawing2D;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Common;
|
||||||
|
using Common.ComInterlop;
|
||||||
|
using Common.Utilities;
|
||||||
|
using Microsoft.PowerToys.Telemetry;
|
||||||
|
using PreviewHandlerCommon;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// SVG Thumbnail Provider.
|
||||||
|
/// </summary>
|
||||||
|
[Guid("36B27788-A8BB-4698-A756-DF9F11F64F84")]
|
||||||
|
[ClassInterface(ClassInterfaceType.None)]
|
||||||
|
[ComVisible(true)]
|
||||||
|
public class SvgThumbnailProvider : IInitializeWithStream, IThumbnailProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the stream object to access file.
|
||||||
|
/// </summary>
|
||||||
|
public IStream Stream { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The maxium dimension (width or height) thumbnail we will generate.
|
||||||
|
/// </summary>
|
||||||
|
private const uint MaxThumbnailSize = 10000;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Captures an image representation of browser contents.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="browser">The WebBrowser instance rendring the SVG.</param>
|
||||||
|
/// <param name="rectangle">The client rectangle to capture from.</param>
|
||||||
|
/// <param name="backgroundColor">The default background color to apply.</param>
|
||||||
|
/// <returns>A Bitmap representing the browser contents.</returns>
|
||||||
|
public static Bitmap GetBrowserContentImage(WebBrowser browser, Rectangle rectangle, Color backgroundColor)
|
||||||
|
{
|
||||||
|
Bitmap image = new Bitmap(rectangle.Width, rectangle.Height);
|
||||||
|
using (Graphics graphics = Graphics.FromImage(image))
|
||||||
|
{
|
||||||
|
IntPtr deviceContextHandle = IntPtr.Zero;
|
||||||
|
RECT rect = new RECT
|
||||||
|
{
|
||||||
|
Left = rectangle.Left,
|
||||||
|
Top = rectangle.Top,
|
||||||
|
Right = rectangle.Right,
|
||||||
|
Bottom = rectangle.Bottom,
|
||||||
|
};
|
||||||
|
|
||||||
|
graphics.Clear(backgroundColor);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
deviceContextHandle = graphics.GetHdc();
|
||||||
|
|
||||||
|
IViewObject viewObject = browser.ActiveXInstance as IViewObject;
|
||||||
|
viewObject.Draw(1, -1, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, deviceContextHandle, ref rect, IntPtr.Zero, IntPtr.Zero, 0);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (deviceContextHandle != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
graphics.ReleaseHdc(deviceContextHandle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrap the SVG markup in HTML with a meta tag to ensure the
|
||||||
|
/// WebBrowser control is in Edge mode to enable SVG rendering.
|
||||||
|
/// We also set the padding and margin for the body to zero as
|
||||||
|
/// there is a default margin of 8.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="content">The content to render.</param>
|
||||||
|
/// <param name="cx">The maximum thumbnail size, in pixels.</param>
|
||||||
|
/// <returns>A thumbnail of the rendered content.</returns>
|
||||||
|
public static Bitmap GetThumbnail(string content, uint cx)
|
||||||
|
{
|
||||||
|
if (cx > MaxThumbnailSize)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap thumbnail = null;
|
||||||
|
|
||||||
|
// Wrap the SVG content in HTML in IE Edge mode so we can ensure
|
||||||
|
// we render properly.
|
||||||
|
string wrappedContent = WrapSVGInHTML(content);
|
||||||
|
WebBrowserExt browser = new WebBrowserExt();
|
||||||
|
browser.Dock = DockStyle.Fill;
|
||||||
|
browser.IsWebBrowserContextMenuEnabled = false;
|
||||||
|
browser.ScriptErrorsSuppressed = true;
|
||||||
|
browser.ScrollBarsEnabled = false;
|
||||||
|
browser.AllowNavigation = false;
|
||||||
|
browser.Width = (int)cx;
|
||||||
|
browser.Height = (int)cx;
|
||||||
|
browser.DocumentText = wrappedContent;
|
||||||
|
|
||||||
|
// Wait for the browser to render the content.
|
||||||
|
while (browser.IsBusy || browser.ReadyState != WebBrowserReadyState.Complete)
|
||||||
|
{
|
||||||
|
Application.DoEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check size of the rendered SVG.
|
||||||
|
var svg = browser.Document.GetElementsByTagName("svg").Cast<HtmlElement>().FirstOrDefault();
|
||||||
|
if (svg != null)
|
||||||
|
{
|
||||||
|
// Update the size of the browser control to fit the SVG
|
||||||
|
// in the visible viewport.
|
||||||
|
browser.Width = svg.OffsetRectangle.Width;
|
||||||
|
browser.Height = svg.OffsetRectangle.Height;
|
||||||
|
|
||||||
|
// Wait for the browser to render the content.
|
||||||
|
while (browser.IsBusy || browser.ReadyState != WebBrowserReadyState.Complete)
|
||||||
|
{
|
||||||
|
Application.DoEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capture the image of the SVG from the browser.
|
||||||
|
thumbnail = GetBrowserContentImage(browser, svg.OffsetRectangle, Color.White);
|
||||||
|
if (thumbnail.Width != cx && thumbnail.Height != cx)
|
||||||
|
{
|
||||||
|
// 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>
|
||||||
|
/// Wrap the SVG markup in HTML with a meta tag to ensure the
|
||||||
|
/// WebBrowser control is in Edge mode to enable SVG rendering.
|
||||||
|
/// We also set the padding and margin for the body to zero as
|
||||||
|
/// there is a default margin of 8.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="svg">The original SVG markup.</param>
|
||||||
|
/// <returns>The SVG content wrapped in HTML.</returns>
|
||||||
|
public static string WrapSVGInHTML(string svg)
|
||||||
|
{
|
||||||
|
string html = @"
|
||||||
|
<head>
|
||||||
|
<meta http-equiv='X-UA-Compatible' content='IE=Edge'>
|
||||||
|
</head>
|
||||||
|
<html>
|
||||||
|
<body style='padding:0px;margin:0px;' scroll='no'>
|
||||||
|
{0}
|
||||||
|
</body>
|
||||||
|
</html>";
|
||||||
|
return string.Format(html, svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap destImage = new Bitmap(width, height);
|
||||||
|
|
||||||
|
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.Clear(Color.White);
|
||||||
|
graphics.DrawImage(image, 0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return destImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void Initialize(IStream pstream, uint grfMode)
|
||||||
|
{
|
||||||
|
// Ignore the grfMode always use read mode to access the file.
|
||||||
|
this.Stream = pstream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void GetThumbnail(uint cx, out IntPtr phbmp, out WTS_ALPHATYPE pdwAlpha)
|
||||||
|
{
|
||||||
|
phbmp = IntPtr.Zero;
|
||||||
|
pdwAlpha = WTS_ALPHATYPE.WTSAT_UNKNOWN;
|
||||||
|
|
||||||
|
if (cx == 0 || cx > MaxThumbnailSize)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string svgData = null;
|
||||||
|
using (var stream = new StreamWrapper(this.Stream as IStream))
|
||||||
|
{
|
||||||
|
using (var reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
svgData = reader.ReadToEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (svgData != null)
|
||||||
|
{
|
||||||
|
Bitmap thumbnail = GetThumbnail(svgData, cx);
|
||||||
|
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
|
||||||
|
{
|
||||||
|
phbmp = thumbnail.GetHbitmap();
|
||||||
|
pdwAlpha = WTS_ALPHATYPE.WTSAT_RGB;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{8FFE09DA-FA4F-4EE1-B3A2-AD5497FBD1AD}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<RootNamespace>SVGThumbnailProvider</RootNamespace>
|
||||||
|
<AssemblyName>SVGThumbnailProvider</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>..\..\..\..\x64\Debug\modules\FileExplorerPreview\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>2</WarningLevel>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
<DocumentationFile>%24%28SolutionDir%29%24%28Platform%29\%24%28Configuration%29\modules\FileExplorerPreview\SvgThumbnailProvider.xml</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>..\..\..\..\x64\Release\modules\FileExplorerPreview\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<DocumentationFile>%24%28SolutionDir%29%24%28Platform%29\%24%28Configuration%29\modules\FileExplorerPreview\SvgThumbnailProvider.xml</DocumentationFile>
|
||||||
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<StartupObject />
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<OutputPath>..\..\..\..\x64\Debug\modules\FileExplorerPreview\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<OutputPath>..\..\..\..\x64\Release\modules\FileExplorerPreview\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Deployment" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="SvgThumbnailProvider.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\Telemetry.csproj">
|
||||||
|
<Project>{5d00d290-4016-4cfe-9e41-1e7c724509ba}</Project>
|
||||||
|
<Name>Telemetry</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\Common\PreviewHandlerCommon.csproj">
|
||||||
|
<Project>{af2349b8-e5b6-4004-9502-687c1c7730b1}</Project>
|
||||||
|
<Name>PreviewHandlerCommon</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="StyleCop.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using SvgPreviewHandler.Utilities;
|
using Common.Utilities;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace UnitTests_SvgPreviewHandler
|
namespace UnitTests_SvgPreviewHandler
|
||||||
|
|||||||
@@ -0,0 +1,178 @@
|
|||||||
|
// 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.Drawing.Imaging;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Runtime.InteropServices.ComTypes;
|
||||||
|
using System.Text;
|
||||||
|
using Moq;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Common.ComInterlop;
|
||||||
|
using SvgThumbnailProvider;
|
||||||
|
|
||||||
|
namespace SvgThumbnailProviderUnitTests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class SvgThumbnailProviderTests
|
||||||
|
{
|
||||||
|
[TestMethod]
|
||||||
|
public void LoadSimpleSVG_ShouldReturnNonNullBitmap()
|
||||||
|
{
|
||||||
|
var svgBuilder = new StringBuilder();
|
||||||
|
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||||
|
svgBuilder.AppendLine("\t<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||||
|
svgBuilder.AppendLine("\t</circle>");
|
||||||
|
svgBuilder.AppendLine("</svg>");
|
||||||
|
|
||||||
|
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||||
|
Assert.IsTrue(thumbnail != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CheckBlockedElements_ShouldReturnNullBitmap_IfBlockedElementsIsPresentInNestedLevel()
|
||||||
|
{
|
||||||
|
var svgBuilder = new StringBuilder();
|
||||||
|
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||||
|
svgBuilder.AppendLine("\t<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||||
|
svgBuilder.AppendLine("\t\t<script>alert(\"valid-message\")</script>");
|
||||||
|
svgBuilder.AppendLine("\t</circle>");
|
||||||
|
svgBuilder.AppendLine("</svg>");
|
||||||
|
|
||||||
|
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||||
|
Assert.IsTrue(thumbnail == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CheckNoSvg_ShouldReturnNullBitmap()
|
||||||
|
{
|
||||||
|
var svgBuilder = new StringBuilder();
|
||||||
|
svgBuilder.AppendLine("<p>foo</p>");
|
||||||
|
|
||||||
|
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||||
|
Assert.IsTrue(thumbnail == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CheckNoSvgEmptyString_ShouldReturnNullBitmap()
|
||||||
|
{
|
||||||
|
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail("", 256);
|
||||||
|
Assert.IsTrue(thumbnail == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CheckNoSvgNullString_ShouldReturnNullBitmap()
|
||||||
|
{
|
||||||
|
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(null, 256);
|
||||||
|
Assert.IsTrue(thumbnail == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CheckZeroSizedThumbnail_ShouldReturnNullBitmap()
|
||||||
|
{
|
||||||
|
string content = "<svg></svg>";
|
||||||
|
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(content, 0);
|
||||||
|
Assert.IsTrue(thumbnail == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void CheckBlockedElements_ShouldReturnBitmap_HTMLWrapped()
|
||||||
|
{
|
||||||
|
var svgBuilder = new StringBuilder();
|
||||||
|
svgBuilder.AppendLine("<html>");
|
||||||
|
svgBuilder.AppendLine("<head>");
|
||||||
|
svgBuilder.AppendLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">");
|
||||||
|
svgBuilder.AppendLine("<meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"utf-8\">");
|
||||||
|
svgBuilder.AppendLine("</head>");
|
||||||
|
svgBuilder.AppendLine("<body>");
|
||||||
|
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||||
|
svgBuilder.AppendLine("<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||||
|
svgBuilder.AppendLine("</circle>");
|
||||||
|
svgBuilder.AppendLine("</svg>");
|
||||||
|
svgBuilder.AppendLine("</body>");
|
||||||
|
svgBuilder.AppendLine("</html>");
|
||||||
|
|
||||||
|
Bitmap thumbnail = SvgThumbnailProvider.SvgThumbnailProvider.GetThumbnail(svgBuilder.ToString(), 256);
|
||||||
|
Assert.IsTrue(thumbnail != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetThumbnail_ValidStreamSVG()
|
||||||
|
{
|
||||||
|
var svgBuilder = new StringBuilder();
|
||||||
|
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||||
|
svgBuilder.AppendLine("<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||||
|
svgBuilder.AppendLine("</circle>");
|
||||||
|
svgBuilder.AppendLine("</svg>");
|
||||||
|
|
||||||
|
SvgThumbnailProvider.SvgThumbnailProvider provider = new SvgThumbnailProvider.SvgThumbnailProvider();
|
||||||
|
|
||||||
|
provider.Initialize(GetMockStream(svgBuilder.ToString()), 0);
|
||||||
|
|
||||||
|
IntPtr bitmap;
|
||||||
|
WTS_ALPHATYPE alphaType;
|
||||||
|
provider.GetThumbnail(256, out bitmap, out alphaType);
|
||||||
|
|
||||||
|
Assert.IsTrue(bitmap != IntPtr.Zero);
|
||||||
|
Assert.IsTrue(alphaType == WTS_ALPHATYPE.WTSAT_RGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void GetThumbnail_ValidStreamHTML()
|
||||||
|
{
|
||||||
|
var svgBuilder = new StringBuilder();
|
||||||
|
svgBuilder.AppendLine("<html>");
|
||||||
|
svgBuilder.AppendLine("<head>");
|
||||||
|
svgBuilder.AppendLine("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=Edge\">");
|
||||||
|
svgBuilder.AppendLine("<meta http-equiv=\"Content-Type\" content=\"text/html\" charset=\"utf-8\">");
|
||||||
|
svgBuilder.AppendLine("</head>");
|
||||||
|
svgBuilder.AppendLine("<body>");
|
||||||
|
svgBuilder.AppendLine("<svg viewBox=\"0 0 100 100\" xmlns=\"http://www.w3.org/2000/svg\">");
|
||||||
|
svgBuilder.AppendLine("<circle cx=\"50\" cy=\"50\" r=\"50\">");
|
||||||
|
svgBuilder.AppendLine("</circle>");
|
||||||
|
svgBuilder.AppendLine("</svg>");
|
||||||
|
svgBuilder.AppendLine("</body>");
|
||||||
|
svgBuilder.AppendLine("</html>");
|
||||||
|
|
||||||
|
SvgThumbnailProvider.SvgThumbnailProvider provider = new SvgThumbnailProvider.SvgThumbnailProvider();
|
||||||
|
|
||||||
|
provider.Initialize(GetMockStream(svgBuilder.ToString()), 0);
|
||||||
|
|
||||||
|
IntPtr bitmap;
|
||||||
|
WTS_ALPHATYPE alphaType;
|
||||||
|
provider.GetThumbnail(256, out bitmap, out alphaType);
|
||||||
|
|
||||||
|
Assert.IsTrue(bitmap != IntPtr.Zero);
|
||||||
|
Assert.IsTrue(alphaType == WTS_ALPHATYPE.WTSAT_RGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IStream GetMockStream(string streamData)
|
||||||
|
{
|
||||||
|
var mockStream = new Mock<IStream>();
|
||||||
|
var streamBytes = Encoding.UTF8.GetBytes(streamData);
|
||||||
|
|
||||||
|
var streamMock = new Mock<IStream>();
|
||||||
|
var firstCall = true;
|
||||||
|
streamMock
|
||||||
|
.Setup(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<IntPtr>()))
|
||||||
|
.Callback<byte[], int, IntPtr>((buffer, countToRead, bytesReadPtr) =>
|
||||||
|
{
|
||||||
|
if (firstCall)
|
||||||
|
{
|
||||||
|
Array.Copy(streamBytes, 0, buffer, 0, streamBytes.Length);
|
||||||
|
Marshal.WriteInt32(bytesReadPtr, streamBytes.Length);
|
||||||
|
firstCall = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Marshal.WriteInt32(bytesReadPtr, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return streamMock.Object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props')" />
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{1EF1EEF0-10F0-4F2E-8550-39B6D8044D3E}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>UnitTests_SvgThumbnailProvider</RootNamespace>
|
||||||
|
<AssemblyName>UnitTests-SvgThumbnailProvider</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
|
||||||
|
<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>
|
||||||
|
<NuGetPackageImportStamp>
|
||||||
|
</NuGetPackageImportStamp>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||||
|
<OutputPath>bin\x64\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
|
<LangVersion>7.3</LangVersion>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\MSTest.TestFramework.2.1.1\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Moq, Version=4.14.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\Moq.4.14.5\lib\net45\Moq.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Configuration" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\..\..\..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="SvgThumbnailProviderTests.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="packages.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Common\PreviewHandlerCommon.csproj">
|
||||||
|
<Project>{af2349b8-e5b6-4004-9502-687c1c7730b1}</Project>
|
||||||
|
<Name>PreviewHandlerCommon</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\SvgThumbnailProvider\SvgThumbnailProvider.csproj">
|
||||||
|
<Project>{8ffe09da-fa4f-4ee1-b3a2-ad5497fbd1ad}</Project>
|
||||||
|
<Name>SvgThumbnailProvider</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Properties\" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<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\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.props'))" />
|
||||||
|
<Error Condition="!Exists('..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets'))" />
|
||||||
|
</Target>
|
||||||
|
<Import Project="..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\..\..\..\packages\MSTest.TestAdapter.2.1.1\build\net45\MSTest.TestAdapter.targets')" />
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<packages>
|
||||||
|
<package id="Castle.Core" version="4.4.0" targetFramework="net472" />
|
||||||
|
<package id="Moq" version="4.14.5" targetFramework="net472" />
|
||||||
|
<package id="MSTest.TestAdapter" version="2.1.1" targetFramework="net472" />
|
||||||
|
<package id="MSTest.TestFramework" version="2.1.1" targetFramework="net472" />
|
||||||
|
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.0" targetFramework="net472" />
|
||||||
|
<package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net472" />
|
||||||
|
</packages>
|
||||||
@@ -103,6 +103,8 @@
|
|||||||
<Compile Include="cominterop\IPreviewHandler.cs" />
|
<Compile Include="cominterop\IPreviewHandler.cs" />
|
||||||
<Compile Include="cominterop\IPreviewHandlerFrame.cs" />
|
<Compile Include="cominterop\IPreviewHandlerFrame.cs" />
|
||||||
<Compile Include="cominterop\IPreviewHandlerVisuals.cs" />
|
<Compile Include="cominterop\IPreviewHandlerVisuals.cs" />
|
||||||
|
<Compile Include="cominterop\IThumbnailProvider.cs" />
|
||||||
|
<Compile Include="cominterop\IViewObject.cs" />
|
||||||
<Compile Include="cominterop\LOGFONT.cs" />
|
<Compile Include="cominterop\LOGFONT.cs" />
|
||||||
<Compile Include="cominterop\MSG.cs" />
|
<Compile Include="cominterop\MSG.cs" />
|
||||||
<Compile Include="cominterop\RECT.cs" />
|
<Compile Include="cominterop\RECT.cs" />
|
||||||
@@ -125,6 +127,7 @@
|
|||||||
<Compile Include="handlers\StreamBasedPreviewHandler.cs" />
|
<Compile Include="handlers\StreamBasedPreviewHandler.cs" />
|
||||||
<Compile Include="examplehandler\TestCustomHandler.cs" />
|
<Compile Include="examplehandler\TestCustomHandler.cs" />
|
||||||
<Compile Include="Utilities\StreamWrapper.cs" />
|
<Compile Include="Utilities\StreamWrapper.cs" />
|
||||||
|
<Compile Include="Utilities\SvgPreviewHandlerHelper.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
<AdditionalFiles Include="..\..\..\codeAnalysis\StyleCop.json">
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
namespace SvgPreviewHandler.Utilities
|
namespace Common.Utilities
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper utilities for Svg Preview Handler.
|
/// Helper utilities for Svg Preview Handler.
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
// 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.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Common.ComInterlop
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the alpha type of the image.
|
||||||
|
/// </summary>
|
||||||
|
public enum WTS_ALPHATYPE : int
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// he bitmap is an unknown format. The Shell tries nonetheless to detect whether the image has an alpha channel.
|
||||||
|
/// </summary>
|
||||||
|
WTSAT_UNKNOWN = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The bitmap is an RGB image without alpha. The alpha channel is invalid and the Shell ignores it.
|
||||||
|
/// </summary>
|
||||||
|
WTSAT_RGB = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The bitmap is an ARGB image with a valid alpha channel.
|
||||||
|
/// </summary>
|
||||||
|
WTSAT_ARGB = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Exposes methods for thumbnail provider.
|
||||||
|
/// </summary>
|
||||||
|
[ComImport]
|
||||||
|
[Guid("e357fccd-a995-4576-b01f-234630154e96")]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IThumbnailProvider
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a thumbnail image and alpha type.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cx">The maximum thumbnail size, in pixels.</param>
|
||||||
|
/// <param name="phbmp">When this method returns, contains a pointer to the thumbnail image handle.</param>
|
||||||
|
/// <param name="pdwAlpha">When this method returns, contains a pointer to one of the values from the WTS_ALPHATYPE enumeration.</param>
|
||||||
|
void GetThumbnail(uint cx, out IntPtr phbmp, out WTS_ALPHATYPE pdwAlpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
src/modules/previewpane/common/cominterop/IViewObject.cs
Normal file
33
src/modules/previewpane/common/cominterop/IViewObject.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// 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.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace Common.ComInterlop
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Enables an object to display itself directly without passing a data object to the caller.
|
||||||
|
/// </summary>
|
||||||
|
[ComImport]
|
||||||
|
[Guid("0000010D-0000-0000-C000-000000000046")]
|
||||||
|
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||||
|
public interface IViewObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Draws a representation of an object onto the specified device context.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dwAspect">Specifies the aspect to be drawn, that is, how the object is to be represented.</param>
|
||||||
|
/// <param name="lindex">Portion of the object that is of interest for the draw operation.</param>
|
||||||
|
/// <param name="pvAspect">Pointer to additional information in a DVASPECTINFO structure that enables drawing optimizations depending on the aspect specified.</param>
|
||||||
|
/// <param name="ptd">Pointer to the DVTARGETDEVICE structure that describes the device for which the object is to be rendered.</param>
|
||||||
|
/// <param name="hdcTargetDev">Information context for the target device indicated by the ptd parameter from which the object can extract device metrics and test the device's capabilities.</param>
|
||||||
|
/// <param name="hdcDraw">Device context on which to draw. For a windowless object, the hdcDraw parameter should be in MM_TEXT mapping mode with its logical coordinates matching the client coordinates of the containing window.</param>
|
||||||
|
/// <param name="lprcBounds">Pointer to a RECTL structure specifying the rectangle on hdcDraw and in which the object should be drawn.</param>
|
||||||
|
/// <param name="lprcWBounds">If hdcDraw is a metafile device context, pointer to a RECTL structure specifying the bounding rectangle in the underlying metafile.</param>
|
||||||
|
/// <param name="pfnContinue">Pointer to a callback function that the view object should call periodically during a lengthy drawing operation to determine whether the operation should continue or be canceled.</param>
|
||||||
|
/// <param name="dwContinue">Value to pass as a parameter to the function pointed to by the pfnContinue parameter.</param>
|
||||||
|
void Draw([MarshalAs(UnmanagedType.U4)] uint dwAspect, int lindex, IntPtr pvAspect, [In] IntPtr ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [MarshalAs(UnmanagedType.Struct)] ref RECT lprcBounds, [In] IntPtr lprcWBounds, IntPtr pfnContinue, [MarshalAs(UnmanagedType.U4)] uint dwContinue);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,8 +16,15 @@ const CLSID CLSID_SHIMActivateMdPreviewHandler = { 0xE0907A95, 0x6F9A, 0x4D1B, {
|
|||||||
// 45769bcc-e8fd-42d0-947e-02beef77a1f5
|
// 45769bcc-e8fd-42d0-947e-02beef77a1f5
|
||||||
const CLSID CLSID_MdPreviewHandler = { 0x45769bcc, 0xe8fd, 0x42d0, { 0x94, 0x7e, 0x02, 0xbe, 0xef, 0x77, 0xa1, 0xf5 } };
|
const CLSID CLSID_MdPreviewHandler = { 0x45769bcc, 0xe8fd, 0x42d0, { 0x94, 0x7e, 0x02, 0xbe, 0xef, 0x77, 0xa1, 0xf5 } };
|
||||||
|
|
||||||
|
// 9C723B8C-4F5C-4147-9DE4-C2808F9AF66B
|
||||||
|
const CLSID CLSID_SHIMActivateSvgThumbnailProvider = { 0x9C723B8C, 0x4F5C, 0x4147, { 0x9D, 0xE4, 0xC2, 0x80, 0x8F, 0x9A, 0xF6, 0x6B } };
|
||||||
|
|
||||||
|
// 36B27788-A8BB-4698-A756-DF9F11F64F84
|
||||||
|
const CLSID CLSID_SvgThumbnailProvider = { 0x36B27788, 0xA8BB, 0x4698, { 0xA7, 0x56, 0xDF, 0x9F, 0x11, 0xF6, 0x4F, 0x84 } };
|
||||||
|
|
||||||
// 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_SHIMActivateSvgPreviewHandler, CLSID_SvgPreviewHandler }
|
{ CLSID_SHIMActivateSvgPreviewHandler, CLSID_SvgPreviewHandler },
|
||||||
|
{ CLSID_SHIMActivateSvgThumbnailProvider, CLSID_SvgThumbnailProvider }
|
||||||
});
|
});
|
||||||
@@ -26,6 +26,20 @@ void PowerPreviewModule::destroy()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto thumbnailProvider : this->m_thumbnailProviders)
|
||||||
|
{
|
||||||
|
if (thumbnailProvider != NULL)
|
||||||
|
{
|
||||||
|
// Disable all the active thumbnail providers.
|
||||||
|
if (this->m_enabled && thumbnailProvider->GetToggleSettingState())
|
||||||
|
{
|
||||||
|
thumbnailProvider->DisablePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
delete thumbnailProvider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,6 +81,15 @@ bool PowerPreviewModule::get_config(_Out_ wchar_t* buffer, _Out_ int* buffer_siz
|
|||||||
previewHandler->GetToggleSettingState());
|
previewHandler->GetToggleSettingState());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto thumbnailProvider : this->m_thumbnailProviders)
|
||||||
|
{
|
||||||
|
settings.add_bool_toggle(
|
||||||
|
thumbnailProvider->GetToggleSettingName(),
|
||||||
|
thumbnailProvider->GetToggleSettingDescription(),
|
||||||
|
thumbnailProvider->GetToggleSettingState());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return settings.serialize_to_buffer(buffer, buffer_size);
|
return settings.serialize_to_buffer(buffer, buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,6 +105,11 @@ void PowerPreviewModule::set_config(const wchar_t* config)
|
|||||||
previewHandler->UpdateState(settings, this->m_enabled);
|
previewHandler->UpdateState(settings, this->m_enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto thumbnailProvider : this->m_thumbnailProviders)
|
||||||
|
{
|
||||||
|
thumbnailProvider->UpdateState(settings, this->m_enabled);
|
||||||
|
}
|
||||||
|
|
||||||
settings.save_to_settings_file();
|
settings.save_to_settings_file();
|
||||||
}
|
}
|
||||||
catch (std::exception const& e)
|
catch (std::exception const& e)
|
||||||
@@ -106,6 +134,19 @@ void PowerPreviewModule::enable()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto thumbnailProvider : this->m_thumbnailProviders)
|
||||||
|
{
|
||||||
|
if (thumbnailProvider->GetToggleSettingState())
|
||||||
|
{
|
||||||
|
// Enable all the thumbnail providers with initial state set as true.
|
||||||
|
thumbnailProvider->EnableThumbnailProvider();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
thumbnailProvider->DisableThumbnailProvider();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->m_enabled)
|
if (!this->m_enabled)
|
||||||
{
|
{
|
||||||
Trace::EnabledPowerPreview(true);
|
Trace::EnabledPowerPreview(true);
|
||||||
@@ -122,6 +163,11 @@ void PowerPreviewModule::disable()
|
|||||||
previewHandler->DisablePreview();
|
previewHandler->DisablePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto thumbnailProvider : this->m_thumbnailProviders)
|
||||||
|
{
|
||||||
|
thumbnailProvider->DisableThumbnailProvider();
|
||||||
|
}
|
||||||
|
|
||||||
if (this->m_enabled)
|
if (this->m_enabled)
|
||||||
{
|
{
|
||||||
Trace::EnabledPowerPreview(false);
|
Trace::EnabledPowerPreview(false);
|
||||||
@@ -156,6 +202,12 @@ void PowerPreviewModule::init_settings()
|
|||||||
{
|
{
|
||||||
previewHandler->LoadState(settings);
|
previewHandler->LoadState(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto thumbnailProvider : this->m_thumbnailProviders)
|
||||||
|
{
|
||||||
|
thumbnailProvider->LoadState(settings);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (std::exception const& e)
|
catch (std::exception const& e)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ private:
|
|||||||
bool m_enabled = false;
|
bool m_enabled = false;
|
||||||
std::wstring m_moduleName;
|
std::wstring m_moduleName;
|
||||||
std::vector<FileExplorerPreviewSettings *> m_previewHandlers;
|
std::vector<FileExplorerPreviewSettings *> m_previewHandlers;
|
||||||
|
std::vector<FileExplorerPreviewSettings*> m_thumbnailProviders;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PowerPreviewModule() :
|
PowerPreviewModule() :
|
||||||
@@ -39,6 +40,16 @@ public:
|
|||||||
L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}",
|
L"{45769bcc-e8fd-42d0-947e-02beef77a1f5}",
|
||||||
L"Markdown Preview Handler",
|
L"Markdown Preview Handler",
|
||||||
new RegistryWrapper())
|
new RegistryWrapper())
|
||||||
|
}),
|
||||||
|
m_thumbnailProviders(
|
||||||
|
{ // TODO: MOVE THIS SVG Thumbnail Provider settings object.
|
||||||
|
new FileExplorerPreviewSettings(
|
||||||
|
true,
|
||||||
|
L"svg-thumbnail-toggle-setting",
|
||||||
|
GET_RESOURCE_STRING(IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION),
|
||||||
|
L"{36B27788-A8BB-4698-A756-DF9F11F64F84}",
|
||||||
|
L"SVG Thumbnail Provider",
|
||||||
|
new RegistryWrapper())
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
init_settings();
|
init_settings();
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ BEGIN
|
|||||||
IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL L"IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL"
|
IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL L"IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL"
|
||||||
IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION L"Svg Previewer"
|
IDS_PREVPANE_SVG_SETTINGS_DESCRIPTION L"Svg Previewer"
|
||||||
IDS_PREVPANE_SVG_SETTINGS_DISPLAYNAME L"SVG Previewer"
|
IDS_PREVPANE_SVG_SETTINGS_DISPLAYNAME L"SVG Previewer"
|
||||||
|
IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION L"Svg Thumbnail Provider"
|
||||||
IDS_EXPLR_SVG_BOOL_TOGGLE_CONTROLL L"EXPLR_SVG_BOOL_TOGGLE_CONTROLL"
|
IDS_EXPLR_SVG_BOOL_TOGGLE_CONTROLL L"EXPLR_SVG_BOOL_TOGGLE_CONTROLL"
|
||||||
IDS_EXPLR_SVG_SETTINGS_DESCRIPTION L"Render SVG images"
|
IDS_EXPLR_SVG_SETTINGS_DESCRIPTION L"Render SVG images"
|
||||||
END
|
END
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#define IDS_EXPLR_SVG_SETTINGS_DESCRIPTION 214
|
#define IDS_EXPLR_SVG_SETTINGS_DESCRIPTION 214
|
||||||
#define IDS_PREVPANE_SVG_SETTINGS_DISPLAYNAME 215
|
#define IDS_PREVPANE_SVG_SETTINGS_DISPLAYNAME 215
|
||||||
#define IDS_PREVPANE_MD_SETTINGS_DISPLAYNAME 216
|
#define IDS_PREVPANE_MD_SETTINGS_DISPLAYNAME 216
|
||||||
|
#define IDS_SVG_THUMBNAIL_PROVIDER_SETTINGS_DESCRIPTION 217
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ namespace PowerPreviewSettings
|
|||||||
// Relative(HKLM/HKCU) sub key path of Preview Handlers list in registry.
|
// Relative(HKLM/HKCU) sub key path of Preview Handlers list in registry.
|
||||||
static LPCWSTR preview_handlers_subkey = L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers";
|
static LPCWSTR preview_handlers_subkey = L"Software\\Microsoft\\Windows\\CurrentVersion\\PreviewHandlers";
|
||||||
|
|
||||||
|
// Relative HKCR sub key path of SVG thumbnail provider in registry
|
||||||
|
static LPCWSTR svg_thumbnail_provider_subkey = L".svg\\shellex\\{E357FCCD-A995-4576-B01F-234630154E96}";
|
||||||
|
|
||||||
// Base Settings Class Implementation
|
// Base Settings Class Implementation
|
||||||
FileExplorerPreviewSettings::FileExplorerPreviewSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, RegistryWrapperIface* registryWrapper) :
|
FileExplorerPreviewSettings::FileExplorerPreviewSettings(bool toggleSettingEnabled, const std::wstring& toggleSettingName, const std::wstring& toggleSettingDescription, LPCWSTR clsid, const std::wstring& registryValueData, RegistryWrapperIface* registryWrapper) :
|
||||||
m_toggleSettingEnabled(toggleSettingEnabled),
|
m_toggleSettingEnabled(toggleSettingEnabled),
|
||||||
@@ -127,4 +130,16 @@ namespace PowerPreviewSettings
|
|||||||
// Delete the registry key to disable preview.
|
// Delete the registry key to disable preview.
|
||||||
return this->m_registryWrapper->DeleteRegistryValue(HKEY_CURRENT_USER, preview_handlers_subkey, this->GetCLSID());
|
return this->m_registryWrapper->DeleteRegistryValue(HKEY_CURRENT_USER, preview_handlers_subkey, this->GetCLSID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LONG FileExplorerPreviewSettings::EnableThumbnailProvider()
|
||||||
|
{
|
||||||
|
// Add registry value to enable thumbnail provider.
|
||||||
|
return this->m_registryWrapper->SetRegistryValue(HKEY_CURRENT_USER, svg_thumbnail_provider_subkey, this->GetCLSID(), REG_SZ, (LPBYTE)this->GetRegistryValueData().c_str(), (DWORD)(this->GetRegistryValueData().length() * sizeof(wchar_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG FileExplorerPreviewSettings::DisableThumbnailProvider()
|
||||||
|
{
|
||||||
|
// Delete the registry key to disable thumbnail provider.
|
||||||
|
return this->m_registryWrapper->DeleteRegistryValue(HKEY_CURRENT_USER, svg_thumbnail_provider_subkey, this->GetCLSID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
namespace PowerPreviewSettings
|
namespace PowerPreviewSettings
|
||||||
{
|
{
|
||||||
// PowerToy Windows Explore File Preview Settings.
|
// PowerToy Windows Explorer File Preview Settings.
|
||||||
class FileExplorerPreviewSettings
|
class FileExplorerPreviewSettings
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -32,5 +32,7 @@ namespace PowerPreviewSettings
|
|||||||
virtual void UpdateState(PowerToysSettings::PowerToyValues& settings, bool enabled);
|
virtual void UpdateState(PowerToysSettings::PowerToyValues& settings, bool enabled);
|
||||||
virtual LONG EnablePreview();
|
virtual LONG EnablePreview();
|
||||||
virtual LONG DisablePreview();
|
virtual LONG DisablePreview();
|
||||||
|
virtual LONG EnableThumbnailProvider();
|
||||||
|
virtual LONG DisableThumbnailProvider();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user