robotgo.go 23 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105
  1. // Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // https://github.com/go-vgo/robotgo/blob/master/LICENSE
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. /*
  11. Package robotgo Go native cross-platform system automation.
  12. Please make sure Golang, GCC is installed correctly before installing RobotGo;
  13. See Requirements:
  14. https://github.com/go-vgo/robotgo#requirements
  15. Installation:
  16. With Go module support (Go 1.11+), just import:
  17. import "github.com/go-vgo/robotgo"
  18. Otherwise, to install the robotgo package, run the command:
  19. go get -u github.com/go-vgo/robotgo
  20. */
  21. package robotgo
  22. /*
  23. #cgo darwin CFLAGS: -x objective-c -Wno-deprecated-declarations
  24. #cgo darwin LDFLAGS: -framework Cocoa -framework OpenGL -framework IOKit
  25. #cgo darwin LDFLAGS: -framework Carbon -framework CoreFoundation
  26. //
  27. #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > MAC_OS_VERSION_14_4
  28. #cgo darwin LDFLAGS: -framework ScreenCaptureKit
  29. #endif
  30. #cgo linux CFLAGS: -I/usr/src
  31. #cgo linux LDFLAGS: -L/usr/src -lm -lX11 -lXtst
  32. #cgo windows LDFLAGS: -lgdi32 -luser32
  33. //
  34. #include "screen/goScreen.h"
  35. #include "mouse/mouse_c.h"
  36. #include "window/goWindow.h"
  37. */
  38. import "C"
  39. import (
  40. "errors"
  41. "image"
  42. "runtime"
  43. "time"
  44. "unsafe"
  45. "github.com/vcaesar/tt"
  46. )
  47. const (
  48. // Version get the robotgo version
  49. Version = "v1.00.0.1189, MT. Baker!"
  50. )
  51. // GetVersion get the robotgo version
  52. func GetVersion() string {
  53. return Version
  54. }
  55. var (
  56. // MouseSleep set the mouse default millisecond sleep time
  57. MouseSleep = 0
  58. // KeySleep set the key default millisecond sleep time
  59. KeySleep = 0
  60. // DisplayID set the screen display id
  61. DisplayID = -1
  62. // NotPid used the hwnd not pid in windows
  63. NotPid bool
  64. // Scale option the os screen scale
  65. Scale bool
  66. )
  67. type (
  68. // Map a map[string]interface{}
  69. Map map[string]interface{}
  70. // CHex define CHex as c rgb Hex type (C.MMRGBHex)
  71. CHex C.MMRGBHex
  72. // CBitmap define CBitmap as C.MMBitmapRef type
  73. CBitmap C.MMBitmapRef
  74. // Handle define window Handle as C.MData type
  75. Handle C.MData
  76. )
  77. // Bitmap define the go Bitmap struct
  78. //
  79. // The common type conversion of bitmap:
  80. //
  81. // https://github.com/go-vgo/robotgo/blob/master/docs/keys.md#type-conversion
  82. type Bitmap struct {
  83. ImgBuf *uint8
  84. Width, Height int
  85. Bytewidth int
  86. BitsPixel uint8
  87. BytesPerPixel uint8
  88. }
  89. // Point is point struct
  90. type Point struct {
  91. X int
  92. Y int
  93. }
  94. // Size is size structure
  95. type Size struct {
  96. W, H int
  97. }
  98. // Rect is rect structure
  99. type Rect struct {
  100. Point
  101. Size
  102. }
  103. // Try handler(err)
  104. func Try(fun func(), handler func(interface{})) {
  105. defer func() {
  106. if err := recover(); err != nil {
  107. handler(err)
  108. }
  109. }()
  110. fun()
  111. }
  112. // MilliSleep sleep tm milli second
  113. func MilliSleep(tm int) {
  114. time.Sleep(time.Duration(tm) * time.Millisecond)
  115. }
  116. // Sleep time.Sleep tm second
  117. func Sleep(tm int) {
  118. time.Sleep(time.Duration(tm) * time.Second)
  119. }
  120. // Deprecated: use the MilliSleep(),
  121. //
  122. // MicroSleep time C.microsleep(tm)
  123. func MicroSleep(tm float64) {
  124. C.microsleep(C.double(tm))
  125. }
  126. // GoString trans C.char to string
  127. func GoString(char *C.char) string {
  128. return C.GoString(char)
  129. }
  130. /*
  131. _______. ______ .______ _______ _______ .__ __.
  132. / | / || _ \ | ____|| ____|| \ | |
  133. | (----`| ,----'| |_) | | |__ | |__ | \| |
  134. \ \ | | | / | __| | __| | . ` |
  135. .----) | | `----.| |\ \----.| |____ | |____ | |\ |
  136. |_______/ \______|| _| `._____||_______||_______||__| \__|
  137. */
  138. // ToMMRGBHex trans CHex to C.MMRGBHex
  139. func ToMMRGBHex(hex CHex) C.MMRGBHex {
  140. return C.MMRGBHex(hex)
  141. }
  142. // UintToHex trans uint32 to robotgo.CHex
  143. func UintToHex(u uint32) CHex {
  144. hex := U32ToHex(C.uint32_t(u))
  145. return CHex(hex)
  146. }
  147. // U32ToHex trans C.uint32_t to C.MMRGBHex
  148. func U32ToHex(hex C.uint32_t) C.MMRGBHex {
  149. return C.MMRGBHex(hex)
  150. }
  151. // U8ToHex trans *C.uint8_t to C.MMRGBHex
  152. func U8ToHex(hex *C.uint8_t) C.MMRGBHex {
  153. return C.MMRGBHex(*hex)
  154. }
  155. // PadHex trans C.MMRGBHex to string
  156. func PadHex(hex C.MMRGBHex) string {
  157. color := C.pad_hex(hex)
  158. gcolor := C.GoString(color)
  159. C.free(unsafe.Pointer(color))
  160. return gcolor
  161. }
  162. // PadHexs trans CHex to string
  163. func PadHexs(hex CHex) string {
  164. return PadHex(C.MMRGBHex(hex))
  165. }
  166. // HexToRgb trans hex to rgb
  167. func HexToRgb(hex uint32) *C.uint8_t {
  168. return C.color_hex_to_rgb(C.uint32_t(hex))
  169. }
  170. // RgbToHex trans rgb to hex
  171. func RgbToHex(r, g, b uint8) C.uint32_t {
  172. return C.color_rgb_to_hex(C.uint8_t(r), C.uint8_t(g), C.uint8_t(b))
  173. }
  174. // GetPxColor get the pixel color return C.MMRGBHex
  175. func GetPxColor(x, y int, displayId ...int) C.MMRGBHex {
  176. cx := C.int32_t(x)
  177. cy := C.int32_t(y)
  178. display := displayIdx(displayId...)
  179. color := C.get_px_color(cx, cy, C.int32_t(display))
  180. return color
  181. }
  182. // GetPixelColor get the pixel color return string
  183. func GetPixelColor(x, y int, displayId ...int) string {
  184. return PadHex(GetPxColor(x, y, displayId...))
  185. }
  186. // GetLocationColor get the location pos's color
  187. func GetLocationColor(displayId ...int) string {
  188. x, y := Location()
  189. return GetPixelColor(x, y, displayId...)
  190. }
  191. // IsMain is main display
  192. func IsMain(displayId int) bool {
  193. return displayId == GetMainId()
  194. }
  195. func displayIdx(id ...int) int {
  196. display := -1
  197. if DisplayID != -1 {
  198. display = DisplayID
  199. }
  200. if len(id) > 0 {
  201. display = id[0]
  202. }
  203. return display
  204. }
  205. func getNumDisplays() int {
  206. return int(C.get_num_displays())
  207. }
  208. // GetHWNDByPid get the hwnd by pid
  209. func GetHWNDByPid(pid int) int {
  210. return int(C.get_hwnd_by_pid(C.uintptr(pid)))
  211. }
  212. // SysScale get the sys scale
  213. func SysScale(displayId ...int) float64 {
  214. display := displayIdx(displayId...)
  215. s := C.sys_scale(C.int32_t(display))
  216. return float64(s)
  217. }
  218. // Scaled get the screen scaled return scale size
  219. func Scaled(x int, displayId ...int) int {
  220. f := ScaleF(displayId...)
  221. return Scaled0(x, f)
  222. }
  223. // Scaled0 return int(x * f)
  224. func Scaled0(x int, f float64) int {
  225. return int(float64(x) * f)
  226. }
  227. // Scaled1 return int(x / f)
  228. func Scaled1(x int, f float64) int {
  229. return int(float64(x) / f)
  230. }
  231. // GetScreenSize get the screen size
  232. func GetScreenSize() (int, int) {
  233. size := C.getMainDisplaySize()
  234. return int(size.w), int(size.h)
  235. }
  236. // GetScreenRect get the screen rect (x, y, w, h)
  237. func GetScreenRect(displayId ...int) Rect {
  238. display := -1
  239. if len(displayId) > 0 {
  240. display = displayId[0]
  241. }
  242. rect := C.getScreenRect(C.int32_t(display))
  243. x, y, w, h := int(rect.origin.x), int(rect.origin.y),
  244. int(rect.size.w), int(rect.size.h)
  245. if runtime.GOOS == "windows" {
  246. // f := ScaleF(displayId...)
  247. f := ScaleF()
  248. x, y, w, h = Scaled0(x, f), Scaled0(y, f), Scaled0(w, f), Scaled0(h, f)
  249. }
  250. return Rect{
  251. Point{X: x, Y: y},
  252. Size{W: w, H: h},
  253. }
  254. }
  255. // GetScaleSize get the screen scale size
  256. func GetScaleSize(displayId ...int) (int, int) {
  257. x, y := GetScreenSize()
  258. f := ScaleF(displayId...)
  259. return int(float64(x) * f), int(float64(y) * f)
  260. }
  261. // CaptureScreen capture the screen return bitmap(c struct),
  262. // use `defer robotgo.FreeBitmap(bitmap)` to free the bitmap
  263. //
  264. // robotgo.CaptureScreen(x, y, w, h int)
  265. func CaptureScreen(args ...int) CBitmap {
  266. var x, y, w, h C.int32_t
  267. displayId := -1
  268. if DisplayID != -1 {
  269. displayId = DisplayID
  270. }
  271. if len(args) > 4 {
  272. displayId = args[4]
  273. }
  274. if len(args) > 3 {
  275. x = C.int32_t(args[0])
  276. y = C.int32_t(args[1])
  277. w = C.int32_t(args[2])
  278. h = C.int32_t(args[3])
  279. } else {
  280. // Get the main screen rect.
  281. rect := GetScreenRect(displayId)
  282. if runtime.GOOS == "windows" {
  283. x = C.int32_t(rect.X)
  284. y = C.int32_t(rect.Y)
  285. }
  286. w = C.int32_t(rect.W)
  287. h = C.int32_t(rect.H)
  288. }
  289. isPid := 0
  290. if NotPid || len(args) > 5 {
  291. isPid = 1
  292. }
  293. bit := C.capture_screen(x, y, w, h, C.int32_t(displayId), C.int8_t(isPid))
  294. return CBitmap(bit)
  295. }
  296. // CaptureGo capture the screen and return bitmap(go struct)
  297. func CaptureGo(args ...int) Bitmap {
  298. bit := CaptureScreen(args...)
  299. defer FreeBitmap(bit)
  300. return ToBitmap(bit)
  301. }
  302. // CaptureImg capture the screen and return image.Image, error
  303. func CaptureImg(args ...int) (image.Image, error) {
  304. bit := CaptureScreen(args...)
  305. if bit == nil {
  306. return nil, errors.New("Capture image not found.")
  307. }
  308. defer FreeBitmap(bit)
  309. return ToImage(bit), nil
  310. }
  311. // FreeBitmap free and dealloc the C bitmap
  312. func FreeBitmap(bitmap CBitmap) {
  313. // C.destroyMMBitmap(bitmap)
  314. C.bitmap_dealloc(C.MMBitmapRef(bitmap))
  315. }
  316. // FreeBitmapArr free and dealloc the C bitmap array
  317. func FreeBitmapArr(bit ...CBitmap) {
  318. for i := 0; i < len(bit); i++ {
  319. FreeBitmap(bit[i])
  320. }
  321. }
  322. // ToMMBitmapRef trans CBitmap to C.MMBitmapRef
  323. func ToMMBitmapRef(bit CBitmap) C.MMBitmapRef {
  324. return C.MMBitmapRef(bit)
  325. }
  326. // ToBitmap trans C.MMBitmapRef to Bitmap
  327. func ToBitmap(bit CBitmap) Bitmap {
  328. bitmap := Bitmap{
  329. ImgBuf: (*uint8)(bit.imageBuffer),
  330. Width: int(bit.width),
  331. Height: int(bit.height),
  332. Bytewidth: int(bit.bytewidth),
  333. BitsPixel: uint8(bit.bitsPerPixel),
  334. BytesPerPixel: uint8(bit.bytesPerPixel),
  335. }
  336. return bitmap
  337. }
  338. // ToCBitmap trans Bitmap to C.MMBitmapRef
  339. func ToCBitmap(bit Bitmap) CBitmap {
  340. cbitmap := C.createMMBitmap_c(
  341. (*C.uint8_t)(bit.ImgBuf),
  342. C.int32_t(bit.Width),
  343. C.int32_t(bit.Height),
  344. C.int32_t(bit.Bytewidth),
  345. C.uint8_t(bit.BitsPixel),
  346. C.uint8_t(bit.BytesPerPixel),
  347. )
  348. return CBitmap(cbitmap)
  349. }
  350. // ToImage convert C.MMBitmapRef to standard image.Image
  351. func ToImage(bit CBitmap) image.Image {
  352. return ToRGBA(bit)
  353. }
  354. // ToRGBA convert C.MMBitmapRef to standard image.RGBA
  355. func ToRGBA(bit CBitmap) *image.RGBA {
  356. bmp1 := ToBitmap(bit)
  357. return ToRGBAGo(bmp1)
  358. }
  359. // ImgToCBitmap trans image.Image to CBitmap
  360. func ImgToCBitmap(img image.Image) CBitmap {
  361. return ToCBitmap(ImgToBitmap(img))
  362. }
  363. // ByteToCBitmap trans []byte to CBitmap
  364. func ByteToCBitmap(by []byte) CBitmap {
  365. img, _ := ByteToImg(by)
  366. return ImgToCBitmap(img)
  367. }
  368. // SetXDisplayName set XDisplay name (Linux)
  369. func SetXDisplayName(name string) error {
  370. cname := C.CString(name)
  371. str := C.set_XDisplay_name(cname)
  372. C.free(unsafe.Pointer(cname))
  373. return toErr(str)
  374. }
  375. // GetXDisplayName get XDisplay name (Linux)
  376. func GetXDisplayName() string {
  377. name := C.get_XDisplay_name()
  378. gname := C.GoString(name)
  379. C.free(unsafe.Pointer(name))
  380. return gname
  381. }
  382. // CloseMainDisplay close the main X11 display
  383. func CloseMainDisplay() {
  384. C.close_main_display()
  385. }
  386. // Deprecated: use the ScaledF(),
  387. //
  388. // ScaleX get the primary display horizontal DPI scale factor, drop
  389. func ScaleX() int {
  390. return int(C.scaleX())
  391. }
  392. /*
  393. .___ ___. ______ __ __ _______. _______
  394. | \/ | / __ \ | | | | / || ____|
  395. | \ / | | | | | | | | | | (----`| |__
  396. | |\/| | | | | | | | | | \ \ | __|
  397. | | | | | `--' | | `--' | .----) | | |____
  398. |__| |__| \______/ \______/ |_______/ |_______|
  399. */
  400. // CheckMouse check the mouse button
  401. func CheckMouse(btn string) C.MMMouseButton {
  402. // button = args[0].(C.MMMouseButton)
  403. m1 := map[string]C.MMMouseButton{
  404. "left": C.LEFT_BUTTON,
  405. "center": C.CENTER_BUTTON,
  406. "right": C.RIGHT_BUTTON,
  407. "wheelDown": C.WheelDown,
  408. "wheelUp": C.WheelUp,
  409. "wheelLeft": C.WheelLeft,
  410. "wheelRight": C.WheelRight,
  411. }
  412. if v, ok := m1[btn]; ok {
  413. return v
  414. }
  415. return C.LEFT_BUTTON
  416. }
  417. // MoveScale calculate the os scale factor x, y
  418. func MoveScale(x, y int, displayId ...int) (int, int) {
  419. if Scale && runtime.GOOS == "windows" {
  420. f := ScaleF()
  421. x, y = Scaled1(x, f), Scaled1(y, f)
  422. }
  423. return x, y
  424. }
  425. // Move move the mouse to (x, y)
  426. //
  427. // Examples:
  428. //
  429. // robotgo.MouseSleep = 100 // 100 millisecond
  430. // robotgo.Move(10, 10)
  431. func Move(x, y int, displayId ...int) {
  432. x, y = MoveScale(x, y, displayId...)
  433. cx := C.int32_t(x)
  434. cy := C.int32_t(y)
  435. C.moveMouse(C.MMPointInt32Make(cx, cy))
  436. MilliSleep(MouseSleep)
  437. }
  438. // Deprecated: use the DragSmooth(),
  439. //
  440. // Drag drag the mouse to (x, y),
  441. // It's not valid now, use the DragSmooth()
  442. func Drag(x, y int, args ...string) {
  443. x, y = MoveScale(x, y)
  444. var button C.MMMouseButton = C.LEFT_BUTTON
  445. cx := C.int32_t(x)
  446. cy := C.int32_t(y)
  447. if len(args) > 0 {
  448. button = CheckMouse(args[0])
  449. }
  450. C.dragMouse(C.MMPointInt32Make(cx, cy), button)
  451. MilliSleep(MouseSleep)
  452. }
  453. // DragSmooth drag the mouse like smooth to (x, y)
  454. //
  455. // Examples:
  456. //
  457. // robotgo.DragSmooth(10, 10)
  458. func DragSmooth(x, y int, args ...interface{}) {
  459. Toggle("left")
  460. MilliSleep(50)
  461. MoveSmooth(x, y, args...)
  462. Toggle("left", "up")
  463. }
  464. // MoveSmooth move the mouse smooth,
  465. // moves mouse to x, y human like, with the mouse button up.
  466. //
  467. // robotgo.MoveSmooth(x, y int, low, high float64, mouseDelay int)
  468. //
  469. // Examples:
  470. //
  471. // robotgo.MoveSmooth(10, 10)
  472. // robotgo.MoveSmooth(10, 10, 1.0, 2.0)
  473. func MoveSmooth(x, y int, args ...interface{}) bool {
  474. // if runtime.GOOS == "windows" {
  475. // f := ScaleF()
  476. // x, y = Scaled0(x, f), Scaled0(y, f)
  477. // }
  478. x, y = MoveScale(x, y)
  479. cx := C.int32_t(x)
  480. cy := C.int32_t(y)
  481. var (
  482. mouseDelay = 1
  483. low C.double
  484. high C.double
  485. )
  486. if len(args) > 2 {
  487. mouseDelay = args[2].(int)
  488. }
  489. if len(args) > 1 {
  490. low = C.double(args[0].(float64))
  491. high = C.double(args[1].(float64))
  492. } else {
  493. low = 1.0
  494. high = 3.0
  495. }
  496. cbool := C.smoothlyMoveMouse(C.MMPointInt32Make(cx, cy), low, high)
  497. MilliSleep(MouseSleep + mouseDelay)
  498. return bool(cbool)
  499. }
  500. // MoveArgs get the mouse relative args
  501. func MoveArgs(x, y int) (int, int) {
  502. mx, my := Location()
  503. mx = mx + x
  504. my = my + y
  505. return mx, my
  506. }
  507. // MoveRelative move mouse with relative
  508. func MoveRelative(x, y int) {
  509. Move(MoveArgs(x, y))
  510. }
  511. // MoveSmoothRelative move mouse smooth with relative
  512. func MoveSmoothRelative(x, y int, args ...interface{}) {
  513. mx, my := MoveArgs(x, y)
  514. MoveSmooth(mx, my, args...)
  515. }
  516. // Location get the mouse location position return x, y
  517. func Location() (int, int) {
  518. pos := C.location()
  519. x := int(pos.x)
  520. y := int(pos.y)
  521. if runtime.GOOS == "windows" {
  522. f := ScaleF()
  523. x, y = Scaled0(x, f), Scaled0(y, f)
  524. }
  525. return x, y
  526. }
  527. // Click click the mouse button
  528. //
  529. // robotgo.Click(button string, double bool)
  530. //
  531. // Examples:
  532. //
  533. // robotgo.Click() // default is left button
  534. // robotgo.Click("right")
  535. // robotgo.Click("wheelLeft")
  536. func Click(args ...interface{}) {
  537. var (
  538. button C.MMMouseButton = C.LEFT_BUTTON
  539. double bool
  540. )
  541. if len(args) > 0 {
  542. button = CheckMouse(args[0].(string))
  543. }
  544. if len(args) > 1 {
  545. double = args[1].(bool)
  546. }
  547. if !double {
  548. C.clickMouse(button)
  549. } else {
  550. C.doubleClick(button)
  551. }
  552. MilliSleep(MouseSleep)
  553. }
  554. // MoveClick move and click the mouse
  555. //
  556. // robotgo.MoveClick(x, y int, button string, double bool)
  557. //
  558. // Examples:
  559. //
  560. // robotgo.MouseSleep = 100
  561. // robotgo.MoveClick(10, 10)
  562. func MoveClick(x, y int, args ...interface{}) {
  563. Move(x, y)
  564. MilliSleep(50)
  565. Click(args...)
  566. }
  567. // MovesClick move smooth and click the mouse
  568. //
  569. // use the `robotgo.MouseSleep = 100`
  570. func MovesClick(x, y int, args ...interface{}) {
  571. MoveSmooth(x, y)
  572. MilliSleep(50)
  573. Click(args...)
  574. }
  575. // Toggle toggle the mouse, support button:
  576. //
  577. // "left", "center", "right",
  578. // "wheelDown", "wheelUp", "wheelLeft", "wheelRight"
  579. //
  580. // Examples:
  581. //
  582. // robotgo.Toggle("left") // default is down
  583. // robotgo.Toggle("left", "up")
  584. func Toggle(key ...interface{}) error {
  585. var button C.MMMouseButton = C.LEFT_BUTTON
  586. if len(key) > 0 {
  587. button = CheckMouse(key[0].(string))
  588. }
  589. down := true
  590. if len(key) > 1 && key[1].(string) == "up" {
  591. down = false
  592. }
  593. C.toggleMouse(C.bool(down), button)
  594. if len(key) > 2 {
  595. MilliSleep(MouseSleep)
  596. }
  597. return nil
  598. }
  599. // MouseDown send mouse down event
  600. func MouseDown(key ...interface{}) error {
  601. return Toggle(key...)
  602. }
  603. // MouseUp send mouse up event
  604. func MouseUp(key ...interface{}) error {
  605. if len(key) <= 0 {
  606. key = append(key, "left")
  607. }
  608. return Toggle(append(key, "up")...)
  609. }
  610. // Scroll scroll the mouse to (x, y)
  611. //
  612. // robotgo.Scroll(x, y, msDelay int)
  613. //
  614. // Examples:
  615. //
  616. // robotgo.Scroll(10, 10)
  617. func Scroll(x, y int, args ...int) {
  618. var msDelay = 10
  619. if len(args) > 0 {
  620. msDelay = args[0]
  621. }
  622. cx := C.int(x)
  623. cy := C.int(y)
  624. C.scrollMouseXY(cx, cy)
  625. MilliSleep(MouseSleep + msDelay)
  626. }
  627. // ScrollDir scroll the mouse with direction to (x, "up")
  628. // supported: "up", "down", "left", "right"
  629. //
  630. // Examples:
  631. //
  632. // robotgo.ScrollDir(10, "down")
  633. // robotgo.ScrollDir(10, "up")
  634. func ScrollDir(x int, direction ...interface{}) {
  635. d := "down"
  636. if len(direction) > 0 {
  637. d = direction[0].(string)
  638. }
  639. if d == "down" {
  640. Scroll(0, -x)
  641. }
  642. if d == "up" {
  643. Scroll(0, x)
  644. }
  645. if d == "left" {
  646. Scroll(x, 0)
  647. }
  648. if d == "right" {
  649. Scroll(-x, 0)
  650. }
  651. // MilliSleep(MouseSleep)
  652. }
  653. // ScrollSmooth scroll the mouse smooth,
  654. // default scroll 5 times and sleep 100 millisecond
  655. //
  656. // robotgo.ScrollSmooth(toy, num, sleep, tox)
  657. //
  658. // Examples:
  659. //
  660. // robotgo.ScrollSmooth(-10)
  661. // robotgo.ScrollSmooth(-10, 6, 200, -10)
  662. func ScrollSmooth(to int, args ...int) {
  663. i := 0
  664. num := 5
  665. if len(args) > 0 {
  666. num = args[0]
  667. }
  668. tm := 100
  669. if len(args) > 1 {
  670. tm = args[1]
  671. }
  672. tox := 0
  673. if len(args) > 2 {
  674. tox = args[2]
  675. }
  676. for {
  677. Scroll(tox, to)
  678. MilliSleep(tm)
  679. i++
  680. if i == num {
  681. break
  682. }
  683. }
  684. MilliSleep(MouseSleep)
  685. }
  686. // ScrollRelative scroll mouse with relative
  687. //
  688. // Examples:
  689. //
  690. // robotgo.ScrollRelative(10, 10)
  691. func ScrollRelative(x, y int, args ...int) {
  692. mx, my := MoveArgs(x, y)
  693. Scroll(mx, my, args...)
  694. }
  695. /*
  696. ____ __ ____ __ .__ __. _______ ______ ____ __ ____
  697. \ \ / \ / / | | | \ | | | \ / __ \ \ \ / \ / /
  698. \ \/ \/ / | | | \| | | .--. | | | | \ \/ \/ /
  699. \ / | | | . ` | | | | | | | | \ /
  700. \ /\ / | | | |\ | | '--' | `--' | \ /\ /
  701. \__/ \__/ |__| |__| \__| |_______/ \______/ \__/ \__/
  702. */
  703. func alertArgs(args ...string) (string, string) {
  704. var (
  705. defaultBtn = "Ok"
  706. cancelBtn = "Cancel"
  707. )
  708. if len(args) > 0 {
  709. defaultBtn = args[0]
  710. }
  711. if len(args) > 1 {
  712. cancelBtn = args[1]
  713. }
  714. return defaultBtn, cancelBtn
  715. }
  716. func showAlert(title, msg string, args ...string) bool {
  717. defaultBtn, cancelBtn := alertArgs(args...)
  718. cTitle := C.CString(title)
  719. cMsg := C.CString(msg)
  720. defaultButton := C.CString(defaultBtn)
  721. cancelButton := C.CString(cancelBtn)
  722. cbool := C.showAlert(cTitle, cMsg, defaultButton, cancelButton)
  723. ibool := int(cbool)
  724. C.free(unsafe.Pointer(cTitle))
  725. C.free(unsafe.Pointer(cMsg))
  726. C.free(unsafe.Pointer(defaultButton))
  727. C.free(unsafe.Pointer(cancelButton))
  728. return ibool == 0
  729. }
  730. // IsValid valid the window
  731. func IsValid() bool {
  732. abool := C.is_valid()
  733. gbool := bool(abool)
  734. return gbool
  735. }
  736. // SetActive set the window active
  737. func SetActive(win Handle) {
  738. SetActiveC(C.MData(win))
  739. }
  740. // SetActiveC set the window active
  741. func SetActiveC(win C.MData) {
  742. C.set_active(win)
  743. }
  744. // GetActive get the active window
  745. func GetActive() Handle {
  746. return Handle(GetActiveC())
  747. }
  748. // GetActiveC get the active window
  749. func GetActiveC() C.MData {
  750. mdata := C.get_active()
  751. // fmt.Println("active----", mdata)
  752. return mdata
  753. }
  754. // MinWindow set the window min
  755. func MinWindow(pid int, args ...interface{}) {
  756. var (
  757. state = true
  758. isPid int
  759. )
  760. if len(args) > 0 {
  761. state = args[0].(bool)
  762. }
  763. if len(args) > 1 || NotPid {
  764. isPid = 1
  765. }
  766. C.min_window(C.uintptr(pid), C.bool(state), C.int8_t(isPid))
  767. }
  768. // MaxWindow set the window max
  769. func MaxWindow(pid int, args ...interface{}) {
  770. var (
  771. state = true
  772. isPid int
  773. )
  774. if len(args) > 0 {
  775. state = args[0].(bool)
  776. }
  777. if len(args) > 1 || NotPid {
  778. isPid = 1
  779. }
  780. C.max_window(C.uintptr(pid), C.bool(state), C.int8_t(isPid))
  781. }
  782. // CloseWindow close the window
  783. func CloseWindow(args ...int) {
  784. if len(args) <= 0 {
  785. C.close_main_window()
  786. return
  787. }
  788. var pid, isPid int
  789. if len(args) > 0 {
  790. pid = args[0]
  791. }
  792. if len(args) > 1 || NotPid {
  793. isPid = 1
  794. }
  795. C.close_window_by_PId(C.uintptr(pid), C.int8_t(isPid))
  796. }
  797. // SetHandle set the window handle
  798. func SetHandle(hwnd int) {
  799. chwnd := C.uintptr(hwnd)
  800. C.setHandle(chwnd)
  801. }
  802. // SetHandlePid set the window handle by pid
  803. func SetHandlePid(pid int, args ...int) {
  804. var isPid int
  805. if len(args) > 0 || NotPid {
  806. isPid = 1
  807. }
  808. C.set_handle_pid_mData(C.uintptr(pid), C.int8_t(isPid))
  809. }
  810. // GetHandById get handle mdata by id
  811. func GetHandById(id int, args ...int) Handle {
  812. isPid := 1
  813. if len(args) > 0 {
  814. isPid = args[0]
  815. }
  816. return GetHandByPid(id, isPid)
  817. }
  818. // GetHandByPid get handle mdata by pid
  819. func GetHandByPid(pid int, args ...int) Handle {
  820. return Handle(GetHandByPidC(pid, args...))
  821. }
  822. // Deprecated: use the GetHandByPid(),
  823. //
  824. // GetHandPid get handle mdata by pid
  825. func GetHandPid(pid int, args ...int) Handle {
  826. return GetHandByPid(pid, args...)
  827. }
  828. // GetHandByPidC get handle mdata by pid
  829. func GetHandByPidC(pid int, args ...int) C.MData {
  830. var isPid int
  831. if len(args) > 0 || NotPid {
  832. isPid = 1
  833. }
  834. return C.set_handle_pid(C.uintptr(pid), C.int8_t(isPid))
  835. }
  836. // GetHandle get the window handle
  837. func GetHandle() int {
  838. hwnd := C.get_handle()
  839. ghwnd := int(hwnd)
  840. // fmt.Println("gethwnd---", ghwnd)
  841. return ghwnd
  842. }
  843. // Deprecated: use the GetHandle(),
  844. //
  845. // # GetBHandle get the window handle, Wno-deprecated
  846. //
  847. // This function will be removed in version v1.0.0
  848. func GetBHandle() int {
  849. tt.Drop("GetBHandle", "GetHandle")
  850. hwnd := C.b_get_handle()
  851. ghwnd := int(hwnd)
  852. //fmt.Println("gethwnd---", ghwnd)
  853. return ghwnd
  854. }
  855. func cgetTitle(pid, isPid int) string {
  856. title := C.get_title_by_pid(C.uintptr(pid), C.int8_t(isPid))
  857. gtitle := C.GoString(title)
  858. return gtitle
  859. }
  860. // GetTitle get the window title return string
  861. //
  862. // Examples:
  863. //
  864. // fmt.Println(robotgo.GetTitle())
  865. //
  866. // ids, _ := robotgo.FindIds()
  867. // robotgo.GetTitle(ids[0])
  868. func GetTitle(args ...int) string {
  869. if len(args) <= 0 {
  870. title := C.get_main_title()
  871. gtitle := C.GoString(title)
  872. return gtitle
  873. }
  874. if len(args) > 1 {
  875. return internalGetTitle(args[0], args[1])
  876. }
  877. return internalGetTitle(args[0])
  878. }
  879. // GetPid get the process id return int32
  880. func GetPid() int {
  881. pid := C.get_PID()
  882. return int(pid)
  883. }
  884. // internalGetBounds get the window bounds
  885. func internalGetBounds(pid, isPid int) (int, int, int, int) {
  886. bounds := C.get_bounds(C.uintptr(pid), C.int8_t(isPid))
  887. return int(bounds.X), int(bounds.Y), int(bounds.W), int(bounds.H)
  888. }
  889. // internalGetClient get the window client bounds
  890. func internalGetClient(pid, isPid int) (int, int, int, int) {
  891. bounds := C.get_client(C.uintptr(pid), C.int8_t(isPid))
  892. return int(bounds.X), int(bounds.Y), int(bounds.W), int(bounds.H)
  893. }
  894. // Is64Bit determine whether the sys is 64bit
  895. func Is64Bit() bool {
  896. b := C.Is64Bit()
  897. return bool(b)
  898. }
  899. func internalActive(pid, isPid int) {
  900. C.active_PID(C.uintptr(pid), C.int8_t(isPid))
  901. }
  902. // ActivePid active the window by Pid,
  903. // If args[0] > 0 on the Windows platform via a window handle to active
  904. // func ActivePid(pid int32, args ...int) {
  905. // var isPid int
  906. // if len(args) > 0 {
  907. // isPid = args[0]
  908. // }
  909. // C.active_PID(C.uintptr(pid), C.uintptr(isPid))
  910. // }
  911. // ActiveName active the window by name
  912. //
  913. // Examples:
  914. //
  915. // robotgo.ActiveName("chrome")
  916. func ActiveName(name string) error {
  917. pids, err := FindIds(name)
  918. if err == nil && len(pids) > 0 {
  919. return ActivePid(pids[0])
  920. }
  921. return err
  922. }