Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RegistryPreview] Enhanced preview for value data #37689

Draft
wants to merge 30 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8d45aba
button and dummy dialog
htcfreek Feb 28, 2025
a8a75db
fill dialog with real data from datagrid
htcfreek Feb 28, 2025
56ab216
last changes
htcfreek Feb 28, 2025
9c48b9e
implement different layouts and improve dialoge
htcfreek Feb 28, 2025
e602563
code changes
htcfreek Feb 28, 2025
c8d1d5e
fix typos
htcfreek Feb 28, 2025
a9a9585
binary preview
htcfreek Feb 28, 2025
691b9ee
changes
htcfreek Feb 28, 2025
6bd2d55
changes
htcfreek Feb 28, 2025
b7ec010
fixes and code improvements
htcfreek Mar 1, 2025
15a89c5
add HexBox control
htcfreek Mar 1, 2025
dddb4c4
finally implement hex box
htcfreek Mar 1, 2025
7bb40dc
spell check + Notice.md
htcfreek Mar 1, 2025
8d14497
spell check
htcfreek Mar 1, 2025
6c95eae
translation and cleanup usings
htcfreek Mar 1, 2025
d60b83c
refactor code
htcfreek Mar 2, 2025
08f935f
changes for different view in binary preview
htcfreek Mar 2, 2025
f0fe236
finish implementation of extendet binary preview
htcfreek Mar 2, 2025
52e4d44
fix typos
htcfreek Mar 2, 2025
7db3c89
last changes
htcfreek Mar 2, 2025
a533c9d
cleanup
htcfreek Mar 3, 2025
12e4645
Color adjustments
htcfreek Mar 5, 2025
f4918f7
code styling
htcfreek Mar 5, 2025
ea9a239
use converter
htcfreek Mar 5, 2025
c06d4bc
Bump versions of HexBox.WinUI and Microsoft.Windows.CsWinRT
htcfreek Mar 6, 2025
62ca584
code fixes
htcfreek Mar 6, 2025
1fc2a88
last changes
htcfreek Mar 6, 2025
7393a33
High contrast fixes
htcfreek Mar 6, 2025
420e1eb
code improvements
htcfreek Mar 6, 2025
a918707
update Notice.md
htcfreek Mar 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spell-check/expect.txt
Original file line number Diff line number Diff line change
@@ -1459,6 +1459,7 @@ SICHINT
SIDs
siex
sigdn
Signedness
SIGNINGSCENARIO
Signtool
SINGLEKEY
8 changes: 5 additions & 3 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -29,7 +29,7 @@
<PackageVersion Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="9.0.0" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="9.0.2" />
<!-- Including Microsoft.Bcl.AsyncInterfaces to force version, since it's used by Microsoft.SemanticKernel. -->
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.2" />
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.2" />
<PackageVersion Include="Microsoft.Diagnostics.Tracing.TraceEvent" Version="3.1.16" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="9.0.2" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.2" />
@@ -48,7 +48,7 @@
TODO: in Common.Dotnet.CsWinRT.props, on upgrade, verify RemoveCsWinRTPackageAnalyzer is no longer needed.
This is present due to a bug in CsWinRT where WPF projects cause the analyzer to fail.
-->
<PackageVersion Include="Microsoft.Windows.CsWinRT" Version="2.1.5" />
<PackageVersion Include="Microsoft.Windows.CsWinRT" Version="2.2.0" />
<PackageVersion Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
<PackageVersion Include="Microsoft.WindowsAppSDK" Version="1.6.241114003" />
<PackageVersion Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
@@ -92,10 +92,12 @@
<PackageVersion Include="UTF.Unknown" Version="2.5.1" />
<PackageVersion Include="WinUIEx" Version="2.2.0" />
<PackageVersion Include="WPF-UI" Version="3.0.5" />
<!-- The warning NU1605 (package downgrade) is thrown in Version 0.1.9 for Microsoft.Windows.SDK.BuildTools -->
<PackageVersion Include="HexBox.WinUI" Version="0.2.0" NoWarn="NU1605" />
</ItemGroup>
<ItemGroup Condition="'$(IsExperimentationLive)'!=''">
<!-- Additional dependencies used by experimentation -->
<PackageVersion Include="Microsoft.VariantAssignment.Client" Version="2.4.17140001" />
<PackageVersion Include="Microsoft.VariantAssignment.Contract" Version="3.0.16990001" />
</ItemGroup>
</Project>
</Project>
3 changes: 2 additions & 1 deletion NOTICE.md
Original file line number Diff line number Diff line change
@@ -1335,7 +1335,7 @@ EXHIBIT A -Mozilla Public License.
- Microsoft.Win32.SystemEvents 9.0.2
- Microsoft.Windows.Compatibility 9.0.2
- Microsoft.Windows.CsWin32 0.2.46-beta
- Microsoft.Windows.CsWinRT 2.1.5
- Microsoft.Windows.CsWinRT 2.2.0
- Microsoft.Windows.SDK.BuildTools 10.0.22621.2428
- Microsoft.WindowsAppSDK 1.6.241114003
- Microsoft.Xaml.Behaviors.WinUI.Managed 2.0.9
@@ -1373,3 +1373,4 @@ EXHIBIT A -Mozilla Public License.
- UTF.Unknown 2.5.1
- WinUIEx 2.2.0
- WPF-UI 3.0.5
- HexBox.WinUI 0.1.9
Original file line number Diff line number Diff line change
@@ -32,6 +32,12 @@
<Folder Include="RegistryPreviewXAML\" />
</ItemGroup>

