windows.go 24 KB

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