├── .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 |
--------------------------------------------------------------------------------