//go:build windows package platform import ( "os" "syscall" "unsafe" ) var ( user32 = syscall.NewLazyDLL("user32.dll") kernel32 = syscall.NewLazyDLL("kernel32.dll") setWindowLong = user32.NewProc("SetWindowLongW") getWindowLong = user32.NewProc("GetWindowLongW") setWindowPos = user32.NewProc("SetWindowPos") enumWindows = user32.NewProc("EnumWindows") getWindowThreadProcessId = user32.NewProc("GetWindowThreadProcessId") getCurrentProcessId = kernel32.NewProc("GetCurrentProcessId") ) const ( GWL_STYLE = ^uintptr(15) // -16 WS_THICKFRAME = 0x00040000 WS_MAXIMIZEBOX = 0x00010000 WS_MINIMIZEBOX = 0x00020000 SWP_FRAMECHANGED = 0x0020 SWP_NOMOVE = 0x0002 SWP_NOSIZE = 0x0001 SWP_NOZORDER = 0x0004 SWP_NOACTIVATE = 0x0010 ) var mainHwnd uintptr // EnableResizeBorder re-adds the WS_THICKFRAME style to // the frameless Wails window so it can be resized from edges. func EnableResizeBorder() { pid, _, _ := getCurrentProcessId.Call() // Find our main window by enumerating top-level windows cb := syscall.NewCallback(func(hwnd uintptr, lparam uintptr) uintptr { var wpid uintptr getWindowThreadProcessId.Call(hwnd, uintptr(unsafe.Pointer(&wpid))) if wpid == pid { // Check if it's a visible owned window (not a child/message-only) style, _, _ := getWindowLong.Call(hwnd, GWL_STYLE) if style&0x10000000 != 0 && style&0x40000000 == 0 { // WS_VISIBLE && !WS_CHILD mainHwnd = hwnd return 0 // stop enumeration } } return 1 // continue }) enumWindows.Call(cb, 0) if mainHwnd == 0 { return } style, _, _ := getWindowLong.Call(mainHwnd, GWL_STYLE) newStyle := style | WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX setWindowLong.Call(mainHwnd, GWL_STYLE, newStyle) setWindowPos.Call(mainHwnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE) // Log for debugging os.Stdout.WriteString("[platform] WS_THICKFRAME enabled on frameless window\n") }