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  }