//go:build windows // ============================================================================ // windowcompact_windows.go — 拖动手柄窗口尺寸切换(Windows 实现) // // Wails 无边框窗口仍带 WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | // WS_MAXIMIZEBOX | WS_BORDER | WS_DLGFRAME 样式位,DWM 对它们强制最小宽度 // (实测约 136px,剥离边框后仍有约 46px),WM_GETMINMAXINFO 的 // PtMinTrackSize 无法覆盖该下限。因此进入收拢状态时临时剥离这些样式位 // (SWP_FRAMECHANGED 使其生效),还原时恢复原样式。 // ============================================================================ package main import ( "unsafe" "github.com/wailsapp/wails/v3/pkg/application" ) const ( gwlStyle = -16 // GWL_STYLE // 触发 DWM 最小宽度强制的样式位 compactStyleMask = 0x00040000 | // WS_THICKFRAME 0x00080000 | // WS_SYSMENU 0x00020000 | // WS_MINIMIZEBOX 0x00010000 | // WS_MAXIMIZEBOX 0x00800000 | // WS_BORDER 0x00400000 // WS_DLGFRAME swpNoMove = 0x0002 swpNoSize = 0x0001 swpNoZOrder2 = 0x0004 swpNoActivate2 = 0x0010 swpFrameChanged = 0x0020 ) var ( procGetWindowLongW = user32.NewProc("GetWindowLongW") procSetWindowLongW = user32.NewProc("SetWindowLongW") ) // 收拢时保存的原始窗口样式(还原用) var compactSavedStyle int32 func compactWindowHwnd(win *application.WebviewWindow) uintptr { if win == nil { return 0 } return uintptr(unsafe.Pointer(win.NativeWindow())) } // compactEnterCompact 进入收拢状态:剥离 DWM 强制最小宽度的样式位后缩小窗口。 func compactEnterCompact(win *application.WebviewWindow, width, height int) { if win.IsMaximised() { win.UnMaximise() // 最大化状态下 SetSize 不生效,先还原 } hwnd := compactWindowHwnd(win) if hwnd != 0 { // 保存并剥离样式位,SWP_FRAMECHANGED 使样式变更立即生效 styleIdx := int32(gwlStyle) style, _, _ := procGetWindowLongW.Call(hwnd, uintptr(styleIdx)) compactSavedStyle = int32(style) newStyle := int32(style) &^ compactStyleMask procSetWindowLongW.Call(hwnd, uintptr(styleIdx), uintptr(newStyle)) procSetWindowPos.Call(hwnd, 0, 0, 0, 0, 0, swpNoMove|swpNoSize|swpNoZOrder2|swpNoActivate2|swpFrameChanged) } win.SetMinSize(width, height) // 解锁 Wails 侧最小尺寸约束 win.SetSize(width, height) } // compactExitCompact 退出收拢状态:恢复原样式位并还原窗口尺寸。 func compactExitCompact(win *application.WebviewWindow, width, height int) { hwnd := compactWindowHwnd(win) if hwnd != 0 && compactSavedStyle != 0 { styleIdx := int32(gwlStyle) procSetWindowLongW.Call(hwnd, uintptr(styleIdx), uintptr(compactSavedStyle)) procSetWindowPos.Call(hwnd, 0, 0, 0, 0, 0, swpNoMove|swpNoSize|swpNoZOrder2|swpNoActivate2|swpFrameChanged) compactSavedStyle = 0 } win.SetSize(width, height) win.SetMinSize(0, 0) }