<PropertyGroup>
<!-- Properties for nuget package. -->
<!-- The warning NU1605 (package downgrade) is thrown by HexBox.WinUI in Version 0.1.9 for Microsoft.Windows.SDK.BuildTools -->
<NoWarn>NU1605</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" />
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" />
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
// 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.IO;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
using Microsoft.UI.Xaml.Media;
using Microsoft.Windows.ApplicationModel.Resources;
using Windows.Foundation.Metadata;
using Windows.UI.ViewManagement;
using HB = HexBox.WinUI;

namespace RegistryPreviewUILib
{
public sealed partial class RegistryPreviewMainPage : Page
{
private static bool _isDataPreviewHexBoxLoaded;

private static AccessibilitySettings accessibilitySettings = new AccessibilitySettings();

internal void ShowEnhancedDataPreview(string name, string type, string value)
{
// Create dialog
_isDataPreviewHexBoxLoaded = false;
var panel = new StackPanel()
{
Spacing = 16,
Padding = new Thickness(0),
};
ContentDialog contentDialog = new ContentDialog()
{
Title = resourceLoader.GetString("DataPreviewTitle") + " - " + name,
Content = panel,
CloseButtonText = resourceLoader.GetString("DataPreviewClose"),
DefaultButton = ContentDialogButton.Primary,
Padding = new Thickness(0),
};

// Add content based on value type
switch (type)
{
case "REG_DWORD":
case "REG_QWORD":
AddHexView(ref panel, ref resourceLoader, value);
break;
case "REG_NONE":
case "REG_BINARY":
// Convert value to BinaryReader
byte[] byteArray = Convert.FromHexString(value.Replace(" ", string.Empty));
MemoryStream memoryStream = new MemoryStream(byteArray);
BinaryReader binaryData = new BinaryReader(memoryStream);
binaryData.ReadBytes(byteArray.Length);

// Convert value to text
// For more printable asci characters the following code lines are required:
// var cpW1252 = CodePagesEncodingProvider.Instance.GetEncoding(1252);
// || b == 128 || (b >= 130 && b <= 140) || b == 142 || (b >= 145 & b <= 156) || b >= 158
// cpW1252.GetString([b]);
string binaryDataText = string.Empty;
foreach (byte b in byteArray)
{
// ASCII codes:
// 9, 10, 13: Space, Line Feed, Carriage Return
// 32-126: Printable characters
// 128, 130-140, 142, 145-156, 158-255: Extended printable characters
if (b == 9 || b == 10 || b == 13 || (b >= 32 && b <= 126))
{
binaryDataText += Convert.ToChar(b);
}
}

// Add controls
AddBinaryView(ref panel, ref resourceLoader, ref binaryData, binaryDataText);
break;
case "REG_MULTI_SZ":
var multiLineBox = new TextBox()
{
IsReadOnly = true,
AcceptsReturn = true,
TextWrapping = TextWrapping.NoWrap,
MaxHeight = 200,
FontSize = 14,
RequestedTheme = panel.ActualTheme,
Text = value,
};
ScrollViewer.SetVerticalScrollBarVisibility(multiLineBox, ScrollBarVisibility.Auto);
ScrollViewer.SetHorizontalScrollBarVisibility(multiLineBox, ScrollBarVisibility.Auto);
panel.Children.Add(multiLineBox);
break;
case "REG_EXPAND_SZ":
AddExpandStringView(ref panel, ref resourceLoader, value);
break;
default: // REG_SZ
var stringBox = new TextBox()
{
IsReadOnly = true,
FontSize = 14,
RequestedTheme = panel.ActualTheme,
Text = value,
};
panel.Children.Add(stringBox);
break;
}

// Use this code to associate the dialog to the appropriate AppWindow by setting
// the dialog's XamlRoot to the same XamlRoot as an element that is already present in the AppWindow.
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 8))
{
contentDialog.XamlRoot = this.Content.XamlRoot;
}

_ = contentDialog.ShowAsync();
}

