| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- //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)
- }
|