mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 19:57:57 +01:00
Self-contained .NET (#22217)
* dotnet sc
* MD preview - C# app
- working self-contained
* Gcode preview - C# app
* DevFiles preview - C# app
* Fix passing path with spaces as cmd arg and monacocpp proj file
* Pdf preview - C# app
* Svg preview - C# app
* Fix comment
* Gcode thumbnail - C# app
TODO:
- installer
- why IThumbnailProvider and IIntializeWithFile doesn't work?
* Pdf thumbnail - C# app
TODO:
- installer
- why IThumbnailProvider and IIntializeWithFile doesn't work?
* Pdf thumbnail - C# app
TODO:
- installer
- why IThumbnailProvider and IIntializeWithFile doesn't work?
* Fix GcodeThumbnailProviderCpp.vcxproj
* Svg thumbnail - C# app
TODO:
- installer
- why IThumbnailProvider and IIntializeWithFile doesn't work?
* Fix Svg tests
* Thumbnail providers - installer
* Self-contained Hosts and FileLocksmith
* Fix hardcoded <RuntimeIdentifier>
* Remove unneeded files
* Try to fix Nuget in PR CI
* Prefix new dlls with PowerToys.
Sign new dlls and exes
* Add new .exe files to ProcessList
* ci: debug by listing all env vars
* ci: try setting variable in the right ci file
* Bring back hardcoded RuntimeIdentifier
* ci: Add comment and remove debug action
* Remove unneeded lib
* [WIP] Platform conditional dotnet files & hardlinks
* Cleanup
* Update expect.txt
* Test fix - ARM installer
* Fix uninstall bug
* Update docs
* Fix failing test
* Add dll details
* Minor cleanup
* Improve resizing
* Add some logs
* Test fix - release build
* Remove InvokeOnControlThread
* Test fix: logger initialization
* Fix arm64 installer
Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
Co-authored-by: Dustin L. Howett <dustin@howett.net>
This commit is contained in:
@@ -21,6 +21,15 @@
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<ApplicationIcon>Assets/Icon.ico</ApplicationIcon>
|
||||
<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>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileLocksmith</PublishDir>
|
||||
<RuntimeIdentifier>win10-$(Platform)</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>False</PublishSingleFile>
|
||||
<PublishReadyToRun>False</PublishReadyToRun>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
<AssemblyName>PowerToys.Hosts</AssemblyName>
|
||||
<DefineConstants>DISABLE_XAML_GENERATED_MAIN,TRACE</DefineConstants>
|
||||
<ApplicationIcon>Assets/Hosts.ico</ApplicationIcon>
|
||||
<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>
|
||||
|
||||
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<Platforms>x86;x64;arm64</Platforms>
|
||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<PublishProfile>win10-$(Platform).pubxml</PublishProfile>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
@@ -22,6 +21,14 @@
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<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>
|
||||
|
||||
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||
|
||||
@@ -10,6 +10,15 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<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>
|
||||
|
||||
@@ -17,6 +17,15 @@
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<PackageProjectUrl>https://awake.den.dev</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/microsoft/powertoys</RepositoryUrl>
|
||||
<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>
|
||||
|
||||
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||
|
||||
@@ -9,7 +9,17 @@
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<UseWPF>true</UseWPF>
|
||||
<StartupObject>ColorPicker.Program</StartupObject>
|
||||
<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>{BA58206B-1493-4C75-BFEA-A85768A1E156}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
|
||||
@@ -11,9 +11,18 @@
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones</OutputPath>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\FancyZones</OutputPath>
|
||||
<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>{5CCC8468-DEC8-4D36-99D4-5C891BEBD481}</ProjectGuid>
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
|
||||
@@ -8,8 +8,17 @@
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<UseWPF>true</UseWPF>
|
||||
<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>{2BE46397-4DFA-414C-9BD4-41E4BBF8CB34}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
|
||||
@@ -19,8 +19,16 @@
|
||||
<AssemblyName>PowerToys.PowerLauncher</AssemblyName>
|
||||
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\modules\launcher\</OutputPath>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<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 Condition="'$(Configuration)'=='Debug'">
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\launcher</PublishDir>
|
||||
<RuntimeIdentifier>win-$(Platform)</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>False</PublishSingleFile>
|
||||
<PublishReadyToRun>False</PublishReadyToRun>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
|
||||
@@ -7,8 +7,18 @@
|
||||
<Nullable>disable</Nullable>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<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>
|
||||
<CsWinRTIncludes>PowerToys.GPOWrapper;PowerToys.PowerAccentKeyboardService</CsWinRTIncludes>
|
||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||
|
||||
@@ -10,10 +10,19 @@
|
||||
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||
<AssemblyName>PowerToys.PowerAccent</AssemblyName>
|
||||
<XamlDebuggingInformation>True</XamlDebuggingInformation>
|
||||
<StartupObject>PowerAccent.UI.Program</StartupObject>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\PowerAccent</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<StartupObject>PowerAccent.UI.Program</StartupObject>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\PowerAccent</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<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>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
// 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;
|
||||
using Common;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Gcode
|
||||
{
|
||||
/// <summary>
|
||||
/// Extends <see cref="StreamBasedPreviewHandler"/> for Gcode Preview Handler.
|
||||
/// </summary>
|
||||
[Guid("ec52dea8-7c9f-4130-a77b-1737d0418507")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComVisible(true)]
|
||||
public class GcodePreviewHandler : StreamBasedPreviewHandler, IDisposable
|
||||
{
|
||||
private GcodePreviewHandlerControl _gcodePreviewControl;
|
||||
private bool disposedValue;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="GcodePreviewHandler"/> class.
|
||||
/// </summary>
|
||||
public GcodePreviewHandler()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override void DoPreview()
|
||||
{
|
||||
_gcodePreviewControl.DoPreview(Stream);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new Telemetry.Events.GcodeFileHandlerLoaded());
|
||||
_gcodePreviewControl = new GcodePreviewHandlerControl();
|
||||
|
||||
return _gcodePreviewControl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes objects
|
||||
/// </summary>
|
||||
/// <param name="disposing">Is Disposing</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_gcodePreviewControl.Dispose();
|
||||
}
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<AssemblyTitle>PowerToys.GcodePreviewHandler</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys GcodePreviewHandler</AssemblyDescription>
|
||||
@@ -11,13 +12,21 @@
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<AssemblyName>PowerToys.GcodePreviewHandler</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>{805306FF-A562-4415-8DEF-E493BDC45918}</ProjectGuid>
|
||||
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Gcode</RootNamespace>
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\..\..\Version.props" />
|
||||
@@ -40,6 +49,7 @@
|
||||
<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>
|
||||
@@ -48,7 +58,9 @@
|
||||
</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>
|
||||
|
||||
@@ -46,52 +46,50 @@ namespace Microsoft.PowerToys.PreviewHandler.Gcode
|
||||
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredGcodePreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
|
||||
{
|
||||
// GPO is disabling this utility. Show an error message instead.
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
_infoBarAdded = true;
|
||||
AddTextBoxControl(Properties.Resource.GpoDisabledErrorText);
|
||||
Resize += FormResized;
|
||||
base.DoPreview(dataSource);
|
||||
});
|
||||
_infoBarAdded = true;
|
||||
AddTextBoxControl(Properties.Resource.GpoDisabledErrorText);
|
||||
Resize += FormResized;
|
||||
base.DoPreview(dataSource);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
InvokeOnControlThread(() =>
|
||||
try
|
||||
{
|
||||
try
|
||||
Bitmap thumbnail = null;
|
||||
|
||||
if (!(dataSource is string filePath))
|
||||
{
|
||||
Bitmap thumbnail = null;
|
||||
|
||||
using (var stream = new ReadonlyStream(dataSource as IStream))
|
||||
{
|
||||
using (var reader = new StreamReader(stream))
|
||||
{
|
||||
thumbnail = GetThumbnail(reader);
|
||||
}
|
||||
}
|
||||
|
||||
_infoBarAdded = false;
|
||||
|
||||
if (thumbnail == null)
|
||||
{
|
||||
_infoBarAdded = true;
|
||||
AddTextBoxControl(Properties.Resource.GcodeWithoutEmbeddedThumbnails);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPictureBoxControl(thumbnail);
|
||||
}
|
||||
|
||||
Resize += FormResized;
|
||||
base.DoPreview(dataSource);
|
||||
PowerToysTelemetry.Log.WriteEvent(new GcodeFilePreviewed());
|
||||
throw new ArgumentException($"{nameof(dataSource)} for {nameof(GcodePreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||
|
||||
using (var reader = new StreamReader(fs))
|
||||
{
|
||||
PreviewError(ex, dataSource);
|
||||
thumbnail = GetThumbnail(reader);
|
||||
}
|
||||
});
|
||||
|
||||
_infoBarAdded = false;
|
||||
|
||||
if (thumbnail == null)
|
||||
{
|
||||
_infoBarAdded = true;
|
||||
AddTextBoxControl(Properties.Resource.GcodeWithoutEmbeddedThumbnails);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddPictureBoxControl(thumbnail);
|
||||
}
|
||||
|
||||
Resize += FormResized;
|
||||
base.DoPreview(fs);
|
||||
PowerToysTelemetry.Log.WriteEvent(new GcodeFilePreviewed());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
PreviewError(ex, dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
63
src/modules/previewpane/GcodePreviewHandler/Program.cs
Normal file
63
src/modules/previewpane/GcodePreviewHandler/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.
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Gcode
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Windows.Threading;
|
||||
using Common.UI;
|
||||
using interop;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
|
||||
|
||||
private static GcodePreviewHandlerControl _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 GcodePreviewHandlerControl();
|
||||
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
|
||||
_previewHandlerControl.DoPreview(filePath);
|
||||
|
||||
NativeEventWaiter.WaitForEventLoop(
|
||||
Constants.GcodePreviewResizeEvent(),
|
||||
() =>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "pch.h"
|
||||
#include "ClassFactory.h"
|
||||
#include "GcodePreviewHandler.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;
|
||||
|
||||
GcodePreviewHandler* pExt = new (std::nothrow) GcodePreviewHandler();
|
||||
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,262 @@
|
||||
#include "pch.h"
|
||||
#include "GcodePreviewHandler.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>
|
||||
|
||||
extern HINSTANCE g_hInst;
|
||||
extern long g_cDllRef;
|
||||
|
||||
GcodePreviewHandler::GcodePreviewHandler() :
|
||||
m_cRef(1), m_hwndParent(NULL), m_rcParent(), m_punkSite(NULL), m_process(NULL)
|
||||
{
|
||||
m_resizeEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::GCODE_PREVIEW_RESIZE_EVENT);
|
||||
|
||||
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
|
||||
logFilePath.append(LogSettings::gcodePrevLogPath);
|
||||
Logger::init(LogSettings::gcodePrevLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||
|
||||
InterlockedIncrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
GcodePreviewHandler::~GcodePreviewHandler()
|
||||
{
|
||||
InterlockedDecrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
#pragma region IUnknown
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
static const QITAB qit[] = {
|
||||
QITABENT(GcodePreviewHandler, IPreviewHandler),
|
||||
QITABENT(GcodePreviewHandler, IInitializeWithFile),
|
||||
QITABENT(GcodePreviewHandler, IPreviewHandlerVisuals),
|
||||
QITABENT(GcodePreviewHandler, IOleWindow),
|
||||
QITABENT(GcodePreviewHandler, IObjectWithSite),
|
||||
{ 0 },
|
||||
};
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
GcodePreviewHandler::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
GcodePreviewHandler::Release()
|
||||
{
|
||||
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||
if (0 == cRef)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return cRef;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IInitializationWithFile
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::Initialize(LPCWSTR pszFilePath, DWORD grfMode)
|
||||
{
|
||||
m_filePath = pszFilePath;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IPreviewHandler
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::SetWindow(HWND hwnd, const RECT* prc)
|
||||
{
|
||||
if (hwnd && prc)
|
||||
{
|
||||
m_hwndParent = hwnd;
|
||||
m_rcParent = *prc;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::SetFocus()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::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 GcodePreviewHandler::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 GcodePreviewHandler::SetRect(const RECT* prc)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (prc != NULL)
|
||||
{
|
||||
if (!m_resizeEvent)
|
||||
{
|
||||
Logger::error(L"Failed to create resize event for GcodePreviewHandler");
|
||||
}
|
||||
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 GcodePreviewHandler");
|
||||
}
|
||||
}
|
||||
}
|
||||
m_rcParent = *prc;
|
||||
hr = S_OK;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::DoPreview()
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger::info(L"Starting GcodePreviewHandler.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.GcodePreviewHandler.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 GcodePreviewHandler.exe. Error: {}", errorMessage);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::Unload()
|
||||
{
|
||||
Logger::info(L"Unload and terminate .exe");
|
||||
|
||||
m_hwndParent = NULL;
|
||||
TerminateProcess(m_process, 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IPreviewHandlerVisuals
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::SetBackgroundColor(COLORREF color)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::SetFont(const LOGFONTW* plf)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::SetTextColor(COLORREF color)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IOleWindow
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::GetWindow(HWND* phwnd)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (phwnd)
|
||||
{
|
||||
*phwnd = m_hwndParent;
|
||||
hr = S_OK;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::ContextSensitiveHelp(BOOL fEnterMode)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IObjectWithSite
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::SetSite(IUnknown* punkSite)
|
||||
{
|
||||
if (m_punkSite)
|
||||
{
|
||||
m_punkSite->Release();
|
||||
m_punkSite = NULL;
|
||||
}
|
||||
return punkSite ? punkSite->QueryInterface(&m_punkSite) : S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP GcodePreviewHandler::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 GcodePreviewHandler :
|
||||
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);
|
||||
|
||||
GcodePreviewHandler();
|
||||
protected:
|
||||
~GcodePreviewHandler();
|
||||
|
||||
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,119 @@
|
||||
<?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.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{5a5dd09d-723a-44d3-8f2b-293584c3d731}</ProjectGuid>
|
||||
<RootNamespace>GcodePreviewHandlerCpp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</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>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</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="GcodePreviewHandler.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ClassFactory.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="GcodePreviewHandler.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="GlobalExportFunctions.def" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="GcodePreviewHandlerCpp.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>
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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="GcodePreviewHandler.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="GcodePreviewHandler.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="GcodePreviewHandlerCpp.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
DllGetClassObject PRIVATE
|
||||
DllCanUnloadNow PRIVATE
|
||||
73
src/modules/previewpane/GcodePreviewHandlerCpp/dllmain.cpp
Normal file
73
src/modules/previewpane/GcodePreviewHandlerCpp/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;
|
||||
|
||||
// {A0257634-8812-4CE8-AF11-FA69ACAEAFAE}
|
||||
static const GUID CLSID_GcodePreviewHandler = { 0xa0257634, 0x8812, 0x4ce8, { 0xaf, 0x11, 0xfa, 0x69, 0xac, 0xae, 0xaf, 0xae } };
|
||||
|
||||
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_GcodePreviewHandler, 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.220929.3" targetFramework="native" />
|
||||
</packages>
|
||||
5
src/modules/previewpane/GcodePreviewHandlerCpp/pch.cpp
Normal file
5
src/modules/previewpane/GcodePreviewHandlerCpp/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/GcodePreviewHandlerCpp/pch.h
Normal file
14
src/modules/previewpane/GcodePreviewHandlerCpp/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/GcodePreviewHandlerCpp/resource.h
Normal file
13
src/modules/previewpane/GcodePreviewHandlerCpp/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 Gcode Preview Handler Module"
|
||||
#define INTERNAL_NAME "PowerToys.GcodePreviewHandlerCpp"
|
||||
#define ORIGINAL_FILENAME "PowerToys.GcodePreviewHandlerCpp.dll"
|
||||
|
||||
// Non-localizable
|
||||
//////////////////////////////
|
||||
@@ -1,32 +1,31 @@
|
||||
// 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.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices.ComTypes;
|
||||
using System.Text;
|
||||
using Common.ComInterlop;
|
||||
using Common.Utilities;
|
||||
|
||||
namespace Microsoft.PowerToys.ThumbnailHandler.Gcode
|
||||
{
|
||||
/// <summary>
|
||||
/// G-code Thumbnail Provider.
|
||||
/// </summary>
|
||||
[Guid("BFEE99B4-B74D-4348-BCA5-E757029647FF")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComVisible(true)]
|
||||
public class GcodeThumbnailProvider : IInitializeWithStream, IThumbnailProvider
|
||||
public class GcodeThumbnailProvider
|
||||
{
|
||||
public GcodeThumbnailProvider(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 IStream Stream { get; private set; }
|
||||
public Stream Stream { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The maximum dimension (width or height) thumbnail we will generate.
|
||||
@@ -140,44 +139,36 @@ namespace Microsoft.PowerToys.ThumbnailHandler.Gcode
|
||||
return destImage;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Initialize(IStream pstream, uint grfMode)
|
||||
/// <summary>
|
||||
/// Generate thumbnail bitmap for provided Gcode file/stream.
|
||||
/// </summary>
|
||||
/// <param name="cx">Maximum thumbnail size, in pixels.</param>
|
||||
/// <returns>Generated bitmap</returns>
|
||||
public Bitmap GetThumbnail(uint cx)
|
||||
{
|
||||
// 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;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredGcodeThumbnailsEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
|
||||
{
|
||||
// GPO is disabling this utility.
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
using (var stream = new ReadonlyStream(this.Stream as IStream))
|
||||
using (var reader = new StreamReader(this.Stream))
|
||||
{
|
||||
using (var reader = new StreamReader(stream))
|
||||
using (Bitmap thumbnail = GetThumbnail(reader, cx))
|
||||
{
|
||||
using (Bitmap thumbnail = GetThumbnail(reader, cx))
|
||||
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
|
||||
{
|
||||
if (thumbnail != null && thumbnail.Size.Width > 0 && thumbnail.Size.Height > 0)
|
||||
{
|
||||
phbmp = thumbnail.GetHbitmap(Color.Transparent);
|
||||
pdwAlpha = WTS_ALPHATYPE.WTSAT_ARGB;
|
||||
}
|
||||
return (Bitmap)thumbnail.Clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<ProjectGuid>{809AA252-E17A-4FA2-B0A1-0450976B763F}</ProjectGuid>
|
||||
<RootNamespace>Microsoft.PowerToys.ThumbnailHandler.Gcode</RootNamespace>
|
||||
@@ -7,13 +8,21 @@
|
||||
<AssemblyTitle>PowerToys.GcodeThumbnailProvider</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys GcodePreviewHandler</AssemblyDescription>
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Description>PowerToys GcodePreviewHandler</Description>
|
||||
<OutputPath>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</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" />
|
||||
@@ -27,6 +36,7 @@
|
||||
<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>
|
||||
|
||||
39
src/modules/previewpane/GcodeThumbnailProvider/Program.cs
Normal file
39
src/modules/previewpane/GcodeThumbnailProvider/Program.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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.ThumbnailHandler.Gcode
|
||||
{
|
||||
using System.Globalization;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
private static GcodeThumbnailProvider _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 GcodeThumbnailProvider(filePath);
|
||||
Bitmap thumbnail = _thumbnailProvider.GetThumbnail(cx);
|
||||
filePath = filePath.Replace(".gcode", ".bmp");
|
||||
thumbnail.Save(filePath, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Gcode thumbnail - wrong number of args: " + args.Length.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "pch.h"
|
||||
#include "ClassFactory.h"
|
||||
#include "GcodeThumbnailProvider.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;
|
||||
|
||||
GcodeThumbnailProvider* pExt = new (std::nothrow) GcodeThumbnailProvider();
|
||||
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,185 @@
|
||||
#include "pch.h"
|
||||
#include "GcodeThumbnailProvider.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;
|
||||
|
||||
GcodeThumbnailProvider::GcodeThumbnailProvider() :
|
||||
m_cRef(1), m_pStream(NULL), m_process(NULL)
|
||||
{
|
||||
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
|
||||
logFilePath.append(LogSettings::gcodeThumbLogPath);
|
||||
Logger::init(LogSettings::gcodeThumbLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||
|
||||
InterlockedIncrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
GcodeThumbnailProvider::~GcodeThumbnailProvider()
|
||||
{
|
||||
InterlockedDecrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
#pragma region IUnknown
|
||||
|
||||
IFACEMETHODIMP GcodeThumbnailProvider::QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
static const QITAB qit[] = {
|
||||
QITABENT(GcodeThumbnailProvider, IThumbnailProvider),
|
||||
QITABENT(GcodeThumbnailProvider, IInitializeWithStream),
|
||||
{ 0 },
|
||||
};
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
GcodeThumbnailProvider::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
GcodeThumbnailProvider::Release()
|
||||
{
|
||||
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||
if (0 == cRef)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return cRef;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IInitializationWithStream
|
||||
|
||||
IFACEMETHODIMP GcodeThumbnailProvider::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 GcodeThumbnailProvider::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"\\GCodeThumbnail-Temp\\";
|
||||
if (!std::filesystem::exists(filePath))
|
||||
{
|
||||
std::filesystem::create_directories(filePath);
|
||||
}
|
||||
|
||||
std::wstring fileName = filePath + guid + L".gcode";
|
||||
|
||||
// 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();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Logger::info(L"Start GcodeThumbnailProvider.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.GcodeThumbnailProvider.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";
|
||||
*phbmp = (HBITMAP)LoadImage(NULL, fileNameBmp.c_str(), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||||
*pdwAlpha = WTS_ALPHATYPE::WTSAT_ARGB;
|
||||
|
||||
std::filesystem::remove(fileNameBmp);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::wstring errorMessage = std::wstring{ winrt::to_hstring(e.what()) };
|
||||
Logger::error(L"Failed to start GcodeThumbnailProvider.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 GcodeThumbnailProvider :
|
||||
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);
|
||||
|
||||
// IPreviewHandler
|
||||
IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP* phbmp, WTS_ALPHATYPE* pdwAlpha);
|
||||
|
||||
GcodeThumbnailProvider();
|
||||
protected:
|
||||
~GcodeThumbnailProvider();
|
||||
|
||||
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,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.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{56cc2f10-6e41-453d-be16-c593a5e58482}</ProjectGuid>
|
||||
<RootNamespace>GcodeThumbnailProviderCpp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</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>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</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="GcodeThumbnailProvider.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ClassFactory.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="GcodeThumbnailProvider.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="GcodeThumbnailProviderCpp.rc" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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="GcodeThumbnailProvider.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="GcodeThumbnailProvider.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="GcodeThumbnailProviderCpp.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
DllGetClassObject PRIVATE
|
||||
DllCanUnloadNow PRIVATE
|
||||
@@ -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;
|
||||
|
||||
// {F2847CBE-CD03-4C83-A359-1A8052C1B9D5}
|
||||
static const GUID CLSID_GcodeThumbnailProvider = { 0xf2847cbe, 0xcd03, 0x4c83, { 0xa3, 0x59, 0x1a, 0x80, 0x52, 0xc1, 0xb9, 0xd5 } };
|
||||
|
||||
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_GcodeThumbnailProvider, 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.220929.3" targetFramework="native" />
|
||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.220914.1" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -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/GcodeThumbnailProviderCpp/pch.h
Normal file
15
src/modules/previewpane/GcodeThumbnailProviderCpp/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/GcodeThumbnailProviderCpp/resource.h
Normal file
13
src/modules/previewpane/GcodeThumbnailProviderCpp/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 Gcode Thumbnail Provider Module"
|
||||
#define INTERNAL_NAME "PowerToys.GcodeThumbnailProviderCpp"
|
||||
#define ORIGINAL_FILENAME "PowerToys.GcodeThumbnailProviderCpp.dll"
|
||||
|
||||
// Non-localizable
|
||||
//////////////////////////////
|
||||
@@ -1,71 +0,0 @@
|
||||
// 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;
|
||||
using Common;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Markdown
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of preview handler for markdown files.
|
||||
/// </summary>
|
||||
[Guid("45769bcc-e8fd-42d0-947e-02beef77a1f5")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComVisible(true)]
|
||||
public class MarkdownPreviewHandler : FileBasedPreviewHandler, IDisposable
|
||||
{
|
||||
private MarkdownPreviewHandlerControl _markdownPreviewHandlerControl;
|
||||
private bool disposedValue;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MarkdownPreviewHandler"/> class.
|
||||
/// </summary>
|
||||
public MarkdownPreviewHandler()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DoPreview()
|
||||
{
|
||||
_markdownPreviewHandlerControl.DoPreview(FilePath);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new Telemetry.Events.MarkdownFileHandlerLoaded());
|
||||
_markdownPreviewHandlerControl = new MarkdownPreviewHandlerControl();
|
||||
|
||||
return _markdownPreviewHandlerControl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes objects
|
||||
/// </summary>
|
||||
/// <param name="disposing">Is Disposing</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_markdownPreviewHandlerControl.Dispose();
|
||||
}
|
||||
|
||||
disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<AssemblyTitle>PowerToys.MarkdownPreviewHandler</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys MarkdownPreviewHandler</AssemblyDescription>
|
||||
@@ -12,12 +13,20 @@
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<RuntimeIdentifiers>win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<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>{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}</ProjectGuid>
|
||||
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Markdown</RootNamespace>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
<AssemblyName>PowerToys.MarkdownPreviewHandler</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -46,6 +55,7 @@
|
||||
<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>
|
||||
@@ -58,6 +68,7 @@
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||
<ProjectReference Include="..\..\..\common\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||
<ProjectReference Include="..\common\PreviewHandlerCommon.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -133,14 +133,11 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
|
||||
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMarkdownPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
|
||||
{
|
||||
// GPO is disabling this utility. Show an error message instead.
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
_infoBarDisplayed = true;
|
||||
_infoBar = GetTextBoxControl(Resources.GpoDisabledErrorText);
|
||||
Resize += FormResized;
|
||||
Controls.Add(_infoBar);
|
||||
base.DoPreview(dataSource);
|
||||
});
|
||||
_infoBarDisplayed = true;
|
||||
_infoBar = GetTextBoxControl(Resources.GpoDisabledErrorText);
|
||||
Resize += FormResized;
|
||||
Controls.Add(_infoBar);
|
||||
base.DoPreview(dataSource);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -153,7 +150,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
|
||||
{
|
||||
if (!(dataSource is string filePath))
|
||||
{
|
||||
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MarkdownPreviewHandler)} must be a string but was a '{typeof(T)}'");
|
||||
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MarkdownPreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
|
||||
}
|
||||
|
||||
string fileText = File.ReadAllText(filePath);
|
||||
@@ -174,80 +171,74 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
|
||||
Dock = DockStyle.Fill,
|
||||
};
|
||||
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
var webView2Options = new CoreWebView2EnvironmentOptions("--block-new-web-contents");
|
||||
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
|
||||
var webView2Options = new CoreWebView2EnvironmentOptions("--block-new-web-contents");
|
||||
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
|
||||
webView2EnvironmentAwaiter = CoreWebView2Environment
|
||||
.CreateAsync(userDataFolder: _webView2UserDataFolder, options: webView2Options)
|
||||
.ConfigureAwait(true).GetAwaiter();
|
||||
webView2EnvironmentAwaiter.OnCompleted(() =>
|
||||
webView2EnvironmentAwaiter.OnCompleted(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
InvokeOnControlThread(async () =>
|
||||
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
|
||||
await _browser.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
|
||||
_browser.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, AssemblyDirectory, CoreWebView2HostResourceAccessKind.Deny);
|
||||
_browser.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
|
||||
_browser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
|
||||
_browser.CoreWebView2.Settings.AreDevToolsEnabled = false;
|
||||
_browser.CoreWebView2.Settings.AreHostObjectsAllowed = false;
|
||||
_browser.CoreWebView2.Settings.IsGeneralAutofillEnabled = false;
|
||||
_browser.CoreWebView2.Settings.IsPasswordAutosaveEnabled = false;
|
||||
_browser.CoreWebView2.Settings.IsScriptEnabled = false;
|
||||
_browser.CoreWebView2.Settings.IsWebMessageEnabled = false;
|
||||
|
||||
// Don't load any resources.
|
||||
_browser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
|
||||
_browser.CoreWebView2.WebResourceRequested += (object sender, CoreWebView2WebResourceRequestedEventArgs e) =>
|
||||
{
|
||||
try
|
||||
// Show local file we've saved with the markdown contents. Block all else.
|
||||
if (new Uri(e.Request.Uri) != _localFileURI)
|
||||
{
|
||||
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
|
||||
await _browser.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
|
||||
_browser.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, AssemblyDirectory, CoreWebView2HostResourceAccessKind.Deny);
|
||||
_browser.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false;
|
||||
_browser.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
|
||||
_browser.CoreWebView2.Settings.AreDevToolsEnabled = false;
|
||||
_browser.CoreWebView2.Settings.AreHostObjectsAllowed = false;
|
||||
_browser.CoreWebView2.Settings.IsGeneralAutofillEnabled = false;
|
||||
_browser.CoreWebView2.Settings.IsPasswordAutosaveEnabled = false;
|
||||
_browser.CoreWebView2.Settings.IsScriptEnabled = false;
|
||||
_browser.CoreWebView2.Settings.IsWebMessageEnabled = false;
|
||||
|
||||
// Don't load any resources.
|
||||
_browser.CoreWebView2.AddWebResourceRequestedFilter("*", CoreWebView2WebResourceContext.All);
|
||||
_browser.CoreWebView2.WebResourceRequested += (object sender, CoreWebView2WebResourceRequestedEventArgs e) =>
|
||||
{
|
||||
// Show local file we've saved with the markdown contents. Block all else.
|
||||
if (new Uri(e.Request.Uri) != _localFileURI)
|
||||
{
|
||||
e.Response = _browser.CoreWebView2.Environment.CreateWebResourceResponse(null, 403, "Forbidden", null);
|
||||
}
|
||||
};
|
||||
|
||||
// WebView2.NavigateToString() limitation
|
||||
// See https://learn.microsoft.com/dotnet/api/microsoft.web.webview2.core.corewebview2.navigatetostring?view=webview2-dotnet-1.0.864.35#remarks
|
||||
// While testing the limit, it turned out it is ~1.5MB, so to be on a safe side we go for 1.5m bytes
|
||||
if (markdownHTML.Length > 1_500_000)
|
||||
{
|
||||
string filename = _webView2UserDataFolder + "\\" + Guid.NewGuid().ToString() + ".html";
|
||||
File.WriteAllText(filename, markdownHTML);
|
||||
_localFileURI = new Uri(filename);
|
||||
_browser.Source = _localFileURI;
|
||||
}
|
||||
else
|
||||
{
|
||||
_browser.NavigateToString(markdownHTML);
|
||||
}
|
||||
|
||||
Controls.Add(_browser);
|
||||
|
||||
_browser.NavigationStarting += async (object sender, CoreWebView2NavigationStartingEventArgs args) =>
|
||||
{
|
||||
if (args.Uri != null && args.Uri != _localFileURI?.ToString() && args.IsUserInitiated)
|
||||
{
|
||||
args.Cancel = true;
|
||||
await Launcher.LaunchUriAsync(new Uri(args.Uri));
|
||||
}
|
||||
};
|
||||
|
||||
if (_infoBarDisplayed)
|
||||
{
|
||||
_infoBar = GetTextBoxControl(Resources.BlockedImageInfoText);
|
||||
Resize += FormResized;
|
||||
Controls.Add(_infoBar);
|
||||
}
|
||||
e.Response = _browser.CoreWebView2.Environment.CreateWebResourceResponse(null, 403, "Forbidden", null);
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
};
|
||||
|
||||
// WebView2.NavigateToString() limitation
|
||||
// See https://learn.microsoft.com/dotnet/api/microsoft.web.webview2.core.corewebview2.navigatetostring?view=webview2-dotnet-1.0.864.35#remarks
|
||||
// While testing the limit, it turned out it is ~1.5MB, so to be on a safe side we go for 1.5m bytes
|
||||
if (markdownHTML.Length > 1_500_000)
|
||||
{
|
||||
string filename = _webView2UserDataFolder + "\\" + Guid.NewGuid().ToString() + ".html";
|
||||
File.WriteAllText(filename, markdownHTML);
|
||||
_localFileURI = new Uri(filename);
|
||||
_browser.Source = _localFileURI;
|
||||
}
|
||||
else
|
||||
{
|
||||
_browser.NavigateToString(markdownHTML);
|
||||
}
|
||||
|
||||
Controls.Add(_browser);
|
||||
|
||||
_browser.NavigationStarting += async (object sender, CoreWebView2NavigationStartingEventArgs args) =>
|
||||
{
|
||||
if (args.Uri != null && args.Uri != _localFileURI?.ToString() && args.IsUserInitiated)
|
||||
{
|
||||
args.Cancel = true;
|
||||
await Launcher.LaunchUriAsync(new Uri(args.Uri));
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
if (_infoBarDisplayed)
|
||||
{
|
||||
_infoBar = GetTextBoxControl(Resources.BlockedImageInfoText);
|
||||
Resize += FormResized;
|
||||
Controls.Add(_infoBar);
|
||||
}
|
||||
}
|
||||
catch (NullReferenceException)
|
||||
{
|
||||
}
|
||||
});
|
||||
|
||||
PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewed());
|
||||
@@ -256,14 +247,11 @@ namespace Microsoft.PowerToys.PreviewHandler.Markdown
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewError { Message = ex.Message });
|
||||
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
Controls.Clear();
|
||||
_infoBarDisplayed = true;
|
||||
_infoBar = GetTextBoxControl(Resources.MarkdownNotPreviewedError);
|
||||
Resize += FormResized;
|
||||
Controls.Add(_infoBar);
|
||||
});
|
||||
Controls.Clear();
|
||||
_infoBarDisplayed = true;
|
||||
_infoBar = GetTextBoxControl(Resources.MarkdownNotPreviewedError);
|
||||
Resize += FormResized;
|
||||
Controls.Add(_infoBar);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
63
src/modules/previewpane/MarkdownPreviewHandler/Program.cs
Normal file
63
src/modules/previewpane/MarkdownPreviewHandler/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.
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Markdown
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Windows.Threading;
|
||||
using Common.UI;
|
||||
using interop;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
|
||||
|
||||
private static MarkdownPreviewHandlerControl _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 MarkdownPreviewHandlerControl();
|
||||
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
|
||||
_previewHandlerControl.DoPreview(filePath);
|
||||
|
||||
NativeEventWaiter.WaitForEventLoop(
|
||||
Constants.MarkdownPreviewResizeEvent(),
|
||||
() =>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview</PublishDir>
|
||||
<RuntimeIdentifier>win10-$(Platform)</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>False</PublishSingleFile>
|
||||
<PublishReadyToRun>False</PublishReadyToRun>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "pch.h"
|
||||
#include "ClassFactory.h"
|
||||
#include "MarkdownPreviewHandler.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;
|
||||
|
||||
MarkdownPreviewHandler* pExt = new (std::nothrow) MarkdownPreviewHandler();
|
||||
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,263 @@
|
||||
#include "pch.h"
|
||||
#include "MarkdownPreviewHandler.h"
|
||||
#include "Generated Files/resource.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>
|
||||
|
||||
extern HINSTANCE g_hInst;
|
||||
extern long g_cDllRef;
|
||||
|
||||
MarkdownPreviewHandler::MarkdownPreviewHandler() :
|
||||
m_cRef(1), m_hwndParent(NULL), m_rcParent(), m_punkSite(NULL), m_process(NULL)
|
||||
{
|
||||
m_resizeEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::MARKDOWN_PREVIEW_RESIZE_EVENT);
|
||||
|
||||
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
|
||||
logFilePath.append(LogSettings::mdPrevLogPath);
|
||||
Logger::init(LogSettings::mdPrevLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||
|
||||
InterlockedIncrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
MarkdownPreviewHandler::~MarkdownPreviewHandler()
|
||||
{
|
||||
InterlockedDecrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
#pragma region IUnknown
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
static const QITAB qit[] = {
|
||||
QITABENT(MarkdownPreviewHandler, IPreviewHandler),
|
||||
QITABENT(MarkdownPreviewHandler, IInitializeWithFile),
|
||||
QITABENT(MarkdownPreviewHandler, IPreviewHandlerVisuals),
|
||||
QITABENT(MarkdownPreviewHandler, IOleWindow),
|
||||
QITABENT(MarkdownPreviewHandler, IObjectWithSite),
|
||||
{ 0 },
|
||||
};
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
MarkdownPreviewHandler::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
MarkdownPreviewHandler::Release()
|
||||
{
|
||||
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||
if (0 == cRef)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return cRef;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IInitializationWithFile
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::Initialize(LPCWSTR pszFilePath, DWORD grfMode)
|
||||
{
|
||||
m_filePath = pszFilePath;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IPreviewHandler
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::SetWindow(HWND hwnd, const RECT* prc)
|
||||
{
|
||||
if (hwnd && prc)
|
||||
{
|
||||
m_hwndParent = hwnd;
|
||||
m_rcParent = *prc;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::SetFocus()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::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 MarkdownPreviewHandler::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 MarkdownPreviewHandler::SetRect(const RECT* prc)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (prc != NULL)
|
||||
{
|
||||
if (!m_resizeEvent)
|
||||
{
|
||||
Logger::error(L"Failed to create resize event for MDPreviewHandler");
|
||||
}
|
||||
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 MDPreviewHandler");
|
||||
}
|
||||
}
|
||||
}
|
||||
m_rcParent = *prc;
|
||||
hr = S_OK;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::DoPreview()
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger::info(L"Starting MarkdownPreviewHandler.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.MarkdownPreviewHandler.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 MarkdownPreviewHandler.exe. Error: {}", errorMessage);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::Unload()
|
||||
|
||||
{
|
||||
Logger::info(L"Unload and terminate .exe");
|
||||
|
||||
TerminateProcess(m_process, 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IPreviewHandlerVisuals
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::SetBackgroundColor(COLORREF color)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::SetFont(const LOGFONTW* plf)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::SetTextColor(COLORREF color)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IOleWindow
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::GetWindow(HWND* phwnd)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (phwnd)
|
||||
{
|
||||
*phwnd = m_hwndParent;
|
||||
hr = S_OK;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::ContextSensitiveHelp(BOOL fEnterMode)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IObjectWithSite
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::SetSite(IUnknown* punkSite)
|
||||
{
|
||||
if (m_punkSite)
|
||||
{
|
||||
m_punkSite->Release();
|
||||
m_punkSite = NULL;
|
||||
}
|
||||
return punkSite ? punkSite->QueryInterface(&m_punkSite) : S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MarkdownPreviewHandler::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 MarkdownPreviewHandler :
|
||||
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);
|
||||
|
||||
MarkdownPreviewHandler();
|
||||
protected:
|
||||
~MarkdownPreviewHandler();
|
||||
|
||||
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,128 @@
|
||||
<?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.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
|
||||
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h markdownpreviewhandler.base.rc markdownpreviewhandler.rc" />
|
||||
</Target>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{ed9a1ac6-aeb0-4569-a6e9-e1696182b545}</ProjectGuid>
|
||||
<RootNamespace>MarkdownPreviewHandlerCpp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</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>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</OutDir>
|
||||
<CopyCppRuntimeToOutputDir>true</CopyCppRuntimeToOutputDir>
|
||||
</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="MarkdownPreviewHandler.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.base.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ClassFactory.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="MarkdownPreviewHandler.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="GlobalExportFunctions.def" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Generated Files/markdownpreviewhandler.rc" />
|
||||
<None Include="markdownpreviewhandler.base.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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Resources.resx" />
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?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="MarkdownPreviewHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.base.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header 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="MarkdownPreviewHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="GlobalExportFunctions.def">
|
||||
<Filter>Source Files</Filter>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
<None Include="markdownpreviewhandler.base.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
<None Include="Resources.resx">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Generated Files/markdownpreviewhandler.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
113
src/modules/previewpane/MarkdownPreviewHandlerCpp/Resources.resx
Normal file
113
src/modules/previewpane/MarkdownPreviewHandlerCpp/Resources.resx
Normal file
@@ -0,0 +1,113 @@
|
||||
<?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">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized CLR Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the CLR Framework object]
|
||||
</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 CLR 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.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: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" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" 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" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<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>
|
||||
</data>
|
||||
</root>
|
||||
@@ -0,0 +1,74 @@
|
||||
// dllmain.cpp : Defines the entry point for the DLL application.
|
||||
#include "pch.h"
|
||||
#include "ClassFactory.h"
|
||||
|
||||
HINSTANCE g_hInst = NULL;
|
||||
long g_cDllRef = 0;
|
||||
|
||||
// {60789D87-9C3C-44AF-B18C-3DE2C2820ED3}
|
||||
static const GUID CLSID_MarkdownPreviewHandler = { 0x60789d87, 0x9c3c, 0x44af, { 0xb1, 0x8c, 0x3d, 0xe2, 0xc2, 0x82, 0xe, 0xd3 } };
|
||||
|
||||
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_MarkdownPreviewHandler, 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,46 @@
|
||||
#include <windows.h>
|
||||
#include "resource.h"
|
||||
#include "../../../../common/version/version.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#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,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.220929.3" targetFramework="native" />
|
||||
</packages>
|
||||
@@ -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/MarkdownPreviewHandlerCpp/pch.h
Normal file
14
src/modules/previewpane/MarkdownPreviewHandlerCpp/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
|
||||
@@ -0,0 +1,13 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by powerpreview.rc
|
||||
|
||||
//////////////////////////////
|
||||
// Non-localizable
|
||||
|
||||
#define FILE_DESCRIPTION "PowerToys Markdown Preview Handler"
|
||||
#define INTERNAL_NAME "PowerToys.MarkdownPreviewHandler"
|
||||
#define ORIGINAL_FILENAME "PowerToys.MarkdownPreviewHandlerCpp.dll"
|
||||
|
||||
// Non-localizable
|
||||
//////////////////////////////
|
||||
14
src/modules/previewpane/MarkdownPreviewHandlerCpp/resource.h
Normal file
14
src/modules/previewpane/MarkdownPreviewHandlerCpp/resource.h
Normal file
@@ -0,0 +1,14 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by markdownpreviewhandler.base.rc
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 101
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,72 +0,0 @@
|
||||
// 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.Monaco
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Common;
|
||||
|
||||
/// <summary>
|
||||
/// Implementation of preview handler for files with source code.
|
||||
/// </summary>
|
||||
[Guid("afbd5a44-2520-4ae0-9224-6cfce8fe4400")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComVisible(true)]
|
||||
public class MonacoPreviewHandler : FileBasedPreviewHandler, IDisposable
|
||||
{
|
||||
private MonacoPreviewHandlerControl _monacoPreviewHandlerControl;
|
||||
private bool _disposedValue;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MonacoPreviewHandler"/> class.
|
||||
/// </summary>
|
||||
public MonacoPreviewHandler()
|
||||
{
|
||||
this.Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[STAThread]
|
||||
public override void DoPreview()
|
||||
{
|
||||
_monacoPreviewHandlerControl.DoPreview(FilePath);
|
||||
}
|
||||
|
||||
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
|
||||
{
|
||||
_monacoPreviewHandlerControl = new MonacoPreviewHandlerControl();
|
||||
|
||||
return _monacoPreviewHandlerControl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes objects
|
||||
/// </summary>
|
||||
/// <param name="disposing">Is Disposing</param>
|
||||
[STAThread]
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_monacoPreviewHandlerControl.Dispose();
|
||||
}
|
||||
|
||||
_disposedValue = true;
|
||||
this.Unload();
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[STAThread]
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<AssemblyTitle>PowerToys.MonacoPreviewHandler</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys MonacoPreviewHandler</AssemblyDescription>
|
||||
<Description>PowerToys MonacoPreviewHandler</Description>
|
||||
@@ -9,14 +11,22 @@
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<RuntimeIdentifiers>win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||
<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" />
|
||||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Monaco</RootNamespace>
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
<AssemblyName>PowerToys.MonacoPreviewHandler</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -35,6 +45,7 @@
|
||||
<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>
|
||||
|
||||
@@ -107,13 +107,10 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
|
||||
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMonacoPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
|
||||
{
|
||||
// GPO is disabling this utility. Show an error message instead.
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
_infoBarAdded = true;
|
||||
AddTextBoxControl(Properties.Resources.GpoDisabledErrorText);
|
||||
Resize += FormResized;
|
||||
base.DoPreview(dataSource);
|
||||
});
|
||||
_infoBarAdded = true;
|
||||
AddTextBoxControl(Properties.Resources.GpoDisabledErrorText);
|
||||
Resize += FormResized;
|
||||
base.DoPreview(dataSource);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -132,7 +129,7 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
|
||||
// Checks if dataSource is a string
|
||||
if (!(dataSource is string filePath))
|
||||
{
|
||||
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MonacoPreviewHandler)} must be a string but was a '{typeof(T)}'");
|
||||
throw new ArgumentException($"{nameof(dataSource)} for {nameof(MonacoPreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
|
||||
}
|
||||
|
||||
// Check if the file is too big.
|
||||
@@ -145,103 +142,94 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
|
||||
|
||||
try
|
||||
{
|
||||
InvokeOnControlThread(() =>
|
||||
Logger.LogInfo("Create WebView2 environment");
|
||||
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
|
||||
webView2EnvironmentAwaiter = CoreWebView2Environment
|
||||
.CreateAsync(userDataFolder: System.Environment.GetEnvironmentVariable("USERPROFILE") +
|
||||
"\\AppData\\LocalLow\\Microsoft\\PowerToys\\MonacoPreview-Temp")
|
||||
.ConfigureAwait(true).GetAwaiter();
|
||||
webView2EnvironmentAwaiter.OnCompleted(async () =>
|
||||
{
|
||||
Logger.LogInfo("Create WebView2 environment");
|
||||
ConfiguredTaskAwaitable<CoreWebView2Environment>.ConfiguredTaskAwaiter
|
||||
webView2EnvironmentAwaiter = CoreWebView2Environment
|
||||
.CreateAsync(userDataFolder: System.Environment.GetEnvironmentVariable("USERPROFILE") +
|
||||
"\\AppData\\LocalLow\\Microsoft\\PowerToys\\MonacoPreview-Temp")
|
||||
.ConfigureAwait(true).GetAwaiter();
|
||||
webView2EnvironmentAwaiter.OnCompleted(() =>
|
||||
_loadingBar.Value = 60;
|
||||
this.Update();
|
||||
try
|
||||
{
|
||||
_loadingBar.Value = 60;
|
||||
this.Update();
|
||||
InvokeOnControlThread(async () =>
|
||||
if (CoreWebView2Environment.GetAvailableBrowserVersionString() == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (CoreWebView2Environment.GetAvailableBrowserVersionString() == null)
|
||||
{
|
||||
throw new WebView2RuntimeNotFoundException();
|
||||
}
|
||||
throw new WebView2RuntimeNotFoundException();
|
||||
}
|
||||
|
||||
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
|
||||
_webView2Environment = webView2EnvironmentAwaiter.GetResult();
|
||||
|
||||
_loadingBar.Value = 70;
|
||||
this.Update();
|
||||
_loadingBar.Value = 70;
|
||||
this.Update();
|
||||
|
||||
// Initialize WebView
|
||||
try
|
||||
{
|
||||
await _webView.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
|
||||
// Initialize WebView
|
||||
try
|
||||
{
|
||||
await _webView.EnsureCoreWebView2Async(_webView2Environment).ConfigureAwait(true);
|
||||
|
||||
// Wait until html is loaded
|
||||
initializeIndexFileAndSelectedFileTask.Wait();
|
||||
// Wait until html is loaded
|
||||
initializeIndexFileAndSelectedFileTask.Wait();
|
||||
|
||||
_webView.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, Settings.AssemblyDirectory, CoreWebView2HostResourceAccessKind.Allow);
|
||||
_webView.CoreWebView2.SetVirtualHostNameToFolderMapping(VirtualHostName, Settings.AssemblyDirectory, CoreWebView2HostResourceAccessKind.Allow);
|
||||
|
||||
Logger.LogInfo("Navigates to string of HTML file");
|
||||
Logger.LogInfo("Navigates to string of HTML file");
|
||||
|
||||
_webView.NavigateToString(_html);
|
||||
_webView.NavigationCompleted += WebView2Init;
|
||||
_webView.Height = this.Height;
|
||||
_webView.Width = this.Width;
|
||||
Controls.Add(_webView);
|
||||
_webView.SendToBack();
|
||||
_loadingBar.Value = 100;
|
||||
this.Update();
|
||||
}
|
||||
catch (NullReferenceException e)
|
||||
{
|
||||
Logger.LogError("NullReferenceException catched. Skipping exception.", e);
|
||||
}
|
||||
}
|
||||
catch (WebView2RuntimeNotFoundException e)
|
||||
{
|
||||
Logger.LogWarning("WebView2 was not found:");
|
||||
Logger.LogWarning(e.Message);
|
||||
Controls.Remove(_loading);
|
||||
Controls.Remove(_loadingBar);
|
||||
Controls.Remove(_loadingBackground);
|
||||
_webView.NavigateToString(_html);
|
||||
_webView.NavigationCompleted += WebView2Init;
|
||||
_webView.Height = this.Height;
|
||||
_webView.Width = this.Width;
|
||||
Controls.Add(_webView);
|
||||
_webView.SendToBack();
|
||||
_loadingBar.Value = 100;
|
||||
this.Update();
|
||||
}
|
||||
catch (NullReferenceException e)
|
||||
{
|
||||
Logger.LogError("NullReferenceException catched. Skipping exception.", e);
|
||||
}
|
||||
}
|
||||
catch (WebView2RuntimeNotFoundException e)
|
||||
{
|
||||
Logger.LogWarning("WebView2 was not found:");
|
||||
Logger.LogWarning(e.Message);
|
||||
Controls.Remove(_loading);
|
||||
Controls.Remove(_loadingBar);
|
||||
Controls.Remove(_loadingBackground);
|
||||
|
||||
// WebView2 not installed message
|
||||
Label errorMessage = new Label();
|
||||
errorMessage.Text = Resources.WebView2_Not_Installed_Message;
|
||||
errorMessage.Width = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Width + 10;
|
||||
errorMessage.Height = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height;
|
||||
Controls.Add(errorMessage);
|
||||
// WebView2 not installed message
|
||||
Label errorMessage = new Label();
|
||||
errorMessage.Text = Resources.WebView2_Not_Installed_Message;
|
||||
errorMessage.Width = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Width + 10;
|
||||
errorMessage.Height = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height;
|
||||
Controls.Add(errorMessage);
|
||||
|
||||
// Download Link
|
||||
Label downloadLink = new LinkLabel();
|
||||
downloadLink.Text = Resources.Download_WebView2;
|
||||
downloadLink.Click += DownloadLink_Click;
|
||||
downloadLink.Top = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height + 10;
|
||||
downloadLink.Width = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Width + 10;
|
||||
downloadLink.Height = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Height;
|
||||
Controls.Add(downloadLink);
|
||||
}
|
||||
});
|
||||
});
|
||||
// Download Link
|
||||
Label downloadLink = new LinkLabel();
|
||||
downloadLink.Text = Resources.Download_WebView2;
|
||||
downloadLink.Click += DownloadLink_Click;
|
||||
downloadLink.Top = TextRenderer.MeasureText(Resources.WebView2_Not_Installed_Message, errorMessage.Font).Height + 10;
|
||||
downloadLink.Width = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Width + 10;
|
||||
downloadLink.Height = TextRenderer.MeasureText(Resources.Download_WebView2, errorMessage.Font).Height;
|
||||
Controls.Add(downloadLink);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
Controls.Remove(_loading);
|
||||
Controls.Remove(_loadingBar);
|
||||
Controls.Remove(_loadingBackground);
|
||||
Label text = new Label();
|
||||
text.Text = Resources.Exception_Occurred;
|
||||
text.Text += e.Message;
|
||||
text.Text += "\n" + e.Source;
|
||||
text.Text += "\n" + e.StackTrace;
|
||||
text.Width = 500;
|
||||
text.Height = 10000;
|
||||
Controls.Add(text);
|
||||
Logger.LogError(e.Message);
|
||||
});
|
||||
Controls.Remove(_loading);
|
||||
Controls.Remove(_loadingBar);
|
||||
Controls.Remove(_loadingBackground);
|
||||
Label text = new Label();
|
||||
text.Text = Resources.Exception_Occurred;
|
||||
text.Text += e.Message;
|
||||
text.Text += "\n" + e.Source;
|
||||
text.Text += "\n" + e.StackTrace;
|
||||
text.Width = 500;
|
||||
text.Height = 10000;
|
||||
Controls.Add(text);
|
||||
Logger.LogError(e.Message);
|
||||
}
|
||||
|
||||
this.Resize += FormResize;
|
||||
@@ -249,18 +237,16 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
|
||||
else
|
||||
{
|
||||
Logger.LogInfo("File is too big to display. Showing error message");
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
Controls.Remove(_loading);
|
||||
_loadingBar.Dispose();
|
||||
Controls.Remove(_loadingBar);
|
||||
Controls.Remove(_loadingBackground);
|
||||
Label errorMessage = new Label();
|
||||
errorMessage.Text = Resources.Max_File_Size_Error.Replace("%1", (_settings.MaxFileSize / 1000).ToString(CultureInfo.CurrentCulture), StringComparison.InvariantCulture);
|
||||
errorMessage.Width = 500;
|
||||
errorMessage.Height = 50;
|
||||
Controls.Add(errorMessage);
|
||||
});
|
||||
|
||||
Controls.Remove(_loading);
|
||||
_loadingBar.Dispose();
|
||||
Controls.Remove(_loadingBar);
|
||||
Controls.Remove(_loadingBackground);
|
||||
Label errorMessage = new Label();
|
||||
errorMessage.Text = Resources.Max_File_Size_Error.Replace("%1", (_settings.MaxFileSize / 1000).ToString(CultureInfo.CurrentCulture), StringComparison.InvariantCulture);
|
||||
errorMessage.Width = 500;
|
||||
errorMessage.Height = 50;
|
||||
Controls.Add(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,46 +336,41 @@ namespace Microsoft.PowerToys.PreviewHandler.Monaco
|
||||
private void SetBackground()
|
||||
{
|
||||
Logger.LogTrace();
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
this.BackColor = Settings.BackgroundColor;
|
||||
});
|
||||
this.BackColor = Settings.BackgroundColor;
|
||||
}
|
||||
|
||||
private void InitializeLoadingScreen()
|
||||
{
|
||||
Logger.LogTrace();
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
_loadingBackground = new Label();
|
||||
_loadingBackground.BackColor = Settings.BackgroundColor;
|
||||
_loadingBackground.Width = this.Width;
|
||||
_loadingBackground.Height = this.Height;
|
||||
Controls.Add(_loadingBackground);
|
||||
_loadingBackground.BringToFront();
|
||||
_loadingBackground = new Label();
|
||||
_loadingBackground.BackColor = Settings.BackgroundColor;
|
||||
_loadingBackground.Width = this.Width;
|
||||
_loadingBackground.Height = this.Height;
|
||||
Controls.Add(_loadingBackground);
|
||||
_loadingBackground.BringToFront();
|
||||
|
||||
_loadingBar = new ProgressBar();
|
||||
_loadingBar.Width = this.Width - 10;
|
||||
_loadingBar.Location = new Point(5, this.Height / 2);
|
||||
_loadingBar.Maximum = 100;
|
||||
_loadingBar.Value = 10;
|
||||
Controls.Add(_loadingBar);
|
||||
_loadingBar = new ProgressBar();
|
||||
_loadingBar.Width = this.Width - 10;
|
||||
_loadingBar.Location = new Point(5, this.Height / 2);
|
||||
_loadingBar.Maximum = 100;
|
||||
_loadingBar.Value = 10;
|
||||
Controls.Add(_loadingBar);
|
||||
|
||||
_loading = new Label();
|
||||
_loading.Text = Resources.Loading_Screen_Message;
|
||||
_loading.Width = this.Width;
|
||||
_loading.Height = 45;
|
||||
_loading.Location = new Point(0, _loadingBar.Location.Y - _loading.Height);
|
||||
_loading.TextAlign = ContentAlignment.TopCenter;
|
||||
_loading.Font = new Font("MS Sans Serif", 16, FontStyle.Bold);
|
||||
_loading.ForeColor = Settings.TextColor;
|
||||
Controls.Add(_loading);
|
||||
_loading = new Label();
|
||||
_loading.Text = Resources.Loading_Screen_Message;
|
||||
_loading.Width = this.Width;
|
||||
_loading.Height = 45;
|
||||
_loading.Location = new Point(0, _loadingBar.Location.Y - _loading.Height);
|
||||
_loading.TextAlign = ContentAlignment.TopCenter;
|
||||
_loading.Font = new Font("MS Sans Serif", 16, FontStyle.Bold);
|
||||
_loading.ForeColor = Settings.TextColor;
|
||||
Controls.Add(_loading);
|
||||
|
||||
_loading.BringToFront();
|
||||
_loadingBar.BringToFront();
|
||||
_loading.BringToFront();
|
||||
_loadingBar.BringToFront();
|
||||
|
||||
this.Update();
|
||||
|
||||
this.Update();
|
||||
});
|
||||
Logger.LogInfo("Loading screen initialized");
|
||||
}
|
||||
|
||||
|
||||
63
src/modules/previewpane/MonacoPreviewHandler/Program.cs
Normal file
63
src/modules/previewpane/MonacoPreviewHandler/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.
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Monaco
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Windows.Threading;
|
||||
using Common.UI;
|
||||
using interop;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
|
||||
|
||||
private static MonacoPreviewHandlerControl _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 MonacoPreviewHandlerControl();
|
||||
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
|
||||
_previewHandlerControl.DoPreview(filePath);
|
||||
|
||||
NativeEventWaiter.WaitForEventLoop(
|
||||
Constants.DevFilesPreviewResizeEvent(),
|
||||
() =>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<PublishDir>$(PowerToysRoot)\$(Platform)\$(Configuration)\modules\FileExplorerPreview</PublishDir>
|
||||
<RuntimeIdentifier>win10-$(Platform)</RuntimeIdentifier>
|
||||
<SelfContained>false</SelfContained>
|
||||
<SelfContained>true</SelfContained>
|
||||
<PublishSingleFile>False</PublishSingleFile>
|
||||
<PublishReadyToRun>False</PublishReadyToRun>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "pch.h"
|
||||
#include "ClassFactory.h"
|
||||
#include "MonacoPreviewHandler.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;
|
||||
|
||||
MonacoPreviewHandler* pExt = new (std::nothrow) MonacoPreviewHandler();
|
||||
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,262 @@
|
||||
#include "pch.h"
|
||||
#include "MonacoPreviewHandler.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>
|
||||
|
||||
extern HINSTANCE g_hInst;
|
||||
extern long g_cDllRef;
|
||||
|
||||
MonacoPreviewHandler::MonacoPreviewHandler() :
|
||||
m_cRef(1), m_hwndParent(NULL), m_rcParent(), m_punkSite(NULL), m_process(NULL)
|
||||
{
|
||||
m_resizeEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::DEV_FILES_PREVIEW_RESIZE_EVENT);
|
||||
|
||||
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
|
||||
logFilePath.append(LogSettings::monacoPrevLogPath);
|
||||
Logger::init(LogSettings::monacoPrevLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||
|
||||
InterlockedIncrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
MonacoPreviewHandler::~MonacoPreviewHandler()
|
||||
{
|
||||
InterlockedDecrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
#pragma region IUnknown
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
static const QITAB qit[] = {
|
||||
QITABENT(MonacoPreviewHandler, IPreviewHandler),
|
||||
QITABENT(MonacoPreviewHandler, IInitializeWithFile),
|
||||
QITABENT(MonacoPreviewHandler, IPreviewHandlerVisuals),
|
||||
QITABENT(MonacoPreviewHandler, IOleWindow),
|
||||
QITABENT(MonacoPreviewHandler, IObjectWithSite),
|
||||
{ 0 },
|
||||
};
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
MonacoPreviewHandler::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
MonacoPreviewHandler::Release()
|
||||
{
|
||||
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||
if (0 == cRef)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return cRef;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IInitializationWithFile
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::Initialize(LPCWSTR pszFilePath, DWORD grfMode)
|
||||
{
|
||||
m_filePath = pszFilePath;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IPreviewHandler
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::SetWindow(HWND hwnd, const RECT* prc)
|
||||
{
|
||||
if (hwnd && prc)
|
||||
{
|
||||
m_hwndParent = hwnd;
|
||||
m_rcParent = *prc;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::SetFocus()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::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 MonacoPreviewHandler::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 MonacoPreviewHandler::SetRect(const RECT* prc)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (prc != NULL)
|
||||
{
|
||||
if (!m_resizeEvent)
|
||||
{
|
||||
Logger::error(L"Failed to create resize event for MonacoPreviewHandler");
|
||||
}
|
||||
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 MonacoPreviewHandler");
|
||||
}
|
||||
}
|
||||
}
|
||||
m_rcParent = *prc;
|
||||
hr = S_OK;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::DoPreview()
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger::info(L"Starting MonacoPreviewHandler.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.MonacoPreviewHandler.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 MonacoPreviewHandler.exe. Error: {}", errorMessage);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::Unload()
|
||||
{
|
||||
Logger::info(L"Unload and terminate .exe");
|
||||
|
||||
m_hwndParent = NULL;
|
||||
TerminateProcess(m_process, 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IPreviewHandlerVisuals
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::SetBackgroundColor(COLORREF color)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::SetFont(const LOGFONTW* plf)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::SetTextColor(COLORREF color)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IOleWindow
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::GetWindow(HWND* phwnd)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (phwnd)
|
||||
{
|
||||
*phwnd = m_hwndParent;
|
||||
hr = S_OK;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::ContextSensitiveHelp(BOOL fEnterMode)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IObjectWithSite
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::SetSite(IUnknown* punkSite)
|
||||
{
|
||||
if (m_punkSite)
|
||||
{
|
||||
m_punkSite->Release();
|
||||
m_punkSite = NULL;
|
||||
}
|
||||
return punkSite ? punkSite->QueryInterface(&m_punkSite) : S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP MonacoPreviewHandler::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,70 @@
|
||||
#pragma once
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <ShlObj.h>
|
||||
#include <string>
|
||||
|
||||
class MonacoPreviewHandler :
|
||||
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);
|
||||
|
||||
MonacoPreviewHandler();
|
||||
protected:
|
||||
~MonacoPreviewHandler();
|
||||
|
||||
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,119 @@
|
||||
<?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.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{b3e869c4-8210-4ebd-a621-ff4c4afcbfa9}</ProjectGuid>
|
||||
<RootNamespace>MonacoPreviewHandlerCpp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</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>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</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="MonacoPreviewHandler.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ClassFactory.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="MonacoPreviewHandler.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="GlobalExportFunctions.def" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="MonacoPreviewHandlerCpp.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>
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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="MonacoPreviewHandler.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="MonacoPreviewHandler.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="MonacoPreviewHandlerCpp.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
73
src/modules/previewpane/MonacoPreviewHandlerCpp/dllmain.cpp
Normal file
73
src/modules/previewpane/MonacoPreviewHandlerCpp/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;
|
||||
|
||||
// {D8034CFA-F34B-41FE-AD45-62FCBB52A6DA}
|
||||
static const GUID CLSID_MonacoPreviewHandler = { 0xd8034cfa, 0xf34b, 0x41fe, { 0xad, 0x45, 0x62, 0xfc, 0xbb, 0x52, 0xa6, 0xda } };
|
||||
|
||||
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_MonacoPreviewHandler, 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.220929.3" targetFramework="native" />
|
||||
</packages>
|
||||
5
src/modules/previewpane/MonacoPreviewHandlerCpp/pch.cpp
Normal file
5
src/modules/previewpane/MonacoPreviewHandlerCpp/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/MonacoPreviewHandlerCpp/pch.h
Normal file
14
src/modules/previewpane/MonacoPreviewHandlerCpp/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/MonacoPreviewHandlerCpp/resource.h
Normal file
13
src/modules/previewpane/MonacoPreviewHandlerCpp/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 Dev Files Preview Handler Module"
|
||||
#define INTERNAL_NAME "PowerToys.MonacoPreviewHandlerCpp"
|
||||
#define ORIGINAL_FILENAME "PowerToys.MonacoPreviewHandlerCpp.dll"
|
||||
|
||||
// Non-localizable
|
||||
//////////////////////////////
|
||||
@@ -1,71 +0,0 @@
|
||||
// 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;
|
||||
using Common;
|
||||
using Microsoft.PowerToys.Telemetry;
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Pdf
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of preview handler for pdf files.
|
||||
/// </summary>
|
||||
[Guid("07665729-6243-4746-95b7-79579308d1b2")]
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComVisible(true)]
|
||||
public class PdfPreviewHandler : StreamBasedPreviewHandler, IDisposable
|
||||
{
|
||||
private PdfPreviewHandlerControl _pdfPreviewHandlerControl;
|
||||
private bool _disposedValue;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PdfPreviewHandler"/> class.
|
||||
/// </summary>
|
||||
public PdfPreviewHandler()
|
||||
{
|
||||
Initialize();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DoPreview()
|
||||
{
|
||||
_pdfPreviewHandlerControl.DoPreview(Stream);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new Telemetry.Events.PdfFileHandlerLoaded());
|
||||
_pdfPreviewHandlerControl = new PdfPreviewHandlerControl();
|
||||
|
||||
return _pdfPreviewHandlerControl;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes objects
|
||||
/// </summary>
|
||||
/// <param name="disposing">Is Disposing</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_pdfPreviewHandlerControl.Dispose();
|
||||
}
|
||||
|
||||
_disposedValue = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Dispose()
|
||||
{
|
||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||
Dispose(disposing: true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<AssemblyTitle>PowerToys.PdfPreviewHandler</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys PdfPreviewHandler</AssemblyDescription>
|
||||
@@ -10,13 +12,21 @@
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<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>{69E1EE8D-143A-4060-9129-4658ACF14AAF}</ProjectGuid>
|
||||
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Pdf</RootNamespace>
|
||||
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
|
||||
<EnableComHosting>true</EnableComHosting>
|
||||
<AssemblyName>PowerToys.PdfPreviewHandler</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -40,6 +50,7 @@
|
||||
<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>
|
||||
@@ -48,7 +59,9 @@
|
||||
</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>
|
||||
|
||||
@@ -55,12 +55,9 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf
|
||||
if (global::PowerToys.GPOWrapper.GPOWrapper.GetConfiguredPdfPreviewEnabledValue() == global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)
|
||||
{
|
||||
// GPO is disabling this utility. Show an error message instead.
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
_infoBar = GetTextBoxControl(Resources.GpoDisabledErrorText);
|
||||
Controls.Add(_infoBar);
|
||||
base.DoPreview(dataSource);
|
||||
});
|
||||
_infoBar = GetTextBoxControl(Resources.GpoDisabledErrorText);
|
||||
Controls.Add(_infoBar);
|
||||
base.DoPreview(dataSource);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -69,7 +66,12 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf
|
||||
|
||||
try
|
||||
{
|
||||
using (var dataStream = new ReadonlyStream(dataSource as IStream))
|
||||
if (!(dataSource is string filePath))
|
||||
{
|
||||
throw new ArgumentException($"{nameof(dataSource)} for {nameof(PdfPreviewHandlerControl)} must be a string but was a '{typeof(T)}'");
|
||||
}
|
||||
|
||||
using (var dataStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
var memStream = new MemoryStream();
|
||||
dataStream.CopyTo(memStream);
|
||||
@@ -82,77 +84,71 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf
|
||||
|
||||
if (pdf.PageCount > 0)
|
||||
{
|
||||
InvokeOnControlThread(() =>
|
||||
_flowLayoutPanel = new FlowLayoutPanel
|
||||
{
|
||||
_flowLayoutPanel = new FlowLayoutPanel
|
||||
{
|
||||
AutoScroll = true,
|
||||
AutoSize = true,
|
||||
Dock = DockStyle.Fill,
|
||||
FlowDirection = FlowDirection.TopDown,
|
||||
WrapContents = false,
|
||||
};
|
||||
_flowLayoutPanel.Resize += FlowLayoutPanel_Resize;
|
||||
AutoScroll = true,
|
||||
AutoSize = true,
|
||||
Dock = DockStyle.Fill,
|
||||
FlowDirection = FlowDirection.TopDown,
|
||||
WrapContents = false,
|
||||
};
|
||||
_flowLayoutPanel.Resize += FlowLayoutPanel_Resize;
|
||||
|
||||
// Only show first 10 pages.
|
||||
for (uint i = 0; i < pdf.PageCount && i < 10; i++)
|
||||
// Only show first 10 pages.
|
||||
for (uint i = 0; i < pdf.PageCount && i < 10; i++)
|
||||
{
|
||||
using (var page = pdf.GetPage(i))
|
||||
{
|
||||
using (var page = pdf.GetPage(i))
|
||||
var image = PageToImage(page);
|
||||
|
||||
var picturePanel = new Panel()
|
||||
{
|
||||
var image = PageToImage(page);
|
||||
|
||||
var picturePanel = new Panel()
|
||||
{
|
||||
Name = "picturePanel",
|
||||
Margin = new Padding(6, 6, 6, 0),
|
||||
Size = CalculateSize(image),
|
||||
BorderStyle = BorderStyle.FixedSingle,
|
||||
};
|
||||
|
||||
var picture = new PictureBox
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Image = image,
|
||||
SizeMode = PictureBoxSizeMode.Zoom,
|
||||
};
|
||||
|
||||
picturePanel.Controls.Add(picture);
|
||||
_flowLayoutPanel.Controls.Add(picturePanel);
|
||||
}
|
||||
}
|
||||
|
||||
if (pdf.PageCount > 10)
|
||||
{
|
||||
var messageBox = new RichTextBox
|
||||
{
|
||||
Name = "messageBox",
|
||||
Text = Resources.PdfMorePagesMessage,
|
||||
BackColor = Color.LightYellow,
|
||||
Dock = DockStyle.Fill,
|
||||
Multiline = true,
|
||||
ReadOnly = true,
|
||||
ScrollBars = RichTextBoxScrollBars.None,
|
||||
BorderStyle = BorderStyle.None,
|
||||
Name = "picturePanel",
|
||||
Margin = new Padding(6, 6, 6, 0),
|
||||
Size = CalculateSize(image),
|
||||
BorderStyle = BorderStyle.FixedSingle,
|
||||
};
|
||||
messageBox.ContentsResized += RTBContentsResized;
|
||||
|
||||
_flowLayoutPanel.Controls.Add(messageBox);
|
||||
var picture = new PictureBox
|
||||
{
|
||||
Dock = DockStyle.Fill,
|
||||
Image = image,
|
||||
SizeMode = PictureBoxSizeMode.Zoom,
|
||||
};
|
||||
|
||||
picturePanel.Controls.Add(picture);
|
||||
_flowLayoutPanel.Controls.Add(picturePanel);
|
||||
}
|
||||
}
|
||||
|
||||
Controls.Add(_flowLayoutPanel);
|
||||
});
|
||||
if (pdf.PageCount > 10)
|
||||
{
|
||||
var messageBox = new RichTextBox
|
||||
{
|
||||
Name = "messageBox",
|
||||
Text = Resources.PdfMorePagesMessage,
|
||||
BackColor = Color.LightYellow,
|
||||
Dock = DockStyle.Fill,
|
||||
Multiline = true,
|
||||
ReadOnly = true,
|
||||
ScrollBars = RichTextBoxScrollBars.None,
|
||||
BorderStyle = BorderStyle.None,
|
||||
};
|
||||
messageBox.ContentsResized += RTBContentsResized;
|
||||
|
||||
_flowLayoutPanel.Controls.Add(messageBox);
|
||||
}
|
||||
|
||||
Controls.Add(_flowLayoutPanel);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (ex.Message.Contains("Unable to update the password. The value provided as the current password is incorrect.", StringComparison.Ordinal))
|
||||
{
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
Controls.Clear();
|
||||
_infoBar = GetTextBoxControl(Resources.PdfPasswordProtectedError);
|
||||
Controls.Add(_infoBar);
|
||||
});
|
||||
Controls.Clear();
|
||||
_infoBar = GetTextBoxControl(Resources.PdfPasswordProtectedError);
|
||||
Controls.Add(_infoBar);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -171,12 +167,9 @@ namespace Microsoft.PowerToys.PreviewHandler.Pdf
|
||||
{
|
||||
PowerToysTelemetry.Log.WriteEvent(new PdfFilePreviewError { Message = ex.Message });
|
||||
|
||||
InvokeOnControlThread(() =>
|
||||
{
|
||||
Controls.Clear();
|
||||
_infoBar = GetTextBoxControl(Resources.PdfNotPreviewedError);
|
||||
Controls.Add(_infoBar);
|
||||
});
|
||||
Controls.Clear();
|
||||
_infoBar = GetTextBoxControl(Resources.PdfNotPreviewedError);
|
||||
Controls.Add(_infoBar);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
63
src/modules/previewpane/PdfPreviewHandler/Program.cs
Normal file
63
src/modules/previewpane/PdfPreviewHandler/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.
|
||||
|
||||
namespace Microsoft.PowerToys.PreviewHandler.Pdf
|
||||
{
|
||||
using System.Globalization;
|
||||
using System.Windows.Threading;
|
||||
using Common.UI;
|
||||
using interop;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
private static CancellationTokenSource _tokenSource = new CancellationTokenSource();
|
||||
|
||||
private static PdfPreviewHandlerControl _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 PdfPreviewHandlerControl();
|
||||
_previewHandlerControl.SetWindow((IntPtr)hwnd, s);
|
||||
_previewHandlerControl.DoPreview(filePath);
|
||||
|
||||
NativeEventWaiter.WaitForEventLoop(
|
||||
Constants.PdfPreviewResizeEvent(),
|
||||
() =>
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "pch.h"
|
||||
#include "ClassFactory.h"
|
||||
#include "PdfPreviewHandler.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;
|
||||
|
||||
PdfPreviewHandler* pExt = new (std::nothrow) PdfPreviewHandler();
|
||||
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/PdfPreviewHandlerCpp/ClassFactory.h
Normal file
24
src/modules/previewpane/PdfPreviewHandlerCpp/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,261 @@
|
||||
#include "pch.h"
|
||||
#include "PdfPreviewHandler.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>
|
||||
|
||||
extern HINSTANCE g_hInst;
|
||||
extern long g_cDllRef;
|
||||
|
||||
PdfPreviewHandler::PdfPreviewHandler() :
|
||||
m_cRef(1), m_hwndParent(NULL), m_rcParent(), m_punkSite(NULL), m_process(NULL)
|
||||
{
|
||||
m_resizeEvent = CreateEvent(nullptr, false, false, CommonSharedConstants::PDF_PREVIEW_RESIZE_EVENT);
|
||||
|
||||
std::filesystem::path logFilePath(PTSettingsHelper::get_local_low_folder_location());
|
||||
logFilePath.append(LogSettings::pdfPrevLogPath);
|
||||
Logger::init(LogSettings::pdfPrevLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());
|
||||
|
||||
InterlockedIncrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
PdfPreviewHandler::~PdfPreviewHandler()
|
||||
{
|
||||
InterlockedDecrement(&g_cDllRef);
|
||||
}
|
||||
|
||||
#pragma region IUnknown
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::QueryInterface(REFIID riid, void** ppv)
|
||||
{
|
||||
static const QITAB qit[] = {
|
||||
QITABENT(PdfPreviewHandler, IPreviewHandler),
|
||||
QITABENT(PdfPreviewHandler, IInitializeWithFile),
|
||||
QITABENT(PdfPreviewHandler, IPreviewHandlerVisuals),
|
||||
QITABENT(PdfPreviewHandler, IOleWindow),
|
||||
QITABENT(PdfPreviewHandler, IObjectWithSite),
|
||||
{ 0 },
|
||||
};
|
||||
return QISearch(this, qit, riid, ppv);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
PdfPreviewHandler::AddRef()
|
||||
{
|
||||
return InterlockedIncrement(&m_cRef);
|
||||
}
|
||||
|
||||
IFACEMETHODIMP_(ULONG)
|
||||
PdfPreviewHandler::Release()
|
||||
{
|
||||
ULONG cRef = InterlockedDecrement(&m_cRef);
|
||||
if (0 == cRef)
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
return cRef;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IInitializationWithFile
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::Initialize(LPCWSTR pszFilePath, DWORD grfMode)
|
||||
{
|
||||
m_filePath = pszFilePath;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IPreviewHandler
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::SetWindow(HWND hwnd, const RECT* prc)
|
||||
{
|
||||
if (hwnd && prc)
|
||||
{
|
||||
m_hwndParent = hwnd;
|
||||
m_rcParent = *prc;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::SetFocus()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::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 PdfPreviewHandler::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 PdfPreviewHandler::SetRect(const RECT* prc)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (prc != NULL)
|
||||
{
|
||||
if (!m_resizeEvent)
|
||||
{
|
||||
Logger::error(L"Failed to create resize event for PdfPreviewHandler");
|
||||
}
|
||||
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 PdfPreviewHandler");
|
||||
}
|
||||
}
|
||||
}
|
||||
hr = S_OK;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::DoPreview()
|
||||
{
|
||||
try
|
||||
{
|
||||
Logger::info(L"Starting PdfPreviewHandler.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.PdfPreviewHandler.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 PdfPreviewHandler.exe. Error: {}", errorMessage);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::Unload()
|
||||
{
|
||||
Logger::info(L"Unload and terminate .exe");
|
||||
|
||||
m_hwndParent = NULL;
|
||||
TerminateProcess(m_process, 0);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IPreviewHandlerVisuals
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::SetBackgroundColor(COLORREF color)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::SetFont(const LOGFONTW* plf)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::SetTextColor(COLORREF color)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IOleWindow
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::GetWindow(HWND* phwnd)
|
||||
{
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
if (phwnd)
|
||||
{
|
||||
*phwnd = m_hwndParent;
|
||||
hr = S_OK;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::ContextSensitiveHelp(BOOL fEnterMode)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region IObjectWithSite
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::SetSite(IUnknown* punkSite)
|
||||
{
|
||||
if (m_punkSite)
|
||||
{
|
||||
m_punkSite->Release();
|
||||
m_punkSite = NULL;
|
||||
}
|
||||
return punkSite ? punkSite->QueryInterface(&m_punkSite) : S_OK;
|
||||
}
|
||||
|
||||
IFACEMETHODIMP PdfPreviewHandler::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 PdfPreviewHandler :
|
||||
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);
|
||||
|
||||
PdfPreviewHandler();
|
||||
protected:
|
||||
~PdfPreviewHandler();
|
||||
|
||||
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,119 @@
|
||||
<?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.220929.3\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{54f7c616-fd41-4e62-bff9-015686914f4d}</ProjectGuid>
|
||||
<RootNamespace>PdfPreviewHandlerCpp</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</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>$(SolutionDir)$(Platform)\$(Configuration)\modules\FileExplorerPreview\</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="pch.h" />
|
||||
<ClInclude Include="PdfPreviewHandler.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ClassFactory.cpp" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader>Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PdfPreviewHandler.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="GlobalExportFunctions.def" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="PdfPreviewHandlerCpp.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>
|
||||
</ItemGroup>
|
||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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.220929.3\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.220929.3\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="PdfPreviewHandler.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="PdfPreviewHandler.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="PdfPreviewHandlerCpp.rc">
|
||||
<Filter>Resource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
73
src/modules/previewpane/PdfPreviewHandlerCpp/dllmain.cpp
Normal file
73
src/modules/previewpane/PdfPreviewHandlerCpp/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;
|
||||
|
||||
// {A5A41CC7-02CB-41D4-8C9B-9087040D6098}
|
||||
static const GUID CLSID_PdfPreviewHandler = { 0xa5a41cc7, 0x2cb, 0x41d4, { 0x8c, 0x9b, 0x90, 0x87, 0x4, 0xd, 0x60, 0x98 } };
|
||||
|
||||
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_PdfPreviewHandler, 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.220929.3" targetFramework="native" />
|
||||
</packages>
|
||||
5
src/modules/previewpane/PdfPreviewHandlerCpp/pch.cpp
Normal file
5
src/modules/previewpane/PdfPreviewHandlerCpp/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/PdfPreviewHandlerCpp/pch.h
Normal file
14
src/modules/previewpane/PdfPreviewHandlerCpp/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
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user