private static void AddHexView(ref StackPanel panel, ref ResourceLoader resourceLoader, string value)
{
var hexBox = new TextBox()
{
Header = resourceLoader.GetString("DataPreviewHex"),
IsReadOnly = true,
FontSize = 14,
RequestedTheme = panel.ActualTheme,
Text = value.Split(" ")[0],
};
var decimalBox = new TextBox()
{
Header = resourceLoader.GetString("DataPreviewDec"),
IsReadOnly = true,
FontSize = 14,
RequestedTheme = panel.ActualTheme,
Text = value.Split(" ")[1].TrimStart('(').TrimEnd(')'),
};
panel.Children.Add(hexBox);
panel.Children.Add(decimalBox);
}

private static void AddBinaryView(ref StackPanel panel, ref ResourceLoader resourceLoader, ref BinaryReader data, string dataText)
{
// Create SelectorBar
var navBar = new SelectorBar()
{
RequestedTheme = panel.ActualTheme,
};
navBar.SelectionChanged += BinaryPreview_SelectorChanged;
navBar.Items.Add(new SelectorBarItem()
{
Text = resourceLoader.GetString("DataPreviewDataView"),
Tag = "DataView",
FontSize = 14,
RequestedTheme = panel.ActualTheme,
IsSelected = true,
});
navBar.Items.Add(new SelectorBarItem()
{
Text = resourceLoader.GetString("DataPreviewVisibleText"),
Tag = "TextView",
FontSize = 14,
RequestedTheme = panel.ActualTheme,
IsSelected = false,
});

// Create HexBox
var binaryPreviewBox = new HB.HexBox()
{
Height = 300,
Width = 500,
ShowAddress = true,
ShowData = true,
ShowText = true,
Columns = 8,
FontSize = 13,
RequestedTheme = panel.ActualTheme,
AddressBrush = (SolidColorBrush)Application.Current.Resources["AccentTextFillColorPrimaryBrush"],
AlternatingDataColumnTextBrush = (SolidColorBrush)Application.Current.Resources["TextFillColorSecondaryBrush"],
SelectionTextBrush = accessibilitySettings.HighContrast ? new SolidColorBrush((Windows.UI.Color)Application.Current.Resources["SystemColorHighlightTextColor"]) : (SolidColorBrush)Application.Current.Resources["TextOnAccentFillColorSelectedTextBrush"],
SelectionBrush = accessibilitySettings.HighContrast ? new SolidColorBrush((Windows.UI.Color)Application.Current.Resources["SystemColorHighlightColor"]) : (SolidColorBrush)Application.Current.Resources["AccentFillColorSelectedTextBackgroundBrush"],
DataFormat = HB.DataFormat.Hexadecimal,
DataSignedness = HB.DataSignedness.Unsigned,
DataType = HB.DataType.Int_1,
Visibility = Visibility.Collapsed,
DataSource = data,
};
binaryPreviewBox.Loaded += BinaryPreview_HexBoxLoaded;

// Create TextBox
var visibleText = new TextBox()
{
IsReadOnly = true,
AcceptsReturn = true,
TextWrapping = TextWrapping.Wrap,
Height = 300,
Width = 495,
FontSize = 13,
Text = dataText,
RequestedTheme = panel.ActualTheme,
Visibility = Visibility.Collapsed,
};

// Add controls: 0 = SelectorBar, 1 = ProgressRing, 2 = HexBox, 3 = TextBox
panel.Children.Add(navBar);
panel.Children.Add(new ProgressRing());
panel.Children.Add(binaryPreviewBox);
panel.Children.Add(visibleText);
}

