Skip to content
Open
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
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
9 changes: 9 additions & 0 deletions src/磁贴美化小工具.Wpf/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<!-- .NET Framework 版本在 .NET Framework 4.6.2 以下,
但操作系统在 Windows 10 及以上,开启多屏不同 DPI 缩放。
详见:https://blog.walterlv.com/post/windows-high-dpi-development-for-wpf.html -->
<AppContextSwitchOverrides value="Switch.System.Windows.DoNotScaleForDpiChanges=false" />
</runtime>
</configuration>
73 changes: 73 additions & 0 deletions src/磁贴美化小工具.Wpf/App.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?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="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC 清单选项
如果想要更改 Windows 用户帐户控制级别,请使用
以下节点之一替换 requestedExecutionLevel 节点。n
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />

指定 requestedExecutionLevel 元素将禁用文件和注册表虚拟化。
如果你的应用程序需要此虚拟化来实现向后兼容性,则删除此
元素。
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- 设计此应用程序与其一起工作且已针对此应用程序进行测试的
Windows 版本的列表。取消评论适当的元素,
Windows 将自动选择最兼容的环境。 -->

<!-- Windows Vista -->
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->

<!-- Windows 7 -->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />-->

<!-- Windows 8 -->
<!--<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />-->

<!-- Windows 8.1 -->
<!--<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />-->

<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />

</application>
</compatibility>


<!-- 以下 DPI 配置包含两种效果:
1. 针对每个屏幕的 DPI 缩放(第二版),在 Windows 10 1607 及以上
2. 仅系统级缩放,在 Windows 10 1607 以下
详见:https://blog.walterlv.com/post/windows-high-dpi-development-for-wpf.html-->
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>

<!-- 启用 Windows 公共控件和对话框的主题(Windows XP 和更高版本) -->
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>

</assembly>
16 changes: 16 additions & 0 deletions src/磁贴美化小工具.Wpf/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Application x:Class="Xiu2.TileTool.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Xiu2.TileTool"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/Core.xaml" />
<ResourceDictionary Source="/Themes/FDS/Window.xaml" />
<ResourceDictionary Source="/Themes/FDS/Button.xaml" />
<ResourceDictionary Source="/Themes/FDS/ListBox.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
27 changes: 27 additions & 0 deletions src/磁贴美化小工具.Wpf/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;

using Xiu2.TileTool.Core;

namespace Xiu2.TileTool
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);

// 判断系统版本
if (Environment.OSVersion.Version.Major != 10)
{
_ = MessageBox.Show($"{AppInfo.Main.AppName}仅支持 Windows10 系统!", "错误", MessageBoxButton.OK);
Shutdown();
}
}
}
}
41 changes: 41 additions & 0 deletions src/磁贴美化小工具.Wpf/Core/AppInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Xiu2.TileTool.Core
{
/// <summary>
/// 包含应用程序的一般信息。
/// </summary>
internal class AppInfo
{
/// <summary>
/// 获取当前应用程序的一般信息。
/// </summary>
public static AppInfo Main { get; } = new AppInfo(Assembly.GetEntryAssembly()!);

public AppInfo(Assembly assembly)
{
AppName = assembly.GetCustomAttribute<AssemblyProductAttribute>()?.Product
?? assembly.GetCustomAttribute<AssemblyTitleAttribute>()!.Title;
Version = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!.InformationalVersion;
Author = assembly.GetCustomAttribute<AssemblyCompanyAttribute>()!.Company;
}

/// <summary>
/// 获取应用名称。
/// </summary>
public string AppName { get; }

/// <summary>
/// 获取版本号(可能带预览标签)。
/// </summary>
public string Version { get; }

/// <summary>
/// 获取作者名。
/// </summary>
public string Author { get; }
}
}
86 changes: 86 additions & 0 deletions src/磁贴美化小工具.Wpf/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using Xiu2.TileTool.Core;

