From 01cd7ae6e36225824b895acbeb2c85fee40667f2 Mon Sep 17 00:00:00 2001 From: ayflying Date: Fri, 31 Oct 2025 17:34:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=85=B3=E9=97=AD=E7=AA=97?= =?UTF-8?q?=E5=8F=A3=E4=B8=8D=E9=80=80=E5=87=BA=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/logic/os/windows.go | 50 ++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/internal/logic/os/windows.go b/internal/logic/os/windows.go index 24b5faa..8b04f13 100644 --- a/internal/logic/os/windows.go +++ b/internal/logic/os/windows.go @@ -17,16 +17,24 @@ import ( // 引入 Windows API 函数 var ( - user32 = syscall.NewLazyDLL("user32.dll") - kernel32 = syscall.NewLazyDLL("kernel32.dll") - showWindow = user32.NewProc("ShowWindow") - getConsoleWnd = kernel32.NewProc("GetConsoleWindow") - freeConsole = kernel32.NewProc("FreeConsole") - attachConsole = kernel32.NewProc("AttachConsole") - allocConsole = kernel32.NewProc("AllocConsole") + user32 = syscall.NewLazyDLL("user32.dll") + kernel32 = syscall.NewLazyDLL("kernel32.dll") + showWindow = user32.NewProc("ShowWindow") + getConsoleWnd = kernel32.NewProc("GetConsoleWindow") + freeConsole = kernel32.NewProc("FreeConsole") + attachConsole = kernel32.NewProc("AttachConsole") + allocConsole = kernel32.NewProc("AllocConsole") + setConsoleCtrlHandler = kernel32.NewProc("SetConsoleCtrlHandler") + consoleCtrlHandler uintptr +) + +const ( + ctrlCloseEvent = 2 ) func (s *sOS) start() { + // 注册控制台关闭事件处理:点击叉叉仅隐藏控制台而不退出程序 + s.setupConsoleCloseHandler() // 系统托盘初始化(设置图标、右键菜单) go systray.Run(s.onSystrayReady, s.onSystrayExit) @@ -34,7 +42,7 @@ func (s *sOS) start() { // 系统托盘初始化(设置图标、右键菜单) func (s *sOS) onSystrayReady() { - s.hideConsole() + // s.hideConsole() var iconByte []byte if !gfile.Exists(s.systray.Icon) { iconByte = gres.GetContent(s.systray.Icon) @@ -94,9 +102,7 @@ func (s *sOS) update(version, server string) { // 隐藏控制台窗口 func (s *sOS) hideConsole() { - // 彻底脱离控制台,避免仅最小化 - freeConsole.Call() - // 获取当前控制台窗口句柄并隐藏窗口 + // 仅隐藏控制台窗口(保留现有缓冲区以便后续显示时保留历史日志) hWnd, _, _ := getConsoleWnd.Call() if hWnd != 0 { // SW_HIDE = 0:隐藏窗口 @@ -124,3 +130,25 @@ func (s *sOS) showConsole() { showWindow.Call(hWnd, 5) } } + +// 注册控制台关闭事件处理器,将关闭事件转换为隐藏行为 +func (s *sOS) setupConsoleCloseHandler() { + if consoleCtrlHandler != 0 { + return + } + consoleCtrlHandler = syscall.NewCallback(func(ctrlType uint32) uintptr { + if ctrlType == ctrlCloseEvent { + // 用户点击控制台窗口的关闭按钮(X):仅隐藏,不退出 + hWnd, _, _ := getConsoleWnd.Call() + if hWnd != 0 { + // SW_HIDE = 0 + showWindow.Call(hWnd, 0) + } + // 返回 TRUE 表示事件已处理,阻止默认终止行为 + return 1 + } + // 其他事件交由系统默认处理 + return 0 + }) + setConsoleCtrlHandler.Call(consoleCtrlHandler, uintptr(1)) +}