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)) +}