├── .gitignore ├── README.md ├── base.go ├── com ├── com.go ├── init.go ├── ole.go ├── taskbarlist.go └── unknown.go ├── def.go ├── error.go ├── fileapi.go ├── gdi.go ├── go.mod ├── guid.go ├── helper.go ├── kernel.go ├── menu.go ├── message.go ├── namedpipeapi.go ├── reg └── reg.go ├── types.go ├── user.go ├── winapi.go └── winnt.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # winapi # 2 | 这是用 Go 编写的调用 Windows API 的包。将 Windows API 转换成 Go 的风格,使其易用。 3 | 4 | ## 使用方法 ## 5 | 本包不依赖任何第三方包、框架或库。 6 | 任何安装了 Go 环境的 Windows 系统都可以使用。 7 | 8 | ## 已实现的或有所改变的 API ## 9 | 我没有照搬 Windows API,而是在做了一些妥善的改动。例如,不封装`CreateWindow`而封装 `CreateWindowEx`,封装之后的Go的函数名为`CreateWindow`。 10 | 11 | ### gdi ### 12 | BitBlt 13 | DeleteObject 14 | GetObject 15 | CreateCompatibleDC 16 | SelectObject 17 | DeleteDC 18 | 19 | ### kernel ### 20 | GetLastError 21 | ExitProcess 22 | CreateFile 23 | ReadFile 24 | WriteFile 25 | SetFilePointer 26 | GetModuleHandle 27 | CloseHandle 28 | FormatMessage 29 | 30 | ### user ### 31 | DefWindowProc
32 | GetMessage
33 | RegisterClass
34 | MessageBox
35 | CreateWindow
36 | ShowWindow
37 | UpdateWindow
38 | TranslateMessage
39 | DispatchMessage
40 | PostQuitMessage
41 | DestroyWindow
42 | LoadString
43 | LoadIcon
44 | LoadCursor
45 | LoadBitmap
46 | LoadImage
47 | BeginPaint
48 | EndPaint
49 | 50 | ### comdlg ### 51 | 暂无 52 | 53 | ## 增加的函数 ## 54 | ErrorBox
55 | ErrorAssert
56 | WinErrorAssert
57 | 58 | ## 不实现的函数 ## 59 | 与线程相关的函数,如`CreateThread`、`CreateMutex`,因为Go已经有了很好的并发特性。 60 | 61 | ## TODO ## 62 | 实现COM接口的封装,DirectX等。 63 | 64 | ## 协议 ## 65 | 本项目采用与`golang`相同的协议。 -------------------------------------------------------------------------------- /base.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "fmt" 7 | "syscall" 8 | "unicode/utf16" 9 | "unsafe" 10 | ) 11 | 12 | // These are flags supported through CreateFile (W7) and CreateFile2 (W8 and beyond) 13 | const ( 14 | FILE_FLAG_WRITE_THROUGH = 0x80000000 15 | FILE_FLAG_OVERLAPPED = 0x40000000 16 | FILE_FLAG_NO_BUFFERING = 0x20000000 17 | FILE_FLAG_RANDOM_ACCESS = 0x10000000 18 | FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000 19 | FILE_FLAG_DELETE_ON_CLOSE = 0x04000000 20 | FILE_FLAG_BACKUP_SEMANTICS = 0x02000000 21 | FILE_FLAG_POSIX_SEMANTICS = 0x01000000 22 | FILE_FLAG_SESSION_AWARE = 0x00800000 23 | FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000 24 | FILE_FLAG_OPEN_NO_RECALL = 0x00100000 25 | FILE_FLAG_FIRST_PIPE_INSTANCE = 0x00080000 26 | ) 27 | 28 | const ( 29 | FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200 30 | FORMAT_MESSAGE_FROM_STRING = 0x00000400 31 | FORMAT_MESSAGE_FROM_HMODULE = 0x00000800 32 | FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000 33 | FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000 34 | FORMAT_MESSAGE_MAX_WIDTH_MASK = 0x000000FF 35 | ) 36 | 37 | func FormatMessage(flags uint32, msgsrc interface{}, msgid uint32, langid uint32, args *byte) (string, error) { 38 | var b [300]uint16 39 | n, err := _FormatMessage(flags, msgsrc, msgid, langid, &b[0], 300, args) 40 | if err != nil { 41 | return "", err 42 | } 43 | for ; n > 0 && (b[n-1] == '\n' || b[n-1] == '\r'); n-- { 44 | } 45 | return string(utf16.Decode(b[:n])), nil 46 | } 47 | 48 | func _FormatMessage(flags uint32, msgsrc interface{}, msgid uint32, langid uint32, buf *uint16, nSize uint32, args *byte) (n uint32, err error) { 49 | r0, _, e1 := syscall.Syscall9(procFormatMessage.Addr(), 7, 50 | uintptr(flags), uintptr(0), uintptr(msgid), uintptr(langid), 51 | uintptr(unsafe.Pointer(buf)), uintptr(nSize), 52 | uintptr(unsafe.Pointer(args)), 0, 0) 53 | n = uint32(r0) 54 | if n == 0 { 55 | err = fmt.Errorf("winapi._FormatMessage error: %d", uint32(e1)) 56 | } 57 | return 58 | } 59 | 60 | /* 61 | typedef struct _SECURITY_ATTRIBUTES { 62 | DWORD nLength; 63 | void *pSecurityDescriptor; 64 | BOOL bInheritHandle; 65 | } SECURITY_ATTRIBUTES; 66 | */ 67 | type SECURITY_ATTRIBUTES struct { 68 | Length uint32 69 | SecurityDescriptor uintptr 70 | InheritHandle int32 71 | } 72 | -------------------------------------------------------------------------------- /com/com.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package com 4 | 5 | import ( 6 | "syscall" 7 | "unsafe" 8 | 9 | "github.com/jthmath/winapi" 10 | ) 11 | 12 | var ( 13 | dll_ole32 = syscall.NewLazyDLL("ole32.dll") 14 | 15 | procCoInitialize = dll_ole32.NewProc("CoInitialize") 16 | procCoCreateInstance = dll_ole32.NewProc("CoCreateInstance") 17 | ) 18 | 19 | /* 20 | var ( 21 | procCoInitialize, _ = modole32.FindProc("CoInitialize") 22 | procCoInitializeEx, _ = modole32.FindProc("CoInitializeEx") 23 | procCoUninitialize, _ = modole32.FindProc("CoUninitialize") 24 | procCoCreateInstance, _ = modole32.FindProc("CoCreateInstance") 25 | procCoTaskMemFree, _ = modole32.FindProc("CoTaskMemFree") 26 | procCLSIDFromProgID, _ = modole32.FindProc("CLSIDFromProgID") 27 | procCLSIDFromString, _ = modole32.FindProc("CLSIDFromString") 28 | procStringFromCLSID, _ = modole32.FindProc("StringFromCLSID") 29 | procStringFromIID, _ = modole32.FindProc("StringFromIID") 30 | procIIDFromString, _ = modole32.FindProc("IIDFromString") 31 | procGetUserDefaultLCID, _ = modkernel32.FindProc("GetUserDefaultLCID") 32 | procCopyMemory, _ = modkernel32.FindProc("RtlMoveMemory") 33 | procVariantInit, _ = modoleaut32.FindProc("VariantInit") 34 | procVariantClear, _ = modoleaut32.FindProc("VariantClear") 35 | procSysAllocString, _ = modoleaut32.FindProc("SysAllocString") 36 | procSysAllocStringLen, _ = modoleaut32.FindProc("SysAllocStringLen") 37 | procSysFreeString, _ = modoleaut32.FindProc("SysFreeString") 38 | procSysStringLen, _ = modoleaut32.FindProc("SysStringLen") 39 | procCreateDispTypeInfo, _ = modoleaut32.FindProc("CreateDispTypeInfo") 40 | procCreateStdDispatch, _ = modoleaut32.FindProc("CreateStdDispatch") 41 | procGetActiveObject, _ = modoleaut32.FindProc("GetActiveObject") 42 | ) 43 | */ 44 | 45 | const ( 46 | CLSCTX_INPROC_SERVER = 0x1 47 | CLSCTX_INPROC_HANDLER = 0x2 48 | CLSCTX_LOCAL_SERVER = 0x4 49 | CLSCTX_INPROC_SERVER16 = 0x8 50 | CLSCTX_REMOTE_SERVER = 0x10 51 | CLSCTX_INPROC_HANDLER16 = 0x20 52 | CLSCTX_RESERVED1 = 0x40 53 | CLSCTX_RESERVED2 = 0x80 54 | CLSCTX_RESERVED3 = 0x100 55 | CLSCTX_RESERVED4 = 0x200 56 | CLSCTX_NO_CODE_DOWNLOAD = 0x400 57 | CLSCTX_RESERVED5 = 0x800 58 | CLSCTX_NO_CUSTOM_MARSHAL = 0x1000 59 | CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000 60 | CLSCTX_NO_FAILURE_LOG = 0x4000 61 | CLSCTX_DISABLE_AAA = 0x8000 62 | CLSCTX_ENABLE_AAA = 0x10000 63 | CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000 64 | CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000 65 | CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000 66 | CLSCTX_ENABLE_CLOAKING = 0x100000 67 | CLSCTX_APPCONTAINER = 0x400000 68 | CLSCTX_ACTIVATE_AAA_AS_IU = 0x800000 69 | CLSCTX_PS_DLL = 0x80000000 70 | ) 71 | 72 | func CoCreateInstance(rclsid *winapi.GUID, 73 | u uintptr, 74 | ClsContext uint32, 75 | riid *winapi.GUID, 76 | ppv uintptr) error { 77 | r, _, _ := syscall.Syscall6(procCoCreateInstance.Addr(), 5, 78 | uintptr(unsafe.Pointer(rclsid)), 79 | uintptr(u), 80 | uintptr(ClsContext), 81 | uintptr(unsafe.Pointer(riid)), 82 | ppv, 83 | 0) 84 | hr := winapi.HRESULT(r) 85 | if hr == 0 { 86 | return nil 87 | } else { 88 | return hr 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /com/init.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package com 4 | 5 | func init() { 6 | if err := CoInitialize(nil); err != nil { 7 | panic(err) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /com/ole.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package com 4 | 5 | import ( 6 | "syscall" 7 | 8 | "github.com/jthmath/winapi" 9 | ) 10 | 11 | func CoInitialize(a interface{}) error { 12 | r1, _, _ := syscall.Syscall(procCoInitialize.Addr(), 1, 0, 0, 0) 13 | hr := winapi.HRESULT(r1) 14 | if r1 == 0 { 15 | return nil 16 | } else { 17 | return hr 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /com/taskbarlist.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package com 4 | 5 | import ( 6 | "syscall" 7 | "unsafe" 8 | 9 | "github.com/jthmath/winapi" 10 | ) 11 | 12 | const ( 13 | TBPF_NOPROGRESS = 0x00000000 14 | TBPF_INDETERMINATE = 0x00000001 15 | TBPF_NORMAL = 0x00000002 16 | TBPF_ERROR = 0x00000004 17 | TBPF_PAUSED = 0x00000008 18 | ) 19 | 20 | type TaskbarList interface { 21 | Unknown 22 | Init() error 23 | SetProgressValue(hWnd winapi.HWND, completed uint64, total uint64) error 24 | SetProgressState(hWnd winapi.HWND, tbpFlags int32) error 25 | } 26 | 27 | type _TaskbarListVtbl struct { 28 | _IUnknownVtbl 29 | HrInit uintptr 30 | AddTab uintptr 31 | DeleteTab uintptr 32 | ActivateTab uintptr 33 | SetActiveAlt uintptr 34 | MarkFullscreenWindow uintptr 35 | SetProgressValue uintptr 36 | SetProgressState uintptr 37 | RegisterTab uintptr 38 | UnregisterTab uintptr 39 | SetTabOrder uintptr 40 | SetTabActive uintptr 41 | ThumbBarAddButtons uintptr 42 | ThumbBarUpdateButtons uintptr 43 | ThumbBarSetImageList uintptr 44 | SetOverlayIcon uintptr 45 | SetThumbnailTooltip uintptr 46 | SetThumbnailClip uintptr 47 | SetTabProperties uintptr 48 | } 49 | 50 | type _TaskbarList struct { 51 | pVtbl *_TaskbarListVtbl 52 | } 53 | 54 | func (this *_TaskbarList) AddRef() uint32 { 55 | r, _, _ := syscall.Syscall(this.pVtbl.AddRef, 1, uintptr(unsafe.Pointer(this)), 0, 0) 56 | return uint32(r) 57 | } 58 | 59 | func (this *_TaskbarList) Release() uint32 { 60 | r, _, _ := syscall.Syscall(this.pVtbl.Release, 1, uintptr(unsafe.Pointer(this)), 0, 0) 61 | return uint32(r) 62 | } 63 | 64 | func (this *_TaskbarList) Init() error { 65 | r, _, _ := syscall.Syscall(this.pVtbl.HrInit, 1, uintptr(unsafe.Pointer(this)), 0, 0) 66 | hr := winapi.HRESULT(r) 67 | if hr == 0 { 68 | return nil 69 | } else { 70 | return hr 71 | } 72 | } 73 | 74 | func (this *_TaskbarList) SetProgressValue(hWnd winapi.HWND, 75 | completed uint64, total uint64) error { 76 | r, _, _ := syscall.Syscall6(this.pVtbl.SetProgressValue, 4, 77 | uintptr(unsafe.Pointer(this)), uintptr(hWnd), uintptr(completed), uintptr(total), 78 | 0, 0) 79 | hr := winapi.HRESULT(r) 80 | if hr == 0 { 81 | return nil 82 | } else { 83 | return hr 84 | } 85 | } 86 | 87 | func (this *_TaskbarList) SetProgressState(hWnd winapi.HWND, tbpFlags int32) error { 88 | r, _, _ := syscall.Syscall(this.pVtbl.SetProgressState, 3, 89 | uintptr(unsafe.Pointer(this)), uintptr(hWnd), uintptr(tbpFlags)) 90 | hr := winapi.HRESULT(r) 91 | if hr == 0 { 92 | return nil 93 | } else { 94 | return hr 95 | } 96 | } 97 | 98 | var CLSID_TaskbarList = winapi.MustMakeGuid("56FDF344-FD6D-11d0-958A-006097C9A090") 99 | 100 | var IID_ITaskbarList4 = winapi.GUID{ 101 | Data1: 3292383128, 102 | Data2: 38353, 103 | Data3: 19434, 104 | Data4: [8]uint8{144, 48, 187, 153, 226, 152, 58, 26}, 105 | } 106 | 107 | func NewTaskbarList() (itl TaskbarList, err error) { 108 | var pTaskbarList *_TaskbarList 109 | err = CoCreateInstance(&CLSID_TaskbarList, 0, CLSCTX_INPROC_SERVER, &IID_ITaskbarList4, 110 | uintptr(unsafe.Pointer(&pTaskbarList))) 111 | if err == nil { 112 | itl = pTaskbarList 113 | } 114 | return 115 | } 116 | -------------------------------------------------------------------------------- /com/unknown.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package com 4 | 5 | import ( 6 | "syscall" 7 | "unsafe" 8 | ) 9 | 10 | type Unknown interface { 11 | AddRef() uint32 12 | Release() uint32 13 | } 14 | 15 | type _IUnknownVtbl struct { 16 | _QueryInterface uintptr 17 | AddRef uintptr 18 | Release uintptr 19 | } 20 | 21 | type _IUnknown struct { 22 | pVtbl *_IUnknownVtbl 23 | } 24 | 25 | func (this *_IUnknown) AddRef() uint32 { 26 | r, _, _ := syscall.Syscall(this.pVtbl.AddRef, 1, uintptr(unsafe.Pointer(this)), 0, 0) 27 | return uint32(r) 28 | } 29 | 30 | func (this *_IUnknown) Release() uint32 { 31 | r, _, _ := syscall.Syscall(this.pVtbl.Release, 1, uintptr(unsafe.Pointer(this)), 0, 0) 32 | return uint32(r) 33 | } 34 | -------------------------------------------------------------------------------- /def.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | const INVALID_HANDLE_VALUE HANDLE = HANDLE(^uintptr(0)) 6 | -------------------------------------------------------------------------------- /error.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | /* 4 | 错误相关,包括 Windows Error Code 和 HRESULT 5 | */ 6 | 7 | package winapi 8 | 9 | import ( 10 | "fmt" 11 | ) 12 | 13 | // 1. Windows Error Code 14 | 15 | type WinErrorCode uint32 16 | 17 | func (this WinErrorCode) Error() string { 18 | var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS 19 | str, err := FormatMessage(flags, nil, uint32(this), 0, nil) 20 | n := uint32(this) 21 | if err == nil { 22 | return fmt.Sprintf("winapi error: %d(0x%08X) - ", n, n) + str 23 | } else { 24 | return fmt.Sprintf("winapi error: %d(0x%08X)", n, n) 25 | } 26 | } 27 | 28 | // 2. HRESULT 29 | 30 | type HRESULT int32 31 | 32 | const ( 33 | S_OK HRESULT = 0 34 | S_FALSE HRESULT = 1 35 | 36 | E_NOTIMPL HRESULT = (0x80004001 & 0x7FFFFFFF) | (^0x7FFFFFFF) 37 | ) 38 | 39 | func (hr HRESULT) Succeeded() bool { 40 | return hr >= 0 41 | } 42 | 43 | func (hr HRESULT) Failed() bool { 44 | return hr < 0 45 | } 46 | 47 | func (hr HRESULT) Error() string { 48 | var flags uint32 = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_IGNORE_INSERTS 49 | str, err := FormatMessage(flags, nil, uint32(int32(hr)), 0, nil) 50 | if err == nil { 51 | return fmt.Sprintf("error: HRESULT = %d(0x%08X) - ", int32(hr), uint32(hr)) + str 52 | } else { 53 | return fmt.Sprintf("error: HRESULT = %d(0x%08X)", int32(hr), uint32(hr)) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /fileapi.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "errors" 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | const _MAX_READ = 1 << 30 12 | 13 | const ( 14 | CREATE_NEW = 1 15 | CREATE_ALWAYS = 2 16 | OPEN_EXISTING = 3 17 | OPEN_ALWAYS = 4 18 | TRUNCATE_EXISTING = 5 19 | ) 20 | 21 | /* 22 | 打开文件的方法如下: 23 | CreateFile("D:/123.txt") 24 | */ 25 | func CreateFile(FileName string, DesiredAccess uint32, ShareMode uint32, 26 | sa *SECURITY_ATTRIBUTES, 27 | CreationDisposition uint32, FlagsAndAttributes uint32, 28 | TemplateFile HANDLE) (HANDLE, error) { 29 | pFileName, err := syscall.UTF16PtrFromString(FileName) 30 | if err != nil { 31 | return 0, err 32 | } 33 | r1, _, e1 := syscall.Syscall9(procCreateFile.Addr(), 7, 34 | uintptr(unsafe.Pointer(pFileName)), 35 | uintptr(DesiredAccess), 36 | uintptr(ShareMode), 37 | uintptr(unsafe.Pointer(sa)), 38 | uintptr(CreationDisposition), 39 | uintptr(FlagsAndAttributes), 40 | uintptr(TemplateFile), 41 | 0, 0) 42 | if r1 == 0 { 43 | wec := WinErrorCode(e1) 44 | if wec != 0 { 45 | return 0, wec 46 | } else { 47 | return 0, errors.New("CreateFile failed.") 48 | } 49 | } else { 50 | return HANDLE(r1), nil 51 | } 52 | } 53 | 54 | func _ReadFile(hFile HANDLE, 55 | pBuffer *byte, NumberOfBytesToRead uint32, 56 | pNumberOfBytesRead *uint32, 57 | pOverlapped *OVERLAPPED) error { 58 | r1, _, e1 := syscall.Syscall6(procReadFile.Addr(), 5, 59 | uintptr(hFile), uintptr(unsafe.Pointer(pBuffer)), uintptr(NumberOfBytesToRead), 60 | uintptr(unsafe.Pointer(pNumberOfBytesRead)), uintptr(unsafe.Pointer(pOverlapped)), 0) 61 | if r1 == 0 { 62 | wec := WinErrorCode(e1) 63 | if wec != 0 { 64 | return wec 65 | } else { 66 | return errors.New("winapi: ReadFile failed.") 67 | } 68 | } else { 69 | return nil 70 | } 71 | } 72 | 73 | func ReadFile(hFile HANDLE, buf []byte, pOverlapped *OVERLAPPED) (uint32, error) { 74 | if buf == nil { 75 | return 0, errors.New("ReadFile: 必须提供有效的缓冲区") 76 | } 77 | var Len int = len(buf) 78 | if Len <= 0 || Len > _MAX_READ { 79 | return 0, errors.New("ReadFile: 缓冲区长度必须大于零且不超过_MAX_READ") 80 | } 81 | var NumberOfBytesRead uint32 = 0 82 | err := _ReadFile(hFile, &buf[0], uint32(Len), &NumberOfBytesRead, pOverlapped) 83 | if err != nil { 84 | return 0, err 85 | } else { 86 | return NumberOfBytesRead, nil 87 | } 88 | } 89 | 90 | /* 91 | BOOL WINAPI WriteFile( 92 | _In_ HANDLE hFile, 93 | _In_ LPCVOID lpBuffer, 94 | _In_ DWORD nNumberOfBytesToWrite, 95 | _Out_opt_ LPDWORD lpNumberOfBytesWritten, 96 | _Inout_opt_ LPOVERLAPPED lpOverlapped 97 | ); 98 | */ 99 | func _WriteFile(hFile HANDLE, 100 | pBuffer *byte, NumberOfBytesToWrite uint32, 101 | pNumberOfBytesWritten *uint32, 102 | pOverlapped *OVERLAPPED) error { 103 | r1, _, e1 := syscall.Syscall6(procWriteFile.Addr(), 5, 104 | uintptr(hFile), uintptr(unsafe.Pointer(pBuffer)), uintptr(NumberOfBytesToWrite), 105 | uintptr(unsafe.Pointer(pNumberOfBytesWritten)), uintptr(unsafe.Pointer(pOverlapped)), 0) 106 | if r1 == 0 { 107 | wec := WinErrorCode(e1) 108 | if wec != 0 { 109 | return wec 110 | } else { 111 | return errors.New("winapi: WriteFile failed.") 112 | } 113 | } else { 114 | return nil 115 | } 116 | } 117 | 118 | func WriteFile(hFile HANDLE, buf []byte, pOverlapped *OVERLAPPED) (uint32, error) { 119 | if buf == nil { 120 | return 0, errors.New("WriteFile: 必须提供有效的缓冲区") 121 | } 122 | var Len int = len(buf) 123 | if Len <= 0 || Len > _MAX_READ { 124 | return 0, errors.New("WriteFile: 缓冲区长度必须大于零且不超过_MAX_READ") 125 | } 126 | var NumberOfBytesWritten uint32 127 | err := _ReadFile(hFile, &buf[0], uint32(Len), &NumberOfBytesWritten, pOverlapped) 128 | if err != nil { 129 | return 0, err 130 | } else { 131 | return NumberOfBytesWritten, nil 132 | } 133 | } 134 | 135 | const ( 136 | FILE_BEGIN = 0 137 | FILE_CURRENT = 1 138 | FILE_END = 2 139 | ) 140 | 141 | func SetFilePointer(hFile HANDLE, DistanceToMove int64, MoveMethod uint32) (NewPointer int64, err error) { 142 | var np int64 143 | r1, _, e1 := syscall.Syscall6(procSetFilePointer.Addr(), 4, 144 | uintptr(hFile), 145 | uintptr(DistanceToMove), 146 | uintptr(unsafe.Pointer(&np)), 147 | uintptr(MoveMethod), 148 | 0, 0) 149 | if r1 == 0 { 150 | wec := WinErrorCode(e1) 151 | if wec != 0 { 152 | err = wec 153 | } else { 154 | err = errors.New("winapi: SetFilePointer failed.") 155 | } 156 | } else { 157 | NewPointer = np 158 | } 159 | return 160 | } 161 | -------------------------------------------------------------------------------- /gdi.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "errors" 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | const HGDI_ERROR HGDIOBJ = HGDIOBJ(^uintptr(0)) 12 | 13 | // Ternary raster operations 14 | const ( 15 | SRCCOPY uint32 = 0x00CC0020 // dest = source 16 | SRCPAINT uint32 = 0x00EE0086 // dest = source OR dest 17 | SRCAND uint32 = 0x008800C6 // dest = source AND dest 18 | SRCINVERT uint32 = 0x00660046 // dest = source XOR dest 19 | SRCERASE uint32 = 0x00440328 // dest = source AND (NOT dest ) 20 | NOTSRCCOPY uint32 = 0x00330008 // dest = (NOT source) 21 | NOTSRCERASE uint32 = 0x001100A6 // dest = (NOT src) AND (NOT dest) 22 | MERGECOPY uint32 = 0x00C000CA // dest = (source AND pattern) 23 | MERGEPAINT uint32 = 0x00BB0226 // dest = (NOT source) OR dest 24 | PATCOPY uint32 = 0x00F00021 // dest = pattern 25 | PATPAINT uint32 = 0x00FB0A09 // dest = DPSnoo 26 | PATINVERT uint32 = 0x005A0049 // dest = pattern XOR dest 27 | DSTINVERT uint32 = 0x00550009 // dest = (NOT dest) 28 | BLACKNESS uint32 = 0x00000042 // dest = BLACK 29 | WHITENESS uint32 = 0x00FF0062 // dest = WHITE 30 | NOMIRRORBITMAP uint32 = 0x80000000 // Do not Mirror the bitmap in this call 31 | CAPTUREBLT uint32 = 0x40000000 // Include layered windows 32 | ) 33 | 34 | func BitBlt(hdcDest HDC, nXDest int32, nYdest int32, nWidth int32, nHeight int32, 35 | hdcSrc HDC, nXSrc int32, nYSrc int32, Rop uint32) error { 36 | r1, _, e1 := syscall.Syscall9(procBitBlt.Addr(), 9, 37 | uintptr(hdcDest), uintptr(nXDest), uintptr(nYdest), uintptr(nWidth), uintptr(nHeight), 38 | uintptr(hdcSrc), uintptr(nXSrc), uintptr(nYSrc), 39 | uintptr(Rop)) 40 | if r1 == 0 { 41 | if e1 != 0 { 42 | return error(e1) 43 | } else { 44 | return errors.New("BitBlt failed.") 45 | } 46 | } else { 47 | return nil 48 | } 49 | } 50 | 51 | func DeleteObject(obj HGDIOBJ) error { 52 | r1, _, _ := syscall.Syscall(procDeleteObject.Addr(), 1, uintptr(obj), 0, 0) 53 | if r1 != 0 { 54 | return nil 55 | } else { 56 | return errors.New("The specified handle is not valid or is currently selected into a DC.") 57 | } 58 | } 59 | 60 | type BITMAP struct { 61 | BmType int32 62 | BmWidth int32 63 | BmHeight int32 64 | BmWidthBytes int32 65 | BmPlanes uint16 66 | BmBitsPixel uint16 67 | BmBits uintptr 68 | } 69 | 70 | // size = 28 (x64) 71 | // size = 24 (x86) 72 | 73 | /* 74 | int GetObject( 75 | _In_ HGDIOBJ hgdiobj, 76 | _In_ int cbBuffer, 77 | _Out_ LPVOID lpvObject 78 | ); 79 | */ 80 | func GetObject(gdiobj HGDIOBJ, cbBuffer int32, pv *byte) int32 { 81 | r1, _, _ := syscall.Syscall(procGetObject.Addr(), 3, 82 | uintptr(gdiobj), uintptr(cbBuffer), uintptr(unsafe.Pointer(pv))) 83 | return int32(r1) 84 | } 85 | 86 | /* 87 | typedef struct tagPAINTSTRUCT { 88 | HDC hdc; 89 | BOOL fErase; 90 | RECT rcPaint; 91 | BOOL fRestore; 92 | BOOL fIncUpdate; 93 | BYTE rgbReserved[32]; 94 | } PAINTSTRUCT 95 | */ 96 | type PAINTSTRUCT struct { 97 | Hdc HDC 98 | FErase int32 99 | RcPaint RECT 100 | FRestore int32 101 | FIncUpdate int32 102 | RGBReserved [32]byte 103 | } 104 | 105 | func BeginPaint(hWnd HWND, ps *PAINTSTRUCT) (hdc HDC, err error) { 106 | r1, _, _ := syscall.Syscall(procBeginPaint.Addr(), 2, 107 | uintptr(hWnd), uintptr(unsafe.Pointer(ps)), 0) 108 | if r1 == 0 { 109 | err = errors.New("BeginPaint failed.") 110 | } else { 111 | hdc = HDC(r1) 112 | } 113 | return 114 | } 115 | 116 | func EndPaint(hWnd HWND, ps *PAINTSTRUCT) { 117 | syscall.Syscall(procEndPaint.Addr(), 2, 118 | uintptr(hWnd), uintptr(unsafe.Pointer(ps)), 0) 119 | } 120 | 121 | func CreateCompatibleDC(dc HDC) (HDC, error) { 122 | r1, _, _ := syscall.Syscall(procCreateCompatibleDC.Addr(), 1, uintptr(dc), 0, 0) 123 | if r1 == 0 { 124 | return 0, errors.New("CreateCompatibleDC failed.") 125 | } else { 126 | return HDC(r1), nil 127 | } 128 | } 129 | 130 | /* 131 | HGDIOBJ SelectObject( 132 | _In_ HDC hdc, 133 | _In_ HGDIOBJ hgdiobj 134 | ); 135 | */ 136 | func SelectObject(hdc HDC, hgdiobj HGDIOBJ) (robj HGDIOBJ, err error) { 137 | r1, _, _ := syscall.Syscall(procSelectObject.Addr(), 2, uintptr(hdc), uintptr(hgdiobj), 0) 138 | if r1 == 0 { 139 | err = errors.New("An error occurs and the selected object is not a region.") 140 | } else if HGDIOBJ(r1) == HGDI_ERROR { 141 | err = errors.New("SelectObject failed.") 142 | } else { 143 | robj = HGDIOBJ(r1) 144 | } 145 | return 146 | } 147 | 148 | func DeleteDC(dc HDC) error { 149 | r1, _, _ := syscall.Syscall(procDeleteDC.Addr(), 1, uintptr(dc), 0, 0) 150 | if r1 == 0 { 151 | return errors.New("DeleteDC failed.") 152 | } else { 153 | return nil 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/jthmath/winapi 2 | 3 | go 1.18 4 | -------------------------------------------------------------------------------- /guid.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "errors" 7 | "fmt" 8 | ) 9 | 10 | type GUID struct { 11 | Data1 uint32 12 | Data2 uint16 13 | Data3 uint16 14 | Data4 [8]uint8 15 | } 16 | 17 | func (this GUID) String() string { 18 | const FormatString = "%08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X" 19 | a := this.Data4[0] 20 | b := this.Data4[1] 21 | u := uint16(a)<<8 | uint16(b) 22 | return fmt.Sprintf(FormatString, this.Data1, this.Data2, this.Data3, u, 23 | this.Data4[2], this.Data4[3], this.Data4[4], 24 | this.Data4[5], this.Data4[6], this.Data4[7]) 25 | } 26 | 27 | func MakeGuid(str string) (r GUID, err error) { 28 | var n int 29 | const FormatString = "%08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X%02X" 30 | var u uint16 31 | var guid GUID 32 | n, err = fmt.Sscanf(str, FormatString, &guid.Data1, &guid.Data2, &guid.Data3, &u, 33 | &guid.Data4[2], &guid.Data4[3], &guid.Data4[4], 34 | &guid.Data4[5], &guid.Data4[6], &guid.Data4[7]) 35 | 36 | if err == nil { 37 | if n != 10 { 38 | err = errors.New("不是有效的 GUID 字符串") 39 | } else { 40 | guid.Data4[0] = uint8(u >> 8) 41 | guid.Data4[1] = uint8(u) 42 | r = guid 43 | } 44 | } 45 | 46 | return 47 | } 48 | 49 | func MustMakeGuid(str string) GUID { 50 | guid, err := MakeGuid(str) 51 | if err != nil { 52 | panic(err) 53 | } 54 | return guid 55 | } 56 | -------------------------------------------------------------------------------- /helper.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "errors" 7 | "syscall" 8 | ) 9 | 10 | func ByteArrayToUint32LittleEndian(b [4]byte) uint32 { 11 | return uint32(b[0]) + uint32(b[1])<<8 + uint32(b[2])<<16 + uint32(b[3])<<24 12 | } 13 | 14 | func ByteArrayToUint64LittleEndian(b [8]byte) uint64 { 15 | var n uint64 16 | for i := uint(0); i < 8; i++ { 17 | n += (uint64(b[i]) << (8 * i)) 18 | } 19 | return n 20 | } 21 | 22 | func Uint32ToByteArrayLittleEndian(n uint32) (r [4]byte) { 23 | r[0] = byte(n) 24 | r[1] = byte(n >> 8) 25 | r[2] = byte(n >> 16) 26 | r[3] = byte(n >> 24) 27 | return 28 | } 29 | 30 | func Uint64ToByteArrayLittleEndian(n uint64) (r [8]byte) { 31 | r[0] = byte(n) 32 | r[1] = byte(n >> 8) 33 | r[2] = byte(n >> 16) 34 | r[3] = byte(n >> 24) 35 | r[4] = byte(n >> 32) 36 | r[5] = byte(n >> 40) 37 | r[6] = byte(n >> 48) 38 | r[7] = byte(n >> 56) 39 | return 40 | } 41 | 42 | func UTF16FromMultiStrings(sl []string) ([]uint16, error) { 43 | n := len(sl) 44 | if n == 0 { 45 | return []uint16{0}, nil 46 | } 47 | //data := make([]uint16, 2048) 48 | for i := 0; i < n; i++ { 49 | if _, err := syscall.UTF16FromString(sl[i]); err != nil { 50 | return []uint16{}, err 51 | } 52 | } 53 | return []uint16{}, nil 54 | } 55 | 56 | func UTF16ToMultiString(u []uint16) (sl []string, err error) { 57 | CommonErrorString := "winapi.ParseMultiSz function: " 58 | if u == nil { 59 | err = errors.New(CommonErrorString + "the param u can not be nil.") 60 | return 61 | } 62 | Len := len(u) 63 | if Len <= 0 || Len == 2 { 64 | err = errors.New(CommonErrorString + "len(u) can not be 0 or 2.") 65 | return 66 | } else if Len == 1 { 67 | if u[0] != 0 { 68 | err = errors.New(CommonErrorString + "if len(u) is 1, u[0] must be 0.") 69 | return 70 | } else { 71 | return []string{}, nil 72 | } 73 | } else { 74 | if u[0] == 0 { 75 | err = errors.New(CommonErrorString + "find empty string.") 76 | return 77 | } 78 | } 79 | 80 | // now, len(u) >= 3. 81 | sa := make([]string, 0) 82 | var i int = 0 83 | var j int = 0 84 | for i := 1; i < Len-1; i++ { 85 | if u[i] == 0 { 86 | str := syscall.UTF16ToString(u[j:i]) 87 | j = i + 1 88 | sa = append(sa, str) 89 | if u[i+1] == 0 { 90 | break 91 | } 92 | } 93 | } 94 | if i >= Len-1 { 95 | err = errors.New(CommonErrorString + "can't find \\0\\0 as end.") 96 | return 97 | } 98 | 99 | sl = make([]string, len(sa)) 100 | copy(sl, sa) 101 | 102 | return 103 | } 104 | 105 | func MakeIntResource(id uint16) uintptr { 106 | return uintptr(id) 107 | } 108 | 109 | func IS_INTRESOURCE(r uintptr) bool { 110 | return (r >> 16) == 0 111 | } 112 | 113 | func LoWord(a uint32) uint16 { 114 | return uint16(a & 0xFFFF) 115 | } 116 | 117 | func HiWord(a uint32) uint16 { 118 | return uint16((a >> 16) & 0xFFFF) 119 | } 120 | -------------------------------------------------------------------------------- /kernel.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "errors" 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | func GetLastError() WinErrorCode { 12 | ret, _, _ := syscall.Syscall(procGetLastError.Addr(), 0, 0, 0, 0) 13 | return WinErrorCode(uint32(ret)) 14 | } 15 | 16 | func ExitProcess(ExitCode uint32) { 17 | syscall.Syscall(procExitProcess.Addr(), 1, uintptr(ExitCode), 0, 0) 18 | } 19 | 20 | func GetModuleHandle(ModuleName string) (h HINSTANCE, err error) { 21 | var a uintptr 22 | var pStr *uint16 23 | 24 | if ModuleName == "" { 25 | a = 0 26 | } else { 27 | pStr, err = syscall.UTF16PtrFromString(ModuleName) 28 | if err != nil { 29 | return 30 | } else { 31 | a = uintptr(unsafe.Pointer(pStr)) 32 | } 33 | } 34 | 35 | r1, _, e1 := syscall.Syscall(procGetModuleHandle.Addr(), 1, a, 0, 0) 36 | if r1 == 0 { 37 | wec := WinErrorCode(e1) 38 | if wec != 0 { 39 | err = wec 40 | } else { 41 | err = errors.New("GetModuleHandle failed.") 42 | } 43 | } else { 44 | h = HINSTANCE(r1) 45 | } 46 | return 47 | } 48 | 49 | func CloseHandle(h HANDLE) (err error) { 50 | r1, _, e1 := syscall.Syscall(procCloseHandle.Addr(), 1, uintptr(h), 0, 0) 51 | if r1 == 0 { 52 | if e1 != 0 { 53 | err = error(e1) 54 | } else { 55 | err = errors.New("CloseHandle failed.") 56 | } 57 | } 58 | return 59 | } 60 | -------------------------------------------------------------------------------- /menu.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "errors" 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | const ( 12 | MF_INSERT = 0x00000000 13 | MF_CHANGE = 0x00000080 14 | MF_APPEND = 0x00000100 15 | MF_DELETE = 0x00000200 16 | MF_REMOVE = 0x00001000 17 | 18 | MF_BYCOMMAND = 0x00000000 19 | MF_BYPOSITION = 0x00000400 20 | 21 | MF_SEPARATOR = 0x00000800 22 | 23 | MF_ENABLED = 0x00000000 24 | MF_GRAYED = 0x00000001 25 | MF_DISABLED = 0x00000002 26 | 27 | MF_UNCHECKED = 0x00000000 28 | MF_CHECKED = 0x00000008 29 | MF_USECHECKBITMAPS = 0x00000200 30 | 31 | MF_STRING = 0x00000000 32 | MF_BITMAP = 0x00000004 33 | MF_OWNERDRAW = 0x00000100 34 | 35 | MF_POPUP = 0x00000010 36 | MF_MENUBARBREAK = 0x00000020 37 | MF_MENUBREAK = 0x00000040 38 | 39 | MF_UNHILITE = 0x00000000 40 | MF_HILITE = 0x00000080 41 | 42 | MF_DEFAULT = 0x00001000 43 | 44 | MF_SYSMENU = 0x00002000 45 | MF_HELP = 0x00004000 46 | MF_RIGHTJUSTIFY = 0x00004000 47 | 48 | MF_MOUSESELECT = 0x00008000 49 | MF_END = 0x00000080 // Obsolete -- only used by old RES files 50 | ) 51 | 52 | func AppendMenu(hMenu HMENU, Flags uint32, IdNewItem uintptr, NewItem string) error { 53 | var err error 54 | var pNewItem *uint16 55 | 56 | if NewItem != "" { 57 | pNewItem, err = syscall.UTF16PtrFromString(NewItem) 58 | if err != nil { 59 | return err 60 | } 61 | } 62 | 63 | return _AppendMenu(hMenu, Flags, IdNewItem, pNewItem) 64 | } 65 | 66 | func _AppendMenu(hMenu HMENU, Flags uint32, IdNewItem uintptr, NewItem *uint16) (err error) { 67 | r1, _, e1 := syscall.Syscall6(procAppendMenu.Addr(), 4, 68 | uintptr(hMenu), uintptr(Flags), IdNewItem, uintptr(unsafe.Pointer(NewItem)), 69 | 0, 0) 70 | if r1 == 0 { 71 | wec := WinErrorCode(e1) 72 | if wec != 0 { 73 | err = wec 74 | } else { 75 | err = errors.New("winapi: AppendMenu failed.") 76 | } 77 | } 78 | return 79 | } 80 | 81 | func CreateMenu() (hMenu HMENU, err error) { 82 | r1, _, e1 := syscall.Syscall(procCreateMenu.Addr(), 0, 0, 0, 0) 83 | if r1 == 0 { 84 | wec := WinErrorCode(e1) 85 | if wec != 0 { 86 | err = wec 87 | } else { 88 | err = errors.New("winapi: CreateMenu failed.") 89 | } 90 | } else { 91 | hMenu = HMENU(r1) 92 | } 93 | return 94 | } 95 | 96 | func CreatePopupMenu() (hMenu HMENU, err error) { 97 | r1, _, e1 := syscall.Syscall(procCreatePopupMenu.Addr(), 0, 0, 0, 0) 98 | if r1 == 0 { 99 | wec := WinErrorCode(e1) 100 | if wec != 0 { 101 | err = wec 102 | } else { 103 | err = errors.New("winapi: CreatePopupMenu failed.") 104 | } 105 | } else { 106 | hMenu = HMENU(r1) 107 | } 108 | return 109 | } 110 | 111 | func DestroyMenu(hMenu HMENU) (err error) { 112 | r1, _, e1 := syscall.Syscall(procDestroyMenu.Addr(), 1, uintptr(hMenu), 0, 0) 113 | if r1 == 0 { 114 | wec := WinErrorCode(e1) 115 | if wec != 0 { 116 | err = wec 117 | } else { 118 | err = errors.New("winapi: DestroyMenu failed.") 119 | } 120 | } 121 | return 122 | } 123 | -------------------------------------------------------------------------------- /message.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "errors" 7 | "syscall" 8 | "unsafe" 9 | ) 10 | 11 | const ( 12 | WM_NULL uint32 = 0x0000 13 | WM_CREATE uint32 = 0x0001 14 | WM_DESTROY uint32 = 0x0002 15 | WM_MOVE uint32 = 0x0003 16 | WM_SIZE uint32 = 0x0005 17 | 18 | WM_ACTIVATE uint32 = 0x0006 19 | 20 | WM_PAINT uint32 = 0x000F 21 | 22 | /* 23 | * WM_ACTIVATE state values 24 | */ 25 | WA_INACTIVE = 0 26 | WA_ACTIVE = 1 27 | WA_CLICKACTIVE = 2 28 | 29 | WM_CLOSE uint32 = 0x0010 30 | WM_QUIT uint32 = 0x0012 31 | 32 | WM_GETMINMAXINFO uint32 = 0x0024 33 | 34 | WM_COMMAND uint32 = 0x0111 35 | ) 36 | 37 | type MSG struct { 38 | Hwnd HWND 39 | Message uint32 40 | WParam uintptr 41 | LParam uintptr 42 | Time uint32 43 | Pt POINT 44 | } 45 | 46 | func GetMessage(pMsg *MSG, hWnd HWND, wMsgFilterMin uint32, wMsgFilterMax uint32) int32 { 47 | r1, _, _ := syscall.Syscall6(procGetMessage.Addr(), 4, 48 | uintptr(unsafe.Pointer(pMsg)), 49 | uintptr(hWnd), 50 | uintptr(wMsgFilterMin), 51 | uintptr(wMsgFilterMax), 52 | 0, 0) 53 | return int32(r1) 54 | } 55 | 56 | func TranslateMessage(pMsg *MSG) error { 57 | r1, _, _ := syscall.Syscall(procTranslateMessage.Addr(), 1, uintptr(unsafe.Pointer(pMsg)), 0, 0) 58 | if r1 == 0 { 59 | return errors.New("winapi: TranslateMessage failed.") 60 | } else { 61 | return nil 62 | } 63 | } 64 | 65 | func DispatchMessage(pMsg *MSG) uintptr { 66 | r1, _, _ := syscall.Syscall(procDispatchMessage.Addr(), 1, uintptr(unsafe.Pointer(pMsg)), 0, 0) 67 | return r1 68 | } 69 | 70 | func PostQuitMessage(ExitCode int32) { 71 | syscall.Syscall(procPostQuitMessage.Addr(), 1, uintptr(ExitCode), 0, 0) 72 | } 73 | 74 | func RegisterWindowMessage(str string) (message uint32, err error) { 75 | p, err := syscall.UTF16PtrFromString(str) 76 | if err != nil { 77 | return 78 | } 79 | 80 | r1, _, e1 := syscall.Syscall(procRegisterWindowMessage.Addr(), 1, 81 | uintptr(unsafe.Pointer(p)), 82 | 0, 0) 83 | if r1 == 0 { 84 | wec := WinErrorCode(e1) 85 | if wec != 0 { 86 | err = wec 87 | } else { 88 | err = errors.New("winapi: RegisterWindowMessage failed.") 89 | } 90 | } else { 91 | message = uint32(r1) 92 | } 93 | return 94 | } 95 | -------------------------------------------------------------------------------- /namedpipeapi.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "errors" 7 | "syscall" 8 | "time" 9 | "unsafe" 10 | ) 11 | 12 | // Define the dwOpenMode values for CreateNamedPipe 13 | const ( 14 | PIPE_ACCESS_INBOUND = 0x00000001 15 | PIPE_ACCESS_OUTBOUND = 0x00000002 16 | PIPE_ACCESS_DUPLEX = 0x00000003 17 | ) 18 | 19 | // Define the Named Pipe End flags for GetNamedPipeInfo 20 | const ( 21 | PIPE_CLIENT_END = 0x00000000 22 | PIPE_SERVER_END = 0x00000001 23 | ) 24 | 25 | // Define the dwPipeMode values for CreateNamedPipe 26 | const ( 27 | PIPE_WAIT = 0x00000000 28 | PIPE_NOWAIT = 0x00000001 29 | PIPE_READMODE_BYTE = 0x00000000 30 | PIPE_READMODE_MESSAGE = 0x00000002 31 | PIPE_TYPE_BYTE = 0x00000000 32 | PIPE_TYPE_MESSAGE = 0x00000004 33 | PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000 34 | PIPE_REJECT_REMOTE_CLIENTS = 0x00000008 35 | ) 36 | 37 | // Define the well known values for CreateNamedPipe nMaxInstances 38 | const PIPE_UNLIMITED_INSTANCES = 255 39 | 40 | func ConnectNamedPipe(hNamedPipe HANDLE, po *OVERLAPPED) (err error) { 41 | r1, _, e1 := syscall.Syscall(procConnectNamedPipe.Addr(), 2, 42 | uintptr(hNamedPipe), uintptr(unsafe.Pointer(po)), 0) 43 | if r1 == 0 { 44 | wec := WinErrorCode(e1) 45 | if wec != 0 { 46 | err = wec 47 | } else { 48 | err = errors.New("ConnectNamedPipe failed.") 49 | } 50 | } 51 | return 52 | } 53 | 54 | func CreateNamedPipe( 55 | name string, 56 | openMode uint32, 57 | pipeMode uint32, 58 | maxInstances uint32, 59 | outBufferSize uint32, 60 | inBufferSize uint32, 61 | defaultTimeOut time.Duration, 62 | sa *SECURITY_ATTRIBUTES) (h HANDLE, err error) { 63 | pName, err := syscall.UTF16PtrFromString(name) 64 | if err != nil { 65 | return 66 | } 67 | 68 | dto := uint32(uint64(defaultTimeOut) / 1e6) 69 | 70 | h, err = _CreateNamedPipe(pName, openMode, pipeMode, maxInstances, 71 | outBufferSize, inBufferSize, dto, sa) 72 | return 73 | } 74 | 75 | func _CreateNamedPipe(pName *uint16, dwOpenMode uint32, dwPipeMode uint32, 76 | nMaxInstances uint32, nOutBufferSize uint32, nInBufferSize uint32, 77 | nDefaultTimeOut uint32, pSecurityAttributes *SECURITY_ATTRIBUTES) (h HANDLE, err error) { 78 | r1, _, e1 := syscall.Syscall9(procCreateNamedPipe.Addr(), 8, 79 | uintptr(unsafe.Pointer(pName)), 80 | uintptr(dwOpenMode), 81 | uintptr(dwPipeMode), 82 | uintptr(nMaxInstances), 83 | uintptr(nOutBufferSize), 84 | uintptr(nInBufferSize), 85 | uintptr(nDefaultTimeOut), 86 | uintptr(unsafe.Pointer(pSecurityAttributes)), 87 | 0) 88 | if h == INVALID_HANDLE_VALUE { 89 | wec := WinErrorCode(e1) 90 | if wec != 0 { 91 | err = wec 92 | } else { 93 | err = errors.New("CreateNamedPipe failed.") 94 | } 95 | } else { 96 | h = HANDLE(r1) 97 | } 98 | return 99 | } 100 | -------------------------------------------------------------------------------- /reg/reg.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package reg 4 | 5 | import ( 6 | "errors" 7 | "fmt" 8 | "syscall" 9 | "unsafe" 10 | 11 | "github.com/jthmath/winapi" 12 | ) 13 | 14 | var ( 15 | dll_Advapi *syscall.LazyDLL = syscall.NewLazyDLL("Advapi32.dll") 16 | ) 17 | 18 | var ( 19 | procRegCreateKeyEx *syscall.LazyProc = dll_Advapi.NewProc("RegCreateKeyExW") 20 | procRegOpenKeyEx *syscall.LazyProc = dll_Advapi.NewProc("RegRegOpenKeyExW") 21 | procRegSetValueEx *syscall.LazyProc = dll_Advapi.NewProc("RegSetValueExW") 22 | procRegCloseKey *syscall.LazyProc = dll_Advapi.NewProc("RegCloseKey") 23 | procRegDeleteKeyEx *syscall.LazyProc = dll_Advapi.NewProc("RegDeleteKeyExW") 24 | procRegQueryValueEx *syscall.LazyProc = dll_Advapi.NewProc("RegQueryValueExW") 25 | ) 26 | 27 | type HKEY uintptr 28 | 29 | type REGSAM winapi.ACCESS_MASK 30 | 31 | const ERROR_SUCCESS int32 = 0 32 | 33 | const ( 34 | HKEY_CLASSES_ROOT HKEY = 0x80000000 35 | HKEY_CURRENT_USER HKEY = 0x80000001 36 | HKEY_LOCAL_MACHINE HKEY = 0x80000002 37 | HKEY_USERS HKEY = 0x80000003 38 | HKEY_CURRENT_CONFIG HKEY = 0x80000005 39 | ) 40 | 41 | const ( 42 | REG_OPTION_BACKUP_RESTORE uint32 = 0x00000004 43 | REG_OPTION_CREATE_LINK uint32 = 0x00000002 44 | REG_OPTION_NON_VOLATILE uint32 = 0x00000000 45 | REG_OPTION_VOLATILE uint32 = 0x00000001 46 | ) 47 | 48 | const ( 49 | KEY_ALL_ACCESS REGSAM = 0xF003F 50 | ) 51 | 52 | const ( 53 | REG_CREATED_NEW_KEY uint32 = 0x00000001 54 | REG_OPENED_EXISTING_KEY uint32 = 0x00000002 55 | ) 56 | 57 | const ( 58 | REG_NONE uint32 = 0 // No value type 59 | REG_SZ uint32 = 1 // Unicode nul terminated string 60 | REG_EXPAND_SZ uint32 = 2 // Unicode nul terminated string(with environment variable references) 61 | 62 | REG_BINARY uint32 = 3 // Free form binary 63 | REG_UINT32 uint32 = 4 // 32-bit number 64 | REG_LINK uint32 = 6 // Symbolic Link (unicode) 65 | REG_MULTI_SZ uint32 = 7 // Multiple Unicode strings 66 | REG_RESOURCE_LIST uint32 = 8 // Resource list in the resource map 67 | REG_FULL_RESOURCE_DESCRIPTOR uint32 = 9 // Resource list in the hardware description 68 | REG_RESOURCE_REQUIREMENTS_LIST uint32 = 10 // 69 | REG_UINT64 uint32 = 11 // 64-bit number 70 | ) 71 | 72 | const ( 73 | KEY_WOW64_32KEY REGSAM = 0x0200 74 | KEY_WOW64_64KEY REGSAM = 0x0100 75 | ) 76 | 77 | func CreateKey(hKey HKEY, SubKey string, Reserved uint32, Class string, 78 | Options uint32, samDesired REGSAM, 79 | sa *winapi.SecurityAttributes) (hkResult HKEY, Disposition uint32, err error) { 80 | pSubKey, err := syscall.UTF16PtrFromString(SubKey) 81 | if err != nil { 82 | return 83 | } 84 | pClass, err := winapi.SpecUTF16PtrFromString(Class) 85 | if err != nil { 86 | return 87 | } 88 | var hKeyResult HKEY 89 | var disposition uint32 90 | r1, _, e1 := syscall.Syscall9(procRegCreateKeyEx.Addr(), 9, 91 | uintptr(hKey), 92 | uintptr(unsafe.Pointer(pSubKey)), 93 | uintptr(Reserved), 94 | uintptr(unsafe.Pointer(pClass)), 95 | uintptr(Options), 96 | uintptr(samDesired), 97 | uintptr(unsafe.Pointer(sa)), 98 | uintptr(unsafe.Pointer(&hKeyResult)), 99 | uintptr(unsafe.Pointer(&disposition))) 100 | n := int32(r1) 101 | if n != ERROR_SUCCESS { 102 | if e1 != 0 { 103 | err = error(e1) 104 | } else { 105 | err = fmt.Errorf("函数 RegCreateKeyEx 返回 %d", n) 106 | } 107 | } else { 108 | hkResult = hKeyResult 109 | Disposition = disposition 110 | } 111 | 112 | return 113 | } 114 | 115 | func SetValue(Key HKEY, ValueName string, Reserved uint32, 116 | Type uint32, Data interface{}) error { 117 | pValueName, err := syscall.UTF16PtrFromString(ValueName) 118 | if err != nil { 119 | return err 120 | } 121 | TypeError := errors.New("函数 SetValue ,Type与实际的数据类型不匹配") 122 | var pData *byte 123 | var cbData uint32 124 | switch Data.(type) { 125 | case []byte: 126 | if Type != REG_BINARY { 127 | return TypeError 128 | } else { 129 | buf := Data.([]byte) 130 | pData = &buf[0] 131 | cbData = uint32(len(buf)) 132 | } 133 | case uint32: 134 | if Type != REG_UINT32 { 135 | return TypeError 136 | } else { 137 | r := winapi.Uint32ToByteArrayLittleEndian(Data.(uint32)) 138 | pData = &r[0] 139 | cbData = 4 140 | } 141 | case uint64: 142 | if Type != REG_UINT64 { 143 | return TypeError 144 | } else { 145 | r := winapi.Uint64ToByteArrayLittleEndian(Data.(uint64)) 146 | pData = &r[0] 147 | cbData = 8 148 | } 149 | case string: 150 | if Type != REG_SZ { 151 | return TypeError 152 | } else { 153 | str := Data.(string) 154 | ustr, err := syscall.UTF16FromString(str) 155 | if err != nil { 156 | return err 157 | } 158 | pData = (*byte)(unsafe.Pointer(&ustr[0])) 159 | cbData = uint32(len(ustr)) * 2 160 | } 161 | case []string: 162 | if Type != REG_MULTI_SZ { 163 | return TypeError 164 | } else { 165 | str := Data.([]string) 166 | su := make([]uint16, 0) 167 | for i := 0; i < len(str); i++ { 168 | ustr, err := syscall.UTF16FromString(str[i]) 169 | if err != nil { 170 | return err 171 | } else { 172 | su = append(su, ustr...) 173 | } 174 | } 175 | su = append(su, 0) 176 | pData = (*byte)(unsafe.Pointer(&su[0])) 177 | cbData = uint32(len(su)) * 2 178 | } 179 | default: 180 | return errors.New("SetValue不支持该类型") 181 | } 182 | return _SetValue(Key, pValueName, Reserved, Type, pData, cbData) 183 | } 184 | 185 | func _SetValue(Key HKEY, ValueName *uint16, Reserved uint32, 186 | Type uint32, Data *byte, cbData uint32) (err error) { 187 | r1, _, e1 := syscall.Syscall6(procRegSetValueEx.Addr(), 6, 188 | uintptr(Key), 189 | uintptr(unsafe.Pointer(ValueName)), 190 | uintptr(Reserved), 191 | uintptr(Type), 192 | uintptr(unsafe.Pointer(Data)), 193 | uintptr(cbData)) 194 | n := int32(r1) 195 | if n != ERROR_SUCCESS { 196 | if e1 != 0 { 197 | err = error(e1) 198 | } else { 199 | err = fmt.Errorf("函数 RegSetValueEx 返回 %d", n) 200 | } 201 | } 202 | return 203 | } 204 | 205 | func CloseKey(Key HKEY) (err error) { 206 | r1, _, e1 := syscall.Syscall(procRegCloseKey.Addr(), 1, 207 | uintptr(unsafe.Pointer(Key)), 0, 0) 208 | if int32(r1) != ERROR_SUCCESS { 209 | if e1 != 0 { 210 | err = error(e1) 211 | } else { 212 | err = errors.New("CloseKey failed.") 213 | } 214 | } 215 | return 216 | } 217 | 218 | func DeleteKey(Key HKEY, SubKey string, samDesired REGSAM, Reserved uint32) (err error) { 219 | pSubKey, err := syscall.UTF16PtrFromString(SubKey) 220 | if err != nil { 221 | return 222 | } 223 | r1, _, e1 := syscall.Syscall6(procRegSetValueEx.Addr(), 4, 224 | uintptr(Key), 225 | uintptr(unsafe.Pointer(pSubKey)), 226 | uintptr(samDesired), 227 | uintptr(Reserved), 228 | 0, 0) 229 | n := int32(r1) 230 | if n != ERROR_SUCCESS { 231 | if e1 != 0 { 232 | err = error(e1) 233 | } else { 234 | err = errors.New("DeleteKey failed.") 235 | } 236 | } 237 | return 238 | } 239 | 240 | func QueryValue(Key HKEY, ValueName string) (Type uint32, Data interface{}, err error) { 241 | pValueName, err := syscall.UTF16PtrFromString(ValueName) 242 | if err != nil { 243 | return 244 | } 245 | var dwType uint32 246 | var dwSize uint32 247 | err = _QueryValue(Key, pValueName, &dwType, nil, &dwSize) 248 | if err != nil { 249 | return 250 | } 251 | switch dwType { 252 | case REG_BINARY: 253 | sb := make([]byte, dwSize) 254 | err = _QueryValue(Key, pValueName, &dwType, &sb[0], &dwSize) 255 | if err != nil { 256 | return 257 | } else { 258 | Data = sb 259 | } 260 | case REG_SZ: 261 | if dwSize == 0 || dwSize%2 != 0 { 262 | err = errors.New("dwSize必须是正偶数") 263 | return 264 | } 265 | buf := make([]uint16, dwSize/2) 266 | err = _QueryValue(Key, pValueName, &dwType, (*byte)(unsafe.Pointer(&buf[0])), &dwSize) 267 | if err != nil { 268 | return 269 | } else { 270 | Data = syscall.UTF16ToString(buf) 271 | } 272 | case REG_MULTI_SZ: 273 | if dwSize == 0 || dwSize%2 != 0 { 274 | err = errors.New("dwSize必须是正偶数") 275 | return 276 | } 277 | buf := make([]uint16, dwSize/2) 278 | err = _QueryValue(Key, pValueName, &dwType, (*byte)(unsafe.Pointer(&buf[0])), &dwSize) 279 | if err != nil { 280 | return 281 | } else { 282 | ss, uerr := winapi.UTF16ToMultiString(buf) 283 | if uerr != nil { 284 | err = uerr 285 | return 286 | } else { 287 | Data = ss 288 | } 289 | } 290 | case REG_UINT32: 291 | var buf [4]byte 292 | err = _QueryValue(Key, pValueName, &dwType, &buf[0], &dwSize) 293 | if err != nil { 294 | return 295 | } else { 296 | Data = winapi.ByteArrayToUint32LittleEndian(buf) 297 | } 298 | case REG_UINT64: 299 | var buf [8]byte 300 | err = _QueryValue(Key, pValueName, &dwType, &buf[0], &dwSize) 301 | if err != nil { 302 | return 303 | } else { 304 | Data = winapi.ByteArrayToUint64LittleEndian(buf) 305 | } 306 | default: 307 | err = errors.New("不支持的类型") 308 | return 309 | } 310 | Type = dwType 311 | return 312 | } 313 | 314 | func _QueryValue(Key HKEY, ValueName *uint16, pType *uint32, 315 | pData *byte, pcbData *uint32) error { 316 | r1, _, _ := syscall.Syscall6(procRegQueryValueEx.Addr(), 6, 317 | uintptr(Key), 318 | uintptr(unsafe.Pointer(ValueName)), 319 | uintptr(0), 320 | uintptr(unsafe.Pointer(pType)), 321 | uintptr(unsafe.Pointer(pData)), 322 | uintptr(unsafe.Pointer(pcbData))) 323 | n := int32(r1) 324 | if n != ERROR_SUCCESS { 325 | return errors.New("_QueryValue failed.") 326 | } else { 327 | return nil 328 | } 329 | } 330 | -------------------------------------------------------------------------------- /types.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | type HANDLE uintptr 6 | 7 | type __HWND struct { 8 | unused int 9 | } 10 | 11 | type HWND uintptr 12 | 13 | type HMENU uintptr 14 | type HINSTANCE uintptr 15 | type HMODULE uintptr 16 | 17 | type HGDIOBJ uintptr 18 | type HDC uintptr 19 | type HICON uintptr 20 | type HCURSOR uintptr 21 | type HBRUSH uintptr 22 | type HBITMAP uintptr 23 | 24 | type OVERLAPPED struct { 25 | Internal uintptr 26 | InternalHigh uintptr 27 | Offset uint32 28 | OffsetHigh uint32 29 | HEvent HANDLE 30 | } 31 | 32 | type POINT struct { 33 | X int32 34 | Y int32 35 | } 36 | 37 | type ACCESS_MASK uint32 38 | 39 | type RECT struct { 40 | Left int32 41 | Top int32 42 | Right int32 43 | Bottom int32 44 | } 45 | -------------------------------------------------------------------------------- /user.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | // 此文件包含 user32.dll 中的函数,其中,关于【消息】的另放在 message.go 中 4 | 5 | package winapi 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | type WNDPROC func(HWND, uint32, uintptr, uintptr) uintptr 15 | 16 | const ( 17 | CS_VREDRAW uint32 = 0x0001 18 | CS_HREDRAW uint32 = 0x0002 19 | CS_DBLCLKS uint32 = 0x0008 20 | CS_OWNDC uint32 = 0x0020 21 | CS_CLASSDC uint32 = 0x0040 22 | CS_PARENTDC uint32 = 0x0080 23 | CS_NOCLOSE uint32 = 0x0200 24 | CS_SAVEBITS uint32 = 0x0800 25 | CS_BYTEALIGNCLIENT uint32 = 0x1000 26 | CS_BYTEALIGNWINDOW uint32 = 0x2000 27 | CS_GLOBALCLASS uint32 = 0x4000 28 | CS_IME uint32 = 0x00010000 29 | CS_DROPSHADOW uint32 = 0x00020000 30 | ) 31 | 32 | type WNDCLASS struct { 33 | Style uint32 34 | PfnWndProc WNDPROC 35 | CbClsExtra int32 36 | CbWndExtra int32 37 | HInstance HINSTANCE 38 | HIcon HICON 39 | HCursor HCURSOR 40 | HbrBackground HBRUSH 41 | Menu interface{} 42 | PszClassName string 43 | HIconSmall HICON 44 | } 45 | 46 | type _WNDCLASS struct { 47 | cbSize uint32 48 | style uint32 49 | pfnWndProcPtr uintptr 50 | cbClsExtra int32 51 | cbWndExtra int32 52 | hInstance HINSTANCE 53 | hIcon HICON 54 | hCursor HCURSOR 55 | hbrBackground HBRUSH 56 | pszMenuName *uint16 57 | pszClassName *uint16 58 | hIconSmall HICON 59 | } 60 | 61 | func newWndProc(proc WNDPROC) uintptr { 62 | return syscall.NewCallback(proc) 63 | } 64 | 65 | func RegisterClass(pWndClass *WNDCLASS) (atom uint16, err error) { 66 | if pWndClass == nil { 67 | err = errors.New("winapi: RegisterClass: pWndClass must not be nil.") 68 | return 69 | } 70 | 71 | _pClassName, err := syscall.UTF16PtrFromString(pWndClass.PszClassName) 72 | if err != nil { 73 | return 74 | } 75 | 76 | if pWndClass.Menu == nil { 77 | err = errors.New("winapi: RegisterClass: can't find Menu.") 78 | return 79 | } 80 | 81 | var Menu uintptr = 70000 82 | 83 | var _pMenuName *uint16 = nil 84 | 85 | switch v := pWndClass.Menu.(type) { 86 | case uint16: 87 | Menu = MakeIntResource(v) 88 | case string: 89 | _pMenuName, err = syscall.UTF16PtrFromString(v) 90 | if err != nil { 91 | return 92 | } 93 | default: 94 | return 0, errors.New("winapi: RegisterClass: Menu's type must be uint16 or string.") 95 | } 96 | 97 | var wc _WNDCLASS 98 | wc.cbSize = uint32(unsafe.Sizeof(wc)) 99 | wc.style = pWndClass.Style 100 | wc.pfnWndProcPtr = newWndProc(pWndClass.PfnWndProc) 101 | wc.cbClsExtra = pWndClass.CbClsExtra 102 | wc.cbWndExtra = pWndClass.CbWndExtra 103 | wc.hInstance = pWndClass.HInstance 104 | wc.hIcon = pWndClass.HIcon 105 | wc.hCursor = pWndClass.HCursor 106 | wc.hbrBackground = pWndClass.HbrBackground 107 | if _pClassName != nil { 108 | wc.pszMenuName = _pMenuName 109 | } else { 110 | wc.pszMenuName = (*uint16)(unsafe.Pointer(Menu)) 111 | } 112 | wc.pszClassName = _pClassName 113 | wc.hIconSmall = pWndClass.HIconSmall 114 | 115 | r1, _, e1 := syscall.Syscall(procRegisterClass.Addr(), 1, uintptr(unsafe.Pointer(&wc)), 0, 0) 116 | n := uint16(r1) 117 | if n == 0 { 118 | wec := WinErrorCode(e1) 119 | if wec != 0 { 120 | err = wec 121 | } else { 122 | err = errors.New("winapi: RegisterClass failed.") 123 | } 124 | } else { 125 | atom = n 126 | } 127 | return 128 | } 129 | 130 | const ( 131 | MB_OK uint32 = 0x00000000 132 | MB_OKCANCEL uint32 = 0x00000001 133 | MB_ABORTRETRYIGNORE uint32 = 0x00000002 134 | MB_YESNOCANCEL uint32 = 0x00000003 135 | MB_YESNO uint32 = 0x00000004 136 | MB_RETRYCANCEL uint32 = 0x00000005 137 | MB_CANCELTRYCONTINUE uint32 = 0x00000006 138 | MB_HELP uint32 = 0x00004000 139 | 140 | MB_ICONERROR uint32 = 0x00000010 141 | ) 142 | 143 | func MessageBox(hWnd HWND, Text string, Caption string, Type uint32) (ret int32, err error) { 144 | pText, err := syscall.UTF16PtrFromString(Text) 145 | if err != nil { 146 | return 147 | } 148 | pCaption, err := syscall.UTF16PtrFromString(Caption) 149 | if err != nil { 150 | return 151 | } 152 | r1, _, e1 := syscall.Syscall6(procMessageBox.Addr(), 4, 153 | uintptr(hWnd), 154 | uintptr(unsafe.Pointer(pText)), 155 | uintptr(unsafe.Pointer(pCaption)), 156 | uintptr(Type), 157 | 0, 0) 158 | n := int32(r1) 159 | if n == 0 { 160 | if e1 != 0 { 161 | err = error(WinErrorCode(e1)) 162 | } else { 163 | err = errors.New("winapi: MessageBox failed.") 164 | } 165 | } else { 166 | ret = n 167 | } 168 | return 169 | } 170 | 171 | func MustMessageBox(hWnd HWND, Text string, Caption string, Type uint32) (ret int32) { 172 | ret, err := MessageBox(hWnd, Text, Caption, Type) 173 | if err != nil { 174 | panic(err) 175 | } 176 | return 177 | } 178 | 179 | func ErrorBox(err error) error { 180 | var e error 181 | if err == nil { 182 | _, e = MessageBox(0, "", "error", MB_OK) 183 | } else { 184 | _, e = MessageBox(0, err.Error(), "error", MB_OK|MB_ICONERROR) 185 | } 186 | return e 187 | } 188 | 189 | func MustErrorBox(err error) { 190 | if e := ErrorBox(err); e != nil { 191 | panic(e) 192 | } 193 | } 194 | 195 | func ErrorAssert(err error) { 196 | if err != nil { 197 | fmt.Println(err) 198 | panic(err) 199 | } 200 | } 201 | 202 | func WinErrorAssert(err error) { 203 | if err != nil { 204 | MustErrorBox(err) 205 | } 206 | } 207 | 208 | func DefWindowProc(hWnd HWND, message uint32, wParam uintptr, lParam uintptr) uintptr { 209 | ret, _, _ := syscall.Syscall6(procDefWindowProc.Addr(), 4, uintptr(hWnd), uintptr(message), wParam, lParam, 0, 0) 210 | return ret 211 | } 212 | 213 | const CW_USEDEFAULT int32 = ^int32(0x7FFFFFFF) // 0x80000000 214 | 215 | func CreateWindow(ClassName string, WindowName string, Style uint32, ExStyle uint32, 216 | X int32, Y int32, Width int32, Height int32, 217 | WndParent HWND, Menu HMENU, inst HINSTANCE, Param uintptr) (hWnd HWND, err error) { 218 | pClassName, err := syscall.UTF16PtrFromString(ClassName) 219 | if err != nil { 220 | return 221 | } 222 | pWindowName, err := syscall.UTF16PtrFromString(WindowName) 223 | if err != nil { 224 | return 225 | } 226 | r1, _, e1 := syscall.Syscall12(procCreateWindow.Addr(), 12, 227 | uintptr(ExStyle), uintptr(unsafe.Pointer(pClassName)), uintptr(unsafe.Pointer(pWindowName)), uintptr(Style), 228 | uintptr(X), uintptr(Y), uintptr(Width), uintptr(Height), 229 | uintptr(WndParent), uintptr(Menu), uintptr(inst), uintptr(Param)) 230 | if r1 == 0 { 231 | if e1 != 0 { 232 | err = error(e1) 233 | } else { 234 | err = errors.New("winapi: CreateWindow failed.") 235 | } 236 | } else { 237 | hWnd = HWND(r1) 238 | } 239 | return 240 | } 241 | 242 | const ( 243 | SW_HIDE int32 = 0 244 | SW_SHOWNORMAL int32 = 1 245 | SW_NORMAL int32 = 1 246 | SW_SHOWMINIMIZED int32 = 2 247 | SW_SHOWMAXIMIZED int32 = 3 248 | SW_MAXIMIZE int32 = 3 249 | SW_SHOWNOACTIVATE int32 = 4 250 | SW_SHOW int32 = 5 251 | SW_MINIMIZE int32 = 6 252 | SW_SHOWMINNOACTIVE int32 = 7 253 | SW_SHOWNA int32 = 8 254 | SW_RESTORE int32 = 9 255 | SW_SHOWDEFAULT int32 = 10 256 | SW_FORCEMINIMIZE int32 = 11 257 | SW_MAX int32 = 11 258 | ) 259 | 260 | // 返回值:如果窗口事先是可见的,返回true 261 | // 如果窗口事先是隐藏的,返回false 262 | func ShowWindow(hWnd HWND, CmdShow int32) bool { 263 | r1, _, _ := syscall.Syscall(procShowWindow.Addr(), 2, uintptr(hWnd), uintptr(CmdShow), 0) 264 | return r1 != 0 265 | } 266 | 267 | func UpdateWindow(hWnd HWND) error { 268 | r1, _, _ := syscall.Syscall(procUpdateWindow.Addr(), 1, uintptr(hWnd), 0, 0) 269 | if r1 == 0 { 270 | return errors.New("winapi: UpdateWindow failed.") // 该函数没有对应的GetLastError值 271 | } else { 272 | return nil 273 | } 274 | } 275 | 276 | func DestroyWindow(hWnd HWND) (err error) { 277 | r1, _, e1 := syscall.Syscall(procDestroyWindow.Addr(), 1, uintptr(hWnd), 0, 0) 278 | if n := int32(r1); n == 0 { 279 | if e1 != 0 { 280 | err = error(e1) 281 | } else { 282 | err = errors.New("winapi: DestroyWindow failed.") 283 | } 284 | } 285 | return 286 | } 287 | 288 | func _LoadString(Inst HINSTANCE, id uint16, Buffer *uint16, BufferMax int32) (int32, error) { 289 | r1, _, e1 := syscall.Syscall6(procLoadString.Addr(), 4, 290 | uintptr(Inst), uintptr(id), uintptr(unsafe.Pointer(Buffer)), uintptr(BufferMax), 291 | 0, 0) 292 | r := int32(r1) 293 | if r > 0 { 294 | return r, nil 295 | } else { 296 | wec := WinErrorCode(e1) 297 | if wec != 0 { 298 | return 0, wec 299 | } else { 300 | return 0, errors.New("winapi: LoadString failed.") 301 | } 302 | } 303 | } 304 | 305 | func LoadString(hInstance HINSTANCE, id uint16) (string, error) { 306 | var err error 307 | var Len, Len1 int32 308 | var p *uint16 = nil 309 | Len, err = _LoadString(hInstance, id, (*uint16)(unsafe.Pointer(&p)), 0) 310 | 311 | if err == nil && Len > 0 { 312 | Buffer := make([]uint16, Len+1) 313 | Len1, err = _LoadString(hInstance, id, &Buffer[0], Len+1) 314 | if err == nil && Len == Len1 { 315 | Buffer[Len] = 0 316 | return syscall.UTF16ToString(Buffer), nil 317 | } else { 318 | return "", err 319 | } 320 | } else if err != nil { 321 | return "", err 322 | } else { 323 | return "", errors.New("winapi: LoadString failed.") 324 | } 325 | } 326 | 327 | func LoadBitmapById(hInst HINSTANCE, id uint16) (HBITMAP, error) { 328 | r1, _, e1 := syscall.Syscall(procLoadBitmap.Addr(), 2, 329 | uintptr(hInst), MakeIntResource(id), 0) 330 | if r1 != 0 { 331 | return HBITMAP(r1), nil 332 | } else { 333 | wec := WinErrorCode(e1) 334 | if wec != 0 { 335 | return 0, wec 336 | } else { 337 | return 0, errors.New("winapi: LoadBitmapById failed.") 338 | } 339 | } 340 | } 341 | 342 | func LoadBitmapByName(hInst HINSTANCE, Name string) (HBITMAP, error) { 343 | p, err := syscall.UTF16PtrFromString(Name) 344 | if err != nil { 345 | return 0, err 346 | } 347 | r1, _, e1 := syscall.Syscall(procLoadBitmap.Addr(), 2, 348 | uintptr(hInst), uintptr(unsafe.Pointer(p)), 0) 349 | if r1 != 0 { 350 | return HBITMAP(r1), nil 351 | } else { 352 | wec := WinErrorCode(e1) 353 | if wec != 0 { 354 | return 0, wec 355 | } else { 356 | return 0, errors.New("winapi: LoadBitmapByName failed.") 357 | } 358 | } 359 | } 360 | 361 | const ( 362 | IDC_ARROW = 32512 363 | ) 364 | 365 | func LoadCursorById(hinst HINSTANCE, id uint16) (cursor HCURSOR, err error) { 366 | r1, _, e1 := syscall.Syscall(procLoadCursor.Addr(), 2, 367 | uintptr(hinst), MakeIntResource(id), 0) 368 | if r1 == 0 { 369 | wec := WinErrorCode(e1) 370 | if wec != 0 { 371 | err = wec 372 | } else { 373 | err = errors.New("winapi: LoadCursorById failed.") 374 | } 375 | } else { 376 | cursor = HCURSOR(r1) 377 | } 378 | return 379 | } 380 | 381 | func LoadCursorByName(hinst HINSTANCE, name string) (cursor HCURSOR, err error) { 382 | pName, err := syscall.UTF16PtrFromString(name) 383 | if err != nil { 384 | return 385 | } 386 | 387 | r1, _, e1 := syscall.Syscall(procLoadCursor.Addr(), 2, 388 | uintptr(hinst), uintptr(unsafe.Pointer(pName)), 0) 389 | if r1 == 0 { 390 | wec := WinErrorCode(e1) 391 | if wec != 0 { 392 | err = wec 393 | } else { 394 | err = errors.New("winapi: LoadCursorByName failed.") 395 | } 396 | } else { 397 | cursor = HCURSOR(r1) 398 | } 399 | return 400 | } 401 | 402 | func LoadIconById(hinst HINSTANCE, id uint16) (icon HICON, err error) { 403 | r1, _, e1 := syscall.Syscall(procLoadIcon.Addr(), 2, 404 | uintptr(hinst), MakeIntResource(id), 0) 405 | if r1 == 0 { 406 | if e1 != 0 { 407 | err = error(e1) 408 | } else { 409 | err = errors.New("winapi: LoadIconById failed.") 410 | } 411 | } else { 412 | icon = HICON(r1) 413 | } 414 | return 415 | } 416 | 417 | func LoadIconByName(hinst HINSTANCE, name string) (icon HICON, err error) { 418 | pName, err := syscall.UTF16PtrFromString(name) 419 | if err != nil { 420 | return 421 | } 422 | 423 | r1, _, e1 := syscall.Syscall(procLoadIcon.Addr(), 2, 424 | uintptr(hinst), uintptr(unsafe.Pointer(pName)), 0) 425 | if r1 == 0 { 426 | wec := WinErrorCode(e1) 427 | if wec != 0 { 428 | err = wec 429 | } else { 430 | err = errors.New("winapi: LoadIconByName failed.") 431 | } 432 | } else { 433 | icon = HICON(r1) 434 | } 435 | return 436 | } 437 | 438 | const ( // LoadImage函数的uType参数 439 | IMAGE_BITMAP = 0 440 | IMAGE_CURSOR = 2 441 | IMAGE_ICON = 1 442 | ) 443 | 444 | const ( // LoadImage函数的fuLoad参数 445 | LR_CREATEDIBSECTION = 0x00002000 446 | LR_DEFAULTCOLOR = 0x00000000 447 | LR_DEFAULTSIZE = 0x00000040 448 | LR_LOADFROMFILE = 0x00000010 449 | LR_LOADMAP3DCOLORS = 0x00001000 450 | LR_LOADTRANSPARENT = 0x00000020 451 | LR_MONOCHROME = 0x00000001 452 | LR_SHARED = 0x00008000 453 | LR_VGACOLOR = 0x00000080 454 | ) 455 | 456 | func LoadImageById(hinst HINSTANCE, id uint16, Type uint32, 457 | cxDesired int32, cyDesired int32, fLoad uint32) (hImage HANDLE, err error) { 458 | r1, _, e1 := syscall.Syscall6(procLoadImage.Addr(), 6, 459 | uintptr(hinst), 460 | MakeIntResource(id), 461 | uintptr(Type), 462 | uintptr(cxDesired), 463 | uintptr(cyDesired), 464 | uintptr(fLoad)) 465 | if r1 == 0 { 466 | if e1 != 0 { 467 | err = error(e1) 468 | } else { 469 | err = errors.New("winapi: LoadImageById failed.") 470 | } 471 | } else { 472 | hImage = HANDLE(r1) 473 | } 474 | return 475 | } 476 | 477 | func LoadImageByName(hinst HINSTANCE, name string, Type uint32, 478 | cxDesired int32, cyDesired int32, fLoad uint32) (hImage HANDLE, err error) { 479 | pName, err := syscall.UTF16PtrFromString(name) 480 | if err != nil { 481 | return 482 | } 483 | r1, _, e1 := syscall.Syscall6(procLoadImage.Addr(), 6, 484 | uintptr(hinst), 485 | uintptr(unsafe.Pointer(pName)), 486 | uintptr(Type), 487 | uintptr(cxDesired), 488 | uintptr(cyDesired), 489 | uintptr(fLoad)) 490 | if r1 == 0 { 491 | wec := WinErrorCode(e1) 492 | if wec != 0 { 493 | err = wec 494 | } else { 495 | err = errors.New("winapi: LoadImageByName failed.") 496 | } 497 | } else { 498 | hImage = HANDLE(r1) 499 | } 500 | return 501 | } 502 | 503 | const ( 504 | CTLCOLOR_MSGBOX HBRUSH = iota 505 | CTLCOLOR_EDIT 506 | CTLCOLOR_LISTBOX 507 | CTLCOLOR_BTN 508 | CTLCOLOR_DLG 509 | CTLCOLOR_SCROLLBAR 510 | CTLCOLOR_STATIC 511 | CTLCOLOR_MAX 512 | 513 | COLOR_SCROLLBAR HBRUSH = 0 514 | COLOR_BACKGROUND HBRUSH = 1 515 | COLOR_ACTIVECAPTION HBRUSH = 2 516 | COLOR_INACTIVECAPTION HBRUSH = 3 517 | COLOR_MENU HBRUSH = 4 518 | COLOR_WINDOW HBRUSH = 5 519 | COLOR_WINDOWFRAME HBRUSH = 6 520 | COLOR_MENUTEXT HBRUSH = 7 521 | COLOR_WINDOWTEXT HBRUSH = 8 522 | COLOR_CAPTIONTEXT HBRUSH = 9 523 | COLOR_ACTIVEBORDER HBRUSH = 10 524 | COLOR_INACTIVEBORDER HBRUSH = 11 525 | COLOR_APPWORKSPACE HBRUSH = 12 526 | COLOR_HIGHLIGHT HBRUSH = 13 527 | COLOR_HIGHLIGHTTEXT HBRUSH = 14 528 | COLOR_BTNFACE HBRUSH = 15 529 | COLOR_BTNSHADOW HBRUSH = 16 530 | COLOR_GRAYTEXT HBRUSH = 17 531 | COLOR_BTNTEXT HBRUSH = 18 532 | COLOR_INACTIVECAPTIONTEXT HBRUSH = 19 533 | COLOR_BTNHIGHLIGHT HBRUSH = 20 534 | 535 | COLOR_3DDKSHADOW HBRUSH = 21 536 | COLOR_3DLIGHT HBRUSH = 22 537 | COLOR_INFOTEXT HBRUSH = 23 538 | COLOR_INFOBK HBRUSH = 24 539 | 540 | COLOR_HOTLIGHT HBRUSH = 26 // 上一个是24,所以这里不能直接用iota 541 | COLOR_GRADIENTACTIVECAPTION HBRUSH = 27 542 | COLOR_GRADIENTINACTIVECAPTION HBRUSH = 28 543 | COLOR_MENUHILIGHT HBRUSH = 29 544 | COLOR_MENUBAR HBRUSH = 30 545 | 546 | COLOR_DESKTOP = COLOR_BACKGROUND 547 | COLOR_3DFACE = COLOR_BTNFACE 548 | COLOR_3DSHADOW = COLOR_BTNSHADOW 549 | COLOR_3DHIGHLIGHT = COLOR_BTNHIGHLIGHT 550 | COLOR_3DHILIGHT = COLOR_BTNHIGHLIGHT 551 | COLOR_BTNHILIGHT = COLOR_BTNHIGHLIGHT 552 | ) 553 | 554 | /* 555 | * Window Styles 556 | */ 557 | const ( 558 | WS_OVERLAPPED uint32 = 0x00000000 559 | WS_POPUP uint32 = 0x80000000 560 | WS_CHILD uint32 = 0x40000000 561 | WS_MINIMIZE uint32 = 0x20000000 562 | WS_VISIBLE uint32 = 0x10000000 563 | WS_DISABLED uint32 = 0x08000000 564 | WS_CLIPSIBLINGS uint32 = 0x04000000 565 | WS_CLIPCHILDREN uint32 = 0x02000000 566 | WS_MAXIMIZE uint32 = 0x01000000 567 | WS_CAPTION uint32 = 0x00C00000 // WS_BORDER | WS_DLGFRAME 568 | WS_BORDER uint32 = 0x00800000 569 | WS_DLGFRAME uint32 = 0x00400000 570 | WS_VSCROLL uint32 = 0x00200000 571 | WS_HSCROLL uint32 = 0x00100000 572 | WS_SYSMENU uint32 = 0x00080000 573 | WS_THICKFRAME uint32 = 0x00040000 574 | WS_GROUP uint32 = 0x00020000 575 | WS_TABSTOP uint32 = 0x00010000 576 | 577 | WS_MINIMIZEBOX uint32 = 0x00020000 578 | WS_MAXIMIZEBOX uint32 = 0x00010000 579 | 580 | WS_TILED uint32 = WS_OVERLAPPED 581 | WS_ICONIC uint32 = WS_MINIMIZE 582 | WS_SIZEBOX uint32 = WS_THICKFRAME 583 | WS_TILEDWINDOW uint32 = WS_OVERLAPPEDWINDOW 584 | 585 | /* 586 | * Common Window Styles 587 | */ 588 | WS_OVERLAPPEDWINDOW uint32 = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | 589 | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX 590 | 591 | WS_POPUPWINDOW uint32 = WS_POPUP | WS_BORDER | WS_SYSMENU 592 | 593 | WS_CHILDWINDOW uint32 = WS_CHILD 594 | ) 595 | 596 | /* 597 | * Extended Window Styles 598 | */ 599 | const ( 600 | WS_EX_DLGMODALFRAME uint32 = 0x00000001 601 | WS_EX_NOPARENTNOTIFY uint32 = 0x00000004 602 | WS_EX_TOPMOST uint32 = 0x00000008 603 | WS_EX_ACCEPTFILES uint32 = 0x00000010 604 | WS_EX_TRANSPARENT uint32 = 0x00000020 605 | 606 | WS_EX_MDICHILD uint32 = 0x00000040 607 | WS_EX_TOOLWINDOW uint32 = 0x00000080 608 | WS_EX_WINDOWEDGE uint32 = 0x00000100 609 | WS_EX_CLIENTEDGE uint32 = 0x00000200 610 | WS_EX_CONTEXTHELP uint32 = 0x00000400 611 | 612 | WS_EX_RIGHT uint32 = 0x00001000 613 | WS_EX_LEFT uint32 = 0x00000000 614 | WS_EX_RTLREADING uint32 = 0x00002000 615 | WS_EX_LTRREADING uint32 = 0x00000000 616 | WS_EX_LEFTSCROLLBAR uint32 = 0x00004000 617 | WS_EX_RIGHTSCROLLBAR uint32 = 0x00000000 618 | 619 | WS_EX_CONTROLPARENT uint32 = 0x00010000 620 | WS_EX_STATICEDGE uint32 = 0x00020000 621 | WS_EX_APPWINDOW uint32 = 0x00040000 622 | 623 | WS_EX_OVERLAPPEDWINDOW uint32 = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE 624 | WS_EX_PALETTEWINDOW uint32 = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST 625 | 626 | WS_EX_LAYERED uint32 = 0x00080000 627 | 628 | WS_EX_NOINHERITLAYOUT uint32 = 0x00100000 // Disable inheritence of mirroring by children 629 | 630 | WS_EX_NOREDIRECTIONBITMAP uint32 = 0x00200000 631 | 632 | WS_EX_LAYOUTRTL uint32 = 0x00400000 // Right to left mirroring 633 | 634 | WS_EX_COMPOSITED uint32 = 0x02000000 635 | WS_EX_NOACTIVATE uint32 = 0x08000000 636 | ) 637 | -------------------------------------------------------------------------------- /winapi.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | import ( 6 | "syscall" 7 | ) 8 | 9 | var ( 10 | dll_gdi = syscall.NewLazyDLL("gdi32.dll") 11 | 12 | procBitBlt = dll_gdi.NewProc("BitBlt") 13 | procDeleteObject = dll_gdi.NewProc("DeleteObject") 14 | procGetObject = dll_gdi.NewProc("GetObject") 15 | procCreateCompatibleDC = dll_gdi.NewProc("CreateCompatibleDC") 16 | procSelectObject = dll_gdi.NewProc("SelectObject") 17 | procDeleteDC = dll_gdi.NewProc("DeleteDC") 18 | ) 19 | 20 | var ( 21 | dll_kernel = syscall.NewLazyDLL("kernel32.dll") 22 | 23 | procGetLastError = dll_kernel.NewProc("GetLastError") 24 | procExitProcess = dll_kernel.NewProc("ExitProcess") 25 | procCreateFile = dll_kernel.NewProc("CreateFileW") 26 | procReadFile = dll_kernel.NewProc("ReadFile") 27 | procWriteFile = dll_kernel.NewProc("WriteFile") 28 | procSetFilePointer = dll_kernel.NewProc("SetFilePointerEx") 29 | procGetModuleHandle = dll_kernel.NewProc("GetModuleHandleW") 30 | procCloseHandle = dll_kernel.NewProc("CloseHandle") 31 | procFormatMessage = dll_kernel.NewProc("FormatMessageW") 32 | procCreateNamedPipe = dll_kernel.NewProc("CreateNamedPipeW") 33 | procConnectNamedPipe = dll_kernel.NewProc("ConnectNamedPipe") 34 | ) 35 | 36 | var ( 37 | dll_user = syscall.NewLazyDLL("user32.dll") 38 | 39 | procDefWindowProc = dll_user.NewProc("DefWindowProcW") 40 | procGetMessage = dll_user.NewProc("GetMessageW") 41 | procRegisterClass = dll_user.NewProc("RegisterClassExW") 42 | procMessageBox = dll_user.NewProc("MessageBoxW") 43 | procCreateWindow = dll_user.NewProc("CreateWindowExW") 44 | procShowWindow = dll_user.NewProc("ShowWindow") 45 | procUpdateWindow = dll_user.NewProc("UpdateWindow") 46 | procTranslateMessage = dll_user.NewProc("TranslateMessage") 47 | procDispatchMessage = dll_user.NewProc("DispatchMessageW") 48 | procPostQuitMessage = dll_user.NewProc("PostQuitMessage") 49 | procDestroyWindow = dll_user.NewProc("DestroyWindow") 50 | procLoadString = dll_user.NewProc("LoadStringW") 51 | procLoadIcon = dll_user.NewProc("LoadIconW") 52 | procLoadCursor = dll_user.NewProc("LoadCursorW") 53 | procLoadBitmap = dll_user.NewProc("LoadBitmapW") 54 | procLoadImage = dll_user.NewProc("LoadImageW") 55 | procBeginPaint = dll_user.NewProc("BeginPaint") 56 | procEndPaint = dll_user.NewProc("EndPaint") 57 | procRegisterWindowMessage = dll_user.NewProc("RegisterWindowMessageW") 58 | 59 | // 菜单 60 | procAppendMenu = dll_user.NewProc("AppendMenuW") 61 | procCreateMenu = dll_user.NewProc("CreateMenu") 62 | procCreatePopupMenu = dll_user.NewProc("CreatePopupMenu") 63 | procDestroyMenu = dll_user.NewProc("DestroyMenu") 64 | ) 65 | 66 | var ( 67 | dll_comdlg = syscall.NewLazyDLL("comdlg32.dll") 68 | 69 | procGetSaveFileName = dll_comdlg.NewProc("GetSaveFileNameW") 70 | procGetOpenFileName = dll_comdlg.NewProc("GetOpenFileNameW") 71 | procCommDlgExtendedError = dll_comdlg.NewProc("CommDlgExtendedError") 72 | ) 73 | -------------------------------------------------------------------------------- /winnt.go: -------------------------------------------------------------------------------- 1 | //go:build windows 2 | 3 | package winapi 4 | 5 | // The following are masks for the predefined standard access types 6 | const ( 7 | DELETE = 0x00010000 8 | READ_CONTROL = 0x00020000 9 | WRITE_DAC = 0x00040000 10 | WRITE_OWNER = 0x00080000 11 | SYNCHRONIZE = 0x00100000 12 | 13 | STANDARD_RIGHTS_REQUIRED = 0x000F0000 14 | 15 | STANDARD_RIGHTS_READ = READ_CONTROL 16 | STANDARD_RIGHTS_WRITE = READ_CONTROL 17 | STANDARD_RIGHTS_EXECUTE = READ_CONTROL 18 | 19 | STANDARD_RIGHTS_ALL = 0x001F0000 20 | 21 | SPECIFIC_RIGHTS_ALL = 0x0000FFFF 22 | ) 23 | 24 | // 25 | // AccessSystemAcl access type 26 | // 27 | const ACCESS_SYSTEM_SECURITY = 0x01000000 28 | 29 | // 30 | // MaximumAllowed access type 31 | // 32 | const MAXIMUM_ALLOWED = 0x02000000 33 | 34 | // 35 | // These are the generic rights. 36 | // 37 | const ( 38 | GENERIC_READ = 0x80000000 39 | GENERIC_WRITE = 0x40000000 40 | GENERIC_EXECUTE = 0x20000000 41 | GENERIC_ALL = 0x10000000 42 | ) 43 | 44 | const ( 45 | FILE_SHARE_READ = 0x00000001 46 | FILE_SHARE_WRITE = 0x00000002 47 | FILE_SHARE_DELETE = 0x00000004 48 | ) 49 | --------------------------------------------------------------------------------