package win32api import ( "errors" "syscall" "unsafe" ) func Keybd_event(keyname string, keydown bool) error { var key int var down uintptr if !keydown { down = KEYEVENTF_KEYUP } switch keyname { case "shift": key = VK_SHIFT case "lshift": key = VK_LSHIFT case "rshift": key = VK_RSHIFT case "a": key = VK_A } user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) keyevent, err := syscall.GetProcAddress(syscall.Handle(user32), "keybd_event") if err != nil { return errors.New("Can't Load Keybd_event API") } syscall.Syscall6(keyevent, 4, uintptr(key), uintptr(key), down, 0, 0, 0) return nil } func Keybd_event_origin(key, keyenv, down, extra uintptr) error { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) keyevent, err := syscall.GetProcAddress(syscall.Handle(user32), "keybd_event") if err != nil { return errors.New("Can't Load Keybd_event API") } syscall.Syscall6(keyevent, 4, key, keyenv, down, extra, 0, 0) return nil } func OpenClipboard(hWnd HWND) error { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) oc, err := syscall.GetProcAddress(syscall.Handle(user32), "OpenClipboard") if err != nil { return errors.New("Can't Load OpenClipboard API") } if hWnd != 0 { if r, _, errno := syscall.Syscall(oc, 1, uintptr(hWnd), 0, 0); r == 0 { return error(errno) } return nil } if r, _, errno := syscall.Syscall(oc, 1, 0, 0, 0); r == 0 { return error(errno) } return nil } func CloseClipboard() error { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) cc, err := syscall.GetProcAddress(syscall.Handle(user32), "CloseClipboard") if err != nil { return errors.New("Can't Load CloseClipboard API") } if r, _, errno := syscall.Syscall(cc, 0, 0, 0, 0); r == 0 { return error(errno) } return nil } func GetClipboardData(uFormat DWORD) (HGLOBAL, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) gcd, err := syscall.GetProcAddress(syscall.Handle(user32), "GetClipboardData") if err != nil { return 0, errors.New("Can't Load GetClipboardData API") } r, _, errno := syscall.Syscall(gcd, 1, uintptr(uFormat), 0, 0) if r == 0 { return 0, error(errno) } return HGLOBAL(r), nil } func EnumClipboardFormats(uFormat DWORD) (DWORD, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) ecf, err := syscall.GetProcAddress(syscall.Handle(user32), "EnumClipboardFormats") if err != nil { return 0, errors.New("Can't Load EnumClipboardFormats API") } r, _, errno := syscall.Syscall(ecf, 1, uintptr(uFormat), 0, 0) if r == 0 { if errno == 0 { return 0, nil } return 0, error(errno) } return DWORD(r), nil } func EnumAllClipboardFormats() ([]DWORD, error) { var formats []DWORD var current DWORD for { format, err := EnumClipboardFormats(current) if err != nil { return nil, err } if format == 0 { break } formats = append(formats, format) current = format } return formats, nil } func GetClipboardFormatName(uFormat DWORD) (string, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return "", errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) gcfn, err := syscall.GetProcAddress(syscall.Handle(user32), "GetClipboardFormatNameW") if err != nil { return "", errors.New("Can't Load GetClipboardFormatName API") } var buffer [256]uint16 r, _, errno := syscall.Syscall6(gcfn, 3, uintptr(uFormat), uintptr(unsafe.Pointer(&buffer)), uintptr(len(buffer)), 0, 0, 0) if r == 0 { return "", error(errno) } return syscall.UTF16ToString(buffer[:]), nil } func RegisterClipboardFormat(lpszFormat string) DWORD { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0 } defer syscall.FreeLibrary(user32) rcf, err := syscall.GetProcAddress(syscall.Handle(user32), "RegisterClipboardFormatW") if err != nil { return 0 } r, _, _ := syscall.Syscall(rcf, 1, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszFormat))), 0, 0) return DWORD(r) } func EmptyClipboard() error { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) ec, err := syscall.GetProcAddress(syscall.Handle(user32), "EmptyClipboard") if err != nil { return errors.New("Can't Load EmptyClipboard API") } if r, _, errno := syscall.Syscall(ec, 0, 0, 0, 0); r == 0 { return error(errno) } return nil } func CountClipboardFormats() (int, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) ccf, err := syscall.GetProcAddress(syscall.Handle(user32), "CountClipboardFormats") if err != nil { return 0, errors.New("Can't Load CountClipboardFormats API") } r, _, errno := syscall.Syscall(ccf, 0, 0, 0, 0) if r == 0 { if errno == 0 { return 0, nil } return 0, error(errno) } return int(r), nil } func GetClipboardOwner() (HWND, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) gco, err := syscall.GetProcAddress(syscall.Handle(user32), "GetClipboardOwner") if err != nil { return 0, errors.New("Can't Load GetClipboardOwner API") } r, _, errno := syscall.Syscall(gco, 0, 0, 0, 0) if r == 0 { if errno == 0 { return 0, nil } return 0, error(errno) } return HWND(r), nil } func GetUpdatedClipboardFormats(lpuiFormats unsafe.Pointer, cFormats int, pcFormats unsafe.Pointer) (int, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) gucf, err := syscall.GetProcAddress(syscall.Handle(user32), "GetUpdatedClipboardFormats") if err != nil { return 0, errors.New("Can't Load GetUpdatedClipboardFormats API") } r, _, errno := syscall.Syscall(gucf, 3, uintptr(lpuiFormats), uintptr(cFormats), uintptr(pcFormats)) if r == 0 { return 0, error(errno) } return int(r), nil } type updatedClipboardFormatsFunc func(lpuiFormats unsafe.Pointer, cFormats int, pcFormats unsafe.Pointer) (int, error) func getUpdatedClipboardFormatsAll(fetch updatedClipboardFormatsFunc) ([]DWORD, error) { if fetch == nil { fetch = GetUpdatedClipboardFormats } for size := 32; ; { formats := make([]uint32, size) var count uint32 _, err := fetch(unsafe.Pointer(&formats[0]), len(formats), unsafe.Pointer(&count)) if err != nil { if errors.Is(err, syscall.ERROR_INSUFFICIENT_BUFFER) { nextSize := size * 2 if count > uint32(size) { nextSize = int(count) } size = nextSize continue } return nil, err } if count > uint32(len(formats)) { size = int(count) continue } res := make([]DWORD, 0, int(count)) for i := 0; i < int(count); i++ { res = append(res, DWORD(formats[i])) } return res, nil } } func GetUpdatedClipboardFormatsAll() ([]DWORD, error) { return getUpdatedClipboardFormatsAll(GetUpdatedClipboardFormats) } func IsClipboardFormatAvailable(uFormat DWORD) (bool, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return false, err } defer syscall.FreeLibrary(user32) icfa, err := syscall.GetProcAddress(syscall.Handle(user32), "IsClipboardFormatAvailable") if err != nil { return false, err } r, _, _ := syscall.Syscall(icfa, 1, uintptr(uFormat), 0, 0) return r != 0, nil } func AddClipboardFormatListener(hWnd HWND) (bool, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return false, err } defer syscall.FreeLibrary(user32) acfl, err := syscall.GetProcAddress(syscall.Handle(user32), "AddClipboardFormatListener") if err != nil { return false, err } r, _, errno := syscall.Syscall(acfl, 1, uintptr(hWnd), 0, 0) if r == 0 { if errno != 0 { return false, error(errno) } return false, syscall.EINVAL } return true, nil } func RemoveClipboardFormatListener(hWnd HWND) (bool, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return false, err } defer syscall.FreeLibrary(user32) rcfl, err := syscall.GetProcAddress(syscall.Handle(user32), "RemoveClipboardFormatListener") if err != nil { return false, err } r, _, errno := syscall.Syscall(rcfl, 1, uintptr(hWnd), 0, 0) if r == 0 { if errno != 0 { return false, error(errno) } return false, syscall.EINVAL } return true, nil } func SetClipboardData(uFormat DWORD, hMem HGLOBAL) (HGLOBAL, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) scd, err := syscall.GetProcAddress(syscall.Handle(user32), "SetClipboardData") if err != nil { return 0, errors.New("Can't Load SetClipboardData API") } r, _, errno := syscall.Syscall(scd, 2, uintptr(uFormat), uintptr(hMem), 0) if r == 0 { return 0, error(errno) } return HGLOBAL(r), nil } func SetClipboardViewer(hWndNewViewer HWND) (HWND, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) scv, err := syscall.GetProcAddress(syscall.Handle(user32), "SetClipboardViewer") if err != nil { return 0, errors.New("Can't Load SetClipboardViewer API") } r, _, errno := syscall.Syscall(scv, 1, uintptr(hWndNewViewer), 0, 0) if r == 0 { if errno == 0 { return 0, nil } return 0, error(errno) } return HWND(r), nil } func GetClipboardSequenceNumber() (DWORD, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) gcsn, err := syscall.GetProcAddress(syscall.Handle(user32), "GetClipboardSequenceNumber") if err != nil { return 0, errors.New("Can't Load GetClipboardSequenceNumber API") } r, _, errno := syscall.Syscall(gcsn, 0, 0, 0, 0) if r == 0 { return 0, error(errno) } return DWORD(r), nil } func CreateWindowEx(dwExStyle DWORD, lpClassName, lpWindowName string, dwStyle DWORD, x, y, nWidth, nHeight int, hWndParent HWND, hMenu HMENU, hInstance HINSTANCE, lpParam unsafe.Pointer) (HWND, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) cwe, err := syscall.GetProcAddress(syscall.Handle(user32), "CreateWindowExW") if err != nil { return 0, errors.New("Can't Load CreateWindowEx API") } r, _, errno := syscall.Syscall12(cwe, 12, uintptr(dwExStyle), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpClassName))), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpWindowName))), uintptr(dwStyle), uintptr(x), uintptr(y), uintptr(nWidth), uintptr(nHeight), uintptr(hWndParent), uintptr(hMenu), uintptr(hInstance), uintptr(lpParam)) if r == 0 { return 0, error(errno) } return HWND(r), nil } func DestroyWindow(hWnd HWND) (bool, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return false, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) dw, err := syscall.GetProcAddress(syscall.Handle(user32), "DestroyWindow") if err != nil { return false, errors.New("Can't Load DestroyWindow API") } r, _, errno := syscall.Syscall(dw, 1, uintptr(hWnd), 0, 0) if r == 0 { if errno != 0 { return false, error(errno) } return false, syscall.EINVAL } return true, nil } func GetMessage(lpMsg *MSG, hWnd HWND, wMsgFilterMin, wMsgFilterMax DWORD) (DWORD, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, errors.New("Can't Load User32 API") } defer syscall.FreeLibrary(user32) gm, err := syscall.GetProcAddress(syscall.Handle(user32), "GetMessageW") if err != nil { return 0, errors.New("Can't Load GetMessage API") } r, _, errno := syscall.Syscall6(gm, 4, uintptr(unsafe.Pointer(lpMsg)), uintptr(hWnd), uintptr(wMsgFilterMin), uintptr(wMsgFilterMax), 0, 0) if int32(r) == -1 { return 0, error(errno) } return DWORD(r), nil } func TranslateMessage(lpMsg *MSG) (bool, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return false, err } defer syscall.FreeLibrary(user32) proc, err := syscall.GetProcAddress(syscall.Handle(user32), "TranslateMessage") if err != nil { return false, err } r, _, _ := syscall.Syscall(proc, 1, uintptr(unsafe.Pointer(lpMsg)), 0, 0) return r != 0, nil } func DispatchMessage(lpMsg *MSG) (LRESULT, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, err } defer syscall.FreeLibrary(user32) proc, err := syscall.GetProcAddress(syscall.Handle(user32), "DispatchMessageW") if err != nil { return 0, err } r, _, _ := syscall.Syscall(proc, 1, uintptr(unsafe.Pointer(lpMsg)), 0, 0) return LRESULT(r), nil } func DefWindowProc(hWnd HWND, uMsg UINT, wParam WPARAM, lParam LPARAM) LRESULT { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0 } defer syscall.FreeLibrary(user32) proc, err := syscall.GetProcAddress(syscall.Handle(user32), "DefWindowProcW") if err != nil { return 0 } r, _, _ := syscall.Syscall6(proc, 4, uintptr(hWnd), uintptr(uMsg), uintptr(wParam), uintptr(lParam), 0, 0) return LRESULT(r) } func PostMessage(hWnd HWND, msg UINT, wParam WPARAM, lParam LPARAM) (bool, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return false, err } defer syscall.FreeLibrary(user32) proc, err := syscall.GetProcAddress(syscall.Handle(user32), "PostMessageW") if err != nil { return false, err } r, _, errno := syscall.Syscall6(proc, 4, uintptr(hWnd), uintptr(msg), uintptr(wParam), uintptr(lParam), 0, 0) if r == 0 { if errno != 0 { return false, error(errno) } return false, syscall.EINVAL } return true, nil } func PostQuitMessage(nExitCode int) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return } defer syscall.FreeLibrary(user32) proc, err := syscall.GetProcAddress(syscall.Handle(user32), "PostQuitMessage") if err != nil { return } syscall.Syscall(proc, 1, uintptr(nExitCode), 0, 0) } func RegisterClassEx(lpWndClass *WNDCLASSEX) (uint16, error) { user32, err := syscall.LoadLibrary("user32.dll") if err != nil { return 0, err } defer syscall.FreeLibrary(user32) proc, err := syscall.GetProcAddress(syscall.Handle(user32), "RegisterClassExW") if err != nil { return 0, err } r, _, err := syscall.Syscall(proc, 1, uintptr(unsafe.Pointer(lpWndClass)), 0, 0) if r == 0 { return 0, err } return uint16(r), nil } func OpenInputDesktop(dwFlags DWORD, fInherit bool, dwDesiredAccess DWORD) (HDESK, error) { proc, err := getProcAddr("user32.dll", "OpenInputDesktop") if err != nil { return 0, err } inherit := uintptr(0) if fInherit { inherit = 1 } r, _, errno := syscall.Syscall(proc, 3, uintptr(dwFlags), inherit, uintptr(dwDesiredAccess)) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return HDESK(r), nil } func CloseDesktop(hDesktop HDESK) error { proc, err := getProcAddr("user32.dll", "CloseDesktop") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 1, uintptr(hDesktop), 0, 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func SwitchDesktop(hDesktop HDESK) error { proc, err := getProcAddr("user32.dll", "SwitchDesktop") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 1, uintptr(hDesktop), 0, 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func GetThreadDesktop(dwThreadId DWORD) (HDESK, error) { proc, err := getProcAddr("user32.dll", "GetThreadDesktop") if err != nil { return 0, err } r, _, errno := syscall.Syscall(proc, 1, uintptr(dwThreadId), 0, 0) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return HDESK(r), nil } func SetThreadDesktop(hDesktop HDESK) error { proc, err := getProcAddr("user32.dll", "SetThreadDesktop") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 1, uintptr(hDesktop), 0, 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func GetDesktopWindow() HWND { proc, err := getProcAddr("user32.dll", "GetDesktopWindow") if err != nil { return 0 } r, _, _ := syscall.Syscall(proc, 0, 0, 0, 0) return HWND(r) } func GetShellWindow() HWND { proc, err := getProcAddr("user32.dll", "GetShellWindow") if err != nil { return 0 } r, _, _ := syscall.Syscall(proc, 0, 0, 0, 0) return HWND(r) } func GetForegroundWindow() HWND { proc, err := getProcAddr("user32.dll", "GetForegroundWindow") if err != nil { return 0 } r, _, _ := syscall.Syscall(proc, 0, 0, 0, 0) return HWND(r) } func GetWindowThreadProcessId(hWnd HWND) (DWORD, DWORD, error) { proc, err := getProcAddr("user32.dll", "GetWindowThreadProcessId") if err != nil { return 0, 0, err } var processID DWORD r, _, errno := syscall.Syscall(proc, 2, uintptr(hWnd), uintptr(unsafe.Pointer(&processID)), 0) threadID := DWORD(r) if threadID == 0 { if errno != 0 { return 0, processID, error(errno) } return 0, processID, syscall.EINVAL } return threadID, processID, nil } func GetWindowText(hWnd HWND) (string, error) { lenProc, err := getProcAddr("user32.dll", "GetWindowTextLengthW") if err != nil { return "", err } textProc, err := getProcAddr("user32.dll", "GetWindowTextW") if err != nil { return "", err } n, _, _ := syscall.Syscall(lenProc, 1, uintptr(hWnd), 0, 0) size := uint32(n) + 1 if size < 2 { size = 2 } buf := make([]uint16, size) r, _, errno := syscall.Syscall(textProc, 3, uintptr(hWnd), uintptr(unsafe.Pointer(&buf[0])), uintptr(size)) if r == 0 { if errno != 0 { return "", error(errno) } return "", nil } return syscall.UTF16ToString(buf[:r]), nil }