Skip to content

Color picker wpf #37149

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

Merged
merged 17 commits into from
Mar 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions .github/actions/spell-check/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ GUITHREADINFO
GValue
gwl
GWLP
GWLSTYLE
hangeul
Hanzi
Hardlines
Expand Down Expand Up @@ -1631,6 +1632,8 @@ tkconverters
TLayout
tlb
tlbimp
TPMLEFTALIGN
TPMRETURNCMD
TMPVAR
TNP
Toolhelp
Expand Down Expand Up @@ -1838,6 +1841,7 @@ WMI
WMICIM
wmimgmt
wmp
WMSYSCOMMAND
wnd
WNDCLASS
WNDCLASSEX
Expand Down
6 changes: 2 additions & 4 deletions src/modules/colorPicker/ColorPickerUI/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@
x:Class="ColorPickerUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
StartupUri="MainWindow.xaml">
StartupUri="MainWindow.xaml"
ThemeMode="System">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
<ResourceDictionary Source="Resources/Styles.xaml" />
<ResourceDictionary Source="Resources/ViewModelViewMappings.xaml" />
</ResourceDictionary.MergedDictionaries>
Expand Down
68 changes: 39 additions & 29 deletions src/modules/colorPicker/ColorPickerUI/ColorEditorWindow.xaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<ui:FluentWindow
<Window
x:Class="ColorPicker.ColorEditorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand All @@ -7,41 +7,51 @@
xmlns:e="http://schemas.microsoft.com/xaml/behaviors"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:ColorPicker.Properties"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
Width="440"
Height="380"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
AutomationProperties.Name="{x:Static p:Resources.cp_editor}"
ExtendsContentIntoTitleBar="True"
ResizeMode="NoResize"
Topmost="True"
WindowCornerPreference="Default"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<e:Interaction.Behaviors>
<behaviors:CloseZoomWindowBehavior />
</e:Interaction.Behaviors>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ui:TitleBar
x:Name="TitleBar"
Title="{x:Static p:Resources.CP_Title}"
Grid.Row="0"
Height="32"
Padding="16,0,16,0"
ShowMaximize="False"
ShowMinimize="False">
<ui:TitleBar.Icon>
<ui:ImageIcon Source="pack://application:,,,/Assets/ColorPicker/icon.ico" />
</ui:TitleBar.Icon>
</ui:TitleBar>
<ContentPresenter
x:Name="contentPresenter"
Grid.Row="1"
Content="{Binding Content}" />
</Grid>
</ui:FluentWindow>
<Border x:Name="MainBorder" BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel
Grid.Row="0"
Background="Transparent"
MouseLeftButtonDown="TitleBar_MouseDown"
MouseRightButtonUp="TitleBar_MouseRightClick">
<Image
Width="20"
Height="20"
Margin="10,5,5,8"
Source="pack://application:,,,/Assets/ColorPicker/icon.ico" />
<TextBlock
Margin="10"
VerticalAlignment="Center"
Text="{x:Static p:Resources.CP_Title}" />
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
Width="50"
Height="30"
Margin="10,-10,-2,1"
Click="Close_Click"
Content="&#xE711;"
FontFamily="{StaticResource IconFontFamily}"
Style="{StaticResource TitleBarCloseButtonStyle}" />
</StackPanel>
</DockPanel>
<ContentPresenter
x:Name="contentPresenter"
Grid.Row="1"
Content="{Binding Content}" />
</Grid>
</Border>
</Window>
152 changes: 147 additions & 5 deletions src/modules/colorPicker/ColorPickerUI/ColorEditorWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,31 @@
// See the LICENSE file in the project root for more information.

using System;

using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Shell;
using ColorPicker.Helpers;
using ControlzEx.Theming;
using ManagedCommon;
using Wpf.Ui.Controls;
using Microsoft.Diagnostics.Tracing.Parsers.ClrPrivate;
using Microsoft.Win32;
using Windows.Graphics;

