Change Titlebar to Custom TitleBar (SettingWindow)

This commit is contained in:
DB p 2021-11-15 05:08:01 +09:00
parent b7d5f4f342
commit 979a7b8b7b
3 changed files with 2084 additions and 1768 deletions

View file

@ -4,6 +4,89 @@
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:ui="http://schemas.modernwpf.com/2019">
<!-- Title Bar -->
<Style x:Key="WindowMainPanelStyle" TargetType="{x:Type Border}">
<Setter Property="BorderBrush" Value="{DynamicResource WindowBorderBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=WindowState}" Value="Maximized">
<Setter Property="BorderThickness" Value="1" />
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="TitleBarButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="{DynamicResource WindowTextBrush}" />
<Setter Property="Padding" Value="0" />
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border
x:Name="border"
Background="#f3f3f3"
BorderThickness="0"
SnapsToDevicePixels="true">
<ContentPresenter
x:Name="contentPresenter"
Margin="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Focusable="False"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="border" Property="Background" Value="#C6C6C6" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="border" Property="Background" Value="#B0B0B0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TitleBarCloseButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="Padding" Value="0" />
<Setter Property="WindowChrome.IsHitTestVisibleInChrome" Value="True" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border
x:Name="border"
Background="Transparent"
BorderThickness="0"
SnapsToDevicePixels="true">
<ContentPresenter
x:Name="contentPresenter"
Margin="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Focusable="False"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="border" Property="Background" Value="#E10000" />
<Setter Property="Foreground" Value="{DynamicResource MouseOverWindowCloseButtonForegroundBrush}" />
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter TargetName="border" Property="Background" Value="{DynamicResource PressedWindowCloseButtonBackgroundBrush}" />
<Setter Property="Foreground" Value="{DynamicResource MouseOverWindowCloseButtonForegroundBrush}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Repeat Button -->
<Style x:Key="DefaultRepeatButtonStyle" TargetType="RepeatButton">
<Setter Property="OverridesDefaultStyle" Value="True" />

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,7 @@ using Flow.Launcher.ViewModel;
using Flow.Launcher.Helper;
using System.Windows.Controls;
using Flow.Launcher.Core.ExternalPlugins;
using System.Runtime.InteropServices;
namespace Flow.Launcher
{
@ -297,5 +298,146 @@ namespace Flow.Launcher
textBox.MoveFocus(tRequest);
}
}
/* Custom TitleBar */
private void OnMinimizeButtonClick(object sender, RoutedEventArgs e)
{
this.WindowState = WindowState.Minimized;
}
private void OnMaximizeRestoreButtonClick(object sender, RoutedEventArgs e)
{
if (this.WindowState == WindowState.Maximized)
{
this.WindowState = WindowState.Normal;
}
else
{
this.WindowState = WindowState.Maximized;
}
}
private void OnCloseButtonClick(object sender, RoutedEventArgs e)
{
this.Close();
}
private void RefreshMaximizeRestoreButton()
{
if (this.WindowState == WindowState.Maximized)
{
this.maximizeButton.Visibility = Visibility.Collapsed;
this.restoreButton.Visibility = Visibility.Visible;
}
else
{
this.maximizeButton.Visibility = Visibility.Visible;
this.restoreButton.Visibility = Visibility.Collapsed;
}
}
private void Window_StateChanged(object sender, EventArgs e)
{
this.RefreshMaximizeRestoreButton();
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
((HwndSource)PresentationSource.FromVisual(this)).AddHook(HookProc);
}
public static IntPtr HookProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_GETMINMAXINFO)
{
// We need to tell the system what our size should be when maximized. Otherwise it will cover the whole screen,
// including the task bar.
MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
// Adjust the maximized size and position to fit the work area of the correct monitor
IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (monitor != IntPtr.Zero)
{
MONITORINFO monitorInfo = new MONITORINFO();
monitorInfo.cbSize = Marshal.SizeOf(typeof(MONITORINFO));
GetMonitorInfo(monitor, ref monitorInfo);
RECT rcWorkArea = monitorInfo.rcWork;
RECT rcMonitorArea = monitorInfo.rcMonitor;
mmi.ptMaxPosition.X = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left);
mmi.ptMaxPosition.Y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top);
mmi.ptMaxSize.X = Math.Abs(rcWorkArea.Right - rcWorkArea.Left);
mmi.ptMaxSize.Y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top);
}
Marshal.StructureToPtr(mmi, lParam, true);
}
return IntPtr.Zero;
}
private const int WM_GETMINMAXINFO = 0x0024;
private const uint MONITOR_DEFAULTTONEAREST = 0x00000002;
[DllImport("user32.dll")]
private static extern IntPtr MonitorFromWindow(IntPtr handle, uint flags);
[DllImport("user32.dll")]
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public RECT(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MONITORINFO
{
public int cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
}
}
}