From abc5c3e24967fab10509032b094654c1706d8756 Mon Sep 17 00:00:00 2001
From: Heiko <61519853+htcfreek@users.noreply.github.com>
Date: Fri, 13 Jun 2025 12:08:01 +0200
Subject: [PATCH] [RegistryPreview] Extended preview for value data (#37689)
## Summary of the Pull Request
Add a button to the data grid that shows a windows for complex value
preview.
### Screenshots
**Button**

**Context menu** (Usefull on long data, if button is scrolled out of
view.)

**Preview: REG_SZ**

**Preview: REG_MULTI_SZ**

**Preview: REG_EXPAND_SZ**

**Preview: REG_DWORD and REG_QWORD**

**Preview: REG_BINARY**


## PR Checklist
- [x] **Closes:** #36877
- [x] **Communication:** I've discussed this with core contributors
already. If work hasn't been agreed, this work might be rejected
- [x] **Tests:** Added/updated and all pass
- [x] **Localization:** All end user facing strings can be localized =>
missing yet
- [ ] **Dev docs:** Added/updated
- [ ] **New binaries:** Added on the required places
- [ ] [JSON for
signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json)
for new binaries
- [ ] [WXS for
installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs)
for new binaries and localization folder
- [ ] [YML for CI
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml)
for new test projects
- [ ] [YML for signed
pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml)
- [ ] **Documentation updated:** If checked, please file a pull request
on [our docs
repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys)
and link it here: #xxx
## Detailed Description of the Pull Request / Additional comments
Additionally this PR updates the context menu for values.
## Validation Steps Performed
Tested code with a local build.
---
.github/actions/spell-check/allow/names.txt | 3 +
.github/actions/spell-check/excludes.txt | 1 +
.github/actions/spell-check/expect.txt | 1 +
.pipelines/applyXamlStyling.ps1 | 7 +-
Directory.Packages.props | 2 +
NOTICE.md | 33 +
src/codeAnalysis/GlobalSuppressions.cs | 44 +
.../RegistryPreview/RegistryPreview.csproj | 2 +-
.../RegistryPreviewXAML/App.xaml | 26 +-
.../Controls/HexBox/AddressFormat.cs | 43 +
.../Controls/HexBox/CanvasCommands.cs | 43 +
.../Controls/HexBox/DataFormat.cs | 28 +
.../Controls/HexBox/DataSignedness.cs | 28 +
.../Controls/HexBox/DataType.cs | 43 +
.../Controls/HexBox/HexBox.cs | 2913 +++++++++++++++++
.../EndianConvert/EndianBinaryReader.cs | 231 ++
.../EndianConvert/EndianBitConverter.cs | 186 ++
.../Library/EndianConvert/Endianness.cs | 28 +
.../EndianConvert/FileFormatException.cs | 60 +
.../Controls/HexBox/TextFormat.cs | 23 +
.../Controls/HexBox/Themes/Generic.xaml | 170 +
.../Controls/HexBox/TypeConverters.cs | 264 ++
.../Controls/HexBox/Utilities.cs | 81 +
.../MonacoEditor}/MonacoEditorControl.xaml | 0
.../MonacoEditor}/MonacoEditorControl.xaml.cs | 0
.../MonacoEditor}/MonacoHelper.cs | 0
.../RegistryPreviewMainPage.DataPreview.cs | 341 ++
.../RegistryPreviewMainPage.Events.cs | 44 +-
.../RegistryPreviewMainPage.Utilities.cs | 1 +
.../RegistryPreviewMainPage.xaml | 59 +-
.../RegistryPreviewUILib.csproj | 20 +-
.../RegistryValue.xaml.cs | 7 +-
.../Strings/en-US/Resources.resw | 69 +-
.../RegistryPreviewUILib/Themes/Generic.xaml | 10 +
34 files changed, 4789 insertions(+), 22 deletions(-)
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/AddressFormat.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/CanvasCommands.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/DataFormat.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/DataSignedness.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/DataType.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/HexBox.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/Library/EndianConvert/EndianBinaryReader.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/Library/EndianConvert/EndianBitConverter.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/Library/EndianConvert/Endianness.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/Library/EndianConvert/FileFormatException.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/TextFormat.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/Themes/Generic.xaml
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/TypeConverters.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/Utilities.cs
rename src/modules/registrypreview/RegistryPreviewUILib/{ => Controls/MonacoEditor}/MonacoEditorControl.xaml (100%)
rename src/modules/registrypreview/RegistryPreviewUILib/{ => Controls/MonacoEditor}/MonacoEditorControl.xaml.cs (100%)
rename src/modules/registrypreview/RegistryPreviewUILib/{ => Controls/MonacoEditor}/MonacoHelper.cs (100%)
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.DataPreview.cs
create mode 100644 src/modules/registrypreview/RegistryPreviewUILib/Themes/Generic.xaml
diff --git a/.github/actions/spell-check/allow/names.txt b/.github/actions/spell-check/allow/names.txt
index f5d259c0f2..f570a231af 100644
--- a/.github/actions/spell-check/allow/names.txt
+++ b/.github/actions/spell-check/allow/names.txt
@@ -91,6 +91,7 @@ Hemmerlein
hlaueriksson
Horvalds
Howett
+hotkidfamily
htcfreek
Huynh
Ionut
@@ -98,6 +99,7 @@ jamrobot
Jaswal
Jaylyn
jefflord
+Jeremic
Jordi
jyuwono
kai
@@ -222,6 +224,7 @@ openai
Quickime
regedit
roslyn
+Skia
Spotify
Vanara
wangyi
diff --git a/.github/actions/spell-check/excludes.txt b/.github/actions/spell-check/excludes.txt
index f7fb1ec196..f5710e72ce 100644
--- a/.github/actions/spell-check/excludes.txt
+++ b/.github/actions/spell-check/excludes.txt
@@ -126,3 +126,4 @@
^src/common/sysinternals/Eula/
^tools/Verification scripts/Check preview handler registration\.ps1$
ignore$
+^src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/.*$
diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index 1dcfdef0e1..68555a02f9 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -1513,6 +1513,7 @@ SICHINT
SIDs
siex
sigdn
+Signedness
SIGNINGSCENARIO
signtool
SINGLEKEY
diff --git a/.pipelines/applyXamlStyling.ps1 b/.pipelines/applyXamlStyling.ps1
index 7cb7b4a4b0..1facedc569 100644
--- a/.pipelines/applyXamlStyling.ps1
+++ b/.pipelines/applyXamlStyling.ps1
@@ -41,6 +41,9 @@ Write-Output ""
Write-Output "Restoring dotnet tools..."
dotnet tool restore --disable-parallel --no-cache
+# Use Regex syntax
+$PathExcludes = "(\\obj\\)|(\\bin\\)|(\\x64\\)|(\\Generated Files\\PowerRenameXAML\\)|(\\RegistryPreviewUILib\\Controls\\HexBox\\)"
+
if (-not $Passive)
{
# Look for unstaged changed files by default
@@ -87,7 +90,7 @@ if (-not $Passive)
}
Write-Output "Running Git Diff: $gitDiffCommand"
- $files = Invoke-Expression $gitDiffCommand | Select-String -Pattern "\.xaml$"
+ $files = Invoke-Expression $gitDiffCommand | Select-String -Pattern "\.xaml$" | Where-Object { $_ -notmatch $PathExcludes }
if (-not $Passive -and -not $Main -and -not $Unstaged -and -not $Staged -and -not $LastCommit)
{
@@ -107,7 +110,7 @@ if (-not $Passive)
else
{
Write-Output "Checking all files (passively)"
- $files = Get-ChildItem -Path "$PSScriptRoot\..\src\*.xaml" -Recurse | Select-Object -ExpandProperty FullName | Where-Object { $_ -notmatch "(\\obj\\)|(\\bin\\)|(\\x64\\)|(\\Generated Files\\PowerRenameXAML\\)" }
+ $files = Get-ChildItem -Path "$PSScriptRoot\..\src\*.xaml" -Recurse | Select-Object -ExpandProperty FullName | Where-Object { $_ -notmatch $PathExcludes }
if ($files.count -gt 0)
{
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 8116fe99b6..06f8e8ddef 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -69,6 +69,8 @@
+
+
diff --git a/NOTICE.md b/NOTICE.md
index 2b94d67a4b..f36311d4ea 100644
--- a/NOTICE.md
+++ b/NOTICE.md
@@ -1427,6 +1427,37 @@ EXHIBIT A -Mozilla Public License.
## Utility: Registry Preview
+### HexBox.WinUI
+
+We use HexBox.WinUI to show a preview of binary values.
+
+**Source**: https://github.com/hotkidfamily/HexBox.WinUI
+
+```
+MIT License
+
+Copyright (c) 2019 Filip Jeremic
+Copyright (c) 2024~2025 hotkidfamily@gmail.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+```
+
### Monaco Editor
**Source**: https://github.com/Microsoft/monaco-editor
@@ -1457,6 +1488,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```
+
## NuGet Packages used by PowerToys
- AdaptiveCards.ObjectModel.WinUI3 2.0.0-beta
@@ -1517,6 +1549,7 @@ SOFTWARE.
- ReverseMarkdown 4.1.0
- ScipBe.Common.Office.OneNote 3.0.1
- SharpCompress 0.37.2
+- SkiaSharp.Views.WinUI 2.88.9
- StreamJsonRpc 2.21.69
- StyleCop.Analyzers 1.2.0-beta.556
- System.CodeDom 9.0.6
diff --git a/src/codeAnalysis/GlobalSuppressions.cs b/src/codeAnalysis/GlobalSuppressions.cs
index d5ff98e548..ae544b0c76 100644
--- a/src/codeAnalysis/GlobalSuppressions.cs
+++ b/src/codeAnalysis/GlobalSuppressions.cs
@@ -76,3 +76,47 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "Peek.FilePreviewer")]
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.INotifyPropertyChangedGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "type", Target = "~T:Peek.UI.Views.TitleBar")]
[assembly: SuppressMessage("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "MVVMTK0049:Using [INotifyPropertyChanged] is not AOT compatible for WinRT", Justification = "Updated MVVM toolkit package introduced this.", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib")]
+
+// HexBox control in RegistryPreviewUILib (We decided to copy the original code and not fix all theses problems for easier updating.)
+[assembly: SuppressMessage("Design", "CA1001:Types that own disposable fields should be disposable", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("Design", "CA1051:Do not declare visible instance fields", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("Globalization", "CA1305:Specify IFormatProvider", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("Naming", "CA1720:Identifiers should not contain type names", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("Performance", "CA1805:Do not initialize unnecessarily", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1623:Property summary documentation should match accessors", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1642:Constructor summary documentation should begin with standard text", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1648: has been used on an element that doesn't inherit from a base class or implement an interface.", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1500:Braces for multi-line statements should not share line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1502:Element should not be on a single line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1503:Braces should not be omitted", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1505:Opening braces should not be followed by blank line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1507:Code should not contain multiple blank lines in a row", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1508:Closing braces should not be preceded by blank line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1509:Opening braces should not be preceded by blank line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1512:Single-line comments should not be followed by blank line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1513:Closing brace should be followed by blank line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1514:Element documentation header should be preceded by blank line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1515:Single-line comment should be preceded by blank line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.LayoutRules", "SA1516:Elements should be separated by blank line", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1119:Statement should not use unnecessary parenthesis", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:File may only contain a single type", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1407:Arithmetic expressions should declare precedence", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1413:Use trailing comma in multi-line initializers", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1300:Element should begin with upper-case letter", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1306:Field names should begin with lower-case letter", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1312:Variable names should begin with lower-case letter", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1200:Using directives should be placed correctly", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1108:Block statements should not contain embedded comments", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1116:Split parameters should start on line after declaration", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1117:Parameters should be on same line or separate lines", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1129:Do not use default value type constructor", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1000:Keywords should be spaced correctly", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1003:Symbols should be spaced correctly", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1005:Single line comments should begin with single space", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1024:Colons Should Be Spaced Correctly", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1025:Code should not contain multiple whitespace in a row", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1028:Code should not contain trailing whitespace", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
+[assembly: SuppressMessage("Usage", "CsWinRT1028:Class is not marked partial", Justification = "", Scope = "namespaceanddescendants", Target = "RegistryPreviewUILib.HexBox")]
diff --git a/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj b/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj
index 36bd1f4f4d..8ca723808f 100644
--- a/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj
+++ b/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj
@@ -31,7 +31,7 @@
-
+
diff --git a/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml
index 7c2836890c..400d0c71fd 100644
--- a/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml
+++ b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml
@@ -10,7 +10,31 @@
-
+
+
+
+
+
+
+
+
+ 1
+ 1,1,1,2
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ 2
+
+
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/AddressFormat.cs b/src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/AddressFormat.cs
new file mode 100644
index 0000000000..8219ed8b51
--- /dev/null
+++ b/src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/AddressFormat.cs
@@ -0,0 +1,43 @@
+// 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.
+
+//
+// 2020-... created by Filip Jeremic (fjeremic) as "HexView.Wpf".
+// 2024-... republished by @hotkidfamily as "HexBox.WinUI".
+// 2025 Included in PowerToys. (Branch master; commit 72dcf64dc858c693a7a16887004c8ddbab61fce7.)
+//
+
+namespace RegistryPreviewUILib.HexBox
+{
+ ///
+ /// Enumerates the address column formatting options.
+ ///
+ public enum AddressFormat
+ {
+ ///
+ /// 16 bit HEX address "0000".
+ ///
+ Address16,
+
+ ///
+ /// 24 bit HEX address "00:0000".
+ ///
+ Address24,
+
+ ///
+ /// 32 bit HEX address "0000:0000".
+ ///
+ Address32,
+
+ ///
+ /// 48 bit HEX address "0000:00000000".
+ ///
+ Address48,
+
+ ///
+ /// 64 bit HEX address "00000000:00000000".
+ ///
+ Address64,
+ }
+}
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/CanvasCommands.cs b/src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/CanvasCommands.cs
new file mode 100644
index 0000000000..dca1f95725
--- /dev/null
+++ b/src/modules/registrypreview/RegistryPreviewUILib/Controls/HexBox/CanvasCommands.cs
@@ -0,0 +1,43 @@
+// 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.
+
+//
+// 2020-... created by Filip Jeremic (fjeremic) as "HexView.Wpf".
+// 2024-... republished by @hotkidfamily as "HexBox.WinUI".
+// 2025 Included in PowerToys. (Branch master; commit 72dcf64dc858c693a7a16887004c8ddbab61fce7.)
+//
+using System;
+using System.Windows.Input;
+
+namespace RegistryPreviewUILib.HexBox
+{
+ public class RelayCommand : ICommand
+ {
+ private readonly Action
-
+
+
+
@@ -51,6 +53,7 @@
+
@@ -59,10 +62,21 @@
Always
-
+
-
+
MSBuild:Compile
+
+ MSBuild:Compile
+
+
+ MSBuild:Compile
+
+
+
+
+
+
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs
index 1bf403c3fa..4bddb8d9a3 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs
@@ -6,7 +6,6 @@ using System;
using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;
using Microsoft.UI.Xaml;
-using Windows.ApplicationModel.DataTransfer;
namespace RegistryPreviewUILib
{
@@ -29,6 +28,8 @@ namespace RegistryPreviewUILib
public string Value { get; set; }
+ public bool IsEmptyBinary { private get; set; }
+
public string ValueOneLine => Value.Replace('\r', ' ');
public string ToolTipText { get; set; }
@@ -54,6 +55,10 @@ namespace RegistryPreviewUILib
}
}
+ public bool ShowPreviewButton =>
+ Type != "ERROR" && Type != string.Empty &&
+ Value != string.Empty && IsEmptyBinary != true;
+
public RegistryValue(string name, string type, string value, string key)
{
this.Name = name;
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw b/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw
index 9324207224..54ef71284e 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw
+++ b/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw
@@ -277,16 +277,20 @@
Copy path
Like "Copy item"
-
+
Copy name
Like "Copy item"
+
+ Copy
+ Like "Copy item"
+
- Copy type
+ Copy
Like "Copy item"
- Copy data
+ Copy
Like "Copy item"
@@ -297,6 +301,65 @@
Copy value with key path
Like "Copy item"
+
+ Show extended preview
+
+
+ Show extended preview
+
+
+ View data
+
+
+ Close
+ like "Close window"
+
+
+ Hexadecimal
+
+
+ Decimal
+
+
+ Raw value
+
+
+ Expanded value
+
+
+ Readable text
+ Means text that is human readable and not only control characters.
+
+
+ Data
+ Like "binary data"
+
+
+ Multiline text value
+
+
+ Text value
+
+
+ Binary data preview
+
+
+ Preview of readable text
+
+
+ Copy
+ Like "copy the value"
+
+
+ Copy text
+ Like "Copy the text"
+
+
+ Select all
+
+
+ Extended data preview
+
New
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/Themes/Generic.xaml b/src/modules/registrypreview/RegistryPreviewUILib/Themes/Generic.xaml
new file mode 100644
index 0000000000..35011f155b
--- /dev/null
+++ b/src/modules/registrypreview/RegistryPreviewUILib/Themes/Generic.xaml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+