namespace ColorPicker
{
/// <summary>
/// Interaction logic for ColorEditorWindow.xaml
/// </summary>
public partial class ColorEditorWindow : FluentWindow
public partial class ColorEditorWindow : Window
{
private readonly AppStateHandler _appStateHandler;

public ColorEditorWindow(AppStateHandler appStateHandler)
{
InitializeComponent();
Wpf.Ui.Appearance.SystemThemeWatcher.Watch(this);
WindowBackdropType = OSVersionHelper.IsWindows11() ? WindowBackdropType.Mica : WindowBackdropType = WindowBackdropType.None;

_appStateHandler = appStateHandler;
Closing += ColorEditorWindow_Closing;
Expand All @@ -35,7 +41,143 @@ private void ColorEditorWindow_Closing(object sender, System.ComponentModel.Canc

protected override void OnSourceInitialized(EventArgs e)
{
WindowChrome.SetWindowChrome(
this,
new WindowChrome
{
CaptionHeight = 0,
CornerRadius = default,
GlassFrameThickness = new Thickness(-1),
ResizeBorderThickness = ResizeMode == ResizeMode.NoResize ? default : new Thickness(4),
UseAeroCaptionButtons = false,
});
if (OSVersionHelper.IsWindows11())
{
// ResizeMode="NoResize" removes rounded corners. So force them to rounded.
IntPtr hWnd = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
DWMWINDOWATTRIBUTE attribute = DWMWINDOWATTRIBUTE.DWMWA_WINDOW_CORNER_PREFERENCE;
DWM_WINDOW_CORNER_PREFERENCE preference = DWM_WINDOW_CORNER_PREFERENCE.DWMWCP_ROUND;
DwmSetWindowAttribute(hWnd, attribute, ref preference, sizeof(uint));
}
else
{
// On Windows10 ResizeMode="NoResize" removes the border so we add a new one.
MainBorder.BorderThickness = new System.Windows.Thickness(0.5);
}

// Hide then Show with WindowStyle="None" will remove the Mica effect. So manually remove the titlebar.
RemoveWindowTitlebarContents();

base.OnSourceInitialized(e);
}

public void RemoveWindowTitlebarContents()
{
IntPtr handle = new WindowInteropHelper(GetWindow(this)).EnsureHandle();
if (handle == IntPtr.Zero)
{
return;
}

int windowStyleLong = GetWindowLong(handle, GWLSTYLE);
windowStyleLong &= ~(int)WindowStyles.WS_SYSMENU;

IntPtr result = SetWindowLong(handle, GWLSTYLE, windowStyleLong);
if (result.ToInt64() == 0)
{
int error = Marshal.GetLastWin32Error();
Logger.LogError($"SetWindowLong error {error}");
}
}

private void Close_Click(object sender, RoutedEventArgs e)
{
Close();
}

private void TitleBar_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
this.DragMove();
}
}

private void TitleBar_MouseRightClick(object sender, MouseButtonEventArgs e)
{
IntPtr hwnd = new WindowInteropHelper(this).Handle;

// Get the mouse position relative to the screen
Point mousePosition = e.GetPosition(this);

Point screenPoint = PointToScreen(mousePosition);

// Display the system menu at the current mouse position
IntPtr hMenu = GetSystemMenu(hwnd, false);
if (hMenu != IntPtr.Zero)
{
int command = TrackPopupMenu(
hMenu,
TPMLEFTALIGN | TPMRETURNCMD,
(int)screenPoint.X,
(int)screenPoint.Y,
0,
hwnd,
IntPtr.Zero);
if (command > 0)
{
SendMessage(hwnd, WMSYSCOMMAND, new IntPtr(command), IntPtr.Zero);
}
}
}

private const int WMSYSCOMMAND = 0x0112;
private const int TPMLEFTALIGN = 0x0000;
private const int TPMRETURNCMD = 0x0100;

// The enum flag for DwmSetWindowAttribute's second parameter, which tells the function what attribute to set.
public enum DWMWINDOWATTRIBUTE
{
DWMWA_WINDOW_CORNER_PREFERENCE = 33,
}

public enum DWM_WINDOW_CORNER_PREFERENCE
{
DWMWCP_DEFAULT = 0,
DWMWCP_DONOTROUND = 1,
DWMWCP_ROUND = 2,
DWMWCP_ROUNDSMALL = 3,
}

// Import dwmapi.dll and define DwmSetWindowAttribute in C# corresponding to the native function.
[DllImport("dwmapi.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
internal static extern void DwmSetWindowAttribute(
IntPtr hwnd,
DWMWINDOWATTRIBUTE attribute,
ref DWM_WINDOW_CORNER_PREFERENCE pvAttribute,
uint cbAttribute);

[DllImport("user32.dll")]
private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);

[DllImport("user32.dll")]
private static extern int TrackPopupMenu(IntPtr hMenu, int uFlags, int x, int y, int nReserved, IntPtr hWnd, IntPtr prcRect);

[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", SetLastError = true)]
private static extern int GetWindowLong(IntPtr hWnd, int nIndex);

[DllImport("user32.dll", SetLastError = true)]
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

public const int GWLSTYLE = -16;

[Flags]
public enum WindowStyles : uint
{
WS_SYSMENU = 0x00080000, // System menu (close/maximize/minimize button area)
}
}
}
1 change: 0 additions & 1 deletion src/modules/colorPicker/ColorPickerUI/ColorPickerUI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
<PackageReference Include="System.IO.Abstractions" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" />
<PackageReference Include="System.Drawing.Common" />
<PackageReference Include="WPF-UI" />
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
xmlns:local="clr-namespace:ColorPicker"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:ColorPicker.Properties"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
mc:Ignorable="d">
<UserControl.Resources>
<Style x:Key="ReadonlyTextBoxStyle" TargetType="{x:Type TextBox}">
Expand Down Expand Up @@ -66,7 +65,6 @@
HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
IsTabStop="{TemplateBinding ScrollViewer.IsTabStop}"
Style="{StaticResource DefaultTextBoxScrollViewerStyle}"
TextElement.Foreground="{TemplateBinding Foreground}"
VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" />
</Grid>
Expand Down Expand Up @@ -173,7 +171,7 @@
Style="{StaticResource SubtleButtonStyle}"
ToolTipService.ToolTip="{x:Static p:Resources.Copy_to_clipboard}">
<Button.Content>
<ui:SymbolIcon FontSize="20" Symbol="Copy20" />
<TextBlock FontFamily="{StaticResource IconFontFamily}" Text="&#xE8C8;" />
</Button.Content>
</Button>
</Grid>
Expand Down
Loading
Loading