1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105 |
- // Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
- // file at the top-level directory of this distribution and at
- // https://github.com/go-vgo/robotgo/blob/master/LICENSE
- //
- // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
- // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
- // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
- // option. This file may not be copied, modified, or distributed
- // except according to those terms.
- /*
- Package robotgo Go native cross-platform system automation.
- Please make sure Golang, GCC is installed correctly before installing RobotGo;
- See Requirements:
- https://github.com/go-vgo/robotgo#requirements
- Installation:
- With Go module support (Go 1.11+), just import:
- import "github.com/go-vgo/robotgo"
- Otherwise, to install the robotgo package, run the command:
- go get -u github.com/go-vgo/robotgo
- */
- package robotgo
- /*
- #cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations
- #cgo darwin LDFLAGS: -framework Cocoa -framework OpenGL -framework IOKit
- #cgo darwin LDFLAGS: -framework Carbon -framework CoreFoundation
- //
- #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > MAC_OS_VERSION_14_4
- #cgo darwin LDFLAGS: -framework ScreenCaptureKit
- #endif
- #cgo linux CFLAGS: -I/usr/src
- #cgo linux LDFLAGS: -L/usr/src -lm -lX11 -lXtst
- #cgo windows LDFLAGS: -lgdi32 -luser32
- //
- #include "screen/goScreen.h"
- #include "mouse/mouse_c.h"
- #include "window/goWindow.h"
- */
- import "C"
- import (
- "errors"
- "image"
- "runtime"
- "time"
- "unsafe"
- "github.com/vcaesar/tt"
- )
- const (
- // Version get the robotgo version
- Version = "v1.00.0.1189, MT. Baker!"
- )
- // GetVersion get the robotgo version
- func GetVersion() string {
- return Version
- }
- var (
- // MouseSleep set the mouse default millisecond sleep time
- MouseSleep = 0
- // KeySleep set the key default millisecond sleep time
- KeySleep = 0
- // DisplayID set the screen display id
- DisplayID = -1
- // NotPid used the hwnd not pid in windows
- NotPid bool
- // Scale option the os screen scale
- Scale bool
- )
- type (
- // Map a map[string]interface{}
- Map map[string]interface{}
- // CHex define CHex as c rgb Hex type (C.MMRGBHex)
- CHex C.MMRGBHex
- // CBitmap define CBitmap as C.MMBitmapRef type
- CBitmap C.MMBitmapRef
- // Handle define window Handle as C.MData type
- Handle C.MData
- )
- // Bitmap define the go Bitmap struct
- //
- // The common type conversion of bitmap:
- //
- // https://github.com/go-vgo/robotgo/blob/master/docs/keys.md#type-conversion
- type Bitmap struct {
- ImgBuf *uint8
- Width, Height int
- Bytewidth int
- BitsPixel uint8
- BytesPerPixel uint8
- }
- // Point is point struct
- type Point struct {
- X int
- Y int
- }
- // Size is size structure
- type Size struct {
- W, H int
- }
- // Rect is rect structure
- type Rect struct {
- Point
- Size
- }
- // Try handler(err)
- func Try(fun func(), handler func(interface{})) {
- defer func() {
- if err := recover(); err != nil {
- handler(err)
- }
- }()
- fun()
- }
- // MilliSleep sleep tm milli second
- func MilliSleep(tm int) {
- time.Sleep(time.Duration(tm) * time.Millisecond)
- }
- // Sleep time.Sleep tm second
- func Sleep(tm int) {
- time.Sleep(time.Duration(tm) * time.Second)
- }
- // Deprecated: use the MilliSleep(),
- //
- // MicroSleep time C.microsleep(tm)
- func MicroSleep(tm float64) {
- C.microsleep(C.double(tm))
- }
- // GoString trans C.char to string
- func GoString(char *C.char) string {
- return C.GoString(char)
- }
- /*
- _______. ______ .______ _______ _______ .__ __.
- / | / || _ \ | ____|| ____|| \ | |
- | (----`| ,----'| |_) | | |__ | |__ | \| |
- \ \ | | | / | __| | __| | . ` |
- .----) | | `----.| |\ \----.| |____ | |____ | |\ |
- |_______/ \______|| _| `._____||_______||_______||__| \__|
- */
- // ToMMRGBHex trans CHex to C.MMRGBHex
- func ToMMRGBHex(hex CHex) C.MMRGBHex {
- return C.MMRGBHex(hex)
- }
- // UintToHex trans uint32 to robotgo.CHex
- func UintToHex(u uint32) CHex {
- hex := U32ToHex(C.uint32_t(u))
- return CHex(hex)
- }
- // U32ToHex trans C.uint32_t to C.MMRGBHex
- func U32ToHex(hex C.uint32_t) C.MMRGBHex {
- return C.MMRGBHex(hex)
- }
- // U8ToHex trans *C.uint8_t to C.MMRGBHex
- func U8ToHex(hex *C.uint8_t) C.MMRGBHex {
- return C.MMRGBHex(*hex)
- }
- // PadHex trans C.MMRGBHex to string
- func PadHex(hex C.MMRGBHex) string {
- color := C.pad_hex(hex)
- gcolor := C.GoString(color)
- C.free(unsafe.Pointer(color))
- return gcolor
- }
- // PadHexs trans CHex to string
- func PadHexs(hex CHex) string {
- return PadHex(C.MMRGBHex(hex))
- }
- // HexToRgb trans hex to rgb
- func HexToRgb(hex uint32) *C.uint8_t {
- return C.color_hex_to_rgb(C.uint32_t(hex))
- }
- // RgbToHex trans rgb to hex
- func RgbToHex(r, g, b uint8) C.uint32_t {
- return C.color_rgb_to_hex(C.uint8_t(r), C.uint8_t(g), C.uint8_t(b))
- }
- // GetPxColor get the pixel color return C.MMRGBHex
- func GetPxColor(x, y int, displayId ...int) C.MMRGBHex {
- cx := C.int32_t(x)
- cy := C.int32_t(y)
- display := displayIdx(displayId...)
- color := C.get_px_color(cx, cy, C.int32_t(display))
- return color
- }
- // GetPixelColor get the pixel color return string
- func GetPixelColor(x, y int, displayId ...int) string {
- return PadHex(GetPxColor(x, y, displayId...))
- }
- // GetLocationColor get the location pos's color
- func GetLocationColor(displayId ...int) string {
- x, y := Location()
- return GetPixelColor(x, y, displayId...)
- }
- // IsMain is main display
- func IsMain(displayId int) bool {
- return displayId == GetMainId()
- }
- func displayIdx(id ...int) int {
- display := -1
- if DisplayID != -1 {
- display = DisplayID
- }
- if len(id) > 0 {
- display = id[0]
- }
- return display
- }
- func getNumDisplays() int {
- return int(C.get_num_displays())
- }
- // GetHWNDByPid get the hwnd by pid
- func GetHWNDByPid(pid int) int {
- return int(C.get_hwnd_by_pid(C.uintptr(pid)))
- }
- // SysScale get the sys scale
- func SysScale(displayId ...int) float64 {
- display := displayIdx(displayId...)
- s := C.sys_scale(C.int32_t(display))
- return float64(s)
- }
- // Scaled get the screen scaled return scale size
- func Scaled(x int, displayId ...int) int {
- f := ScaleF(displayId...)
- return Scaled0(x, f)
- }
- // Scaled0 return int(x * f)
- func Scaled0(x int, f float64) int {
- return int(float64(x) * f)
- }
- // Scaled1 return int(x / f)
- func Scaled1(x int, f float64) int {
- return int(float64(x) / f)
- }
- // GetScreenSize get the screen size
- func GetScreenSize() (int, int) {
- size := C.getMainDisplaySize()
- return int(size.w), int(size.h)
- }
- // GetScreenRect get the screen rect (x, y, w, h)
- func GetScreenRect(displayId ...int) Rect {
- display := -1
- if len(displayId) > 0 {
- display = displayId[0]
- }
- rect := C.getScreenRect(C.int32_t(display))
- x, y, w, h := int(rect.origin.x), int(rect.origin.y),
- int(rect.size.w), int(rect.size.h)
- if runtime.GOOS == "windows" {
- // f := ScaleF(displayId...)
- f := ScaleF()
- x, y, w, h = Scaled0(x, f), Scaled0(y, f), Scaled0(w, f), Scaled0(h, f)
- }
- return Rect{
- Point{X: x, Y: y},
- Size{W: w, H: h},
- }
- }
- // GetScaleSize get the screen scale size
- func GetScaleSize(displayId ...int) (int, int) {
- x, y := GetScreenSize()
- f := ScaleF(displayId...)
- return int(float64(x) * f), int(float64(y) * f)
- }
- // CaptureScreen capture the screen return bitmap(c struct),
- // use `defer robotgo.FreeBitmap(bitmap)` to free the bitmap
- //
- // robotgo.CaptureScreen(x, y, w, h int)
- func CaptureScreen(args ...int) CBitmap {
- var x, y, w, h C.int32_t
- displayId := -1
- if DisplayID != -1 {
- displayId = DisplayID
- }
- if len(args) > 4 {
- displayId = args[4]
- }
- if len(args) > 3 {
- x = C.int32_t(args[0])
- y = C.int32_t(args[1])
- w = C.int32_t(args[2])
- h = C.int32_t(args[3])
- } else {
- // Get the main screen rect.
- rect := GetScreenRect(displayId)
- if runtime.GOOS == "windows" {
- x = C.int32_t(rect.X)
- y = C.int32_t(rect.Y)
- }
- w = C.int32_t(rect.W)
- h = C.int32_t(rect.H)
- }
- isPid := 0
- if NotPid || len(args) > 5 {
- isPid = 1
- }
- bit := C.capture_screen(x, y, w, h, C.int32_t(displayId), C.int8_t(isPid))
- return CBitmap(bit)
- }
- // CaptureGo capture the screen and return bitmap(go struct)
- func CaptureGo(args ...int) Bitmap {
- bit := CaptureScreen(args...)
- defer FreeBitmap(bit)
- return ToBitmap(bit)
- }
- // CaptureImg capture the screen and return image.Image, error
- func CaptureImg(args ...int) (image.Image, error) {
- bit := CaptureScreen(args...)
- if bit == nil {
- return nil, errors.New("Capture image not found.")
- }
- defer FreeBitmap(bit)
- return ToImage(bit), nil
- }
- // FreeBitmap free and dealloc the C bitmap
- func FreeBitmap(bitmap CBitmap) {
- // C.destroyMMBitmap(bitmap)
- C.bitmap_dealloc(C.MMBitmapRef(bitmap))
- }
- // FreeBitmapArr free and dealloc the C bitmap array
- func FreeBitmapArr(bit ...CBitmap) {
- for i := 0; i < len(bit); i++ {
- FreeBitmap(bit[i])
- }
- }
- // ToMMBitmapRef trans CBitmap to C.MMBitmapRef
- func ToMMBitmapRef(bit CBitmap) C.MMBitmapRef {
- return C.MMBitmapRef(bit)
- }
- // ToBitmap trans C.MMBitmapRef to Bitmap
- func ToBitmap(bit CBitmap) Bitmap {
- bitmap := Bitmap{
- ImgBuf: (*uint8)(bit.imageBuffer),
- Width: int(bit.width),
- Height: int(bit.height),
- Bytewidth: int(bit.bytewidth),
- BitsPixel: uint8(bit.bitsPerPixel),
- BytesPerPixel: uint8(bit.bytesPerPixel),
- }
- return bitmap
- }
- // ToCBitmap trans Bitmap to C.MMBitmapRef
- func ToCBitmap(bit Bitmap) CBitmap {
- cbitmap := C.createMMBitmap_c(
- (*C.uint8_t)(bit.ImgBuf),
- C.int32_t(bit.Width),
- C.int32_t(bit.Height),
- C.int32_t(bit.Bytewidth),
- C.uint8_t(bit.BitsPixel),
- C.uint8_t(bit.BytesPerPixel),
- )
- return CBitmap(cbitmap)
- }
- // ToImage convert C.MMBitmapRef to standard image.Image
- func ToImage(bit CBitmap) image.Image {
- return ToRGBA(bit)
- }
- // ToRGBA convert C.MMBitmapRef to standard image.RGBA
- func ToRGBA(bit CBitmap) *image.RGBA {
- bmp1 := ToBitmap(bit)
- return ToRGBAGo(bmp1)
- }
- // ImgToCBitmap trans image.Image to CBitmap
- func ImgToCBitmap(img image.Image) CBitmap {
- return ToCBitmap(ImgToBitmap(img))
- }
- // ByteToCBitmap trans []byte to CBitmap
- func ByteToCBitmap(by []byte) CBitmap {
- img, _ := ByteToImg(by)
- return ImgToCBitmap(img)
- }
- // SetXDisplayName set XDisplay name (Linux)
- func SetXDisplayName(name string) error {
- cname := C.CString(name)
- str := C.set_XDisplay_name(cname)
- C.free(unsafe.Pointer(cname))
- return toErr(str)
- }
- // GetXDisplayName get XDisplay name (Linux)
- func GetXDisplayName() string {
- name := C.get_XDisplay_name()
- gname := C.GoString(name)
- C.free(unsafe.Pointer(name))
- return gname
- }
- // CloseMainDisplay close the main X11 display
- func CloseMainDisplay() {
- C.close_main_display()
- }
- // Deprecated: use the ScaledF(),
- //
- // ScaleX get the primary display horizontal DPI scale factor, drop
- func ScaleX() int {
- return int(C.scaleX())
- }
- /*
- .___ ___. ______ __ __ _______. _______
- | \/ | / __ \ | | | | / || ____|
- | \ / | | | | | | | | | | (----`| |__
- | |\/| | | | | | | | | | \ \ | __|
- | | | | | `--' | | `--' | .----) | | |____
- |__| |__| \______/ \______/ |_______/ |_______|
- */
- // CheckMouse check the mouse button
- func CheckMouse(btn string) C.MMMouseButton {
- // button = args[0].(C.MMMouseButton)
- m1 := map[string]C.MMMouseButton{
- "left": C.LEFT_BUTTON,
- "center": C.CENTER_BUTTON,
- "right": C.RIGHT_BUTTON,
- "wheelDown": C.WheelDown,
- "wheelUp": C.WheelUp,
- "wheelLeft": C.WheelLeft,
- "wheelRight": C.WheelRight,
- }
- if v, ok := m1[btn]; ok {
- return v
- }
- return C.LEFT_BUTTON
- }
- // MoveScale calculate the os scale factor x, y
- func MoveScale(x, y int, displayId ...int) (int, int) {
- if Scale && runtime.GOOS == "windows" {
- f := ScaleF()
- x, y = Scaled1(x, f), Scaled1(y, f)
- }
- return x, y
- }
- // Move move the mouse to (x, y)
- //
- // Examples:
- //
- // robotgo.MouseSleep = 100 // 100 millisecond
- // robotgo.Move(10, 10)
- func Move(x, y int, displayId ...int) {
- x, y = MoveScale(x, y, displayId...)
- cx := C.int32_t(x)
- cy := C.int32_t(y)
- C.moveMouse(C.MMPointInt32Make(cx, cy))
- MilliSleep(MouseSleep)
- }
- // Deprecated: use the DragSmooth(),
- //
- // Drag drag the mouse to (x, y),
- // It's not valid now, use the DragSmooth()
- func Drag(x, y int, args ...string) {
- x, y = MoveScale(x, y)
- var button C.MMMouseButton = C.LEFT_BUTTON
- cx := C.int32_t(x)
- cy := C.int32_t(y)
- if len(args) > 0 {
- button = CheckMouse(args[0])
- }
- C.dragMouse(C.MMPointInt32Make(cx, cy), button)
- MilliSleep(MouseSleep)
- }
- // DragSmooth drag the mouse like smooth to (x, y)
- //
- // Examples:
- //
- // robotgo.DragSmooth(10, 10)
- func DragSmooth(x, y int, args ...interface{}) {
- Toggle("left")
- MilliSleep(50)
- MoveSmooth(x, y, args...)
- Toggle("left", "up")
- }
- // MoveSmooth move the mouse smooth,
- // moves mouse to x, y human like, with the mouse button up.
- //
- // robotgo.MoveSmooth(x, y int, low, high float64, mouseDelay int)
- //
- // Examples:
- //
- // robotgo.MoveSmooth(10, 10)
- // robotgo.MoveSmooth(10, 10, 1.0, 2.0)
- func MoveSmooth(x, y int, args ...interface{}) bool {
- // if runtime.GOOS == "windows" {
- // f := ScaleF()
- // x, y = Scaled0(x, f), Scaled0(y, f)
- // }
- x, y = MoveScale(x, y)
- cx := C.int32_t(x)
- cy := C.int32_t(y)
- var (
- mouseDelay = 1
- low C.double
- high C.double
- )
- if len(args) > 2 {
- mouseDelay = args[2].(int)
- }
- if len(args) > 1 {
- low = C.double(args[0].(float64))
- high = C.double(args[1].(float64))
- } else {
- low = 1.0
- high = 3.0
- }
- cbool := C.smoothlyMoveMouse(C.MMPointInt32Make(cx, cy), low, high)
- MilliSleep(MouseSleep + mouseDelay)
- return bool(cbool)
- }
- // MoveArgs get the mouse relative args
- func MoveArgs(x, y int) (int, int) {
- mx, my := Location()
- mx = mx + x
- my = my + y
- return mx, my
- }
- // MoveRelative move mouse with relative
- func MoveRelative(x, y int) {
- Move(MoveArgs(x, y))
- }
- // MoveSmoothRelative move mouse smooth with relative
- func MoveSmoothRelative(x, y int, args ...interface{}) {
- mx, my := MoveArgs(x, y)
- MoveSmooth(mx, my, args...)
- }
- // Location get the mouse location position return x, y
- func Location() (int, int) {
- pos := C.location()
- x := int(pos.x)
- y := int(pos.y)
- if runtime.GOOS == "windows" {
- f := ScaleF()
- x, y = Scaled0(x, f), Scaled0(y, f)
- }
- return x, y
- }
- // Click click the mouse button
- //
- // robotgo.Click(button string, double bool)
- //
- // Examples:
- //
- // robotgo.Click() // default is left button
- // robotgo.Click("right")
- // robotgo.Click("wheelLeft")
- func Click(args ...interface{}) {
- var (
- button C.MMMouseButton = C.LEFT_BUTTON
- double bool
- )
- if len(args) > 0 {
- button = CheckMouse(args[0].(string))
- }
- if len(args) > 1 {
- double = args[1].(bool)
- }
- if !double {
- C.clickMouse(button)
- } else {
- C.doubleClick(button)
- }
- MilliSleep(MouseSleep)
- }
- // MoveClick move and click the mouse
- //
- // robotgo.MoveClick(x, y int, button string, double bool)
- //
- // Examples:
- //
- // robotgo.MouseSleep = 100
- // robotgo.MoveClick(10, 10)
- func MoveClick(x, y int, args ...interface{}) {
- Move(x, y)
- MilliSleep(50)
- Click(args...)
- }
- // MovesClick move smooth and click the mouse
- //
- // use the `robotgo.MouseSleep = 100`
- func MovesClick(x, y int, args ...interface{}) {
- MoveSmooth(x, y)
- MilliSleep(50)
- Click(args...)
- }
- // Toggle toggle the mouse, support button:
- //
- // "left", "center", "right",
- // "wheelDown", "wheelUp", "wheelLeft", "wheelRight"
- //
- // Examples:
- //
- // robotgo.Toggle("left") // default is down
- // robotgo.Toggle("left", "up")
- func Toggle(key ...interface{}) error {
- var button C.MMMouseButton = C.LEFT_BUTTON
- if len(key) > 0 {
- button = CheckMouse(key[0].(string))
- }
- down := true
- if len(key) > 1 && key[1].(string) == "up" {
- down = false
- }
- C.toggleMouse(C.bool(down), button)
- if len(key) > 2 {
- MilliSleep(MouseSleep)
- }
- return nil
- }
- // MouseDown send mouse down event
- func MouseDown(key ...interface{}) error {
- return Toggle(key...)
- }
- // MouseUp send mouse up event
- func MouseUp(key ...interface{}) error {
- if len(key) <= 0 {
- key = append(key, "left")
- }
- return Toggle(append(key, "up")...)
- }
- // Scroll scroll the mouse to (x, y)
- //
- // robotgo.Scroll(x, y, msDelay int)
- //
- // Examples:
- //
- // robotgo.Scroll(10, 10)
- func Scroll(x, y int, args ...int) {
- var msDelay = 10
- if len(args) > 0 {
- msDelay = args[0]
- }
- cx := C.int(x)
- cy := C.int(y)
- C.scrollMouseXY(cx, cy)
- MilliSleep(MouseSleep + msDelay)
- }
- // ScrollDir scroll the mouse with direction to (x, "up")
- // supported: "up", "down", "left", "right"
- //
- // Examples:
- //
- // robotgo.ScrollDir(10, "down")
- // robotgo.ScrollDir(10, "up")
- func ScrollDir(x int, direction ...interface{}) {
- d := "down"
- if len(direction) > 0 {
- d = direction[0].(string)
- }
- if d == "down" {
- Scroll(0, -x)
- }
- if d == "up" {
- Scroll(0, x)
- }
- if d == "left" {
- Scroll(x, 0)
- }
- if d == "right" {
- Scroll(-x, 0)
- }
- // MilliSleep(MouseSleep)
- }
- // ScrollSmooth scroll the mouse smooth,
- // default scroll 5 times and sleep 100 millisecond
- //
- // robotgo.ScrollSmooth(toy, num, sleep, tox)
- //
- // Examples:
- //
- // robotgo.ScrollSmooth(-10)
- // robotgo.ScrollSmooth(-10, 6, 200, -10)
- func ScrollSmooth(to int, args ...int) {
- i := 0
- num := 5
- if len(args) > 0 {
- num = args[0]
- }
- tm := 100
- if len(args) > 1 {
- tm = args[1]
- }
- tox := 0
- if len(args) > 2 {
- tox = args[2]
- }
- for {
- Scroll(tox, to)
- MilliSleep(tm)
- i++
- if i == num {
- break
- }
- }
- MilliSleep(MouseSleep)
- }
- // ScrollRelative scroll mouse with relative
- //
- // Examples:
- //
- // robotgo.ScrollRelative(10, 10)
- func ScrollRelative(x, y int, args ...int) {
- mx, my := MoveArgs(x, y)
- Scroll(mx, my, args...)
- }
- /*
- ____ __ ____ __ .__ __. _______ ______ ____ __ ____
- \ \ / \ / / | | | \ | | | \ / __ \ \ \ / \ / /
- \ \/ \/ / | | | \| | | .--. | | | | \ \/ \/ /
- \ / | | | . ` | | | | | | | | \ /
- \ /\ / | | | |\ | | '--' | `--' | \ /\ /
- \__/ \__/ |__| |__| \__| |_______/ \______/ \__/ \__/
- */
- func alertArgs(args ...string) (string, string) {
- var (
- defaultBtn = "Ok"
- cancelBtn = "Cancel"
- )
- if len(args) > 0 {
- defaultBtn = args[0]
- }
- if len(args) > 1 {
- cancelBtn = args[1]
- }
- return defaultBtn, cancelBtn
- }
- func showAlert(title, msg string, args ...string) bool {
- defaultBtn, cancelBtn := alertArgs(args...)
- cTitle := C.CString(title)
- cMsg := C.CString(msg)
- defaultButton := C.CString(defaultBtn)
- cancelButton := C.CString(cancelBtn)
- cbool := C.showAlert(cTitle, cMsg, defaultButton, cancelButton)
- ibool := int(cbool)
- C.free(unsafe.Pointer(cTitle))
- C.free(unsafe.Pointer(cMsg))
- C.free(unsafe.Pointer(defaultButton))
- C.free(unsafe.Pointer(cancelButton))
- return ibool == 0
- }
- // IsValid valid the window
- func IsValid() bool {
- abool := C.is_valid()
- gbool := bool(abool)
- return gbool
- }
- // SetActive set the window active
- func SetActive(win Handle) {
- SetActiveC(C.MData(win))
- }
- // SetActiveC set the window active
- func SetActiveC(win C.MData) {
- C.set_active(win)
- }
- // GetActive get the active window
- func GetActive() Handle {
- return Handle(GetActiveC())
- }
- // GetActiveC get the active window
- func GetActiveC() C.MData {
- mdata := C.get_active()
- // fmt.Println("active----", mdata)
- return mdata
- }
- // MinWindow set the window min
- func MinWindow(pid int, args ...interface{}) {
- var (
- state = true
- isPid int
- )
- if len(args) > 0 {
- state = args[0].(bool)
- }
- if len(args) > 1 || NotPid {
- isPid = 1
- }
- C.min_window(C.uintptr(pid), C.bool(state), C.int8_t(isPid))
- }
- // MaxWindow set the window max
- func MaxWindow(pid int, args ...interface{}) {
- var (
- state = true
- isPid int
- )
- if len(args) > 0 {
- state = args[0].(bool)
- }
- if len(args) > 1 || NotPid {
- isPid = 1
- }
- C.max_window(C.uintptr(pid), C.bool(state), C.int8_t(isPid))
- }
- // CloseWindow close the window
- func CloseWindow(args ...int) {
- if len(args) <= 0 {
- C.close_main_window()
- return
- }
- var pid, isPid int
- if len(args) > 0 {
- pid = args[0]
- }
- if len(args) > 1 || NotPid {
- isPid = 1
- }
- C.close_window_by_PId(C.uintptr(pid), C.int8_t(isPid))
- }
- // SetHandle set the window handle
- func SetHandle(hwnd int) {
- chwnd := C.uintptr(hwnd)
- C.setHandle(chwnd)
- }
- // SetHandlePid set the window handle by pid
- func SetHandlePid(pid int, args ...int) {
- var isPid int
- if len(args) > 0 || NotPid {
- isPid = 1
- }
- C.set_handle_pid_mData(C.uintptr(pid), C.int8_t(isPid))
- }
- // GetHandById get handle mdata by id
- func GetHandById(id int, args ...int) Handle {
- isPid := 1
- if len(args) > 0 {
- isPid = args[0]
- }
- return GetHandByPid(id, isPid)
- }
- // GetHandByPid get handle mdata by pid
- func GetHandByPid(pid int, args ...int) Handle {
- return Handle(GetHandByPidC(pid, args...))
- }
- // Deprecated: use the GetHandByPid(),
- //
- // GetHandPid get handle mdata by pid
- func GetHandPid(pid int, args ...int) Handle {
- return GetHandByPid(pid, args...)
- }
- // GetHandByPidC get handle mdata by pid
- func GetHandByPidC(pid int, args ...int) C.MData {
- var isPid int
- if len(args) > 0 || NotPid {
- isPid = 1
- }
- return C.set_handle_pid(C.uintptr(pid), C.int8_t(isPid))
- }
- // GetHandle get the window handle
- func GetHandle() int {
- hwnd := C.get_handle()
- ghwnd := int(hwnd)
- // fmt.Println("gethwnd---", ghwnd)
- return ghwnd
- }
- // Deprecated: use the GetHandle(),
- //
- // # GetBHandle get the window handle, Wno-deprecated
- //
- // This function will be removed in version v1.0.0
- func GetBHandle() int {
- tt.Drop("GetBHandle", "GetHandle")
- hwnd := C.b_get_handle()
- ghwnd := int(hwnd)
- //fmt.Println("gethwnd---", ghwnd)
- return ghwnd
- }
- func cgetTitle(pid, isPid int) string {
- title := C.get_title_by_pid(C.uintptr(pid), C.int8_t(isPid))
- gtitle := C.GoString(title)
- return gtitle
- }
- // GetTitle get the window title return string
- //
- // Examples:
- //
- // fmt.Println(robotgo.GetTitle())
- //
- // ids, _ := robotgo.FindIds()
- // robotgo.GetTitle(ids[0])
- func GetTitle(args ...int) string {
- if len(args) <= 0 {
- title := C.get_main_title()
- gtitle := C.GoString(title)
- return gtitle
- }
- if len(args) > 1 {
- return internalGetTitle(args[0], args[1])
- }
- return internalGetTitle(args[0])
- }
- // GetPid get the process id return int32
- func GetPid() int {
- pid := C.get_PID()
- return int(pid)
- }
- // internalGetBounds get the window bounds
- func internalGetBounds(pid, isPid int) (int, int, int, int) {
- bounds := C.get_bounds(C.uintptr(pid), C.int8_t(isPid))
- return int(bounds.X), int(bounds.Y), int(bounds.W), int(bounds.H)
- }
- // internalGetClient get the window client bounds
- func internalGetClient(pid, isPid int) (int, int, int, int) {
- bounds := C.get_client(C.uintptr(pid), C.int8_t(isPid))
- return int(bounds.X), int(bounds.Y), int(bounds.W), int(bounds.H)
- }
- // Is64Bit determine whether the sys is 64bit
- func Is64Bit() bool {
- b := C.Is64Bit()
- return bool(b)
- }
- func internalActive(pid, isPid int) {
- C.active_PID(C.uintptr(pid), C.int8_t(isPid))
- }
- // ActivePid active the window by Pid,
- // If args[0] > 0 on the Windows platform via a window handle to active
- // func ActivePid(pid int32, args ...int) {
- // var isPid int
- // if len(args) > 0 {
- // isPid = args[0]
- // }
- // C.active_PID(C.uintptr(pid), C.uintptr(isPid))
- // }
- // ActiveName active the window by name
- //
- // Examples:
- //
- // robotgo.ActiveName("chrome")
- func ActiveName(name string) error {
- pids, err := FindIds(name)
- if err == nil && len(pids) > 0 {
- return ActivePid(pids[0])
- }
- return err
- }
|