private static void AddExpandStringView(ref StackPanel panel, ref ResourceLoader resourceLoader, string value)
{
var stringBoxRaw = new TextBox()
{
Header = resourceLoader.GetString("DataPreviewRawValue"),
IsReadOnly = true,
FontSize = 14,
RequestedTheme = panel.ActualTheme,
Text = value,
};
var stringBoxExp = new TextBox()
{
Header = resourceLoader.GetString("DataPreviewExpandedValue"),
IsReadOnly = true,
FontSize = 14,
RequestedTheme = panel.ActualTheme,
Text = Environment.ExpandEnvironmentVariables(value),
};
panel.Children.Add(stringBoxRaw);
panel.Children.Add(stringBoxExp);
}

private static void BinaryPreview_SelectorChanged(SelectorBar sender, SelectorBarSelectionChangedEventArgs args)
{
// Child controls: 0 = SelectorBar, 1 = ProgressRing, 2 = HexBox, 3 = TextBox
var stackPanel = sender.Parent as StackPanel;
var progressRing = (ProgressRing)stackPanel.Children[1];
var hexBox = (HB.HexBox)stackPanel.Children[2];
var textBox = (TextBox)stackPanel.Children[3];

if (sender.SelectedItem.Tag.ToString() == "DataView")
{
textBox.Visibility = Visibility.Collapsed;
if (_isDataPreviewHexBoxLoaded)
{
progressRing.Visibility = Visibility.Collapsed;
hexBox.Visibility = Visibility.Visible;
}
else
{
hexBox.Visibility = Visibility.Collapsed;
progressRing.Visibility = Visibility.Visible;
}
}
else
{
progressRing.Visibility = Visibility.Collapsed;
hexBox.Visibility = Visibility.Collapsed;
textBox.Visibility = Visibility.Visible;

// Workaround for wrong text selection (color) after switching back to "Visible text"
textBox.Focus(FocusState.Programmatic);
textBox.Select(0, 0);
}
}

private static void BinaryPreview_HexBoxLoaded(object sender, RoutedEventArgs e)
{
_isDataPreviewHexBoxLoaded = true;
var hexBox = (HB.HexBox)sender;
var stackPanel = hexBox.Parent as StackPanel;
var selectorBar = stackPanel.Children[0] as SelectorBar;
var progressRing = stackPanel.Children[1] as ProgressRing;

if (selectorBar.SelectedItem.Tag.ToString() == "DataView")
{
progressRing.Visibility = Visibility.Collapsed;
hexBox.Visibility = Visibility.Visible;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -357,5 +357,12 @@ private void MonacoEditor_TextChanged(object sender, EventArgs e)
saveButton.IsEnabled = true;
});
}

// Command to show data preview
public void ButtonEnhancePreview_Click(object sender, RoutedEventArgs e)
{
RegistryValue data = ((Button)sender).DataContext as RegistryValue;
ShowEnhancedDataPreview(data.Name, data.Type, data.Value);
}
}
}
Original file line number Diff line number Diff line change
@@ -479,6 +479,7 @@ private bool ParseRegistryFile(string filenameText)
case "REG_NONE":
if (value.Length <= 0)
{
registryValue.IsEmptyBinary = true;
value = resourceLoader.GetString("ZeroLength");
}
else
Loading
Oops, something went wrong.