mouse_rs/sys/
windows.rs

1#![allow(dead_code)]
2use crate::types::{keys::Keys, Point};
3use libloading::Library;
4use winapi::shared::windef::POINT;
5
6const MOUSEEVENTF_ABSOLUTE: i32 = 0x8000;
7const MOUSEEVENTF_MOVE: i32 = 0x1;
8const MOUSEEVENTF_WHEEL: i32 = 0x800;
9const MOUSEEVENTF_HWHEEL: i32 = 0x1000;
10const MOUSEEVENTF_LEFTDOWN: i32 = 0x2;
11const MOUSEEVENTF_LEFTUP: i32 = 0x4;
12const MOUSEEVENTF_RIGHTDOWN: i32 = 0x8;
13const MOUSEEVENTF_RIGHTUP: i32 = 0x10;
14const MOUSEEVENTF_MIDDLEDOWN: i32 = 0x20;
15const MOUSEEVENTF_MIDDLEUP: i32 = 0x40;
16const MOUSEEVENTF_XDOWN: i32 = 0x0080;
17const MOUSEEVENTF_XUP: i32 = 0x0100;
18
19fn win_translate_key(key: (&Keys, &Keys)) -> i32 {
20    match key {
21        (Keys::WHEEL, Keys::HORIZONTAL) => MOUSEEVENTF_HWHEEL,
22        (Keys::WHEEL, Keys::VERTICAL) => MOUSEEVENTF_WHEEL,
23
24        (Keys::DOWN, Keys::LEFT) => MOUSEEVENTF_LEFTDOWN,
25        (Keys::UP, Keys::LEFT) => MOUSEEVENTF_LEFTUP,
26
27        (Keys::DOWN, Keys::RIGHT) => MOUSEEVENTF_RIGHTDOWN,
28        (Keys::UP, Keys::RIGHT) => MOUSEEVENTF_RIGHTUP,
29
30        (Keys::DOWN, Keys::MIDDLE) => MOUSEEVENTF_MIDDLEDOWN,
31        (Keys::UP, Keys::MIDDLE) => MOUSEEVENTF_MIDDLEUP,
32
33        (Keys::DOWN, Keys::WHEEL) => MOUSEEVENTF_MIDDLEDOWN,
34        (Keys::UP, Keys::WHEEL) => MOUSEEVENTF_MIDDLEUP,
35
36        (Keys::DOWN, Keys::X) => MOUSEEVENTF_XDOWN,
37        (Keys::UP, Keys::X) => MOUSEEVENTF_XUP,
38        _ => panic!("Invalid parameter passed, please use constants from types::keys"),
39    }
40}
41
42impl From<POINT> for Point {
43    fn from(other: POINT) -> Point {
44        Point {
45            x: other.x as _,
46            y: other.y as _,
47        }
48    }
49}
50
51pub struct Mouse {
52    user32: Library,
53}
54
55#[allow(unreachable_code, unused_variables)]
56impl Mouse {
57    fn translate_button(button: &Keys) -> (&Keys, i32) {
58        return match button {
59            Keys::X => (&Keys::X, 0x10000),
60            Keys::X2 => (&Keys::X2, 0x20000),
61            _ => (button, 0),
62        };
63    }
64
65    fn mouse_event(
66        &self,
67        dw_flags: i32,
68        dx: i32,
69        dy: i32,
70        dw_data: i32,
71        dw_extra_info: i32,
72    ) -> Result<(), Box<dyn std::error::Error>> {
73        unsafe {
74            let mouse_event: libloading::Symbol<
75                unsafe extern "C" fn(
76                    dw_flags: i32,
77                    dx: i32,
78                    dy: i32,
79                    dw_data: i32,
80                    dw_extra_info: i32,
81                ),
82            > = self.user32.get(b"mouse_event")?;
83            Ok(mouse_event(dw_flags, dx, dy, dw_data, dw_extra_info))
84        }
85    }
86
87    pub fn new() -> Mouse {
88        Mouse {
89            user32: libloading::Library::new("user32").unwrap(),
90        }
91    }
92
93    pub fn move_to(&self, x: i32, y: i32) -> Result<(), Box<dyn std::error::Error>> {
94        unsafe {
95            let set_cursor_pos: libloading::Symbol<unsafe extern "C" fn(x: i32, y: i32)> =
96                self.user32.get(b"SetCursorPos")?;
97            Ok(set_cursor_pos(x, y))
98        }
99    }
100
101    pub fn press(&self, button: &Keys) -> Result<(), Box<dyn std::error::Error>> {
102        let (button, data) = Mouse::translate_button(button);
103        let code = win_translate_key((&Keys::DOWN, button));
104        self.mouse_event(code, 0, 0, data, 0)
105    }
106
107    pub fn release(&self, button: &Keys) -> Result<(), Box<dyn std::error::Error>> {
108        let (button, data) = Mouse::translate_button(button);
109        let code = win_translate_key((&Keys::UP, button));
110        self.mouse_event(code, 0, 0, data, 0)
111    }
112
113    pub fn get_position(&self) -> Result<Point, Box<dyn std::error::Error>> {
114        let mut pos: POINT = POINT { x: 0, y: 0 };
115        unsafe {
116            let get_cursor_pos: libloading::Symbol<unsafe extern "C" fn(lp_point: &POINT) -> bool> =
117                self.user32.get(b"GetCursorPos")?;
118            get_cursor_pos(&mut pos);
119            Ok(pos.into())
120        }
121    }
122
123    pub fn wheel(&self, delta: i32) -> Result<(), Box<dyn std::error::Error>> {
124        let code = win_translate_key((&Keys::WHEEL, &Keys::VERTICAL));
125        self.mouse_event(code, 0, 0, delta * 120, 0)
126    }
127}