github.com/Seikaijyu/gio@v0.0.1/app/internal/windows/windows.go (about) 1 // SPDX-License-Identifier: Unlicense OR MIT 2 3 //go:build windows 4 // +build windows 5 6 package windows 7 8 import ( 9 "fmt" 10 "runtime" 11 "time" 12 "unicode/utf16" 13 "unsafe" 14 15 syscall "golang.org/x/sys/windows" 16 ) 17 18 type CompositionForm struct { 19 dwStyle uint32 20 ptCurrentPos Point 21 rcArea Rect 22 } 23 24 type CandidateForm struct { 25 dwIndex uint32 26 dwStyle uint32 27 ptCurrentPos Point 28 rcArea Rect 29 } 30 31 type Rect struct { 32 Left, Top, Right, Bottom int32 33 } 34 35 type WndClassEx struct { 36 CbSize uint32 37 Style uint32 38 LpfnWndProc uintptr 39 CnClsExtra int32 40 CbWndExtra int32 41 HInstance syscall.Handle 42 HIcon syscall.Handle 43 HCursor syscall.Handle 44 HbrBackground syscall.Handle 45 LpszMenuName *uint16 46 LpszClassName *uint16 47 HIconSm syscall.Handle 48 } 49 50 type Margins struct { 51 CxLeftWidth int32 52 CxRightWidth int32 53 CyTopHeight int32 54 CyBottomHeight int32 55 } 56 57 type Msg struct { 58 Hwnd syscall.Handle 59 Message uint32 60 WParam uintptr 61 LParam uintptr 62 Time uint32 63 Pt Point 64 LPrivate uint32 65 } 66 67 type Point struct { 68 X, Y int32 69 } 70 71 type MinMaxInfo struct { 72 PtReserved Point 73 PtMaxSize Point 74 PtMaxPosition Point 75 PtMinTrackSize Point 76 PtMaxTrackSize Point 77 } 78 79 type NCCalcSizeParams struct { 80 Rgrc [3]Rect 81 LpPos *WindowPos 82 } 83 84 type WindowPos struct { 85 HWND syscall.Handle 86 HWNDInsertAfter syscall.Handle 87 x int32 88 y int32 89 cx int32 90 cy int32 91 flags uint32 92 } 93 94 type WindowPlacement struct { 95 length uint32 96 flags uint32 97 showCmd uint32 98 ptMinPosition Point 99 ptMaxPosition Point 100 rcNormalPosition Rect 101 rcDevice Rect 102 } 103 104 type MonitorInfo struct { 105 cbSize uint32 106 Monitor Rect 107 WorkArea Rect 108 Flags uint32 109 } 110 111 const ( 112 TRUE = 1 113 114 CPS_CANCEL = 0x0004 115 116 CS_HREDRAW = 0x0002 117 CS_INSERTCHAR = 0x2000 118 CS_NOMOVECARET = 0x4000 119 CS_VREDRAW = 0x0001 120 CS_OWNDC = 0x0020 121 122 CW_USEDEFAULT = -2147483648 123 124 GWL_STYLE = ^(uintptr(16) - 1) // -16 125 126 GCS_COMPSTR = 0x0008 127 GCS_COMPREADSTR = 0x0001 128 GCS_CURSORPOS = 0x0080 129 GCS_DELTASTART = 0x0100 130 GCS_RESULTREADSTR = 0x0200 131 GCS_RESULTSTR = 0x0800 132 133 CFS_POINT = 0x0002 134 CFS_CANDIDATEPOS = 0x0040 135 136 HWND_TOPMOST = ^(uint32(1) - 1) // -1 137 138 HTCAPTION = 2 139 HTCLIENT = 1 140 HTLEFT = 10 141 HTRIGHT = 11 142 HTTOP = 12 143 HTTOPLEFT = 13 144 HTTOPRIGHT = 14 145 HTBOTTOM = 15 146 HTBOTTOMLEFT = 16 147 HTBOTTOMRIGHT = 17 148 149 IDC_APPSTARTING = 32650 // Standard arrow and small hourglass 150 IDC_ARROW = 32512 // Standard arrow 151 IDC_CROSS = 32515 // Crosshair 152 IDC_HAND = 32649 // Hand 153 IDC_HELP = 32651 // Arrow and question mark 154 IDC_IBEAM = 32513 // I-beam 155 IDC_NO = 32648 // Slashed circle 156 IDC_SIZEALL = 32646 // Four-pointed arrow pointing north, south, east, and west 157 IDC_SIZENESW = 32643 // Double-pointed arrow pointing northeast and southwest 158 IDC_SIZENS = 32645 // Double-pointed arrow pointing north and south 159 IDC_SIZENWSE = 32642 // Double-pointed arrow pointing northwest and southeast 160 IDC_SIZEWE = 32644 // Double-pointed arrow pointing west and east 161 IDC_UPARROW = 32516 // Vertical arrow 162 IDC_WAIT = 32514 // Hour 163 164 INFINITE = 0xFFFFFFFF 165 166 LOGPIXELSX = 88 167 168 MDT_EFFECTIVE_DPI = 0 169 170 MONITOR_DEFAULTTOPRIMARY = 1 171 172 NI_COMPOSITIONSTR = 0x0015 173 174 SIZE_MAXIMIZED = 2 175 SIZE_MINIMIZED = 1 176 SIZE_RESTORED = 0 177 178 SCS_SETSTR = GCS_COMPREADSTR | GCS_COMPSTR 179 180 SM_CXSIZEFRAME = 32 181 SM_CYSIZEFRAME = 33 182 183 SW_SHOWDEFAULT = 10 184 SW_SHOWMINIMIZED = 2 185 SW_SHOWMAXIMIZED = 3 186 SW_SHOWNORMAL = 1 187 SW_SHOW = 5 188 189 SWP_FRAMECHANGED = 0x0020 190 SWP_NOMOVE = 0x0002 191 SWP_NOOWNERZORDER = 0x0200 192 SWP_NOSIZE = 0x0001 193 SWP_NOZORDER = 0x0004 194 SWP_SHOWWINDOW = 0x0040 195 196 USER_TIMER_MINIMUM = 0x0000000A 197 198 VK_CONTROL = 0x11 199 VK_LWIN = 0x5B 200 VK_MENU = 0x12 201 VK_RWIN = 0x5C 202 VK_SHIFT = 0x10 203 204 VK_BACK = 0x08 205 VK_DELETE = 0x2e 206 VK_DOWN = 0x28 207 VK_END = 0x23 208 VK_ESCAPE = 0x1b 209 VK_HOME = 0x24 210 VK_LEFT = 0x25 211 VK_NEXT = 0x22 212 VK_PRIOR = 0x21 213 VK_RIGHT = 0x27 214 VK_RETURN = 0x0d 215 VK_SPACE = 0x20 216 VK_TAB = 0x09 217 VK_UP = 0x26 218 219 VK_F1 = 0x70 220 VK_F2 = 0x71 221 VK_F3 = 0x72 222 VK_F4 = 0x73 223 VK_F5 = 0x74 224 VK_F6 = 0x75 225 VK_F7 = 0x76 226 VK_F8 = 0x77 227 VK_F9 = 0x78 228 VK_F10 = 0x79 229 VK_F11 = 0x7A 230 VK_F12 = 0x7B 231 232 VK_OEM_1 = 0xba 233 VK_OEM_PLUS = 0xbb 234 VK_OEM_COMMA = 0xbc 235 VK_OEM_MINUS = 0xbd 236 VK_OEM_PERIOD = 0xbe 237 VK_OEM_2 = 0xbf 238 VK_OEM_3 = 0xc0 239 VK_OEM_4 = 0xdb 240 VK_OEM_5 = 0xdc 241 VK_OEM_6 = 0xdd 242 VK_OEM_7 = 0xde 243 VK_OEM_102 = 0xe2 244 245 UNICODE_NOCHAR = 65535 246 247 WM_CANCELMODE = 0x001F 248 WM_CHAR = 0x0102 249 WM_CLOSE = 0x0010 250 WM_CREATE = 0x0001 251 WM_DPICHANGED = 0x02E0 252 WM_DESTROY = 0x0002 253 WM_ERASEBKGND = 0x0014 254 WM_GETMINMAXINFO = 0x0024 255 WM_IME_COMPOSITION = 0x010F 256 WM_IME_ENDCOMPOSITION = 0x010E 257 WM_IME_STARTCOMPOSITION = 0x010D 258 WM_KEYDOWN = 0x0100 259 WM_KEYUP = 0x0101 260 WM_KILLFOCUS = 0x0008 261 WM_LBUTTONDOWN = 0x0201 262 WM_LBUTTONUP = 0x0202 263 WM_MBUTTONDOWN = 0x0207 264 WM_MBUTTONUP = 0x0208 265 WM_MOUSEMOVE = 0x0200 266 WM_MOUSEWHEEL = 0x020A 267 WM_MOUSEHWHEEL = 0x020E 268 WM_NCACTIVATE = 0x0086 269 WM_NCHITTEST = 0x0084 270 WM_NCCALCSIZE = 0x0083 271 WM_PAINT = 0x000F 272 WM_QUIT = 0x0012 273 WM_SETCURSOR = 0x0020 274 WM_SETFOCUS = 0x0007 275 WM_SHOWWINDOW = 0x0018 276 WM_SIZE = 0x0005 277 WM_SYSKEYDOWN = 0x0104 278 WM_SYSKEYUP = 0x0105 279 WM_RBUTTONDOWN = 0x0204 280 WM_RBUTTONUP = 0x0205 281 WM_TIMER = 0x0113 282 WM_UNICHAR = 0x0109 283 WM_DROPFILES = 0x0233 284 WM_USER = 0x0400 285 WM_WINDOWPOSCHANGED = 0x0047 286 287 WS_CLIPCHILDREN = 0x02000000 288 WS_CLIPSIBLINGS = 0x04000000 289 WS_MAXIMIZE = 0x01000000 290 WS_ICONIC = 0x20000000 291 WS_VISIBLE = 0x10000000 292 WS_OVERLAPPED = 0x00000000 293 WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | 294 WS_MINIMIZEBOX | WS_MAXIMIZEBOX 295 WS_CAPTION = 0x00C00000 296 WS_SYSMENU = 0x00080000 297 WS_THICKFRAME = 0x00040000 298 WS_MINIMIZEBOX = 0x00020000 299 WS_MAXIMIZEBOX = 0x00010000 300 301 WS_EX_APPWINDOW = 0x00040000 302 WS_EX_WINDOWEDGE = 0x00000100 303 304 QS_ALLINPUT = 0x04FF 305 306 MWMO_WAITALL = 0x0001 307 MWMO_INPUTAVAILABLE = 0x0004 308 309 WAIT_OBJECT_0 = 0 310 311 PM_REMOVE = 0x0001 312 PM_NOREMOVE = 0x0000 313 314 GHND = 0x0042 315 316 CF_UNICODETEXT = 13 317 IMAGE_BITMAP = 0 318 IMAGE_ICON = 1 319 IMAGE_CURSOR = 2 320 321 LR_CREATEDIBSECTION = 0x00002000 322 LR_DEFAULTCOLOR = 0x00000000 323 LR_DEFAULTSIZE = 0x00000040 324 LR_LOADFROMFILE = 0x00000010 325 LR_LOADMAP3DCOLORS = 0x00001000 326 LR_LOADTRANSPARENT = 0x00000020 327 LR_MONOCHROME = 0x00000001 328 LR_SHARED = 0x00008000 329 LR_VGACOLOR = 0x00000080 330 ) 331 332 var ( 333 // kernel32.dll是Windows操作系统的核心库,包含了许多底层的系统函数 334 kernel32 = syscall.NewLazySystemDLL("kernel32.dll") 335 336 // GetModuleHandleW函数用于获取一个模块的句柄,这个模块必须已经被加载到调用线程的进程中 337 _GetModuleHandleW = kernel32.NewProc("GetModuleHandleW") 338 339 // GlobalAlloc函数用于在全局内存中分配指定大小的内存块 340 _GlobalAlloc = kernel32.NewProc("GlobalAlloc") 341 342 // GlobalFree函数用于释放之前由GlobalAlloc函数分配的内存块 343 _GlobalFree = kernel32.NewProc("GlobalFree") 344 345 // GlobalLock函数用于锁定之前由GlobalAlloc函数分配的内存块,防止系统移动这个内存块 346 _GlobalLock = kernel32.NewProc("GlobalLock") 347 348 // GlobalUnlock函数用于解锁之前由GlobalLock函数锁定的内存块 349 _GlobalUnlock = kernel32.NewProc("GlobalUnlock") 350 351 // user32.dll是Windows操作系统的用户界面库,包含了许多用于创建和管理窗口的函数 352 user32 = syscall.NewLazySystemDLL("user32.dll") 353 354 _GetForegroundWindow = user32.NewProc("GetForegroundWindow") 355 // AdjustWindowRectEx函数用于计算需要的窗口大小,以便在窗口周围留出足够的空间放置指定的窗口装饰 356 _AdjustWindowRectEx = user32.NewProc("AdjustWindowRectEx") 357 358 // CallMsgFilterW函数用于将一个消息传递给当前线程的消息过滤函数 359 _CallMsgFilter = user32.NewProc("CallMsgFilterW") 360 361 // CloseClipboard函数用于关闭剪贴板,结束剪贴板的更新 362 _CloseClipboard = user32.NewProc("CloseClipboard") 363 364 // CreateWindowExW函数用于创建一个新的窗口 365 _CreateWindowEx = user32.NewProc("CreateWindowExW") 366 367 // DefWindowProcW函数是默认的窗口过程函数,用于处理窗口接收到的消息 368 _DefWindowProc = user32.NewProc("DefWindowProcW") 369 370 // DestroyWindow函数用于销毁一个窗口 371 _DestroyWindow = user32.NewProc("DestroyWindow") 372 373 // DispatchMessageW函数用于将一个消息发送给指定的窗口过程 374 _DispatchMessage = user32.NewProc("DispatchMessageW") 375 376 // EmptyClipboard函数用于清空剪贴板的内容 377 _EmptyClipboard = user32.NewProc("EmptyClipboard") 378 379 // GetWindowRect函数用于获取一个窗口的尺寸和位置 380 _GetWindowRect = user32.NewProc("GetWindowRect") 381 382 // GetClientRect函数用于获取一个窗口的客户区的尺寸和位置 383 _GetClientRect = user32.NewProc("GetClientRect") 384 385 // GetClipboardData函数用于获取剪贴板上的数据 386 _GetClipboardData = user32.NewProc("GetClipboardData") 387 388 // GetDC函数用于获取一个窗口的设备上下文,用于在窗口上绘图 389 _GetDC = user32.NewProc("GetDC") 390 391 // GetDpiForWindow函数用于获取一个窗口的DPI设置 392 _GetDpiForWindow = user32.NewProc("GetDpiForWindow") 393 394 // GetKeyState函数用于获取一个虚拟键的状态 395 _GetKeyState = user32.NewProc("GetKeyState") 396 397 // GetMessageW函数用于从当前线程的消息队列中获取一个消息 398 _GetMessage = user32.NewProc("GetMessageW") 399 400 // GetMessageTime函数用于获取最后一个消息的时间 401 _GetMessageTime = user32.NewProc("GetMessageTime") 402 403 // GetMonitorInfoW函数用于获取一个显示器的信息 404 _GetMonitorInfo = user32.NewProc("GetMonitorInfoW") 405 406 // GetSystemMetrics函数用于获取系统的一些参数,如屏幕尺寸、颜色深度等 407 _GetSystemMetrics = user32.NewProc("GetSystemMetrics") 408 409 // GetWindowLongPtrW函数用于获取窗口的一些属性,如窗口过程、窗口样式等 410 _GetWindowLong = user32.NewProc("GetWindowLongPtrW") 411 412 // GetWindowLongW函数用于获取窗口的一些属性,如窗口过程、窗口样式等,这是一个32位版本的函数 413 _GetWindowLong32 = user32.NewProc("GetWindowLongW") 414 415 // GetWindowPlacement函数用于获取窗口的放置信息,如窗口的位置、大小、显示状态等 416 _GetWindowPlacement = user32.NewProc("GetWindowPlacement") 417 418 // KillTimer函数用于销毁一个定时器 419 _KillTimer = user32.NewProc("KillTimer") 420 421 // LoadCursorW函数用于加载一个光标 422 _LoadCursor = user32.NewProc("LoadCursorW") 423 424 // LoadImageW函数用于加载一个图像,如位图、图标、光标等 425 _LoadImage = user32.NewProc("LoadImageW") 426 427 // MonitorFromPoint函数用于获取包含指定点的显示器的句柄 428 _MonitorFromPoint = user32.NewProc("MonitorFromPoint") 429 430 // MonitorFromWindow函数用于获取包含指定窗口的显示器的句柄 431 _MonitorFromWindow = user32.NewProc("MonitorFromWindow") 432 433 // MoveWindow函数用于移动一个窗口 434 _MoveWindow = user32.NewProc("MoveWindow") 435 436 // MsgWaitForMultipleObjectsEx函数用于等待多个对象变为可信号状态 437 _MsgWaitForMultipleObjectsEx = user32.NewProc("MsgWaitForMultipleObjectsEx") 438 439 // OpenClipboard函数用于打开剪贴板,开始对剪贴板的更新 440 _OpenClipboard = user32.NewProc("OpenClipboard") 441 442 // PeekMessageW函数用于检查当前线程的消息队列,看是否有消息 443 _PeekMessage = user32.NewProc("PeekMessageW") 444 445 // PostMessageW函数用于向指定的窗口发送一个消息 446 _PostMessage = user32.NewProc("PostMessageW") 447 448 // PostQuitMessage函数用于向当前线程的消息队列发送一个退出消息 449 _PostQuitMessage = user32.NewProc("PostQuitMessage") 450 451 // ReleaseCapture函数用于释放鼠标捕获 452 _ReleaseCapture = user32.NewProc("ReleaseCapture") 453 454 // RegisterClassExW函数用于注册一个窗口类,这个窗口类可以用于创建窗口 455 _RegisterClassExW = user32.NewProc("RegisterClassExW") 456 457 // ReleaseDC函数用于释放之前由GetDC函数获取的设备上下文 458 _ReleaseDC = user32.NewProc("ReleaseDC") 459 460 // ScreenToClient函数用于将屏幕坐标转换为客户区坐标 461 _ScreenToClient = user32.NewProc("ScreenToClient") 462 463 // ShowWindow函数用于显示或隐藏一个窗口 464 _ShowWindow = user32.NewProc("ShowWindow") 465 466 // SetCapture函数用于设置鼠标捕获,使一个窗口接收所有的鼠标输入 467 _SetCapture = user32.NewProc("SetCapture") 468 469 // SetCursor函数用于设置光标 470 _SetCursor = user32.NewProc("SetCursor") 471 472 // SetClipboardData函数用于设置剪贴板的数据 473 _SetClipboardData = user32.NewProc("SetClipboardData") 474 // Windows User32 API 函数 475 _SetForegroundWindow = user32.NewProc("SetForegroundWindow") // 将键盘焦点设置到指定的窗口 476 _SetFocus = user32.NewProc("SetFocus") // 设置键盘焦点到指定的窗口 477 _SetProcessDPIAware = user32.NewProc("SetProcessDPIAware") // 设置当前进程为DPI感知,使得窗口在高DPI设置下正确显示 478 _SetTimer = user32.NewProc("SetTimer") // 设置一个定时器,当定时器到达设定时间时,系统会发送一个WM_TIMER消息 479 _SetWindowLong = user32.NewProc("SetWindowLongPtrW") // 改变一个窗口的属性 480 _SetWindowLong32 = user32.NewProc("SetWindowLongW") // 改变一个窗口的属性(32位版本) 481 _SetWindowPlacement = user32.NewProc("SetWindowPlacement") // 设置窗口的显示状态和位置 482 _SetWindowPos = user32.NewProc("SetWindowPos") // 改变窗口的大小和位置 483 _SetWindowText = user32.NewProc("SetWindowTextW") // 设置窗口的标题 484 _TranslateMessage = user32.NewProc("TranslateMessage") // 将虚拟键消息转换为字符消息 485 _UnregisterClass = user32.NewProc("UnregisterClassW") // 注销窗口类 486 _UpdateWindow = user32.NewProc("UpdateWindow") // 更新窗口的客户区 487 488 // Windows Shcore API 函数 489 shcore = syscall.NewLazySystemDLL("shcore") 490 _GetDpiForMonitor = shcore.NewProc("GetDpiForMonitor") // 获取指定监视器的DPI设置 491 492 // Windows Gdi32 API 函数 493 gdi32 = syscall.NewLazySystemDLL("gdi32") 494 _GetDeviceCaps = gdi32.NewProc("GetDeviceCaps") // 获取设备的能力 495 496 // Windows Imm32 API 函数 497 imm32 = syscall.NewLazySystemDLL("imm32") 498 _ImmGetContext = imm32.NewProc("ImmGetContext") // 获取输入上下文 499 _ImmGetCompositionString = imm32.NewProc("ImmGetCompositionStringW") // 获取组合字符串 500 _ImmNotifyIME = imm32.NewProc("ImmNotifyIME") // 发送通知到输入法 501 _ImmReleaseContext = imm32.NewProc("ImmReleaseContext") // 释放输入上下文 502 _ImmSetCandidateWindow = imm32.NewProc("ImmSetCandidateWindow") // 设置候选窗口 503 _ImmSetCompositionWindow = imm32.NewProc("ImmSetCompositionWindow") // 设置组合窗口 504 505 // Windows Dwmapi API 函数 506 dwmapi = syscall.NewLazySystemDLL("dwmapi") 507 _DwmExtendFrameIntoClientArea = dwmapi.NewProc("DwmExtendFrameIntoClientArea") // 扩展窗口帧到客户区 508 509 // Windows Shell32 API 函数 510 shell32 = syscall.NewLazyDLL("shell32.dll") 511 _ProcDragAcceptFiles = shell32.NewProc("DragAcceptFiles") // 允许窗口接受拖放文件 512 _ProcDragQueryFile = shell32.NewProc("DragQueryFileW") // 获取拖放文件的信息,注意,只有DragQueryFileW才使用w_char*编码字符串,DragQueryFileA使用char*编码字符串 513 _ProcDragFinish = shell32.NewProc("DragFinish") // 释放拖放文件的资源 514 ) 515 516 // 窗口是否接受文件拖放 517 func DragAcceptFiles(hwnd syscall.Handle, accept bool) { 518 if accept { 519 _ProcDragAcceptFiles.Call(uintptr(hwnd), uintptr(1)) 520 } else { 521 _ProcDragAcceptFiles.Call(uintptr(hwnd), uintptr(0)) 522 523 } 524 } 525 526 // 获取拖放文件的数量 527 func DragQueryFileCount(hDrop uintptr) uint32 { 528 r, _, _ := _ProcDragQueryFile.Call(uintptr(hDrop), uintptr(0xFFFFFFFF), 0, 0) 529 return uint32(r) 530 } 531 532 // MAX_PATH 是Windows操作系统中路径名的最大长度,其值为260 533 const MAX_PATH = 260 534 535 // 获取单个拖动到窗口的文件 536 func DragFile(hDrop uintptr) string { 537 if DragQueryFileCount(hDrop) == 0 { 538 return "" 539 } 540 buf := make([]uint16, MAX_PATH) 541 // 第二次调用DragQueryFile获取文件名 542 _ProcDragQueryFile.Call(hDrop, 0, uintptr(unsafe.Pointer(&buf[0])), uintptr(MAX_PATH)) 543 544 // 将UTF-16字符串转换为Go字符串 545 return syscall.UTF16ToString(buf) 546 } 547 548 // 获取多个拖动到窗口的文件 549 func DragFiles(hDrop uintptr) []string { 550 count := DragQueryFileCount(hDrop) 551 // 没有文件 552 if count == 0 { 553 return nil 554 } 555 // 获取文件数量 556 files := make([]string, count) 557 // MAX_PATH 是Windows操作系统中路径名的最大长度,其值为260 558 buf := make([]uint16, MAX_PATH) 559 for i := uint32(0); i < count; i++ { 560 // 第二次调用DragQueryFile获取文件名 561 _ProcDragQueryFile.Call(hDrop, uintptr(i), uintptr(unsafe.Pointer(&buf[0])), uintptr(MAX_PATH)) 562 563 // 将UTF-16字符串转换为Go字符串 564 files[i] = syscall.UTF16ToString(buf) 565 } 566 return files 567 } 568 569 // 释放拖放文件的资源 570 func DragFinish(hDrop uintptr) { 571 _ProcDragFinish.Call(hDrop) 572 } 573 574 func AdjustWindowRectEx(r *Rect, dwStyle uint32, bMenu int, dwExStyle uint32) { 575 _AdjustWindowRectEx.Call(uintptr(unsafe.Pointer(r)), uintptr(dwStyle), uintptr(bMenu), uintptr(dwExStyle)) 576 } 577 578 func CallMsgFilter(m *Msg, nCode uintptr) bool { 579 r, _, _ := _CallMsgFilter.Call(uintptr(unsafe.Pointer(m)), nCode) 580 return r != 0 581 } 582 583 func CloseClipboard() error { 584 r, _, err := _CloseClipboard.Call() 585 if r == 0 { 586 return fmt.Errorf("CloseClipboard: %v", err) 587 } 588 return nil 589 } 590 591 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) { 592 wname := syscall.StringToUTF16Ptr(lpWindowName) 593 hwnd, _, err := _CreateWindowEx.Call( 594 uintptr(dwExStyle), 595 uintptr(lpClassName), 596 uintptr(unsafe.Pointer(wname)), 597 uintptr(dwStyle), 598 uintptr(x), uintptr(y), 599 uintptr(w), uintptr(h), 600 uintptr(hWndParent), 601 uintptr(hMenu), 602 uintptr(hInstance), 603 uintptr(lpParam)) 604 if hwnd == 0 { 605 return 0, fmt.Errorf("CreateWindowEx failed: %v", err) 606 } 607 return syscall.Handle(hwnd), nil 608 } 609 610 func DefWindowProc(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) uintptr { 611 r, _, _ := _DefWindowProc.Call(uintptr(hwnd), uintptr(msg), wparam, lparam) 612 return r 613 } 614 615 func DestroyWindow(hwnd syscall.Handle) { 616 _DestroyWindow.Call(uintptr(hwnd)) 617 } 618 619 func DispatchMessage(m *Msg) { 620 _DispatchMessage.Call(uintptr(unsafe.Pointer(m))) 621 } 622 623 func DwmExtendFrameIntoClientArea(hwnd syscall.Handle, margins Margins) error { 624 r, _, _ := _DwmExtendFrameIntoClientArea.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&margins))) 625 if r != 0 { 626 return fmt.Errorf("DwmExtendFrameIntoClientArea: %#x", r) 627 } 628 return nil 629 } 630 631 func EmptyClipboard() error { 632 r, _, err := _EmptyClipboard.Call() 633 if r == 0 { 634 return fmt.Errorf("EmptyClipboard: %v", err) 635 } 636 return nil 637 } 638 639 func GetWindowRect(hwnd syscall.Handle) Rect { 640 var r Rect 641 _GetWindowRect.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&r))) 642 return r 643 } 644 645 func GetClientRect(hwnd syscall.Handle) Rect { 646 var r Rect 647 _GetClientRect.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&r))) 648 return r 649 } 650 651 func GetClipboardData(format uint32) (syscall.Handle, error) { 652 r, _, err := _GetClipboardData.Call(uintptr(format)) 653 if r == 0 { 654 return 0, fmt.Errorf("GetClipboardData: %v", err) 655 } 656 return syscall.Handle(r), nil 657 } 658 659 func GetDC(hwnd syscall.Handle) (syscall.Handle, error) { 660 hdc, _, err := _GetDC.Call(uintptr(hwnd)) 661 if hdc == 0 { 662 return 0, fmt.Errorf("GetDC failed: %v", err) 663 } 664 return syscall.Handle(hdc), nil 665 } 666 667 func GetModuleHandle() (syscall.Handle, error) { 668 h, _, err := _GetModuleHandleW.Call(uintptr(0)) 669 if h == 0 { 670 return 0, fmt.Errorf("GetModuleHandleW failed: %v", err) 671 } 672 return syscall.Handle(h), nil 673 } 674 675 func getDeviceCaps(hdc syscall.Handle, index int32) int { 676 c, _, _ := _GetDeviceCaps.Call(uintptr(hdc), uintptr(index)) 677 return int(c) 678 } 679 680 func getDpiForMonitor(hmonitor syscall.Handle, dpiType uint32) int { 681 var dpiX, dpiY uintptr 682 _GetDpiForMonitor.Call(uintptr(hmonitor), uintptr(dpiType), uintptr(unsafe.Pointer(&dpiX)), uintptr(unsafe.Pointer(&dpiY))) 683 return int(dpiX) 684 } 685 686 // GetSystemDPI returns the effective DPI of the system. 687 func GetSystemDPI() int { 688 // Check for GetDpiForMonitor, introduced in Windows 8.1. 689 if _GetDpiForMonitor.Find() == nil { 690 hmon := monitorFromPoint(Point{}, MONITOR_DEFAULTTOPRIMARY) 691 return getDpiForMonitor(hmon, MDT_EFFECTIVE_DPI) 692 } else { 693 // Fall back to the physical device DPI. 694 screenDC, err := GetDC(0) 695 if err != nil { 696 return 96 697 } 698 defer ReleaseDC(screenDC) 699 return getDeviceCaps(screenDC, LOGPIXELSX) 700 } 701 } 702 703 func GetKeyState(nVirtKey int32) int16 { 704 c, _, _ := _GetKeyState.Call(uintptr(nVirtKey)) 705 return int16(c) 706 } 707 708 func GetMessage(m *Msg, hwnd syscall.Handle, wMsgFilterMin, wMsgFilterMax uint32) int32 { 709 r, _, _ := _GetMessage.Call(uintptr(unsafe.Pointer(m)), 710 uintptr(hwnd), 711 uintptr(wMsgFilterMin), 712 uintptr(wMsgFilterMax)) 713 return int32(r) 714 } 715 716 func GetMessageTime() time.Duration { 717 r, _, _ := _GetMessageTime.Call() 718 return time.Duration(r) * time.Millisecond 719 } 720 721 func GetSystemMetrics(nIndex int) int { 722 r, _, _ := _GetSystemMetrics.Call(uintptr(nIndex)) 723 return int(r) 724 } 725 726 // GetWindowDPI returns the effective DPI of the window. 727 func GetWindowDPI(hwnd syscall.Handle) int { 728 // Check for GetDpiForWindow, introduced in Windows 10. 729 if _GetDpiForWindow.Find() == nil { 730 dpi, _, _ := _GetDpiForWindow.Call(uintptr(hwnd)) 731 return int(dpi) 732 } else { 733 return GetSystemDPI() 734 } 735 } 736 737 func GetWindowPlacement(hwnd syscall.Handle) *WindowPlacement { 738 var wp WindowPlacement 739 wp.length = uint32(unsafe.Sizeof(wp)) 740 _GetWindowPlacement.Call(uintptr(hwnd), uintptr(unsafe.Pointer(&wp))) 741 return &wp 742 } 743 744 func GetMonitorInfo(hwnd syscall.Handle) MonitorInfo { 745 var mi MonitorInfo 746 mi.cbSize = uint32(unsafe.Sizeof(mi)) 747 v, _, _ := _MonitorFromWindow.Call(uintptr(hwnd), MONITOR_DEFAULTTOPRIMARY) 748 _GetMonitorInfo.Call(v, uintptr(unsafe.Pointer(&mi))) 749 return mi 750 } 751 752 func GetWindowLong(hwnd syscall.Handle, index uintptr) (val uintptr) { 753 if runtime.GOARCH == "386" { 754 val, _, _ = _GetWindowLong32.Call(uintptr(hwnd), index) 755 } else { 756 val, _, _ = _GetWindowLong.Call(uintptr(hwnd), index) 757 } 758 return 759 } 760 761 func ImmGetContext(hwnd syscall.Handle) syscall.Handle { 762 h, _, _ := _ImmGetContext.Call(uintptr(hwnd)) 763 return syscall.Handle(h) 764 } 765 766 func ImmReleaseContext(hwnd, imc syscall.Handle) { 767 _ImmReleaseContext.Call(uintptr(hwnd), uintptr(imc)) 768 } 769 770 func ImmNotifyIME(imc syscall.Handle, action, index, value int) { 771 _ImmNotifyIME.Call(uintptr(imc), uintptr(action), uintptr(index), uintptr(value)) 772 } 773 774 func ImmGetCompositionString(imc syscall.Handle, key int) string { 775 size, _, _ := _ImmGetCompositionString.Call(uintptr(imc), uintptr(key), 0, 0) 776 if int32(size) <= 0 { 777 return "" 778 } 779 u16 := make([]uint16, size/unsafe.Sizeof(uint16(0))) 780 _ImmGetCompositionString.Call(uintptr(imc), uintptr(key), uintptr(unsafe.Pointer(&u16[0])), size) 781 return string(utf16.Decode(u16)) 782 } 783 784 func ImmGetCompositionValue(imc syscall.Handle, key int) int { 785 val, _, _ := _ImmGetCompositionString.Call(uintptr(imc), uintptr(key), 0, 0) 786 return int(int32(val)) 787 } 788 789 func ImmSetCompositionWindow(imc syscall.Handle, x, y int) { 790 f := CompositionForm{ 791 dwStyle: CFS_POINT, 792 ptCurrentPos: Point{ 793 X: int32(x), Y: int32(y), 794 }, 795 } 796 _ImmSetCompositionWindow.Call(uintptr(imc), uintptr(unsafe.Pointer(&f))) 797 } 798 799 func ImmSetCandidateWindow(imc syscall.Handle, x, y int) { 800 f := CandidateForm{ 801 dwStyle: CFS_CANDIDATEPOS, 802 ptCurrentPos: Point{ 803 X: int32(x), Y: int32(y), 804 }, 805 } 806 _ImmSetCandidateWindow.Call(uintptr(imc), uintptr(unsafe.Pointer(&f))) 807 } 808 809 func SetWindowLong(hwnd syscall.Handle, idx uintptr, style uintptr) { 810 if runtime.GOARCH == "386" { 811 _SetWindowLong32.Call(uintptr(hwnd), idx, style) 812 } else { 813 _SetWindowLong.Call(uintptr(hwnd), idx, style) 814 } 815 } 816 817 func SetWindowPlacement(hwnd syscall.Handle, wp *WindowPlacement) { 818 _SetWindowPlacement.Call(uintptr(hwnd), uintptr(unsafe.Pointer(wp))) 819 } 820 821 func SetWindowPos(hwnd syscall.Handle, hwndInsertAfter uint32, x, y, dx, dy int32, style uintptr) { 822 _SetWindowPos.Call(uintptr(hwnd), uintptr(hwndInsertAfter), 823 uintptr(x), uintptr(y), 824 uintptr(dx), uintptr(dy), 825 style, 826 ) 827 } 828 829 func SetWindowText(hwnd syscall.Handle, title string) { 830 wname := syscall.StringToUTF16Ptr(title) 831 _SetWindowText.Call(uintptr(hwnd), uintptr(unsafe.Pointer(wname))) 832 } 833 834 func GlobalAlloc(size int) (syscall.Handle, error) { 835 r, _, err := _GlobalAlloc.Call(GHND, uintptr(size)) 836 if r == 0 { 837 return 0, fmt.Errorf("GlobalAlloc: %v", err) 838 } 839 return syscall.Handle(r), nil 840 } 841 842 func GlobalFree(h syscall.Handle) { 843 _GlobalFree.Call(uintptr(h)) 844 } 845 846 func GlobalLock(h syscall.Handle) (unsafe.Pointer, error) { 847 r, _, err := _GlobalLock.Call(uintptr(h)) 848 if r == 0 { 849 return nil, fmt.Errorf("GlobalLock: %v", err) 850 } 851 return unsafe.Pointer(r), nil 852 } 853 854 func GlobalUnlock(h syscall.Handle) { 855 _GlobalUnlock.Call(uintptr(h)) 856 } 857 858 func KillTimer(hwnd syscall.Handle, nIDEvent uintptr) error { 859 r, _, err := _SetTimer.Call(uintptr(hwnd), uintptr(nIDEvent), 0, 0) 860 if r == 0 { 861 return fmt.Errorf("KillTimer failed: %v", err) 862 } 863 return nil 864 } 865 866 func LoadCursor(curID uint16) (syscall.Handle, error) { 867 h, _, err := _LoadCursor.Call(0, uintptr(curID)) 868 if h == 0 { 869 return 0, fmt.Errorf("LoadCursorW failed: %v", err) 870 } 871 return syscall.Handle(h), nil 872 } 873 874 func LoadImage(hInst syscall.Handle, res uint32, typ uint32, cx, cy int, fuload uint32) (syscall.Handle, error) { 875 h, _, err := _LoadImage.Call(uintptr(hInst), uintptr(res), uintptr(typ), uintptr(cx), uintptr(cy), uintptr(fuload)) 876 if h == 0 { 877 return 0, fmt.Errorf("LoadImageW failed: %v", err) 878 } 879 return syscall.Handle(h), nil 880 } 881 882 func MoveWindow(hwnd syscall.Handle, x, y, width, height int32, repaint bool) { 883 var paint uintptr 884 if repaint { 885 paint = TRUE 886 } 887 _MoveWindow.Call(uintptr(hwnd), uintptr(x), uintptr(y), uintptr(width), uintptr(height), paint) 888 } 889 890 func monitorFromPoint(pt Point, flags uint32) syscall.Handle { 891 r, _, _ := _MonitorFromPoint.Call(uintptr(pt.X), uintptr(pt.Y), uintptr(flags)) 892 return syscall.Handle(r) 893 } 894 895 func MsgWaitForMultipleObjectsEx(nCount uint32, pHandles uintptr, millis, mask, flags uint32) (uint32, error) { 896 r, _, err := _MsgWaitForMultipleObjectsEx.Call(uintptr(nCount), pHandles, uintptr(millis), uintptr(mask), uintptr(flags)) 897 res := uint32(r) 898 if res == 0xFFFFFFFF { 899 return 0, fmt.Errorf("MsgWaitForMultipleObjectsEx failed: %v", err) 900 } 901 return res, nil 902 } 903 904 func OpenClipboard(hwnd syscall.Handle) error { 905 r, _, err := _OpenClipboard.Call(uintptr(hwnd)) 906 if r == 0 { 907 return fmt.Errorf("OpenClipboard: %v", err) 908 } 909 return nil 910 } 911 912 func PeekMessage(m *Msg, hwnd syscall.Handle, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool { 913 r, _, _ := _PeekMessage.Call(uintptr(unsafe.Pointer(m)), uintptr(hwnd), uintptr(wMsgFilterMin), uintptr(wMsgFilterMax), uintptr(wRemoveMsg)) 914 return r != 0 915 } 916 917 func PostQuitMessage(exitCode uintptr) { 918 _PostQuitMessage.Call(exitCode) 919 } 920 921 func PostMessage(hwnd syscall.Handle, msg uint32, wParam, lParam uintptr) error { 922 r, _, err := _PostMessage.Call(uintptr(hwnd), uintptr(msg), wParam, lParam) 923 if r == 0 { 924 return fmt.Errorf("PostMessage failed: %v", err) 925 } 926 return nil 927 } 928 929 func ReleaseCapture() bool { 930 r, _, _ := _ReleaseCapture.Call() 931 return r != 0 932 } 933 934 func RegisterClassEx(cls *WndClassEx) (uint16, error) { 935 a, _, err := _RegisterClassExW.Call(uintptr(unsafe.Pointer(cls))) 936 if a == 0 { 937 return 0, fmt.Errorf("RegisterClassExW failed: %v", err) 938 } 939 return uint16(a), nil 940 } 941 942 func ReleaseDC(hdc syscall.Handle) { 943 _ReleaseDC.Call(uintptr(hdc)) 944 } 945 946 func SetForegroundWindow(hwnd syscall.Handle) { 947 _SetForegroundWindow.Call(uintptr(hwnd)) 948 } 949 950 func SetFocus(hwnd syscall.Handle) { 951 _SetFocus.Call(uintptr(hwnd)) 952 } 953 954 func SetProcessDPIAware() { 955 _SetProcessDPIAware.Call() 956 } 957 958 func SetCapture(hwnd syscall.Handle) syscall.Handle { 959 r, _, _ := _SetCapture.Call(uintptr(hwnd)) 960 return syscall.Handle(r) 961 } 962 963 func SetClipboardData(format uint32, mem syscall.Handle) error { 964 r, _, err := _SetClipboardData.Call(uintptr(format), uintptr(mem)) 965 if r == 0 { 966 return fmt.Errorf("SetClipboardData: %v", err) 967 } 968 return nil 969 } 970 971 func SetCursor(h syscall.Handle) { 972 _SetCursor.Call(uintptr(h)) 973 } 974 975 func SetTimer(hwnd syscall.Handle, nIDEvent uintptr, uElapse uint32, timerProc uintptr) error { 976 r, _, err := _SetTimer.Call(uintptr(hwnd), uintptr(nIDEvent), uintptr(uElapse), timerProc) 977 if r == 0 { 978 return fmt.Errorf("SetTimer failed: %v", err) 979 } 980 return nil 981 } 982 983 func ScreenToClient(hwnd syscall.Handle, p *Point) { 984 _ScreenToClient.Call(uintptr(hwnd), uintptr(unsafe.Pointer(p))) 985 } 986 987 func ShowWindow(hwnd syscall.Handle, nCmdShow int32) { 988 _ShowWindow.Call(uintptr(hwnd), uintptr(nCmdShow)) 989 } 990 991 func TranslateMessage(m *Msg) { 992 _TranslateMessage.Call(uintptr(unsafe.Pointer(m))) 993 } 994 995 func UnregisterClass(cls uint16, hInst syscall.Handle) { 996 _UnregisterClass.Call(uintptr(cls), uintptr(hInst)) 997 } 998 999 func UpdateWindow(hwnd syscall.Handle) { 1000 _UpdateWindow.Call(uintptr(hwnd)) 1001 } 1002 1003 func (p WindowPlacement) Rect() Rect { 1004 return p.rcNormalPosition 1005 } 1006 1007 func (p WindowPlacement) IsMinimized() bool { 1008 return p.showCmd == SW_SHOWMINIMIZED 1009 } 1010 1011 func (p WindowPlacement) IsMaximized() bool { 1012 return p.showCmd == SW_SHOWMAXIMIZED 1013 } 1014 1015 func (p *WindowPlacement) Set(Left, Top, Right, Bottom int) { 1016 p.rcNormalPosition.Left = int32(Left) 1017 p.rcNormalPosition.Top = int32(Top) 1018 p.rcNormalPosition.Right = int32(Right) 1019 p.rcNormalPosition.Bottom = int32(Bottom) 1020 }