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  }