namespace Xiu2.TileTool
{
internal static class Program
{
[STAThread]
static void Main(string[] args)
{
// 启动前一个进程实例。
Mutex? newMutex = null;
try
{
#pragma warning disable IDE0067 // 丢失范围之前释放对象
newMutex = new Mutex(true, "a8851f5e-cbb5-4466-bd72-d95c9bea4dea", out bool createdNew);
#pragma warning restore IDE0067 // 丢失范围之前释放对象
if (!createdNew)
{
if (args.Length > 0 && args[0] != "")
{
// 右键菜单启动:杀掉已存在的进程。
KillSameNameProcess();
}
else
{
// 用户双击启动,打开之前已打开的窗口。
var current = Process.GetCurrentProcess();
var process = Process.GetProcessesByName(current.ProcessName).FirstOrDefault(x => x.Id != current.Id);
if (process != null)
{
var hwnd = process.MainWindowHandle;
ShowWindow(hwnd, 9);
SetForegroundWindow(hwnd);
return;
}
}
}
}
catch (Exception)
{
// 忽略任何多实例处理相关的异常。
}

// 启动自己。
var app = new App();
app.InitializeComponent();
app.Run();
}

/// <summary>
/// 结束同名进程。
/// </summary>
private static void KillSameNameProcess()
{
var name = AppInfo.Main.AppName;
// 获取当前进程信息。
Process currentProcess = Process.GetCurrentProcess();
// 获取同名进程信息。
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
// 判断该进程主窗口标题是否含有 XXX 字符串。
if (process.MainWindowTitle.Contains(name))
{
// 如果不是当前进程,就结束它。
if (process.Id != currentProcess.Id)
{
process.Kill();
}
}
}
}

[DllImport("user32.dll")]
private static extern int ShowWindow(IntPtr hwnd, uint nCmdShow);

[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
}
10 changes: 10 additions & 0 deletions src/磁贴美化小工具.Wpf/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Windows;

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
43 changes: 43 additions & 0 deletions src/磁贴美化小工具.Wpf/Themes/Core.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<Color x:Key="Color.Theme">#0B6AB4</Color>
<Color x:Key="Color.Theme.Light1">#2286CC</Color>
<Color x:Key="Color.Theme.Dark1">#014696</Color>
<Color x:Key="Color.Foreground">White</Color>
<Color x:Key="Color.Foreground.Disable">#999999</Color>
<Color x:Key="Color.Background">#2B2B2B</Color>
<Color x:Key="Color.Theme.Foreground">White</Color>
<Color x:Key="Color.Theme.Foreground.Disable">#999999</Color>
<Color x:Key="Color.Theme.Background">#2B2B2B</Color>
<Color x:Key="Color.Background.Header">#353536</Color>
<Color x:Key="Color.Background.Items">#353536</Color>
<Color x:Key="Color.Background.Footer">#353536</Color>
<Color x:Key="Color.Background.Float">#353536</Color>
<Color x:Key="Color.Background.Control">#353536</Color>
<SolidColorBrush x:Key="Brush.Theme" Color="{StaticResource Color.Theme}" />
<SolidColorBrush x:Key="Brush.Theme.Light1" Color="{StaticResource Color.Theme.Light1}" />
<SolidColorBrush x:Key="Brush.Theme.Dark1" Color="{StaticResource Color.Theme.Dark1}" />
<SolidColorBrush x:Key="Brush.Foreground" Color="{StaticResource Color.Foreground}" />
<SolidColorBrush x:Key="Brush.Foreground.Disable" Color="{StaticResource Color.Foreground.Disable}" />
<SolidColorBrush x:Key="Brush.Background" Color="{StaticResource Color.Background}" />
<SolidColorBrush x:Key="Brush.Theme.Foreground" Color="{StaticResource Color.Theme.Foreground}" />
<SolidColorBrush x:Key="Brush.Theme.Foreground.Disable" Color="{StaticResource Color.Theme.Foreground.Disable}" />
<SolidColorBrush x:Key="Brush.Theme.Background" Color="{StaticResource Color.Theme.Background}" />
<SolidColorBrush x:Key="Brush.Background.Header" Color="{StaticResource Color.Background.Header}" />
<SolidColorBrush x:Key="Brush.Background.Items" Color="{StaticResource Color.Background.Items}" />
<SolidColorBrush x:Key="Brush.Background.Footer" Color="{StaticResource Color.Background.Footer}" />
<SolidColorBrush x:Key="Brush.Background.Float" Color="{StaticResource Color.Background.Float}" />
<SolidColorBrush x:Key="Brush.Background.Control" Color="{StaticResource Color.Background.Control}" />

<Style x:Key="Style.FocusVisual.Default">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle StrokeThickness="2" Stroke="{StaticResource Brush.Foreground}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

</ResourceDictionary>
67 changes: 67 additions & 0 deletions src/磁贴美化小工具.Wpf/Themes/FDS/Button.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:effects="clr-namespace:Walterlv.Windows.Effects">

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/Core.xaml" />
</ResourceDictionary.MergedDictionaries>

<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="14" />
<Setter Property="Margin" Value="4 0" />
<Setter Property="Padding" Value="24 0" />
<Setter Property="Height" Value="32" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Foreground" Value="{StaticResource Brush.Theme.Foreground}" />
<Setter Property="Background" Value="{StaticResource Brush.Theme}" />
<Setter Property="effects:TiltEffect2D.IsEnabled" Value="True" />
<Setter Property="Stylus.IsPressAndHoldEnabled" Value="False" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="Stylus.IsTapFeedbackEnabled" Value="False" />
<Setter Property="Stylus.IsTouchFeedbackEnabled" Value="False" />
<Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<Border x:Name="Bd"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}" />
<TextBlock x:Name="ContentTextBlock" Foreground="{TemplateBinding Foreground}"
Margin="{TemplateBinding Padding}"
FontSize="{TemplateBinding FontSize}" Text="{TemplateBinding Content}"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<!-- When the pointer is over the button. -->
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsStylusOver" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="#4ff4f4f4" />
</MultiTrigger>
<!-- When the pointer is pressed. -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="AreAnyTouchesOver" Value="False" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="#4f1f1f1f" />
</MultiTrigger>
<!-- When the touch device is pressed. -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True" />
<Condition Property="AreAnyTouchesOver" Value="True" />
</MultiTrigger.Conditions>
<Setter TargetName="Bd" Property="Background" Value="#4f000000" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

</ResourceDictionary>
Loading