From c4bffa500d252fd9bafc2a184138204d9a69650c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B0=9A=E7=BE=8E?= <2370337237@qq.com> Date: Thu, 13 Mar 2025 14:08:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B5=AE=E5=8A=A8=E5=9B=BE?= =?UTF-8?q?=E6=A0=87=E4=BB=A5=E5=8F=8A=E5=9B=BE=E6=A0=87=E5=8F=B3=E9=94=AE?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E8=8F=9C=E5=8D=95=EF=BC=8C=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E5=B7=A6=E5=8F=B3=E8=BE=B9=E7=BC=98=E5=81=9C=E9=9D=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MainForm.cs | 987 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 962 insertions(+), 25 deletions(-) diff --git a/MainForm.cs b/MainForm.cs index 9bd7f77..405c9e2 100644 --- a/MainForm.cs +++ b/MainForm.cs @@ -7,6 +7,7 @@ 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; // 添加Registry访问支持 namespace QuickLauncher @@ -45,6 +46,12 @@ namespace QuickLauncher { 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()) { @@ -74,6 +81,12 @@ namespace QuickLauncher { 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()) { @@ -117,10 +130,119 @@ namespace QuickLauncher 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; + + // 添加到左侧面板 + 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(); @@ -134,6 +256,9 @@ namespace QuickLauncher toolTip1.UseFading = true; toolTip1.IsBalloon = false; // 使用标准样式 + // 移除最小化按钮,保留最大化按钮 + this.MinimizeBox = false; + // 初始化数据和UI InitializeUI(); @@ -142,12 +267,29 @@ namespace QuickLauncher 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) @@ -708,6 +850,14 @@ namespace QuickLauncher 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 @@ -732,6 +882,13 @@ namespace QuickLauncher settings = JsonSerializer.Deserialize(json) ?? new AppSettings(); iconSize = settings.IconSize; // 加载保存的图标大小 leftPanel.Width = settings.LeftPanelWidth; + + // 确保floatingIcon已初始化 + if (floatingIcon != null) + { + floatingIcon.Location = settings.FloatingIconPosition; + // 不要在这里设置Visible属性,让ShowFloatingIcon方法来控制 + } } catch { @@ -836,35 +993,10 @@ namespace QuickLauncher categoryLabel.Font = new Font("Microsoft YaHei UI", 11); categoryLabel.ForeColor = isDarkMode ? Color.FromArgb(0, 0, 0) : Color.FromArgb(255, 255, 255); - // 创建左侧面板调整手柄 - CreateResizeHandle(); - // 刷新分类列表 RefreshCategoryList(); } - // 创建左侧面板调整手柄 - private void CreateResizeHandle() - { - // 创建调整手柄 - resizeHandle = new Panel - { - Width = 5, - Dock = DockStyle.Right, - Cursor = Cursors.SizeWE, - BackColor = Color.Transparent - }; - - // 添加鼠标事件 - resizeHandle.MouseDown += ResizeHandle_MouseDown; - resizeHandle.MouseMove += ResizeHandle_MouseMove; - resizeHandle.MouseUp += ResizeHandle_MouseUp; - - // 添加到左侧面板 - leftPanel.Controls.Add(resizeHandle); - resizeHandle.BringToFront(); - } - // 调整手柄鼠标按下事件 private void ResizeHandle_MouseDown(object sender, MouseEventArgs e) { @@ -1610,6 +1742,794 @@ namespace QuickLauncher 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 @@ -1744,6 +2664,12 @@ namespace QuickLauncher 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); @@ -1757,6 +2683,17 @@ namespace QuickLauncher 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);