mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-06 03:07:04 +02:00
[EnvVar][Hosts][RegPrev]Decouple and refactor to make it "packable" as nuget package (#32604)
* WIP Hosts - remove deps * Add consumer app * Move App and MainWindow to Consumer app. Make Hosts dll * Try consume it * Fix errors * Make it work with custom build targets * Dependency injection Refactor Explicit page creation Wire missing dependencies * Fix installer * Remove unneeded stuff * Fix build again * Extract UI and logic from MainWindow to RegistryPreviewMainPage * Convert to lib Change namespace to RegistryPreviewUILib Remove PT deps * Add exe app and move App.xaml and MainWindow.xaml * Consume the lib * Update Hosts package creation * Fix RegistryPreview package creation * Rename RegistryPreviewUI back to RegistryPreview * Back to consuming lib * Ship icons and assets in nuget packages * Rename to EnvironmentVariablesUILib and convert to lib * Add app and consume * Telemetry * GPO * nuget * Rename HostsPackageConsumer to Hosts and Hosts lib to HostsUILib * Assets cleanup * nuget struct * v0 * assets * [Hosts] Re-add AppList to Lib Assets, [RegPrev] Copy lib assets to out dir * Sign UI dlls * Revert WinUIEx bump * Cleanup * Align deps * version exception dll * Fix RegistryPreview crashes * XAML format * XAML format 2 * Pack .pri files in lib/ dir --------- Co-authored-by: Darshak Bhatti <dabhatti@microsoft.com>
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 135 KiB |
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Windows.Data.Json;
|
||||
using WinUIEx;
|
||||
|
||||
namespace RegistryPreview
|
||||
{
|
||||
public sealed partial class MainWindow : WindowEx
|
||||
{
|
||||
/// <summary>
|
||||
/// Event handler to grab the main window's size and position before it closes
|
||||
/// </summary>
|
||||
private void AppWindow_Closing(Microsoft.UI.Windowing.AppWindow sender, Microsoft.UI.Windowing.AppWindowClosingEventArgs args)
|
||||
{
|
||||
jsonWindowPlacement.SetNamedValue("appWindow.Position.X", JsonValue.CreateNumberValue(appWindow.Position.X));
|
||||
jsonWindowPlacement.SetNamedValue("appWindow.Position.Y", JsonValue.CreateNumberValue(appWindow.Position.Y));
|
||||
jsonWindowPlacement.SetNamedValue("appWindow.Size.Width", JsonValue.CreateNumberValue(appWindow.Size.Width));
|
||||
jsonWindowPlacement.SetNamedValue("appWindow.Size.Height", JsonValue.CreateNumberValue(appWindow.Size.Height));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event that is will prevent the app from closing if the "save file" flag is active
|
||||
/// </summary>
|
||||
public void Window_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
// Save window placement
|
||||
SaveWindowPlacementFile(settingsFolder, windowPlacementFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
// 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.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Storage;
|
||||
using WinUIEx;
|
||||
|
||||
namespace RegistryPreview
|
||||
{
|
||||
public sealed partial class MainWindow : WindowEx
|
||||
{
|
||||
private void OpenWindowPlacementFile(string path, string filename)
|
||||
{
|
||||
string fileContents = string.Empty;
|
||||
string storageFile = Path.Combine(path, filename);
|
||||
if (File.Exists(storageFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
StreamReader reader = new StreamReader(storageFile);
|
||||
fileContents = reader.ReadToEnd();
|
||||
reader.Close();
|
||||
}
|
||||
catch
|
||||
{
|
||||
// set up default JSON blob
|
||||
fileContents = "{ }";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.Run(() => SaveWindowPlacementFile(path, filename)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
jsonWindowPlacement = Windows.Data.Json.JsonObject.Parse(fileContents);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// set up default JSON blob
|
||||
fileContents = "{ }";
|
||||
jsonWindowPlacement = Windows.Data.Json.JsonObject.Parse(fileContents);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the window placement JSON blob out to a local file
|
||||
/// </summary>
|
||||
private async void SaveWindowPlacementFile(string path, string filename)
|
||||
{
|
||||
StorageFolder storageFolder = null;
|
||||
StorageFile storageFile = null;
|
||||
string fileContents = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
storageFolder = await StorageFolder.GetFolderFromPathAsync(path);
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
Directory.CreateDirectory(path);
|
||||
storageFolder = await StorageFolder.GetFolderFromPathAsync(path);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
storageFile = await storageFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists);
|
||||
}
|
||||
catch (FileNotFoundException ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
storageFile = await storageFolder.CreateFileAsync(filename);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (jsonWindowPlacement != null)
|
||||
{
|
||||
fileContents = jsonWindowPlacement.Stringify();
|
||||
await Windows.Storage.FileIO.WriteTextAsync(storageFile, fileContents);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\Version.props" />
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows10.0.20348.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<RootNamespace>RegistryPreview</RootNamespace>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<Platforms>x86;x64;ARM64</Platforms>
|
||||
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<SelfContained>true</SelfContained>
|
||||
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps</OutputPath>
|
||||
<AssemblyName>PowerToys.RegistryPreview</AssemblyName>
|
||||
<ApplicationIcon>Assets\RegistryPreview\RegistryPreview.ico</ApplicationIcon>
|
||||
<!-- MRT from windows app sdk will search for a pri file with the same name of the module before defaulting to resources.pri -->
|
||||
<ProjectPriFileName>PowerToys.RegistryPreview.pri</ProjectPriFileName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Remove="RegistryPreviewXAML\App.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="RegistryPreviewXAML\App.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="RegistryPreviewXAML\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
|
||||
<PropertyGroup Condition="'$(Platform)'=='x64'">
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
|
||||
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
|
||||
Tools extension to be activated for this project even if the Windows App SDK Nuget
|
||||
package has not yet been restored.
|
||||
-->
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- HACK: Common.UI is referenced, even if it is not used, to force dll versions to be the same as in other projects that use it. It's still unclear why this is the case, but this is need for flattening the install directory. -->
|
||||
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
<ProjectReference Include="..\RegistryPreviewUILib\RegistryPreviewUILib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyPRIFileToOutputDir" AfterTargets="Build">
|
||||
<Message Text="Executing CopyDLLs task" Importance="High" />
|
||||
<ItemGroup>
|
||||
<PRIFile Include="$(OutDir)**\PowerToys.RegistryPreviewUILib.pri" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(PRIFile)" DestinationFolder="$(OutDir)" />
|
||||
|
||||
<Message Text="Copied build files" Importance="High" />
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
|
||||
Explorer "Package and Publish" context menu entry to be enabled for this project even if
|
||||
the Windows App SDK Nuget package has not yet been restored.
|
||||
-->
|
||||
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Application
|
||||
x:Class="RegistryPreview.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:RegistryPreview">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources xmlns="using:Microsoft.UI.Xaml.Controls" />
|
||||
<!-- Other merged dictionaries here -->
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
<!-- Other app resources here -->
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,106 @@
|
||||
// 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.Web;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
namespace RegistryPreview
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides application-specific behavior to supplement the default Application class.
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="App"/> class.
|
||||
/// Initializes the singleton application object. This is the first line of authored code
|
||||
/// executed, and as such is the logical equivalent of main() or WinMain().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the application is launched.
|
||||
/// </summary>
|
||||
/// <param name="args">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
|
||||
{
|
||||
// Keeping commented out but this is invaluable for protocol activation testing.
|
||||
// #if DEBUG
|
||||
// System.Diagnostics.Debugger.Launch();
|
||||
// #endif
|
||||
|
||||
// Open With... handler - gets activation arguments if they are available.
|
||||
AppActivationArguments activatedArgs = AppInstance.GetCurrent().GetActivatedEventArgs();
|
||||
if (activatedArgs.Kind == ExtendedActivationKind.File)
|
||||
{
|
||||
// Covers the double click exe scenario and treated as no file loaded
|
||||
AppFilename = string.Empty;
|
||||
if (activatedArgs.Data != null)
|
||||
{
|
||||
IFileActivatedEventArgs eventArgs = (IFileActivatedEventArgs)activatedArgs.Data;
|
||||
if (eventArgs.Files.Count > 0)
|
||||
{
|
||||
AppFilename = eventArgs.Files[0].Path;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (activatedArgs.Kind == ExtendedActivationKind.Protocol)
|
||||
{
|
||||
// When the app is the default handler for REG files and the filename has non-ASCII characters, the app gets activated by Protocol
|
||||
AppFilename = string.Empty;
|
||||
if (activatedArgs.Data != null)
|
||||
{
|
||||
IProtocolActivatedEventArgs eventArgs = (IProtocolActivatedEventArgs)activatedArgs.Data;
|
||||
if (eventArgs.Uri.AbsoluteUri.Length > 0)
|
||||
{
|
||||
AppFilename = eventArgs.Uri.Query.Replace("?ContractId=Windows.File&Verb=open&File=", string.Empty);
|
||||
AppFilename = HttpUtility.UrlDecode(AppFilename);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Right click on a REG file and selected Preview
|
||||
// Grab the command line parameters directly from the Environment since this is expected to be run
|
||||
// via Context Menu of a REG file.
|
||||
string[] cmdArgs = Environment.GetCommandLineArgs();
|
||||
if (cmdArgs == null)
|
||||
{
|
||||
// Covers the double click exe scenario and treated as no file loaded
|
||||
AppFilename = string.Empty;
|
||||
}
|
||||
else if (cmdArgs.Length == 2)
|
||||
{
|
||||
// GetCommandLineArgs() send in the called EXE as 0 and the selected filename as 1
|
||||
AppFilename = cmdArgs[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Anything else should be treated as no file loaded
|
||||
AppFilename = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
// Start the application
|
||||
appWindow = new MainWindow();
|
||||
appWindow.Activate();
|
||||
}
|
||||
|
||||
private Window appWindow;
|
||||
|
||||
#pragma warning disable SA1401 // Fields should be private
|
||||
#pragma warning disable CA2211 // Non-constant fields should not be visible. TODO: consider making it a property
|
||||
public static string AppFilename;
|
||||
#pragma warning restore CA2211 // Non-constant fields should not be visible
|
||||
#pragma warning restore SA1401 // Fields should be private
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
<winuiex:WindowEx
|
||||
x:Class="RegistryPreview.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:winuiex="using:WinUIEx"
|
||||
MinWidth="480"
|
||||
MinHeight="320"
|
||||
Closed="Window_Closed"
|
||||
mc:Ignorable="d">
|
||||
<Window.SystemBackdrop>
|
||||
<MicaBackdrop />
|
||||
</Window.SystemBackdrop>
|
||||
|
||||
<Grid x:Name="MainGrid" Loaded="Grid_Loaded">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid
|
||||
x:Name="titleBar"
|
||||
Grid.Row="0"
|
||||
Height="32"
|
||||
Margin="16,0"
|
||||
ColumnSpacing="16"
|
||||
IsHitTestVisible="True">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!--<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>-->
|
||||
<ColumnDefinition x:Name="IconColumn" Width="Auto" />
|
||||
<ColumnDefinition x:Name="TitleColumn" Width="Auto" />
|
||||
<!--<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>-->
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image
|
||||
Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Source="../Assets/RegistryPreview/RegistryPreview.ico" />
|
||||
<TextBlock
|
||||
x:Name="titleBarText"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding ApplicationTitle}" />
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</winuiex:WindowEx>
|
||||
@@ -0,0 +1,136 @@
|
||||
// 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 ManagedCommon;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using RegistryPreviewUILib;
|
||||
using Windows.Data.Json;
|
||||
using Windows.Graphics;
|
||||
using WinUIEx;
|
||||
|
||||
namespace RegistryPreview
|
||||
{
|
||||
public sealed partial class MainWindow : WindowEx
|
||||
{
|
||||
// Const values
|
||||
private const string APPNAME = "RegistryPreview";
|
||||
|
||||
// private members
|
||||
private Microsoft.UI.Windowing.AppWindow appWindow;
|
||||
private JsonObject jsonWindowPlacement;
|
||||
private string settingsFolder = string.Empty;
|
||||
private string windowPlacementFile = "app-placement.json";
|
||||
|
||||
private RegistryPreviewMainPage MainPage { get; }
|
||||
|
||||
internal MainWindow()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
// Open settings file; this moved to after the window tweak because it gives the window time to start up
|
||||
settingsFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Microsoft\PowerToys\" + APPNAME;
|
||||
OpenWindowPlacementFile(settingsFolder, windowPlacementFile);
|
||||
|
||||
// Update the Win32 looking window with the correct icon (and grab the appWindow handle for later)
|
||||
IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this);
|
||||
Microsoft.UI.WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);
|
||||
appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);
|
||||
appWindow.SetIcon("Assets\\RegistryPreview\\RegistryPreview.ico");
|
||||
|
||||
// TODO(stefan)
|
||||
appWindow.Closing += AppWindow_Closing;
|
||||
Activated += MainWindow_Activated;
|
||||
|
||||
// Extend the canvas to include the title bar so the app can support theming
|
||||
ExtendsContentIntoTitleBar = true;
|
||||
SetTitleBar(titleBar);
|
||||
|
||||
// if have settings, update the location of the window
|
||||
if (jsonWindowPlacement != null)
|
||||
{
|
||||
// resize the window
|
||||
if (jsonWindowPlacement.ContainsKey("appWindow.Size.Width") && jsonWindowPlacement.ContainsKey("appWindow.Size.Height"))
|
||||
{
|
||||
SizeInt32 size;
|
||||
size.Width = (int)jsonWindowPlacement.GetNamedNumber("appWindow.Size.Width");
|
||||
size.Height = (int)jsonWindowPlacement.GetNamedNumber("appWindow.Size.Height");
|
||||
|
||||
// check to make sure the size values are reasonable before attempting to restore the last saved size
|
||||
if (size.Width >= 320 && size.Height >= 240)
|
||||
{
|
||||
appWindow.Resize(size);
|
||||
}
|
||||
}
|
||||
|
||||
// reposition the window
|
||||
if (jsonWindowPlacement.ContainsKey("appWindow.Position.X") && jsonWindowPlacement.ContainsKey("appWindow.Position.Y"))
|
||||
{
|
||||
PointInt32 point;
|
||||
point.X = (int)jsonWindowPlacement.GetNamedNumber("appWindow.Position.X");
|
||||
point.Y = (int)jsonWindowPlacement.GetNamedNumber("appWindow.Position.Y");
|
||||
|
||||
// check to make sure the move values are reasonable before attempting to restore the last saved location
|
||||
if (point.X >= 0 && point.Y >= 0)
|
||||
{
|
||||
appWindow.Move(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MainPage = new RegistryPreviewMainPage(this, this.UpdateWindowTitle, App.AppFilename);
|
||||
|
||||
WindowHelpers.BringToForeground(windowHandle);
|
||||
}
|
||||
|
||||
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
|
||||
{
|
||||
if (args.WindowActivationState == WindowActivationState.Deactivated)
|
||||
{
|
||||
titleBarText.Foreground =
|
||||
(SolidColorBrush)Application.Current.Resources["WindowCaptionForegroundDisabled"];
|
||||
}
|
||||
else
|
||||
{
|
||||
titleBarText.Foreground =
|
||||
(SolidColorBrush)Application.Current.Resources["WindowCaptionForeground"];
|
||||
}
|
||||
}
|
||||
|
||||
private void Grid_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
MainGrid.Children.Add(MainPage);
|
||||
Grid.SetRow(MainPage, 1);
|
||||
}
|
||||
|
||||
public void UpdateWindowTitle(string title)
|
||||
{
|
||||
string filename = title;
|
||||
|
||||
if (string.IsNullOrEmpty(filename))
|
||||
{
|
||||
titleBarText.Text = APPNAME;
|
||||
appWindow.Title = APPNAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] file = filename.Split('\\');
|
||||
if (file.Length > 0)
|
||||
{
|
||||
titleBarText.Text = file[file.Length - 1] + " - " + APPNAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
titleBarText.Text = filename + " - " + APPNAME;
|
||||
}
|
||||
|
||||
// Continue to update the window's title, after updating the custom title bar
|
||||
appWindow.Title = titleBarText.Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root"
|
||||
xmlns=""
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
19
src/modules/registrypreview/RegistryPreview/app.manifest
Normal file
19
src/modules/registrypreview/RegistryPreview/app.manifest
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="RegistryPreview.app"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
|
||||
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
|
||||
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
Reference in New Issue
Block a user