github.com/cybriq/giocore@v0.0.7-0.20210703034601-cfb9cb5f3900/app/internal/windows/windows.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 // +build windows 4 5 package windows 6 7 import ( 8 "fmt" 9 "runtime" 10 "time" 11 "unsafe" 12 13 syscall "golang.org/x/sys/windows" 14 ) 15 16 type Rect struct { 17 Left, Top, Right, Bottom int32 18 } 19 20 type WndClassEx struct { 21 CbSize uint32 22 Style uint32 23 LpfnWndProc uintptr 24 CnClsExtra int32 25 CbWndExtra int32 26 HInstance syscall.Handle 27 HIcon syscall.Handle 28 HCursor syscall.Handle 29 HbrBackground syscall.Handle 30 LpszMenuName *uint16 31 LpszClassName *uint16 32 HIconSm syscall.Handle 33 } 34 35 type Msg struct { 36 Hwnd syscall.Handle 37 Message uint32 38 WParam uintptr 39 LParam uintptr 40 Time uint32 41 Pt Point 42 LPrivate uint32 43 } 44 45 type Point struct { 46 X, Y int32 47 } 48 49 type MinMaxInfo struct { 50 PtReserved Point 51 PtMaxSize Point 52 PtMaxPosition Point 53 PtMinTrackSize Point 54 PtMaxTrackSize Point 55 } 56 57 type WindowPlacement struct { 58 length uint32 59 flags uint32 60 showCmd uint32 61 ptMinPosition Point 62 ptMaxPosition Point 63 rcNormalPosition Rect 64 rcDevice Rect 65 } 66 67 type MonitorInfo struct { 68 cbSize uint32 69 Monitor Rect 70 WorkArea Rect 71 Flags uint32 72 } 73 74 const ( 75 TRUE = 1 76 77 CS_HREDRAW = 0x0002 78 CS_VREDRAW = 0x0001 79 CS_OWNDC = 0x0020 80 81 CW_USEDEFAULT = -2147483648 82 83 GWL_STYLE = ^(uint32(16) - 1) // -16 84 HWND_TOPMOST = ^(uint32(1) - 1) // -1 85 86 HTCLIENT = 1 87 88 IDC_ARROW = 32512 89 IDC_IBEAM = 32513 90 IDC_HAND = 32649 91 IDC_CROSS = 32515 92 IDC_SIZENS = 32645 93 IDC_SIZEWE = 32644 94 IDC_SIZEALL = 32646 95 96 INFINITE = 0xFFFFFFFF 97 98 LOGPIXELSX = 88 99 100 MDT_EFFECTIVE_DPI = 0 101 102 MONITOR_DEFAULTTOPRIMARY = 1 103 104 SIZE_MAXIMIZED = 2 105 SIZE_MINIMIZED = 1 106 SIZE_RESTORED = 0 107 108 SW_SHOWDEFAULT = 10 109 110 SWP_FRAMECHANGED = 0x0020 111 SWP_NOMOVE = 0x0002 112 SWP_NOOWNERZORDER = 0x0200 113 SWP_NOSIZE = 0x0001 114 SWP_NOZORDER = 0x0004 115 116 USER_TIMER_MINIMUM = 0x0000000A 117 118 VK_CONTROL = 0x11 119 VK_LWIN = 0x5B 120 VK_MENU = 0x12 121 VK_RWIN = 0x5C 122 VK_SHIFT = 0x10 123 124 VK_BACK = 0x08 125 VK_DELETE = 0x2e 126 VK_DOWN = 0x28 127 VK_END = 0x23 128 VK_ESCAPE = 0x1b 129 VK_HOME = 0x24 130 VK_LEFT = 0x25 131 VK_NEXT = 0x22 132 VK_PRIOR = 0x21 133 VK_RIGHT = 0x27 134 VK_RETURN = 0x0d 135 VK_SPACE = 0x20 136 VK_TAB = 0x09 137 VK_UP = 0x26 138 139 VK_F1 = 0x70 140 VK_F2 = 0x71 141 VK_F3 = 0x72 142 VK_F4 = 0x73 143 VK_F5 = 0x74 144 VK_F6 = 0x75 145 VK_F7 = 0x76 146 VK_F8 = 0x77 147 VK_F9 = 0x78 148 VK_F10 = 0x79 149 VK_F11 = 0x7A 150 VK_F12 = 0x7B 151 152 VK_OEM_1 = 0xba 153 VK_OEM_PLUS = 0xbb 154 VK_OEM_COMMA = 0xbc 155 VK_OEM_MINUS = 0xbd 156 VK_OEM_PERIOD = 0xbe 157 VK_OEM_2 = 0xbf 158 VK_OEM_3 = 0xc0 159 VK_OEM_4 = 0xdb 160 VK_OEM_5 = 0xdc 161 VK_OEM_6 = 0xdd 162 VK_OEM_7 = 0xde 163 VK_OEM_102 = 0xe2 164 165 UNICODE_NOCHAR = 65535 166 167 WM_CANCELMODE = 0x001F 168 WM_CHAR = 0x0102 169 WM_CREATE = 0x0001 170 WM_DPICHANGED = 0x02E0 171 WM_DESTROY = 0x0002 172 WM_ERASEBKGND = 0x0014 173 WM_KEYDOWN = 0x0100 174 WM_KEYUP = 0x0101 175 WM_LBUTTONDOWN = 0x0201 176 WM_LBUTTONUP = 0x0202 177 WM_MBUTTONDOWN = 0x0207 178 WM_MBUTTONUP = 0x0208 179 WM_MOUSEMOVE = 0x0200 180 WM_MOUSEWHEEL = 0x020A 181 WM_MOUSEHWHEEL = 0x020E 182 WM_PAINT = 0x000F 183 WM_CLOSE = 0x0010 184 WM_QUIT = 0x0012 185 WM_SETCURSOR = 0x0020 186 WM_SETFOCUS = 0x0007 187 WM_KILLFOCUS = 0x0008 188 WM_SHOWWINDOW = 0x0018 189 WM_SIZE = 0x0005 190 WM_SYSKEYDOWN = 0x0104 191 WM_SYSKEYUP = 0x0105 192 WM_RBUTTONDOWN = 0x0204 193 WM_RBUTTONUP = 0x0205 194 WM_TIMER = 0x0113 195 WM_UNICHAR = 0x0109 196 WM_USER = 0x0400 197 WM_GETMINMAXINFO = 0x0024 198 199 WS_CLIPCHILDREN = 0x00010000 200 WS_CLIPSIBLINGS = 0x04000000 201 WS_VISIBLE = 0x10000000 202 WS_OVERLAPPED = 0x00000000 203 WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | 204 WS_MINIMIZEBOX | WS_MAXIMIZEBOX 205 WS_CAPTION = 0x00C00000 206 WS_SYSMENU = 0x00080000 207 WS_THICKFRAME = 0x00040000 208 WS_MINIMIZEBOX = 0x00020000 209 WS_MAXIMIZEBOX = 0x00010000 210 211 WS_EX_APPWINDOW = 0x00040000 212 WS_EX_WINDOWEDGE = 0x00000100 213 214 QS_ALLINPUT = 0x04FF 215 216 MWMO_WAITALL = 0x0001 217 MWMO_INPUTAVAILABLE = 0x0004 218 219 WAIT_OBJECT_0 = 0 220 221 PM_REMOVE = 0x0001 222 PM_NOREMOVE = 0x0000 223 224 GHND = 0x0042 225 226 CF_UNICODETEXT = 13 227 IMAGE_BITMAP = 0 228 IMAGE_ICON = 1 229 IMAGE_CURSOR = 2 230 231 LR_CREATEDIBSECTION = 0x00002000 232 LR_DEFAULTCOLOR = 0x00000000 233 LR_DEFAULTSIZE = 0x00000040 234 LR_LOADFROMFILE = 0x00000010 235 LR_LOADMAP3DCOLORS = 0x00001000 236 LR_LOADTRANSPARENT = 0x00000020 237 LR_MONOCHROME = 0x00000001 238 LR_SHARED = 0x00008000 239 LR_VGACOLOR = 0x00000080 240 ) 241 242 var ( 243 kernel32 = syscall.NewLazySystemDLL("kernel32.dll") 244 _GetModuleHandleW = kernel32.NewProc("GetModuleHandleW") 245 _GlobalAlloc = kernel32.NewProc("GlobalAlloc") 246 _GlobalFree = kernel32.NewProc("GlobalFree") 247 _GlobalLock = kernel32.NewProc("GlobalLock") 248 _GlobalUnlock = kernel32.NewProc("GlobalUnlock") 249 250 user32 = syscall.NewLazySystemDLL("user32.dll") 251 _AdjustWindowRectEx = user32.NewProc("AdjustWindowRectEx") 252 _CallMsgFilter = user32.NewProc("CallMsgFilterW") 253 _CloseClipboard = user32.NewProc("CloseClipboard") 254 _CreateWindowEx = user32.NewProc("CreateWindowExW") 255 _DefWindowProc = user32.NewProc("DefWindowProcW") 256 _DestroyWindow = user32.NewProc("DestroyWindow") 257 _DispatchMessage = user32.NewProc("DispatchMessageW") 258 _EmptyClipboard = user32.NewProc("EmptyClipboard") 259 _GetClientRect = user32.NewProc("GetClientRect") 260 _GetClipboardData = user32.NewProc("GetClipboardData") 261 _GetDC = user32.NewProc("GetDC") 262 _GetDpiForWindow = user32.NewProc("GetDpiForWindow") 263 _GetKeyState = user32.NewProc("GetKeyState") 264 _GetMessage = user32.NewProc("GetMessageW") 265 _GetMessageTime = user32.NewProc("GetMessageTime") 266 _GetMonitorInfo = user32.NewProc("GetMonitorInfoW") 267 _GetWindowLong = user32.NewProc("GetWindowLongPtrW") 268 _GetWindowPlacement = user32.NewProc("GetWindowPlacement") 269 _KillTimer = user32.NewProc("KillTimer") 270 _LoadCursor = user32.NewProc("LoadCursorW") 271 _LoadImage = user32.NewProc("LoadImageW") 272 _MonitorFromPoint = user32.NewProc("MonitorFromPoint") 273 _MonitorFromWindow = user32.NewProc("MonitorFromWindow") 274 _MoveWindow = user32.NewProc("MoveWindow") 275 _MsgWaitForMultipleObjectsEx = user32.NewProc("MsgWaitForMultipleObjectsEx") 276 _OpenClipboard = user32.NewProc("OpenClipboard") 277 _PeekMessage = user32.NewProc("PeekMessageW") 278 _PostMessage = user32.NewProc("PostMessageW") 279 _PostQuitMessage = user32.NewProc("PostQuitMessage") 280 _ReleaseCapture = user32.NewProc("ReleaseCapture") 281 _RegisterClassExW = user32.NewProc("RegisterClassExW") 282 _ReleaseDC = user32.NewProc("ReleaseDC") 283 _ScreenToClient = user32.NewProc("ScreenToClient") 284 _ShowWindow = user32.NewProc("ShowWindow") 285 _SetCapture = user32.NewProc("SetCapture") 286 _SetCursor = user32.NewProc("SetCursor") 287 _SetClipboardData = user32.NewProc("SetClipboardData") 288 _SetForegroundWindow = user32.NewProc("SetForegroundWindow") 289 _SetFocus = user32.NewProc("SetFocus") 290 _SetProcessDPIAware = user32.NewProc("SetProcessDPIAware") 291 _SetTimer = user32.NewProc("SetTimer") 292 _SetWindowLong = user32.NewProc("SetWindowLongPtrW") 293 _SetWindowPlacement = user32.NewProc("SetWindowPlacement") 294 _SetWindowPos = user32.NewProc("SetWindowPos") 295 _SetWindowText = user32.NewProc("SetWindowTextW") 296 _TranslateMessage = user32.NewProc("TranslateMessage") 297 _UnregisterClass = user32.NewProc("UnregisterClassW") 298 _UpdateWindow = user32.NewProc("UpdateWindow") 299 300 shcore = syscall.NewLazySystemDLL("shcore") 301 _GetDpiForMonitor = shcore.NewProc("GetDpiForMonitor") 302 303 gdi32 = syscall.NewLazySystemDLL("gdi32") 304 _GetDeviceCaps = gdi32.NewProc("GetDeviceCaps") 305 ) 306 307 func AdjustWindowRectEx(r *Rect, dwStyle uint32, bMenu int, dwExStyle uint32) { 308 _AdjustWindowRectEx.Call(uintptr(unsafe.Pointer(r)), uintptr(dwStyle), uintptr(bMenu), uintptr(dwExStyle)) 309 issue34474KeepAlive(r) 310 } 311 312 func CallMsgFilter(m *Msg, nCode uintptr) bool { 313 r, _, _ := _CallMsgFilter.Call(uintptr(unsafe.Pointer(m)), nCode) 314 issue34474KeepAlive(m) 315 return r != 0 316 } 317 318 func CloseClipboard() error { 319 r, _, err := _CloseClipboard.Call() 320 if r == 0 { 321 return fmt.Errorf("CloseClipboard: %v", err) 322 } 323 return nil 324 } 325 326 func CreateWindowEx(dwExStyle uint32, lpClassName uint16, lpWindowName string, dwStyle uint32, x, y, w, h int32, hWndParent, hMenu, hInstance syscall.Handle, lpParam uintptr) (syscall.Handle, error) { 327 wname := syscall.StringToUTF16Ptr(lpWindowName) 328 hwnd, _, err := _CreateWindowEx.Call( 329 uintptr(dwExStyle), 330 uintptr(lpClassName), 331 uintptr(unsafe.Pointer(wname)), 332 uintptr(dwStyle), 333 uintptr(x), uintptr(y), 334 uintptr(w), uintptr(h), 335 uintptr(hWndParent), 336 uintptr(hMenu), 337 uintptr(hInstance), 338 uintptr(lpParam)) 339 issue34474KeepAlive(wname) 340 if hwnd == 0 { 341 return 0, fmt.Errorf("CreateWindowEx failed: %v", err) 342 } 343 return syscall.Handle(hwnd), nil 344 } 345 346 func DefWindowProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) uintptr { 347 r, _, _ := _DefWindowProc.Call(uintptr(hwnd), uintptr(msg), wparam, lparam) 348 return r 349 } 350 351 func DestroyWindow(hwnd syscall.Handle) { 352 _DestroyWindow.Call(uintptr(hwnd)) 353 } 354 355 func DispatchMessage(m *Msg) { 356 _DispatchMessage.Call(uintptr(unsafe.Pointer(m))) 357 issue34474KeepAlive(m) 358 } 359 360 func EmptyClipboard() error { 361 r, _, err := _EmptyClipboard.Call() 362 if r == 0 { 363 return fmt.Errorf("EmptyClipboard: %v", err) 364 } 365 return nil 366 } 367 368 func GetClientRect(hwnd syscall.Handle, r *Rect) { 369 _GetClientRect.Call(uintptr(hwnd), uintptr(unsafe.Pointer(r))) 370 issue34474KeepAlive(r) 371 } 372 373 func GetClipboardData(format uint32) (syscall.Handle, error) { 374 r, _, err := _GetClipboardData.Call(uintptr(format)) 375 if r == 0 { 376 return 0, fmt.Errorf("GetClipboardData: %v", err) 377 } 378 return syscall.Handle(r), nil 379 } 380 381 func GetDC(hwnd syscall.Handle) (syscall.Handle, error) { 382 hdc, _, err := _GetDC.Call(uintptr(hwnd)) 383 if hdc == 0 { 384 return 0, fmt.Errorf("GetDC failed: %v", err) 385 } 386 return syscall.Handle(hdc), nil 387 } 388 389 func GetModuleHandle() (syscall.Handle, error) { 390 h, _, err := _GetModuleHandleW.Call(uintptr(0)) 391 if h == 0 { 392 return 0, fmt.Errorf("GetModuleHandleW failed: %v", err) 393 } 394 return syscall.Handle(h), nil 395 } 396 397 func getDeviceCaps(hdc syscall.Handle, index int32) int { 398 c, _, _ := _GetDeviceCaps.Call(uintptr(hdc), uintptr(index)) 399 return int(c) 400 } 401 402 func getDpiForMonitor(hmonitor syscall.Handle, dpiType uint32) int { 403 var dpiX, dpiY uintptr 404 _GetDpiForMonitor.Call(uintptr(hmonitor), uintptr(dpiType), uintptr(unsafe.Pointer(&dpiX)), uintptr(unsafe.Pointer(&dpiY))) 405 return int(dpiX) 406 } 407 408 // GetSystemDPI returns the effective DPI of the system. 409 func GetSystemDPI() int { 410 // Check for GetDpiForMonitor, introduced in Windows 8.1. 411 if _GetDpiForMonitor.Find() == nil { 412 hmon := monitorFromPoint(Point{}, MONITOR_DEFAULTTOPRIMARY) 413 return getDpiForMonitor(hmon, MDT_EFFECTIVE_DPI) 414 } else { 415 // Fall back to the physical device DPI. 416 screenDC, err := GetDC(0) 417 if err != nil { 418 return 96 419 } 420 defer ReleaseDC(screenDC) 421 return getDeviceCaps(screenDC, LOGPIXELSX) 422 } 423 } 424 425 func GetKeyState(nVirtKey int32) int16 { 426 c, _, _ := _GetKeyState.Call(uintptr(nVirtKey)) 427 return int16(c) 428 } 429 430 func GetMessage(m *Msg, hwnd syscall.Handle, wMsgFilterMin, wMsgFilterMax uint32) int32 { 431 r, _, _ := _GetMessage.Call(uintptr(unsafe.Pointer(m)), 432 uintptr(hwnd), 433 uintptr(wMsgFilterMin), 434 uintptr(wMsgFilterMax)) 435 issue34474KeepAlive(m) 436 return int32(r) 437 } 438 439 func GetMessageTime() time.Duration { 440 r, _, _ := _GetMessageTime.Call() 441 return time.Duration(r) * time.Millisecond 442 } 443 444 // GetWindowDPI returns the effective DPI of the window. 445 func GetWindowDPI(hwnd syscall.Handle) int { 446 // Check for GetDpiForWindow, introduced in Windows 10. 447 if _GetDpiForWindow.Find() == nil { 448 dpi, _, _ := _GetDpiForWindow.Call(uintptr(hwnd)) 449 return int(dpi) 450 } else { 451 return GetSystemDPI() 452 } 453 } 454 455 func GetWindowPlacement(hwnd syscall.Handle) *WindowPlacement { 456 var wp WindowPlacement 457 wp.length = uint32(unsafe.Sizeof(wp)) 458 _GetWindowPlacement.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&wp))) 459 return &wp 460 } 461 462 func GetMonitorInfo(hwnd syscall.Handle) MonitorInfo { 463 var mi MonitorInfo 464 mi.cbSize = uint32(unsafe.Sizeof(mi)) 465 v, _, _ := _MonitorFromWindow.Call(uintptr(hwnd), MONITOR_DEFAULTTOPRIMARY) 466 _GetMonitorInfo.Call(v, uintptr(unsafe.Pointer(&mi))) 467 return mi 468 } 469 470 func GetWindowLong(hwnd syscall.Handle) (style uintptr) { 471 style, _, _ = _GetWindowLong.Call(uintptr(hwnd), uintptr(GWL_STYLE)) 472 return 473 } 474 475 func SetWindowLong(hwnd syscall.Handle, idx uint32, style uintptr) { 476 _SetWindowLong.Call(uintptr(hwnd), uintptr(idx), style) 477 } 478 479 func SetWindowPlacement(hwnd syscall.Handle, wp *WindowPlacement) { 480 _SetWindowPlacement.Call(uintptr(hwnd), uintptr(unsafe.Pointer(wp))) 481 } 482 483 func SetWindowPos(hwnd syscall.Handle, hwndInsertAfter uint32, x, y, dx, dy int32, style uintptr) { 484 _SetWindowPos.Call(uintptr(hwnd), uintptr(hwndInsertAfter), 485 uintptr(x), uintptr(y), 486 uintptr(dx), uintptr(dy), 487 style, 488 ) 489 } 490 491 func SetWindowText(hwnd syscall.Handle, title string) { 492 wname := syscall.StringToUTF16Ptr(title) 493 _SetWindowText.Call(uintptr(hwnd), uintptr(unsafe.Pointer(wname))) 494 } 495 496 func GlobalAlloc(size int) (syscall.Handle, error) { 497 r, _, err := _GlobalAlloc.Call(GHND, uintptr(size)) 498 if r == 0 { 499 return 0, fmt.Errorf("GlobalAlloc: %v", err) 500 } 501 return syscall.Handle(r), nil 502 } 503 504 func GlobalFree(h syscall.Handle) { 505 _GlobalFree.Call(uintptr(h)) 506 } 507 508 func GlobalLock(h syscall.Handle) (uintptr, error) { 509 r, _, err := _GlobalLock.Call(uintptr(h)) 510 if r == 0 { 511 return 0, fmt.Errorf("GlobalLock: %v", err) 512 } 513 return r, nil 514 } 515 516 func GlobalUnlock(h syscall.Handle) { 517 _GlobalUnlock.Call(uintptr(h)) 518 } 519 520 func KillTimer(hwnd syscall.Handle, nIDEvent uintptr) error { 521 r, _, err := _SetTimer.Call(uintptr(hwnd), uintptr(nIDEvent), 0, 0) 522 if r == 0 { 523 return fmt.Errorf("KillTimer failed: %v", err) 524 } 525 return nil 526 } 527 528 func LoadCursor(curID uint16) (syscall.Handle, error) { 529 h, _, err := _LoadCursor.Call(0, uintptr(curID)) 530 if h == 0 { 531 return 0, fmt.Errorf("LoadCursorW failed: %v", err) 532 } 533 return syscall.Handle(h), nil 534 } 535 536 func LoadImage(hInst syscall.Handle, res uint32, typ uint32, cx, cy int, fuload uint32) (syscall.Handle, error) { 537 h, _, err := _LoadImage.Call(uintptr(hInst), uintptr(res), uintptr(typ), uintptr(cx), uintptr(cy), uintptr(fuload)) 538 if h == 0 { 539 return 0, fmt.Errorf("LoadImageW failed: %v", err) 540 } 541 return syscall.Handle(h), nil 542 } 543 544 func MoveWindow(hwnd syscall.Handle, x, y, width, height int32, repaint bool) { 545 var paint uintptr 546 if repaint { 547 paint = TRUE 548 } 549 _MoveWindow.Call(uintptr(hwnd), uintptr(x), uintptr(y), uintptr(width), uintptr(height), paint) 550 } 551 552 func monitorFromPoint(pt Point, flags uint32) syscall.Handle { 553 r, _, _ := _MonitorFromPoint.Call(uintptr(pt.X), uintptr(pt.Y), uintptr(flags)) 554 return syscall.Handle(r) 555 } 556 557 func MsgWaitForMultipleObjectsEx(nCount uint32, pHandles uintptr, millis, mask, flags uint32) (uint32, error) { 558 r, _, err := _MsgWaitForMultipleObjectsEx.Call(uintptr(nCount), pHandles, uintptr(millis), uintptr(mask), uintptr(flags)) 559 res := uint32(r) 560 if res == 0xFFFFFFFF { 561 return 0, fmt.Errorf("MsgWaitForMultipleObjectsEx failed: %v", err) 562 } 563 return res, nil 564 } 565 566 func OpenClipboard(hwnd syscall.Handle) error { 567 r, _, err := _OpenClipboard.Call(uintptr(hwnd)) 568 if r == 0 { 569 return fmt.Errorf("OpenClipboard: %v", err) 570 } 571 return nil 572 } 573 574 func PeekMessage(m *Msg, hwnd syscall.Handle, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool { 575 r, _, _ := _PeekMessage.Call(uintptr(unsafe.Pointer(m)), uintptr(hwnd), uintptr(wMsgFilterMin), uintptr(wMsgFilterMax), uintptr(wRemoveMsg)) 576 issue34474KeepAlive(m) 577 return r != 0 578 } 579 580 func PostQuitMessage(exitCode uintptr) { 581 _PostQuitMessage.Call(exitCode) 582 } 583 584 func PostMessage(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) error { 585 r, _, err := _PostMessage.Call(uintptr(hwnd), uintptr(msg), wParam, lParam) 586 if r == 0 { 587 return fmt.Errorf("PostMessage failed: %v", err) 588 } 589 return nil 590 } 591 592 func ReleaseCapture() bool { 593 r, _, _ := _ReleaseCapture.Call() 594 return r != 0 595 } 596 597 func RegisterClassEx(cls *WndClassEx) (uint16, error) { 598 a, _, err := _RegisterClassExW.Call(uintptr(unsafe.Pointer(cls))) 599 issue34474KeepAlive(cls) 600 if a == 0 { 601 return 0, fmt.Errorf("RegisterClassExW failed: %v", err) 602 } 603 return uint16(a), nil 604 } 605 606 func ReleaseDC(hdc syscall.Handle) { 607 _ReleaseDC.Call(uintptr(hdc)) 608 } 609 610 func SetForegroundWindow(hwnd syscall.Handle) { 611 _SetForegroundWindow.Call(uintptr(hwnd)) 612 } 613 614 func SetFocus(hwnd syscall.Handle) { 615 _SetFocus.Call(uintptr(hwnd)) 616 } 617 618 func SetProcessDPIAware() { 619 _SetProcessDPIAware.Call() 620 } 621 622 func SetCapture(hwnd syscall.Handle) syscall.Handle { 623 r, _, _ := _SetCapture.Call(uintptr(hwnd)) 624 return syscall.Handle(r) 625 } 626 627 func SetClipboardData(format uint32, mem syscall.Handle) error { 628 r, _, err := _SetClipboardData.Call(uintptr(format), uintptr(mem)) 629 if r == 0 { 630 return fmt.Errorf("SetClipboardData: %v", err) 631 } 632 return nil 633 } 634 635 func SetCursor(h syscall.Handle) { 636 _SetCursor.Call(uintptr(h)) 637 } 638 639 func SetTimer(hwnd syscall.Handle, nIDEvent uintptr, uElapse uint32, timerProc uintptr) error { 640 r, _, err := _SetTimer.Call(uintptr(hwnd), uintptr(nIDEvent), uintptr(uElapse), timerProc) 641 if r == 0 { 642 return fmt.Errorf("SetTimer failed: %v", err) 643 } 644 return nil 645 } 646 647 func ScreenToClient(hwnd syscall.Handle, p *Point) { 648 _ScreenToClient.Call(uintptr(hwnd), uintptr(unsafe.Pointer(p))) 649 issue34474KeepAlive(p) 650 } 651 652 func ShowWindow(hwnd syscall.Handle, nCmdShow int32) { 653 _ShowWindow.Call(uintptr(hwnd), uintptr(nCmdShow)) 654 } 655 656 func TranslateMessage(m *Msg) { 657 _TranslateMessage.Call(uintptr(unsafe.Pointer(m))) 658 issue34474KeepAlive(m) 659 } 660 661 func UnregisterClass(cls uint16, hInst syscall.Handle) { 662 _UnregisterClass.Call(uintptr(cls), uintptr(hInst)) 663 } 664 665 func UpdateWindow(hwnd syscall.Handle) { 666 _UpdateWindow.Call(uintptr(hwnd)) 667 } 668 669 // issue34474KeepAlive calls runtime.KeepAlive as a 670 // workaround for golang.org/issue/34474. 671 func issue34474KeepAlive(v interface{}) { 672 runtime.KeepAlive(v) 673 }