ToolBox/MainForm.cs
2025-03-17 23:34:35 +08:00

2810 lines
113 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Linq;
using System.Runtime.InteropServices; // 添加P/Invoke支持
using System.Drawing.Drawing2D; // 添加GDI+支持
using System.Drawing.Imaging; // 添加图像处理支持
using Microsoft.Win32;
using System.Diagnostics; // 添加Registry访问支持
namespace QuickLauncher
{
public partial class MainForm : Form
{
// Windows 11 UI相关
private bool isDarkMode = false;
private Color accentColor = Color.FromArgb(0, 120, 212); // Windows默认蓝色
private readonly Color lightBackColor = Color.FromArgb(243, 243, 243);
private readonly Color darkBackColor = Color.FromArgb(32, 32, 32);
private readonly Color lightTextColor = Color.FromArgb(0, 0, 0);
private readonly Color darkTextColor = Color.FromArgb(255, 255, 255);
private readonly int cornerRadius = 8; // Windows 11圆角半径
// P/Invoke用于实现Windows 11 Mica效果
[DllImport("dwmapi.dll")]
private static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
// DWM属性常量
private const int DWMWA_USE_IMMERSIVE_DARK_MODE = 20;
private const int DWMWA_MICA_EFFECT = 1029;
// 添加圆角支持的类
private class RoundedPanel : Panel
{
private int _cornerRadius = 8;
public int CornerRadius
{
get { return _cornerRadius; }
set { _cornerRadius = value; Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// 设置高质量绘图模式
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
// 创建圆角路径
using (GraphicsPath path = new GraphicsPath())
{
path.AddArc(0, 0, CornerRadius, CornerRadius, 180, 90);
path.AddArc(Width - CornerRadius, 0, CornerRadius, CornerRadius, 270, 90);
path.AddArc(Width - CornerRadius, Height - CornerRadius, CornerRadius, CornerRadius, 0, 90);
path.AddArc(0, Height - CornerRadius, CornerRadius, CornerRadius, 90, 90);
path.CloseAllFigures();
this.Region = new Region(path);
}
}
}
// 添加圆角按钮支持的类
private class RoundedButton : Button
{
private int _cornerRadius = 8;
public int CornerRadius
{
get { return _cornerRadius; }
set { _cornerRadius = value; Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
// 设置高质量绘图模式
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
// 创建圆角路径
using (GraphicsPath path = new GraphicsPath())
{
path.AddArc(0, 0, CornerRadius, CornerRadius, 180, 90);
path.AddArc(Width - CornerRadius, 0, CornerRadius, CornerRadius, 270, 90);
path.AddArc(Width - CornerRadius, Height - CornerRadius, CornerRadius, CornerRadius, 0, 90);
path.AddArc(0, Height - CornerRadius, CornerRadius, CornerRadius, 90, 90);
path.CloseAllFigures();
this.Region = new Region(path);
}
}
}
// 原有的字段
private Dictionary<string, List<ShortcutItem>> categories;
private string dataFilePath = "shortcuts.json";
private string settingsFilePath = "settings.json";
private const int CATEGORY_BUTTON_HEIGHT = 40;
private string currentCategory = "";
private ContextMenuStrip categoryContextMenu;
private ContextMenuStrip shortcutsPanelContextMenu;
private ContextMenuStrip shortcutItemContextMenu;
private int iconSize = 48; // 默认图标大小
private const int MIN_ICON_SIZE = 24; // 最小图标大小
private const int MAX_ICON_SIZE = 256; // 增加最大图标大小到256
private const int ICON_SIZE_STEP = 16; // 增加每次缩放的步长
// 左侧面板调整相关
private bool isResizing = false;
private int resizingStartX = 5;
private int initialPanelWidth = 5;
private const int MIN_PANEL_WIDTH = 200;
private const int MAX_PANEL_WIDTH = 500;
private Panel resizeHandle;
// 用于保存设置的类
private class AppSettings
{
public string LastSelectedCategory { get; set; } = "";
public string SortMode { get; set; } = "Name"; // Name, DateAdded
public int IconSize { get; set; } = 48; // 保存图标大小
public int LeftPanelWidth { get; set; } = 300; // 左侧面板宽度
public bool EnableAutoDocking { get; set; } = false; // 启用自动停靠
public Point FloatingIconPosition { get; set; } = new Point(0, 0); // 浮动图标位置
public bool ShowFloatingIconOnStartup { get; set; } = false; // 启动时不显示浮动图标
public string FloatingIconPath { get; set; } = ""; // 浮动按钮图标路径
}
private AppSettings settings = new AppSettings();
// 添加浮动图标相关代码
private NotifyIcon notifyIcon;
private Form floatingIcon;
private bool isFloatingIconVisible = false;
// 修改ResizeHandle相关代码添加鼠标光标
private void InitializeResizeHandle()
{
// 创建调整大小的控件
resizeHandle = new Panel
{
Width = 5,
Dock = DockStyle.Right,
BackColor = Color.Transparent,
Cursor = Cursors.SizeWE // 设置为水平调整大小的光标
};
// 添加事件处理
resizeHandle.MouseDown += ResizeHandle_MouseDown;
resizeHandle.MouseMove += ResizeHandle_MouseMove;
resizeHandle.MouseUp += ResizeHandle_MouseUp;
resizeHandle.MouseEnter += (s, e) => resizeHandle.Cursor = Cursors.SizeWE;
resizeHandle.MouseLeave += (s, e) =>
{
if (!isResizing)
{
resizeHandle.Cursor = Cursors.SizeWE;
}
};
// 添加到左侧面板
leftPanel.Controls.Add(resizeHandle);
resizeHandle.BringToFront();
}
// 修改停靠方法,改进停靠行为
private bool isDocked = false;
private FormBorderStyle originalBorderStyle;
private Size originalSize;
private Point originalLocation;
private FormWindowState originalWindowState;
private const int DOCK_THRESHOLD = 10; // 停靠阈值
private void DockToScreenEdge()
{
// 检查是否启用自动停靠
if (!settings.EnableAutoDocking)
return;
Screen currentScreen = Screen.FromControl(this);
Rectangle screenBounds = currentScreen.WorkingArea;
bool shouldDock = false;
DockStyle dockPosition = DockStyle.None;
// 检查左边缘
if (Math.Abs(this.Left - screenBounds.Left) <= DOCK_THRESHOLD)
{
shouldDock = true;
dockPosition = DockStyle.Left;
}
// 检查右边缘
else if (Math.Abs(screenBounds.Right - (this.Left + this.Width)) <= DOCK_THRESHOLD)
{
shouldDock = true;
dockPosition = DockStyle.Right;
}
// 如果应该停靠但尚未停靠
if (shouldDock && !isDocked)
{
// 保存原始状态
originalBorderStyle = this.FormBorderStyle;
originalSize = this.Size;
originalLocation = this.Location;
originalWindowState = this.WindowState;
// 应用停靠样式
ApplyDockStyle(dockPosition, screenBounds);
isDocked = true;
}
// 如果不应该停靠但当前已停靠
else if (!shouldDock && isDocked)
{
// 恢复原始状态
this.FormBorderStyle = originalBorderStyle;
this.Size = originalSize;
this.Location = originalLocation;
this.WindowState = originalWindowState;
isDocked = false;
}
}
private void ApplyDockStyle(DockStyle dockPosition, Rectangle screenBounds)
{
// 设置为无边框样式
this.FormBorderStyle = FormBorderStyle.SizableToolWindow;
// 根据停靠位置调整窗体
if (dockPosition == DockStyle.Left)
{
this.Location = new Point(screenBounds.Left, screenBounds.Top);
this.Size = new Size(Math.Min(this.Width, screenBounds.Width / 4), screenBounds.Height);
}
else if (dockPosition == DockStyle.Right)
{
this.Location = new Point(screenBounds.Right - Math.Min(this.Width, screenBounds.Width / 4), screenBounds.Top);
this.Size = new Size(Math.Min(this.Width, screenBounds.Width / 4), screenBounds.Height);
}
// 设置窗体始终置顶
this.TopMost = true;
}
public MainForm()
{
InitializeComponent();
// 配置工具提示 - 调整为更合适的值
toolTip1 = new ToolTip();
toolTip1.AutoPopDelay = 5000;
toolTip1.InitialDelay = 200; // 稍微增加初始延迟
toolTip1.ReshowDelay = 200; // 稍微增加重新显示延迟
toolTip1.ShowAlways = true;
toolTip1.UseFading = true;
toolTip1.IsBalloon = false; // 使用标准样式
// 移除最小化按钮,保留最大化按钮
this.MinimizeBox = false;
// 初始化数据和UI
InitializeUI();
// 应用Windows 11风格
ApplyWin11Style();
SetupContextMenus();
SetupEventHandlers();
// 初始化浮动图标必须在LoadSettings之前
InitializeNotifyIcon();
// 加载设置
LoadSettings();
LoadData();
SelectDefaultCategory();
// 监听系统主题变化
SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged;
// 初始化调整大小的控件
InitializeResizeHandle();
// 确保主窗口显示,浮动图标隐藏
this.Show();
this.Activate();
if (floatingIcon != null)
{
HideFloatingIcon();
}
}
private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e)
{
if (e.Category == UserPreferenceCategory.General)
{
// 在UI线程中更新主题
if (this.InvokeRequired)
{
this.Invoke(new Action(() => UpdateTheme()));
}
else
{
UpdateTheme();
}
}
}
private void UpdateTheme()
{
// 更新深色模式状态
isDarkMode = IsSystemUsingSysemDarkTheme();
// 重新应用Windows 11风格
ApplyWin11Style();
}
// 应用Windows 11风格
private void ApplyWin11Style()
{
// 检测系统主题
isDarkMode = IsSystemUsingSysemDarkTheme();
// 应用Mica效果
if (Environment.OSVersion.Version.Build >= 22000) // Windows 11
{
try
{
// 应用深色/浅色模式
int darkMode = isDarkMode ? 1 : 0;
DwmSetWindowAttribute(this.Handle, DWMWA_USE_IMMERSIVE_DARK_MODE, ref darkMode, sizeof(int));
// 应用Mica效果
int micaEffect = 1;
DwmSetWindowAttribute(this.Handle, DWMWA_MICA_EFFECT, ref micaEffect, sizeof(int));
}
catch (Exception)
{
// 如果不支持,则使用备用方案
this.BackColor = isDarkMode ? darkBackColor : lightBackColor;
}
}
else
{
// 在Windows 10上使用备用方案
this.BackColor = isDarkMode ? darkBackColor : lightBackColor;
}
// 应用主题颜色
ApplyThemeColors();
}
// 检测系统是否使用深色主题
private bool IsSystemUsingSysemDarkTheme()
{
try
{
using (var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"))
{
if (key != null)
{
var value = key.GetValue("AppsUseLightTheme");
if (value != null && value is int)
{
return (int)value == 0;
}
}
}
}
catch { }
return false;
}
// 应用主题颜色
private void ApplyThemeColors()
{
// 设置主窗体颜色
this.ForeColor = isDarkMode ? darkTextColor : lightTextColor;
// 设置左侧面板颜色
leftPanel.BackColor = isDarkMode ? Color.FromArgb(40, 40, 40) : Color.FromArgb(243, 243, 243);
// 设置右侧面板颜色
rightPanel.BackColor = isDarkMode ? Color.FromArgb(32, 32, 32) : Color.FromArgb(250, 250, 250);
// 设置工具面板颜色
toolPanel.BackColor = isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(230, 230, 230);
// 设置快捷方式面板颜色
shortcutsPanel.BackColor = isDarkMode ? Color.FromArgb(32, 32, 32) : Color.FromArgb(250, 250, 250);
// 设置分类文字颜色
categoryLabel.ForeColor = isDarkMode ? Color.FromArgb(255, 255, 255) : Color.FromArgb(0, 0, 0);
// 设置添加按钮颜色
addButton.BackColor = accentColor;
addButton.ForeColor = Color.White;
addButton.FlatAppearance.BorderSize = 0;
// 设置菜单颜色
menuStrip.BackColor = isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(230, 230, 230);
menuStrip.ForeColor = isDarkMode ? darkTextColor : lightTextColor;
// 设置菜单项颜色
foreach (ToolStripMenuItem item in menuStrip.Items)
{
item.ForeColor = isDarkMode ? Color.White : Color.Black;
// 设置下拉菜单项颜色
foreach (ToolStripItem dropItem in item.DropDownItems)
{
if (dropItem is ToolStripMenuItem menuItem)
{
menuItem.ForeColor = isDarkMode ? Color.White : Color.Black;
}
}
}
// 设置菜单渲染器
menuStrip.Renderer = new ModernMenuRenderer(isDarkMode);
// 刷新分类列表和当前分类的快捷方式仅当categories已初始化时
if (categories != null)
{
RefreshCategoryList();
if (!string.IsNullOrEmpty(currentCategory))
{
ShowCategoryItems(currentCategory);
}
}
}
// 设置上下文菜单
private void SetupContextMenus()
{
// 分类右键菜单
categoryContextMenu = new ContextMenuStrip();
categoryContextMenu.Items.Add("添加新分类", null, (s, e) => AddCategory_Click(s, e));
categoryContextMenu.Items.Add("删除当前分类", null, (s, e) => DeleteCategory_Click(s, e));
categoryContextMenu.Items.Add("重命名分类", null, (s, e) => RenameCategory_Click(s, e));
// 应用主题颜色
categoryContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
// 右侧面板右键菜单
shortcutsPanelContextMenu = new ContextMenuStrip();
shortcutsPanelContextMenu.Items.Add("添加程序", null, (s, e) => AddButton_Click(s, e));
shortcutsPanelContextMenu.Items.Add("-"); // 分隔线
shortcutsPanelContextMenu.Items.Add("按名称排序", null, (s, e) => SortShortcuts("Name"));
shortcutsPanelContextMenu.Items.Add("按添加时间排序", null, (s, e) => SortShortcuts("DateAdded"));
shortcutsPanelContextMenu.Items.Add("按使用频率排序", null, (s, e) => SortShortcuts("UsageCount"));
shortcutsPanelContextMenu.Items.Add("-"); // 分隔线
// 添加图标大小调整菜单,增加更多选项
var sizeMenu = new ToolStripMenuItem("图标大小");
sizeMenu.DropDownItems.Add("超小图标 (24px)", null, (s, e) => { ResizeIcons(24); });
sizeMenu.DropDownItems.Add("小图标 (48px)", null, (s, e) => { ResizeIcons(48); });
sizeMenu.DropDownItems.Add("中图标 (64px)", null, (s, e) => { ResizeIcons(64); });
sizeMenu.DropDownItems.Add("大图标 (96px)", null, (s, e) => { ResizeIcons(96); });
sizeMenu.DropDownItems.Add("较大图标 (128px)", null, (s, e) => { ResizeIcons(128); });
sizeMenu.DropDownItems.Add("超大图标 (192px)", null, (s, e) => { ResizeIcons(192); });
sizeMenu.DropDownItems.Add("巨大图标 (256px)", null, (s, e) => { ResizeIcons(256); });
shortcutsPanelContextMenu.Items.Add(sizeMenu);
// 添加主题切换选项
shortcutsPanelContextMenu.Items.Add("-"); // 分隔线
var themeMenu = new ToolStripMenuItem("主题设置");
themeMenu.DropDownItems.Add("浅色主题", null, (s, e) => { ChangeTheme(false); });
themeMenu.DropDownItems.Add("深色主题", null, (s, e) => { ChangeTheme(true); });
themeMenu.DropDownItems.Add("跟随系统", null, (s, e) => { FollowSystemTheme(); });
shortcutsPanelContextMenu.Items.Add(themeMenu);
// 应用主题颜色
shortcutsPanelContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
// 快捷方式项目右键菜单
shortcutItemContextMenu = new ContextMenuStrip();
shortcutItemContextMenu.Items.Add("启动", null, (s, e) =>
{
if (shortcutItemContextMenu.Tag is ShortcutItem item)
{
LaunchApplication(item.Path);
}
});
shortcutItemContextMenu.Items.Add("删除", null, (s, e) =>
{
if (shortcutItemContextMenu.Tag is ShortcutItem item)
{
DeleteShortcut(item);
}
});
shortcutItemContextMenu.Items.Add("重命名", null, (s, e) =>
{
if (shortcutItemContextMenu.Tag is ShortcutItem item)
{
RenameShortcut(item);
}
});
shortcutItemContextMenu.Items.Add("属性", null, (s, e) =>
{
if (shortcutItemContextMenu.Tag is ShortcutItem item)
{
ShowShortcutProperties(item);
}
});
shortcutItemContextMenu.Items.Add("打开程序目录", null, (s, e) =>
{
if (shortcutItemContextMenu.Tag is ShortcutItem item)
{
OpenProgramDirectory(item.Path);
}
});
// 应用主题颜色
shortcutItemContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
}
// 切换主题
private void ChangeTheme(bool darkMode)
{
isDarkMode = darkMode;
ApplyThemeColors();
// 更新上下文菜单渲染器
categoryContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
shortcutsPanelContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
shortcutItemContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
}
// 跟随系统主题
private void FollowSystemTheme()
{
isDarkMode = IsSystemUsingSysemDarkTheme();
ApplyThemeColors();
// 更新上下文菜单渲染器
categoryContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
shortcutsPanelContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
shortcutItemContextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
}
// 现代菜单渲染器
private class ModernMenuRenderer : ToolStripProfessionalRenderer
{
private bool _isDarkMode;
public ModernMenuRenderer(bool isDarkMode) : base(new ModernColorTable(isDarkMode))
{
_isDarkMode = isDarkMode;
}
protected override void OnRenderMenuItemBackground(ToolStripItemRenderEventArgs e)
{
if (e.Item.Selected)
{
// 选中项背景
Rectangle rect = new Rectangle(2, 0, e.Item.Width - 4, e.Item.Height);
Color highlightColor = _isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(210, 230, 250);
using (SolidBrush brush = new SolidBrush(highlightColor))
{
e.Graphics.FillRoundedRectangle(brush, rect, 4);
}
}
else
{
// 普通项背景
Color backColor = _isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(250, 250, 250);
using (SolidBrush brush = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(brush, e.Item.ContentRectangle);
}
}
}
protected override void OnRenderToolStripBackground(ToolStripRenderEventArgs e)
{
// 菜单背景
Color backColor = _isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(250, 250, 250);
using (SolidBrush brush = new SolidBrush(backColor))
{
e.Graphics.FillRectangle(brush, e.AffectedBounds);
}
}
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
// 菜单文本颜色
e.TextColor = _isDarkMode ? Color.FromArgb(240, 240, 240) : Color.FromArgb(20, 20, 20);
base.OnRenderItemText(e);
}
protected override void OnRenderSeparator(ToolStripSeparatorRenderEventArgs e)
{
// 分隔线颜色
Color lineColor = _isDarkMode ? Color.FromArgb(80, 80, 80) : Color.FromArgb(200, 200, 200);
int y = e.Item.Height / 2;
using (Pen pen = new Pen(lineColor))
{
e.Graphics.DrawLine(pen, 4, y, e.Item.Width - 4, y);
}
}
}
// 现代菜单颜色表
private class ModernColorTable : ProfessionalColorTable
{
private bool _isDarkMode;
public ModernColorTable(bool isDarkMode)
{
_isDarkMode = isDarkMode;
}
// 菜单项
public override Color MenuItemSelected => _isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(210, 230, 250);
public override Color MenuItemBorder => Color.Transparent;
// 菜单栏
public override Color MenuBorder => Color.Transparent;
public override Color MenuItemSelectedGradientBegin => _isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(210, 230, 250);
public override Color MenuItemSelectedGradientEnd => _isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(210, 230, 250);
public override Color MenuItemPressedGradientBegin => _isDarkMode ? Color.FromArgb(80, 80, 80) : Color.FromArgb(190, 210, 240);
public override Color MenuItemPressedGradientEnd => _isDarkMode ? Color.FromArgb(80, 80, 80) : Color.FromArgb(190, 210, 240);
// 工具栏
public override Color ToolStripDropDownBackground => _isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(250, 250, 250);
public override Color ImageMarginGradientBegin => _isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(250, 250, 250);
public override Color ImageMarginGradientMiddle => _isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(250, 250, 250);
public override Color ImageMarginGradientEnd => _isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(250, 250, 250);
}
// 调整图标大小
private void ResizeIcons(int newSize)
{
if (newSize >= MIN_ICON_SIZE && newSize <= MAX_ICON_SIZE)
{
iconSize = newSize;
settings.IconSize = iconSize;
SaveSettings();
if (!string.IsNullOrEmpty(currentCategory))
{
ShowCategoryItems(currentCategory);
}
}
}
// 处理鼠标滚轮事件
private void ShortcutsPanel_MouseWheel(object sender, MouseEventArgs e)
{
// 检查Ctrl键是否按下
if (ModifierKeys == Keys.Control)
{
// 向上滚动,放大图标
if (e.Delta > 0)
{
ResizeIcons(iconSize + ICON_SIZE_STEP);
}
// 向下滚动,缩小图标
else if (e.Delta < 0)
{
ResizeIcons(iconSize - ICON_SIZE_STEP);
}
}
}
// 重命名分类
private void RenameCategory_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(currentCategory))
{
MessageBox.Show("请先选择要重命名的分类", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
using (var dialog = new Form())
{
dialog.Text = "重命名分类";
dialog.Size = new Size(350, 150);
dialog.StartPosition = FormStartPosition.CenterParent;
dialog.FormBorderStyle = FormBorderStyle.FixedDialog;
dialog.MaximizeBox = false;
dialog.MinimizeBox = false;
var label = new Label() { Text = "新名称:", Location = new Point(10, 20) };
var textBox = new TextBox() { Text = currentCategory, Location = new Point(120, 17), Width = 180 };
var button = new RoundedButton() { Text = "确定", DialogResult = DialogResult.OK, Location = new Point(110, 60), CornerRadius = cornerRadius, BackColor = accentColor, ForeColor = Color.White };
dialog.Controls.AddRange(new Control[] { label, textBox, button });
dialog.AcceptButton = button;
if (dialog.ShowDialog() == DialogResult.OK && !string.IsNullOrWhiteSpace(textBox.Text))
{
string newName = textBox.Text.Trim();
if (newName != currentCategory && !categories.ContainsKey(newName))
{
var items = categories[currentCategory];
categories.Remove(currentCategory);
categories[newName] = items;
string oldCategory = currentCategory;
currentCategory = newName;
SaveData();
RefreshCategoryList();
ShowCategoryItems(currentCategory);
}
else if (categories.ContainsKey(newName) && newName != currentCategory)
{
MessageBox.Show("该分类名称已存在", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
// 排序快捷方式
private void SortShortcuts(string sortMode)
{
if (string.IsNullOrEmpty(currentCategory) || !categories.ContainsKey(currentCategory))
return;
settings.SortMode = sortMode;
SaveSettings();
switch (sortMode)
{
case "Name":
categories[currentCategory] = categories[currentCategory].OrderBy(s => s.Name).ToList();
break;
case "DateAdded":
categories[currentCategory] = categories[currentCategory].OrderByDescending(s => s.DateAdded).ToList();
break;
case "UsageCount":
categories[currentCategory] = categories[currentCategory].OrderByDescending(s => s.UsageCount).ToList();
break;
}
SaveData();
ShowCategoryItems(currentCategory);
}
// 删除快捷方式
private void DeleteShortcut(ShortcutItem item)
{
if (string.IsNullOrEmpty(currentCategory) || !categories.ContainsKey(currentCategory))
return;
if (MessageBox.Show($"确定要删除 '{item.Name}' 吗?", "确认删除",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
categories[currentCategory].Remove(item);
SaveData();
ShowCategoryItems(currentCategory);
}
}
// 重命名快捷方式
private void RenameShortcut(ShortcutItem item)
{
using (var dialog = new Form())
{
dialog.Text = "重命名快捷方式";
dialog.Size = new Size(350, 150);
dialog.StartPosition = FormStartPosition.CenterParent;
dialog.FormBorderStyle = FormBorderStyle.FixedDialog;
dialog.MaximizeBox = false;
dialog.MinimizeBox = false;
var label = new Label() { Text = "新名称:", Location = new Point(10, 20) };
var textBox = new TextBox() { Text = item.Name, Location = new Point(120, 17), Width = 180 };
var button = new RoundedButton() { Text = "确定", DialogResult = DialogResult.OK, Location = new Point(110, 60), CornerRadius = cornerRadius, BackColor = accentColor, ForeColor = Color.White };
dialog.Controls.AddRange(new Control[] { label, textBox, button });
dialog.AcceptButton = button;
if (dialog.ShowDialog() == DialogResult.OK && !string.IsNullOrWhiteSpace(textBox.Text))
{
item.Name = textBox.Text.Trim();
SaveData();
ShowCategoryItems(currentCategory);
}
}
}
// 显示快捷方式属性
private void ShowShortcutProperties(ShortcutItem item)
{
using (var dialog = new Form())
{
dialog.Text = "快捷方式属性";
dialog.Size = new Size(400, 300);
dialog.StartPosition = FormStartPosition.CenterParent;
dialog.FormBorderStyle = FormBorderStyle.FixedDialog;
dialog.MaximizeBox = false;
dialog.MinimizeBox = false;
// 使用当前图标大小显示图标
var icon = new PictureBox
{
Size = new Size(Math.Min(64, iconSize), Math.Min(64, iconSize)), // 限制属性对话框中的图标大小
Location = new Point(20, 20),
Image = item.Icon ?? SystemIcons.Application.ToBitmap(),
SizeMode = PictureBoxSizeMode.StretchImage
};
var nameLabel = new Label() { Text = "名称:", Location = new Point(20, 80), AutoSize = true };
var nameValue = new Label() { Text = item.Name, Location = new Point(120, 80), AutoSize = true };
var pathLabel = new Label() { Text = "路径:", Location = new Point(20, 110), AutoSize = true };
var pathValue = new Label() { Text = item.Path, Location = new Point(120, 110), Width = 250, AutoEllipsis = true };
var dateLabel = new Label() { Text = "添加日期:", Location = new Point(20, 140), AutoSize = true };
var dateValue = new Label() { Text = item.DateAdded.ToString(), Location = new Point(120, 140), AutoSize = true };
var usageLabel = new Label() { Text = "使用次数:", Location = new Point(20, 170), AutoSize = true };
var usageValue = new Label() { Text = item.UsageCount.ToString(), Location = new Point(120, 170), AutoSize = true };
var button = new RoundedButton() { Text = "确定", DialogResult = DialogResult.OK, Location = new Point(150, 220), CornerRadius = cornerRadius, BackColor = accentColor, ForeColor = Color.White };
dialog.Controls.AddRange(new Control[] { icon, nameLabel, nameValue, pathLabel, pathValue,
dateLabel, dateValue, usageLabel, usageValue, button });
dialog.AcceptButton = button;
dialog.ShowDialog();
}
}
// 打开程序目录
private void OpenProgramDirectory(string programPath)
{
try
{
if (File.Exists(programPath))
{
// 使用explorer.exe /select, 来打开文件所在目录并高亮显示该文件
Process.Start("explorer.exe", $"/select,\"{programPath}\"");
}
else
{
MessageBox.Show("文件不存在,无法打开所在目录", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
catch (Exception ex)
{
MessageBox.Show($"打开程序目录时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// 选择默认分类
private void SelectDefaultCategory()
{
// 如果没有分类,不做任何操作
if (categories.Count == 0)
return;
// 尝试选择上次选择的分类
if (!string.IsNullOrEmpty(settings.LastSelectedCategory) &&
categories.ContainsKey(settings.LastSelectedCategory))
{
currentCategory = settings.LastSelectedCategory;
ShowCategoryItems(currentCategory);
return;
}
// 如果没有上次选择的分类或该分类不存在,选择第一个分类
currentCategory = categories.Keys.First();
ShowCategoryItems(currentCategory);
}
// 保存设置
private void SaveSettings()
{
try
{
settings.LastSelectedCategory = currentCategory;
settings.IconSize = iconSize;
settings.LeftPanelWidth = leftPanel.Width;
// 添加null检查
if (floatingIcon != null)
{
settings.FloatingIconPosition = floatingIcon.Location;
// 不要在这里设置FloatingIconPath它应该只在ChangeFloatingIconImage方法中设置
}
var options = new JsonSerializerOptions
{
WriteIndented = true
};
var data = JsonSerializer.Serialize(settings, options);
File.WriteAllText(settingsFilePath, data);
}
catch (Exception ex)
{
MessageBox.Show($"保存设置失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// 加载设置
private void LoadSettings()
{
if (File.Exists(settingsFilePath))
{
try
{
var json = File.ReadAllText(settingsFilePath);
settings = JsonSerializer.Deserialize<AppSettings>(json) ?? new AppSettings();
iconSize = settings.IconSize; // 加载保存的图标大小
leftPanel.Width = settings.LeftPanelWidth;
// 确保floatingIcon已初始化
if (floatingIcon != null)
{
floatingIcon.Location = settings.FloatingIconPosition;
// 不要在这里设置Visible属性让ShowFloatingIcon方法来控制
}
}
catch
{
settings = new AppSettings();
}
}
}
private void SetupEventHandlers()
{
// 清除所有事件处理器 - 移除不存在的引用
addButton.Click -= AddButton_Click;
this.FormClosing -= MainForm_FormClosing;
shortcutsPanel.MouseWheel -= ShortcutsPanel_MouseWheel;
// 只为shortcutsPanel添加拖放支持
shortcutsPanel.AllowDrop = true;
shortcutsPanel.DragEnter += ShortcutsPanel_DragEnter;
shortcutsPanel.DragDrop += ShortcutsPanel_DragDrop;
// 添加鼠标滚轮事件处理
shortcutsPanel.MouseWheel += ShortcutsPanel_MouseWheel;
// 为shortcutsPanel添加鼠标移动事件用于处理空白区域的工具提示
shortcutsPanel.MouseMove += ShortcutsPanel_MouseMove;
// 为shortcutsPanel添加右键菜单
shortcutsPanel.ContextMenuStrip = shortcutsPanelContextMenu;
// 绑定添加程序按钮事件
addButton.Click += AddButton_Click;
// 绑定窗体关闭事件,保存当前选择的分类
this.FormClosing += MainForm_FormClosing;
}
// 添加缺失的事件处理方法
private void ShortcutsPanel_DragEnter(object sender, DragEventArgs e)
{
Console.WriteLine("DragEnter triggered");
if (e.Data.GetDataPresent(DataFormats.FileDrop) && !string.IsNullOrEmpty(currentCategory))
{
e.Effect = DragDropEffects.Copy;
}
else
{
e.Effect = DragDropEffects.None;
}
}
private void ShortcutsPanel_DragDrop(object sender, DragEventArgs e)
{
Console.WriteLine("DragDrop triggered");
if (string.IsNullOrEmpty(currentCategory))
{
MessageBox.Show("请先选择一个分类", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
bool addedAny = false;
foreach (string file in files)
{
if (File.Exists(file))
{
AddNewShortcut(file, currentCategory);
addedAny = true;
}
}
if (!addedAny)
{
MessageBox.Show("没有找到有效的文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
SaveSettings();
}
private void InitializeUI()
{
// 初始化数据
categories = new Dictionary<string, List<ShortcutItem>>();
// 设置窗体样式
this.FormBorderStyle = FormBorderStyle.Sizable;
this.MinimumSize = new Size(800, 600);
// 设置控件样式
addButton.FlatStyle = FlatStyle.Flat;
addButton.FlatAppearance.BorderSize = 0;
addButton.BackColor = accentColor;
addButton.ForeColor = Color.White;
addButton.Font = new Font("Microsoft YaHei UI", 10, FontStyle.Regular);
// 设置分类标签样式
categoryLabel.Font = new Font("Microsoft YaHei UI", 11);
categoryLabel.ForeColor = isDarkMode ? Color.FromArgb(0, 0, 0) : Color.FromArgb(255, 255, 255);
// 刷新分类列表
RefreshCategoryList();
}
// 调整手柄鼠标按下事件
private void ResizeHandle_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
isResizing = true;
resizingStartX = e.X;
initialPanelWidth = leftPanel.Width;
// 捕获鼠标
resizeHandle.Capture = true;
// 设置鼠标光标
this.Cursor = Cursors.SizeWE;
resizeHandle.Cursor = Cursors.SizeWE;
}
}
// 调整手柄鼠标移动事件
private void ResizeHandle_MouseMove(object sender, MouseEventArgs e)
{
if (isResizing)
{
// 计算新宽度
int newWidth = initialPanelWidth + (e.X - resizingStartX);
// 限制宽度范围
if (newWidth < MIN_PANEL_WIDTH)
newWidth = MIN_PANEL_WIDTH;
else if (newWidth > MAX_PANEL_WIDTH)
newWidth = MAX_PANEL_WIDTH;
// 设置新宽度
leftPanel.Width = newWidth;
// 刷新布局
this.PerformLayout();
}
}
// 调整手柄鼠标释放事件
private void ResizeHandle_MouseUp(object sender, MouseEventArgs e)
{
if (isResizing)
{
// 先保存设置
settings.LeftPanelWidth = leftPanel.Width;
SaveSettings();
// 在鼠标释放后刷新一次分类列表
RefreshCategoryList();
// 重置调整状态
isResizing = false;
// 恢复默认鼠标光标
this.Cursor = Cursors.Default;
// 最后释放鼠标捕获
resizeHandle.Capture = false;
// 确保调整手柄保持正确的光标
resizeHandle.Cursor = Cursors.SizeWE;
}
}
// 添加窗体鼠标移动事件处理
protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
// 如果正在调整大小,确保鼠标光标保持为调整大小状态
if (isResizing)
{
this.Cursor = Cursors.SizeWE;
resizeHandle.Cursor = Cursors.SizeWE;
}
}
private void AddCategory_Click(object sender, EventArgs e)
{
using (var dialog = new Form())
{
dialog.Text = "添加新分类";
dialog.Size = new Size(350, 200);
dialog.StartPosition = FormStartPosition.CenterParent;
dialog.FormBorderStyle = FormBorderStyle.FixedDialog;
dialog.MaximizeBox = false;
dialog.MinimizeBox = false;
dialog.BackColor = isDarkMode ? Color.FromArgb(45, 45, 45) : Color.FromArgb(240, 240, 240);
dialog.ForeColor = isDarkMode ? Color.White : Color.Black;
// 应用Windows 11深色/浅色模式到标题栏
if (Environment.OSVersion.Version.Build >= 22000)
{
int darkMode = isDarkMode ? 1 : 0;
DwmSetWindowAttribute(dialog.Handle, DWMWA_USE_IMMERSIVE_DARK_MODE, ref darkMode, sizeof(int));
}
var label = new Label()
{
Text = "分类名称:",
Location = new Point(10, 20),
ForeColor = isDarkMode ? Color.White : Color.Black,
AutoSize = true
};
var textBox = new TextBox()
{
Location = new Point(120, 17),
Width = 180,
BackColor = isDarkMode ? Color.FromArgb(60, 60, 60) : Color.White,
ForeColor = isDarkMode ? Color.White : Color.Black,
BorderStyle = BorderStyle.FixedSingle
};
var button = new RoundedButton()
{
Text = "确定",
DialogResult = DialogResult.OK,
Location = new Point(110, 60),
Width = 100,
Height = 30,
BackColor = accentColor,
ForeColor = Color.White,
CornerRadius = cornerRadius
};
dialog.Controls.AddRange(new Control[] { label, textBox, button });
dialog.AcceptButton = button;
// 确保在显示对话框之前应用主题
dialog.HandleCreated += (s, ev) =>
{
if (Environment.OSVersion.Version.Build >= 22000)
{
int darkMode = isDarkMode ? 1 : 0;
DwmSetWindowAttribute(dialog.Handle, DWMWA_USE_IMMERSIVE_DARK_MODE, ref darkMode, sizeof(int));
}
};
if (dialog.ShowDialog() == DialogResult.OK && !string.IsNullOrWhiteSpace(textBox.Text))
{
string newCategory = textBox.Text.Trim();
if (!categories.ContainsKey(newCategory))
{
categories[newCategory] = new List<ShortcutItem>();
SaveData();
RefreshCategoryList();
// 自动选择新创建的分类
SwitchCategory(newCategory);
}
}
}
}
private void DeleteCategory_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(currentCategory))
{
MessageBox.Show("请先选择要删除的分类", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
if (MessageBox.Show($"确定要删除分类 '{currentCategory}' 吗?", "确认删除",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
categories.Remove(currentCategory);
SaveData();
RefreshCategoryList();
shortcutsPanel.Controls.Clear();
currentCategory = "";
// 删除分类后,选择新的默认分类
if (categories.Count > 0)
{
currentCategory = categories.Keys.First();
ShowCategoryItems(currentCategory);
}
}
}
private void RefreshCategoryList()
{
// 如果categories为空直接返回
if (categories == null)
return;
// 保存resizeHandle的引用
Panel savedResizeHandle = resizeHandle;
// 清除所有控件但保留resizeHandle
leftPanel.Controls.Clear();
// 重新添加resizeHandle
if (savedResizeHandle != null)
{
leftPanel.Controls.Add(savedResizeHandle);
savedResizeHandle.BringToFront();
}
int buttonY = 10;
foreach (var category in categories.Keys)
{
var categoryPanel = new RoundedPanel
{
Width = leftPanel.Width - 5,
Height = CATEGORY_BUTTON_HEIGHT,
Location = new Point(0, buttonY),
CornerRadius = cornerRadius
};
var btn = new RoundedButton
{
Text = category,
Width = leftPanel.Width - 20,
Height = CATEGORY_BUTTON_HEIGHT,
Location = new Point(10, 0),
FlatStyle = FlatStyle.Flat,
BackColor = category == currentCategory ?
accentColor :
(isDarkMode ? Color.FromArgb(60, 60, 60) : Color.FromArgb(230, 230, 230)),
ForeColor = category == currentCategory ?
Color.White :
(isDarkMode ? Color.FromArgb(240, 240, 240) : Color.FromArgb(20, 20, 20)),
Tag = category,
CornerRadius = cornerRadius,
FlatAppearance = { BorderSize = 0 }
};
// 移除旧的事件处理器
btn.Click -= null;
btn.Click += (s, e) =>
{
currentCategory = category;
foreach (Control panel in leftPanel.Controls)
{
if (panel is RoundedPanel && panel.Controls.Count > 0)
{
var button = panel.Controls[0] as RoundedButton;
if (button != null)
{
string btnCategory = button.Tag as string;
button.BackColor = btnCategory == category ?
accentColor :
(isDarkMode ? Color.FromArgb(60, 60, 60) : Color.FromArgb(230, 230, 230));
button.ForeColor = btnCategory == category ?
Color.White :
(isDarkMode ? Color.FromArgb(240, 240, 240) : Color.FromArgb(20, 20, 20));
}
}
}
ShowCategoryItems(category);
};
// 添加右键菜单
btn.ContextMenuStrip = categoryContextMenu;
categoryPanel.Controls.Add(btn);
categoryPanel.AllowDrop = true;
// 移除旧的事件处理器
categoryPanel.DragEnter -= null;
categoryPanel.DragDrop -= null;
categoryPanel.DragEnter += (s, e) =>
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
e.Effect = DragDropEffects.Copy;
}
};
categoryPanel.DragDrop += (s, e) =>
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
foreach (string file in files)
{
if (File.Exists(file))
{
AddNewShortcut(file, category);
}
}
};
leftPanel.Controls.Add(categoryPanel);
buttonY += CATEGORY_BUTTON_HEIGHT + 5;
}
}
private void ShowCategoryItems(string category)
{
shortcutsPanel.Controls.Clear();
if (categories.ContainsKey(category))
{
// 更新顶部分类标签
categoryLabel.Text = $"当前分类: {category}";
// 根据设置的排序模式排序
List<ShortcutItem> sortedItems = categories[category];
switch (settings.SortMode)
{
case "Name":
sortedItems = sortedItems.OrderBy(s => s.Name).ToList();
break;
case "DateAdded":
sortedItems = sortedItems.OrderByDescending(s => s.DateAdded).ToList();
break;
case "UsageCount":
sortedItems = sortedItems.OrderByDescending(s => s.UsageCount).ToList();
break;
}
foreach (var item in sortedItems)
{
AddShortcutControl(item, category);
}
}
}
private void AddShortcutControl(ShortcutItem item, string category)
{
// 根据当前图标大小调整面板大小
int panelWidth = Math.Max(80, iconSize + 10);
int panelHeight = iconSize + 60;
var panel = new RoundedPanel
{
Width = panelWidth,
Height = panelHeight,
Margin = new Padding(5),
Tag = item,
BackColor = isDarkMode ? Color.FromArgb(50, 50, 50) : Color.FromArgb(245, 245, 245),
CornerRadius = cornerRadius
};
var icon = new PictureBox
{
Size = new Size(iconSize, iconSize),
Location = new Point((panel.Width - iconSize) / 2, 5),
Image = GetItemIcon(item),
SizeMode = PictureBoxSizeMode.Zoom,
Tag = item,
Cursor = Cursors.Hand
};
// 创建一个新的文本框控件实例
var label = new TextBox();
// 计算文本所需的高度
// TextRenderer.MeasureText: 测量指定文本在给定条件下需要的尺寸
// item.Name: 要显示的文本内容
// new Font(): 创建微软雅黑8号字体
// new Size(panel.Width, 0): 指定宽度限制,高度不限
// TextFormatFlags.WordBreak: 允许在单词间换行
// TextFormatFlags.TextBoxControl: 使用文本框的文本渲染规则
// .Height + 10: 获取计算出的高度并额外添加10像素的边距
var textHeight = TextRenderer.MeasureText(item.Name, new Font("Microsoft YaHei", 8), new Size(panel.Width, 0), TextFormatFlags.WordBreak | TextFormatFlags.TextBoxControl).Height + 10;
label.Text = item.Name; // 设置显示的文本内容
label.AutoSize = false; // 禁用自动尺寸调整
label.TextAlign = HorizontalAlignment.Center; // 文本水平居中对齐
label.MinimumSize = new Size(panel.Width, 30); // 设置最小尺寸
label.MaximumSize = new Size(panelWidth, 0); // 设置最大宽度,高度不限
label.Location = new Point(0, iconSize + 20); // 设置位置在图标下方10像素
label.Tag = item; // 存储关联的数据项
label.Cursor = Cursors.Hand; // 鼠标悬停时显示手型光标
label.ForeColor = isDarkMode ? Color.FromArgb(240, 240, 240) : Color.FromArgb(20, 20, 20); // 根据暗/亮模式设置文字颜色
label.Padding = new Padding(0); // 设置内边距为2像素
label.Font = new Font("Microsoft YaHei", 8); // 设置字体为微软雅黑8号
label.Multiline = true; // 启用多行显示
label.ReadOnly = true; // 设置为只读,防止编辑
label.BorderStyle = BorderStyle.None; // 移除边框
label.BackColor = panel.BackColor; // 背景色与面板一致
label.Height = textHeight; // 应用计算出的高度
// 将图标和文本框添加到面板中
panel.Controls.Add(icon); // 添加图标控件
panel.Controls.Add(label); // 添加文本框控件
// 设置右键菜单
panel.ContextMenuStrip = shortcutItemContextMenu;
icon.ContextMenuStrip = shortcutItemContextMenu;
label.ContextMenuStrip = shortcutItemContextMenu;
// 为右键菜单项设置Tag
//foreach (ToolStripItem menuItem in shortcutItemContextMenu.Items)
//{
// if (menuItem is ToolStripMenuItem)
// {
// menuItem.Tag = item;
// }
//}
// 添加鼠标右键点击事件,在显示菜单前绑定当前选中的 ShortcutItem
EventHandler rightClickHandler = (s, e) =>
{
if (s is Control control && control.Parent is RoundedPanel panel && panel.Tag is ShortcutItem item)
{
shortcutItemContextMenu.Tag = item; // 绑定当前选中的快捷方式
}
};
// 绑定到所有相关控件
panel.MouseDown += (s, e) => { if (e.Button == MouseButtons.Right) rightClickHandler(s, e); };
icon.MouseDown += (s, e) => { if (e.Button == MouseButtons.Right) rightClickHandler(s, e); };
label.MouseDown += (s, e) => { if (e.Button == MouseButtons.Right) rightClickHandler(s, e); };
// 双击事件 - 启动应用程序或预览图片
EventHandler doubleClickHandler = (s, e) =>
{
if (IsImageFile(item.Path))
{
ShowImagePreview(item.Path);
}
else
{
LaunchApplication(item.Path); // 启动应用程序
}
};
panel.DoubleClick += doubleClickHandler;
icon.DoubleClick += doubleClickHandler;
label.DoubleClick += doubleClickHandler;
// 添加鼠标悬停效果
panel.MouseEnter += Panel_MouseEnter;
panel.MouseLeave += Panel_MouseLeave;
icon.MouseEnter += Panel_MouseEnter;
icon.MouseLeave += Panel_MouseLeave;
label.MouseEnter += Panel_MouseEnter;
label.MouseLeave += Panel_MouseLeave;
// 添加鼠标点击效果
panel.MouseDown += Panel_MouseDown;
panel.MouseUp += Panel_MouseUp;
icon.MouseDown += Panel_MouseDown;
icon.MouseUp += Panel_MouseUp;
label.MouseDown += Panel_MouseDown;
label.MouseUp += Panel_MouseUp;
// 设置工具提示
string tipText = GetTooltipText(item);
toolTip1.SetToolTip(panel, tipText);
toolTip1.SetToolTip(icon, tipText);
toolTip1.SetToolTip(label, tipText);
shortcutsPanel.Controls.Add(panel);
}
private Image GetItemIcon(ShortcutItem item)
{
if (IsImageFile(item.Path))
{
try
{
// 为图片文件创建缩略图
using (var img = Image.FromFile(item.Path))
{
return new Bitmap(img, new Size(iconSize, iconSize));
}
}
catch
{
return item.Icon ?? SystemIcons.Application.ToBitmap();
}
}
return item.Icon ?? SystemIcons.Application.ToBitmap();
}
private bool IsImageFile(string path)
{
string ext = Path.GetExtension(path).ToLower();
return new[] { ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".ico" }.Contains(ext);
}
private string GetTooltipText(ShortcutItem item)
{
string type = IsImageFile(item.Path) ? "图片文件" : "应用程序";
return $"名称: {item.Name}\n类型: {type}\n路径: {item.Path}\n" +
$"添加时间: {item.DateAdded:yyyy-MM-dd}\n使用次数: {item.UsageCount}";
}
private void ShowImagePreview(string imagePath)
{
try
{
using (var previewForm = new Form())
{
previewForm.Text = Path.GetFileName(imagePath);
previewForm.StartPosition = FormStartPosition.CenterScreen;
previewForm.BackColor = isDarkMode ? Color.FromArgb(32, 32, 32) : Color.FromArgb(243, 243, 243);
previewForm.WindowState = FormWindowState.Normal;
var pictureBox = new PictureBox
{
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.Zoom,
Image = Image.FromFile(imagePath)
};
// 设置窗体大小为屏幕大小的80%
var screen = Screen.FromControl(this);
previewForm.Size = new Size(
(int)(screen.WorkingArea.Width * 0.8),
(int)(screen.WorkingArea.Height * 0.8)
);
// 添加ESC键关闭功能
previewForm.KeyPreview = true;
previewForm.KeyDown += (s, e) =>
{
if (e.KeyCode == Keys.Escape)
previewForm.Close();
};
// 添加鼠标滚轮缩放
pictureBox.MouseWheel += (s, e) =>
{
if (ModifierKeys == Keys.Control)
{
float zoom = e.Delta > 0 ? 1.1f : 0.9f;
pictureBox.Size = new Size(
(int)(pictureBox.Size.Width * zoom),
(int)(pictureBox.Size.Height * zoom)
);
}
};
var item = categories[currentCategory].FirstOrDefault(i => i.Path == imagePath);
if (item != null)
{
item.UsageCount++;
item.LastUsed = DateTime.Now;
SaveData();
}
previewForm.Controls.Add(pictureBox);
previewForm.ShowDialog();
}
}
catch (Exception ex)
{
MessageBox.Show($"无法预览图片: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// 鼠标进入面板时的效果
private void Panel_MouseEnter(object sender, EventArgs e)
{
if (sender is Control control && control.Parent is RoundedPanel panel)
{
// 应用悬停效果
panel.BackColor = isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(230, 230, 230);
// 显示工具提示
if (panel.Tag is ShortcutItem item)
{
toolTip1.SetToolTip(panel, $"名称: {item.Name}\n路径: {item.Path}\n添加时间: {item.DateAdded.ToString("yyyy-MM-dd")}\n使用次数: {item.UsageCount}");
toolTip1.SetToolTip(control, $"名称: {item.Name}\n路径: {item.Path}\n添加时间: {item.DateAdded.ToString("yyyy-MM-dd")}\n使用次数: {item.UsageCount}");
}
}
else if (sender is RoundedPanel directPanel && directPanel.Tag is ShortcutItem directItem)
{
// 直接是面板的情况
directPanel.BackColor = isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(230, 230, 230);
toolTip1.SetToolTip(directPanel, $"名称: {directItem.Name}\n路径: {directItem.Path}\n添加时间: {directItem.DateAdded.ToString("yyyy-MM-dd")}\n使用次数: {directItem.UsageCount}");
}
}
// 鼠标离开面板时的效果
private void Panel_MouseLeave(object sender, EventArgs e)
{
if (sender is Control control && control.Parent is RoundedPanel panel)
{
// 恢复正常颜色
panel.BackColor = isDarkMode ? Color.FromArgb(50, 50, 50) : Color.FromArgb(245, 245, 245);
}
else if (sender is RoundedPanel directPanel)
{
// 直接是面板的情况
directPanel.BackColor = isDarkMode ? Color.FromArgb(50, 50, 50) : Color.FromArgb(245, 245, 245);
}
}
// 鼠标按下时的效果
private void Panel_MouseDown(object sender, MouseEventArgs e)
{
if (sender is Control control && control.Parent is RoundedPanel panel)
{
// 应用按下效果
panel.BackColor = isDarkMode ? Color.FromArgb(90, 90, 90) : Color.FromArgb(210, 210, 210);
}
else if (sender is RoundedPanel directPanel)
{
// 直接是面板的情况
directPanel.BackColor = isDarkMode ? Color.FromArgb(90, 90, 90) : Color.FromArgb(210, 210, 210);
}
}
// 鼠标释放时的效果
private void Panel_MouseUp(object sender, MouseEventArgs e)
{
if (sender is Control control && control.Parent is RoundedPanel panel)
{
// 恢复悬停颜色
panel.BackColor = isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(230, 230, 230);
}
else if (sender is RoundedPanel directPanel)
{
// 直接是面板的情况
directPanel.BackColor = isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(230, 230, 230);
}
}
// 添加面板鼠标移动事件处理
private void ShortcutsPanel_MouseMove(object sender, MouseEventArgs e)
{
// 获取鼠标位置下的控件
Control control = shortcutsPanel.GetChildAtPoint(e.Location);
// 如果鼠标不在任何子控件上,则隐藏工具提示
if (control == null)
{
toolTip1.RemoveAll();
}
}
// 添加工具提示组件
private ToolTip toolTip1 = new ToolTip();
private void AddButton_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(currentCategory))
{
MessageBox.Show("请先选择一个分类", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "应用程序|*.exe|所有文件|*.*";
if (dialog.ShowDialog() == DialogResult.OK)
{
AddNewShortcut(dialog.FileName, currentCategory);
}
}
}
private void AddNewShortcut(string filePath, string category)
{
// 放宽文件类型限制,允许任何文件类型
var item = new ShortcutItem
{
Name = Path.GetFileNameWithoutExtension(filePath),
Path = filePath,
DateAdded = DateTime.Now,
UsageCount = 0
};
item.LoadIcon();
categories[category].Add(item);
SaveData();
if (category == currentCategory)
{
ShowCategoryItems(category);
}
}
// 启动应用程序
private void LaunchApplication(string path)
{
try
{
// 查找并更新使用次数
if (!string.IsNullOrEmpty(currentCategory) && categories.ContainsKey(currentCategory))
{
var item = categories[currentCategory].FirstOrDefault(i => i.Path == path);
if (item != null)
{
item.UsageCount++;
item.LastUsed = DateTime.Now;
SaveData();
}
}
var startInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = path,
UseShellExecute = true
};
System.Diagnostics.Process.Start(startInfo);
}
catch (Exception ex)
{
MessageBox.Show($"启动程序失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void SaveData()
{
try
{
var options = new JsonSerializerOptions
{
WriteIndented = true
};
var data = JsonSerializer.Serialize(categories, options);
File.WriteAllText(dataFilePath, data);
}
catch (Exception ex)
{
MessageBox.Show($"保存配置失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void LoadData()
{
if (File.Exists(dataFilePath))
{
try
{
var json = File.ReadAllText(dataFilePath);
categories = JsonSerializer.Deserialize<Dictionary<string, List<ShortcutItem>>>(json);
// 加载所有图标
foreach (var category in categories.Values)
{
foreach (var item in category)
{
item.LoadIcon();
}
}
RefreshCategoryList();
// 如果有上次选择的分类,则选择它
if (!string.IsNullOrEmpty(settings.LastSelectedCategory) && categories.ContainsKey(settings.LastSelectedCategory))
{
SwitchCategory(settings.LastSelectedCategory);
}
// 否则选择第一个分类
else if (categories.Count > 0)
{
SwitchCategory(categories.Keys.First());
}
}
catch (Exception ex)
{
MessageBox.Show($"加载配置失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
categories = new Dictionary<string, List<ShortcutItem>>();
}
}
else
{
// 如果没有数据文件,创建一个默认分类
categories = new Dictionary<string, List<ShortcutItem>>();
categories["默认分类"] = new List<ShortcutItem>();
SaveData();
RefreshCategoryList();
SwitchCategory("默认分类");
}
}
private void SwitchCategory(string category)
{
currentCategory = category;
RefreshCategoryList();
ShowCategoryItems(category);
SaveSettings(); // 保存当前选择的分类
}
private void button1_Click(object sender, EventArgs e)
{
isDarkMode = !isDarkMode; // 切换主题状态
ApplyTheme(isDarkMode);
}
private void ApplyTheme(bool darkMode)
{
if (darkMode)
{
ChangeTheme(true);
}
else
ChangeTheme(false);
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
form1.StartPosition = FormStartPosition.CenterParent;
form1.ShowDialog(this);
}
// 初始化通知图标和浮动图标
private void InitializeNotifyIcon()
{
try
{
// 创建通知区域图标
notifyIcon = new NotifyIcon
{
Icon = this.Icon,
Text = "工具箱",
Visible = true
};
// 创建右键菜单
ContextMenuStrip contextMenu = new ContextMenuStrip();
contextMenu.Items.Add("显示主窗口", null, (s, e) => { ShowMainWindowAndHideIcon(); });
contextMenu.Items.Add("-");
contextMenu.Items.Add("添加新快捷方式", null, (s, e) => { ShowMainWindowAndAddShortcut(); });
contextMenu.Items.Add("打开最近使用的项目", null, (s, e) => { ShowRecentItemsMenu(); });
contextMenu.Items.Add("-");
// 添加浮动图标控制选项
var floatingIconMenu = new ToolStripMenuItem("浮动图标");
floatingIconMenu.DropDownItems.Add("显示浮动图标", null, (s, e) => { ShowFloatingIcon(); });
floatingIconMenu.DropDownItems.Add("隐藏浮动图标", null, (s, e) => { HideFloatingIcon(); });
contextMenu.Items.Add(floatingIconMenu);
contextMenu.Items.Add("设置", null, (s, e) => { ShowSettingsDialog(); });
contextMenu.Items.Add("-");
contextMenu.Items.Add("退出", null, (s, e) => { ExitApplication(); });
// 应用主题颜色
contextMenu.Renderer = new ModernMenuRenderer(isDarkMode);
notifyIcon.ContextMenuStrip = contextMenu;
notifyIcon.MouseClick += (s, e) =>
{
if (e.Button == MouseButtons.Left)
{
ShowMainWindowAndHideIcon();
}
};
// 创建浮动图标窗体
CreateFloatingIcon();
// 不再根据设置自动显示浮动图标
// 浮动图标只会在主窗口最小化或关闭时显示
}
catch (Exception ex)
{
// 记录错误但不中断程序运行
MessageBox.Show($"初始化通知图标时出错: {ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
// 显示主窗口并隐藏浮动图标
private void ShowMainWindowAndHideIcon()
{
HideFloatingIcon();
ShowMainWindow();
}
// 显示主窗口
private void ShowMainWindow()
{
this.Show();
this.WindowState = FormWindowState.Normal;
this.Activate();
}
// 重写窗体状态改变事件
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
// 当窗口最小化时,显示浮动图标
if (this.WindowState == FormWindowState.Minimized)
{
this.Hide();
ShowFloatingIcon();
}
}
// 重写窗体关闭事件
protected override void OnFormClosing(FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true; // 取消关闭操作
this.Hide(); // 隐藏窗体
ShowFloatingIcon(); // 显示浮动图标
}
else
{
// 清理资源
if (notifyIcon != null)
{
notifyIcon.Visible = false;
notifyIcon.Dispose();
}
if (floatingIcon != null && !floatingIcon.IsDisposed)
{
floatingIcon.Close();
floatingIcon.Dispose();
}
base.OnFormClosing(e);
}
}
// 创建浮动图标窗体
private void CreateFloatingIcon()
{
try
{
floatingIcon = new Form
{
Size = new Size(64, 64), // 增大尺寸,更容易点击
FormBorderStyle = FormBorderStyle.None,
ShowInTaskbar = false,
TopMost = true,
StartPosition = FormStartPosition.Manual,
TransparencyKey = Color.Magenta, // 设置透明色
BackColor = Color.Magenta, // 设置背景色为透明色
Visible = false // 确保创建时默认隐藏
};
// 创建一个圆形面板作为图标容器
RoundedPanel iconPanel = new RoundedPanel
{
Size = new Size(64, 64), // 增大尺寸
Location = new Point(0, 0),
CornerRadius = 60, // 完全圆形
BackColor = Color.FromArgb(50, 50, 50) // 使用强调色,更加醒目
};
// 添加阴影效果
iconPanel.Paint += (s, e) =>
{
// 设置高质量绘图模式
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
// 绘制阴影
using (GraphicsPath path = new GraphicsPath())
{
path.AddEllipse(0, 0, iconPanel.Width, iconPanel.Height);
// 创建渐变背景
Color baseColor = isDarkMode ? Color.FromArgb(50, 50, 50) : Color.FromArgb(240, 240, 240);
Color gradientColor = isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(220, 220, 220);
using (LinearGradientBrush bgBrush = new LinearGradientBrush(
new Point(0, 0),
new Point(0, iconPanel.Height),
baseColor,
gradientColor))
{
e.Graphics.FillPath(bgBrush, path);
}
// 创建阴影效果
using (PathGradientBrush brush = new PathGradientBrush(path))
{
brush.CenterColor = Color.FromArgb(0, 0, 0, 0);
brush.SurroundColors = new Color[] { Color.FromArgb(80, 0, 0, 0) }; // 增强阴影效果
brush.WrapMode = WrapMode.Clamp;
// 绘制阴影
e.Graphics.FillPath(brush, path);
}
// 绘制边框 - 使用白色或深色边框增加对比度
using (Pen pen = new Pen(isDarkMode ? Color.FromArgb(180, 180, 180) : Color.FromArgb(50, 50, 50), 1.5f))
{
// 设置平滑连接和端点
pen.LineJoin = LineJoin.Round;
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
pen.Alignment = PenAlignment.Center; // 确保边框居中对齐
// 使用更平滑的方式绘制圆形
e.Graphics.DrawEllipse(pen, 0, 0, iconPanel.Width - 1, iconPanel.Height - 1);
}
// 添加内部边框,创造更精致的外观
using (Pen innerPen = new Pen(isDarkMode ? Color.FromArgb(70, 70, 70) : Color.FromArgb(220, 220, 220), 1f))
{
innerPen.LineJoin = LineJoin.Round;
innerPen.StartCap = LineCap.Round;
innerPen.EndCap = LineCap.Round;
innerPen.Alignment = PenAlignment.Center; // 确保边框居中对齐
// 使用更平滑的方式绘制内部圆形
e.Graphics.DrawEllipse(innerPen, 2, 2, iconPanel.Width - 5, iconPanel.Height - 5);
}
}
};
// 添加图标
PictureBox iconBox = new PictureBox
{
Size = new Size(48, 48), // 稍微调整图标尺寸
Location = new Point(8, 8), // 居中放置
SizeMode = PictureBoxSizeMode.StretchImage,
BackColor = Color.Transparent // 使用透明背景,让图标更清晰
};
// 尝试加载自定义图标
Image iconImage = null;
if (!string.IsNullOrEmpty(settings.FloatingIconPath) && File.Exists(settings.FloatingIconPath))
{
try
{
iconImage = Image.FromFile(settings.FloatingIconPath);
}
catch
{
// 如果加载失败,使用默认图标
iconImage = this.Icon.ToBitmap();
}
}
else
{
// 使用默认图标
iconImage = this.Icon.ToBitmap();
}
// 优化图标显示
try {
// 尝试创建高质量图标
Bitmap highQualityIcon = new Bitmap(48, 48);
using (Graphics g = Graphics.FromImage(highQualityIcon))
{
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.DrawImage(iconImage, 0, 0, 48, 48);
}
iconBox.Image = highQualityIcon;
}
catch {
// 如果失败,使用原始图标
iconBox.Image = iconImage;
}
iconPanel.Controls.Add(iconBox);
floatingIcon.Controls.Add(iconPanel);
// 添加鼠标事件
bool isDragging = false;
Point dragStartPoint = Point.Empty;
// 添加双击事件
iconPanel.DoubleClick += (s, e) => {
ShowMainWindowAndHideIcon();
};
iconBox.DoubleClick += (s, e) => {
ShowMainWindowAndHideIcon();
};
// 鼠标进入时的效果 - 使用更明显的高亮效果
iconPanel.MouseEnter += (s, e) =>
{
// 高亮效果 - 使用更亮的颜色
Color brighterColor = Color.FromArgb(
Math.Min(Color.FromArgb(50, 50, 50).R + 30, 255),
Math.Min(Color.FromArgb(50, 50, 50).G + 30, 255),
Math.Min(Color.FromArgb(50, 50, 50).B + 30, 255)
);
iconPanel.BackColor = brighterColor;
// 不再设置窗体背景色
};
// 鼠标离开时的效果
iconPanel.MouseLeave += (s, e) =>
{
iconPanel.BackColor = Color.FromArgb(50, 50, 50);
// 不再设置窗体背景色
};
iconPanel.MouseDown += (s, e) =>
{
if (e.Button == MouseButtons.Left)
{
isDragging = true;
dragStartPoint = e.Location;
// 按下效果 - 使用更深的颜色
Color darkerColor = Color.FromArgb(
Math.Max(Color.FromArgb(50, 50, 50).R - 30, 0),
Math.Max(Color.FromArgb(50, 50, 50).G - 30, 0),
Math.Max(Color.FromArgb(50, 50, 50).B - 30, 0)
);
iconPanel.BackColor = darkerColor;
// 不再设置窗体背景色
}
};
iconPanel.MouseMove += (s, e) =>
{
if (isDragging)
{
// 计算新位置
Point newLocation = new Point(
floatingIcon.Location.X + e.X - dragStartPoint.X,
floatingIcon.Location.Y + e.Y - dragStartPoint.Y
);
// 确保不超出屏幕边界
newLocation = EnsureIconOnScreen(newLocation);
// 应用新位置
floatingIcon.Location = newLocation;
}
};
iconPanel.MouseUp += (s, e) =>
{
if (isDragging)
{
isDragging = false;
// 恢复悬停效果
Color brighterColor = Color.FromArgb(
Math.Min(Color.FromArgb(50, 50, 50).R + 30, 255),
Math.Min(Color.FromArgb(50, 50, 50).G + 30, 255),
Math.Min(Color.FromArgb(50, 50, 50).B + 30, 255)
);
iconPanel.BackColor = brighterColor;
// 不再设置窗体背景色
}
else if (e.Button == MouseButtons.Left)
{
// 单击左键时显示主窗口并隐藏浮动图标
ShowMainWindowAndHideIcon();
}
};
// 为图标也添加相同的事件处理
iconBox.MouseEnter += (s, e) => {
// 使用与面板相同的高亮效果
Color brighterColor = Color.FromArgb(
Math.Min(Color.FromArgb(50, 50, 50).R + 30, 255),
Math.Min(Color.FromArgb(50, 50, 50).G + 30, 255),
Math.Min(Color.FromArgb(50, 50, 50).B + 30, 255)
);
iconPanel.BackColor = brighterColor;
// 不再设置窗体背景色
};
iconBox.MouseLeave += (s, e) => {
// 恢复正常颜色
iconPanel.BackColor = Color.FromArgb(50, 50, 50);
// 不再设置窗体背景色
};
iconBox.MouseDown += (s, e) => {
if (e.Button == MouseButtons.Left)
{
isDragging = true;
dragStartPoint = e.Location;
// 按下效果 - 使用更深的颜色
Color darkerColor = Color.FromArgb(
Math.Max(Color.FromArgb(50, 50, 50).R - 30, 0),
Math.Max(Color.FromArgb(50, 50, 50).G - 30, 0),
Math.Max(Color.FromArgb(50, 50, 50).B - 30, 0)
);
iconPanel.BackColor = darkerColor;
// 不再设置窗体背景色
}
};
iconBox.MouseMove += (s, e) => {
if (isDragging)
{
// 计算新位置
Point newLocation = new Point(
floatingIcon.Location.X + e.X - dragStartPoint.X,
floatingIcon.Location.Y + e.Y - dragStartPoint.Y
);
// 确保不超出屏幕边界
newLocation = EnsureIconOnScreen(newLocation);
// 应用新位置
floatingIcon.Location = newLocation;
}
};
iconBox.MouseUp += (s, e) => {
if (isDragging)
{
isDragging = false;
// 恢复悬停效果
Color brighterColor = Color.FromArgb(
Math.Min(Color.FromArgb(50, 50, 50).R + 30, 255),
Math.Min(Color.FromArgb(50, 50, 50).G + 30, 255),
Math.Min(Color.FromArgb(50, 50, 50).B + 30, 255)
);
iconPanel.BackColor = brighterColor;
// 不再设置窗体背景色
}
else if (e.Button == MouseButtons.Left)
{
// 单击左键时显示主窗口并隐藏浮动图标
ShowMainWindowAndHideIcon();
}
};
// 右键菜单
ContextMenuStrip iconMenu = new ContextMenuStrip();
iconMenu.Items.Add("显示主窗口", null, (s, e) => { ShowMainWindowAndHideIcon(); });
iconMenu.Items.Add("-");
iconMenu.Items.Add("添加新快捷方式", null, (s, e) => { ShowMainWindowAndAddShortcut(); });
iconMenu.Items.Add("打开最近使用的项目", null, (s, e) => { ShowRecentItemsMenu(); });
iconMenu.Items.Add("-");
iconMenu.Items.Add("修改浮动按钮图标", null, (s, e) => { ChangeFloatingIconImage(); });
iconMenu.Items.Add("-");
iconMenu.Items.Add("设置", null, (s, e) => { ShowSettingsDialog(); });
iconMenu.Items.Add("-");
iconMenu.Items.Add("退出", null, (s, e) => { ExitApplication(); });
// 应用主题颜色
iconMenu.Renderer = new ModernMenuRenderer(isDarkMode);
iconPanel.ContextMenuStrip = iconMenu;
iconBox.ContextMenuStrip = iconMenu;
}
catch (Exception ex)
{
MessageBox.Show($"创建浮动图标时出错: {ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
// 显示主窗口并立即打开添加快捷方式对话框
private void ShowMainWindowAndAddShortcut()
{
ShowMainWindowAndHideIcon();
// 等待主窗口完全显示
this.BeginInvoke(new Action(() =>
{
if (!string.IsNullOrEmpty(currentCategory))
{
AddButton_Click(null, EventArgs.Empty);
}
else
{
MessageBox.Show("请先选择一个分类", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}));
}
// 显示最近使用的项目菜单
private void ShowRecentItemsMenu()
{
try
{
// 创建一个临时菜单
ContextMenuStrip recentMenu = new ContextMenuStrip();
recentMenu.Renderer = new ModernMenuRenderer(isDarkMode);
// 获取最近使用的项目所有分类中按最后使用时间排序的前10个项目
var recentItems = categories
.SelectMany(c => c.Value)
.Where(item => item.LastUsed > DateTime.MinValue)
.OrderByDescending(item => item.LastUsed)
.Take(10)
.ToList();
if (recentItems.Count > 0)
{
foreach (var item in recentItems)
{
var menuItem = new ToolStripMenuItem(item.Name);
// 尝试设置图标
try
{
if (item.Icon != null)
{
menuItem.Image = new Bitmap(item.Icon, new Size(16, 16));
}
}
catch { }
menuItem.Tag = item;
menuItem.Click += (s, e) =>
{
if (s is ToolStripMenuItem mi && mi.Tag is ShortcutItem shortcut)
{
LaunchApplication(shortcut.Path);
}
};
recentMenu.Items.Add(menuItem);
}
}
else
{
var noItemsMenuItem = new ToolStripMenuItem("没有最近使用的项目");
noItemsMenuItem.Enabled = false;
recentMenu.Items.Add(noItemsMenuItem);
}
// 显示菜单
recentMenu.Show(Cursor.Position);
}
catch (Exception ex)
{
MessageBox.Show($"显示最近使用项目时出错: {ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
// 显示设置对话框
private void ShowSettingsDialog()
{
ShowMainWindowAndHideIcon();
// 等待主窗口完全显示
this.BeginInvoke(new Action(() =>
{
// 这里可以打开设置对话框
MessageBox.Show("设置功能尚未实现", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}));
}
// 退出应用程序
private void ExitApplication()
{
// 确认是否退出
if (MessageBox.Show("确定要退出程序吗?", "确认", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
try
{
// 保存设置
SaveSettings();
// 清理资源
if (notifyIcon != null)
{
notifyIcon.Visible = false;
notifyIcon.Dispose();
notifyIcon = null;
}
if (floatingIcon != null && !floatingIcon.IsDisposed)
{
floatingIcon.Close();
floatingIcon.Dispose();
floatingIcon = null;
}
// 使用 ExitThread 而不是 Exit
Application.ExitThread();
}
catch (Exception ex)
{
MessageBox.Show($"退出程序时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
// 如果出错,强制退出
Environment.Exit(0);
}
}
}
// 显示浮动图标
private void ShowFloatingIcon()
{
if (floatingIcon == null)
{
try
{
CreateFloatingIcon();
}
catch (Exception ex)
{
MessageBox.Show($"创建浮动图标时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
if (!isFloatingIconVisible && floatingIcon != null)
{
try
{
// 设置初始位置(屏幕右侧中间)
Screen screen = Screen.PrimaryScreen;
// 如果有保存的位置,使用保存的位置
Point iconPosition;
if (settings.FloatingIconPosition.X != 0 && settings.FloatingIconPosition.Y != 0)
{
iconPosition = settings.FloatingIconPosition;
// 确保图标在屏幕内
iconPosition = EnsureIconOnScreen(iconPosition);
}
else
{
// 默认位置:屏幕右侧中间
iconPosition = new Point(
screen.WorkingArea.Right - floatingIcon.Width - 20,
screen.WorkingArea.Bottom / 2 - floatingIcon.Height / 2
);
}
floatingIcon.Location = iconPosition;
floatingIcon.Show();
isFloatingIconVisible = true;
// 移除淡入效果代码,直接显示
}
catch (Exception ex)
{
MessageBox.Show($"显示浮动图标时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
// 隐藏浮动图标
private void HideFloatingIcon()
{
if (isFloatingIconVisible && floatingIcon != null)
{
try
{
// 保存当前位置
settings.FloatingIconPosition = floatingIcon.Location;
SaveSettings();
// 移除淡出效果代码,直接隐藏
floatingIcon.Hide();
isFloatingIconVisible = false;
}
catch (Exception ex)
{
// 如果出现错误,尝试直接隐藏
try
{
floatingIcon.Hide();
isFloatingIconVisible = false;
}
catch { }
MessageBox.Show($"隐藏浮动图标时出错: {ex.Message}", "警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
// 完全重写确保图标在屏幕内的方法
private Point EnsureIconOnScreen(Point position)
{
if (floatingIcon == null)
return position;
// 获取包含该点的屏幕
Screen screen = Screen.FromPoint(position);
if (screen == null)
{
screen = Screen.PrimaryScreen;
}
Rectangle workArea = screen.WorkingArea;
// 获取浮动图标的实际大小
int iconWidth = floatingIcon.Width;
int iconHeight = floatingIcon.Height;
// 计算实际可见图标的大小(圆形部分)
int visibleIconSize = 64; // 圆形图标的直径
// 计算边缘偏移量
int leftOffset = 0; // 左侧不需要偏移
int topOffset = 0; // 顶部不需要偏移
int rightOffset = iconWidth - visibleIconSize; // 右侧偏移量等于窗体宽度减去可见图标宽度
int bottomOffset = iconHeight - visibleIconSize; // 底部偏移量等于窗体高度减去可见图标高度
// 为了确保图标能够完全贴近右侧边缘,额外增加偏移量
//rightOffset += 10; // 额外增加20像素的偏移量
// 确保X坐标在屏幕内
if (position.X < workArea.Left - leftOffset)
{
position.X = workArea.Left - leftOffset;
}
else if (position.X + iconWidth > workArea.Right + rightOffset)
{
// 确保图标可以完全贴近屏幕右侧边缘
position.X = workArea.Right + rightOffset - iconWidth;
}
// 确保Y坐标在屏幕内
if (position.Y < workArea.Top - topOffset)
{
position.Y = workArea.Top - topOffset;
}
else if (position.Y + iconHeight > workArea.Bottom + bottomOffset)
{
position.Y = workArea.Bottom + bottomOffset - iconHeight;
}
return position;
}
// 切换浮动图标显示状态
private void ToggleFloatingIcon()
{
if (isFloatingIconVisible)
HideFloatingIcon();
else
ShowFloatingIcon();
}
// 修改浮动按钮图标
private void ChangeFloatingIconImage()
{
try
{
// 显示文件选择对话框
using (OpenFileDialog dialog = new OpenFileDialog())
{
dialog.Title = "选择新的浮动按钮图标";
dialog.Filter = "图标文件|*.ico;*.png;*.jpg;*.jpeg;*.bmp;*.gif|所有文件|*.*";
dialog.Multiselect = false;
if (dialog.ShowDialog() == DialogResult.OK)
{
string iconPath = dialog.FileName;
// 检查文件是否存在
if (!File.Exists(iconPath))
{
MessageBox.Show("选择的文件不存在", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
// 尝试加载图标
try
{
Image newIcon = Image.FromFile(iconPath);
// 查找浮动图标中的PictureBox控件
if (floatingIcon != null && !floatingIcon.IsDisposed)
{
foreach (Control control in floatingIcon.Controls)
{
if (control is RoundedPanel panel)
{
foreach (Control panelControl in panel.Controls)
{
if (panelControl is PictureBox iconBox)
{
// 更新图标
iconBox.Image = newIcon;
// 保存图标路径到设置
settings.FloatingIconPath = iconPath;
SaveSettings();
MessageBox.Show("浮动按钮图标已更新", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
}
}
}
}
MessageBox.Show("无法找到浮动按钮图标控件", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show($"加载图标文件失败: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show($"修改浮动按钮图标时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
public class ShortcutItem
{
public string Name { get; set; }
public string Path { get; set; }
[System.Text.Json.Serialization.JsonIgnore]
public Bitmap Icon { get; set; }
public DateTime DateAdded { get; set; } = DateTime.Now;
public DateTime LastUsed { get; set; } = DateTime.MinValue;
public int UsageCount { get; set; } = 0;
public string Description { get; set; } = ""; // 添加描述属性
public string Arguments { get; set; } = ""; // 添加启动参数
public bool RunAsAdmin { get; set; } = false; // 是否以管理员身份运行
public string Category { get; set; } = ""; // 所属分类
public string CustomIconPath { get; set; } = ""; // 自定义图标路径
public string BackgroundColor { get; set; } = ""; // 自定义背景色
public int SortOrder { get; set; } = 0; // 排序顺序
// 用于序列化的构造函数
public ShortcutItem()
{
}
// 加载图标的方法
public void LoadIcon()
{
try
{
// 如果有自定义图标,优先使用自定义图标
if (!string.IsNullOrEmpty(CustomIconPath) && File.Exists(CustomIconPath))
{
try
{
// 尝试加载自定义图标
using (System.Drawing.Icon customIcon = new System.Drawing.Icon(CustomIconPath))
{
Icon = customIcon.ToBitmap();
return;
}
}
catch
{
// 如果自定义图标加载失败,继续使用默认图标
}
}
// 使用关联图标
if (File.Exists(Path))
{
using (System.Drawing.Icon icon = System.Drawing.Icon.ExtractAssociatedIcon(Path))
{
if (icon != null)
{
Icon = icon.ToBitmap();
}
else
{
Icon = SystemIcons.Application.ToBitmap();
}
}
}
else
{
Icon = SystemIcons.Application.ToBitmap();
}
}
catch
{
Icon = SystemIcons.Application.ToBitmap();
}
}
// 获取格式化的最后使用时间
public string GetFormattedLastUsed()
{
if (LastUsed == DateTime.MinValue)
return "从未使用";
TimeSpan span = DateTime.Now - LastUsed;
if (span.TotalDays > 365)
return $"{Math.Floor(span.TotalDays / 365)}年前";
if (span.TotalDays > 30)
return $"{Math.Floor(span.TotalDays / 30)}个月前";
if (span.TotalDays > 1)
return $"{Math.Floor(span.TotalDays)}天前";
if (span.TotalHours > 1)
return $"{Math.Floor(span.TotalHours)}小时前";
if (span.TotalMinutes > 1)
return $"{Math.Floor(span.TotalMinutes)}分钟前";
return "刚刚";
}
// 获取背景颜色
public Color GetBackgroundColor(bool isDarkMode)
{
// 如果有自定义背景色,尝试解析
if (!string.IsNullOrEmpty(BackgroundColor))
{
try
{
// 尝试解析颜色字符串,格式为 R,G,B
string[] parts = BackgroundColor.Split(',');
if (parts.Length == 3 &&
int.TryParse(parts[0], out int r) &&
int.TryParse(parts[1], out int g) &&
int.TryParse(parts[2], out int b))
{
return Color.FromArgb(r, g, b);
}
}
catch
{
// 解析失败,使用默认颜色
}
}
// 返回默认颜色
return isDarkMode ? Color.FromArgb(50, 50, 50) : Color.FromArgb(245, 245, 245);
}
}
// 添加GDI+扩展方法
public static class GraphicsExtensions
{
public static void FillRoundedRectangle(this Graphics graphics, Brush brush, Rectangle bounds, int cornerRadius)
{
if (graphics == null)
throw new ArgumentNullException("graphics");
if (brush == null)
throw new ArgumentNullException("brush");
// 设置高质量绘图模式
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
using (GraphicsPath path = CreateRoundedRectangle(bounds, cornerRadius))
{
graphics.FillPath(brush, path);
}
}
public static void DrawRoundedRectangle(this Graphics graphics, Pen pen, Rectangle bounds, int cornerRadius)
{
if (graphics == null)
throw new ArgumentNullException("graphics");
if (pen == null)
throw new ArgumentNullException("pen");
// 设置高质量绘图模式
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphics.CompositingQuality = CompositingQuality.HighQuality;
// 设置平滑连接和端点
pen.LineJoin = LineJoin.Round;
pen.StartCap = LineCap.Round;
pen.EndCap = LineCap.Round;
using (GraphicsPath path = CreateRoundedRectangle(bounds, cornerRadius))
{
graphics.DrawPath(pen, path);
}
}
private static GraphicsPath CreateRoundedRectangle(Rectangle bounds, int cornerRadius)
{
GraphicsPath path = new GraphicsPath();
if (cornerRadius > 0)
{
path.AddArc(bounds.X, bounds.Y, cornerRadius * 2, cornerRadius * 2, 180, 90);
path.AddArc(bounds.Right - cornerRadius * 2, bounds.Y, cornerRadius * 2, cornerRadius * 2, 270, 90);
path.AddArc(bounds.Right - cornerRadius * 2, bounds.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 0, 90);
path.AddArc(bounds.X, bounds.Bottom - cornerRadius * 2, cornerRadius * 2, cornerRadius * 2, 90, 90);
path.CloseFigure();
}
else
{
path.AddRectangle(bounds);
}
return path;
}
}
}