node-native-win-utils 1.0.4 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -6
- package/dist/index.d.ts +6 -2
- package/dist/index.js +6 -2
- package/package.json +8 -2
- package/prebuilds/win32-x64/node.napi.node +0 -0
- package/src/cpp/{keyBoardHandler.cpp → keyboard.cpp} +40 -0
- package/src/cpp/main.cpp +6 -1
- package/src/cpp/mouse.cpp +175 -0
package/README.md
CHANGED
|
@@ -2,25 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
# Node Native Win Utils
|
|
4
4
|
|
|
5
|
-
I did it for myself because I didn't feel like dealing with libraries like 'node-ffi' to implement this functionality. Maybe someone will find it useful.
|
|
5
|
+
I did it for myself because I didn't feel like dealing with libraries like 'node-ffi' to implement this functionality. Maybe someone will find it useful. It's WINDOWS OS ONLY
|
|
6
6
|
|
|
7
|
-
This package
|
|
7
|
+
This package is a native addon for Node.js that allows you to perform various utility operations on Windows systems. It includes key event listeners, window data retrieval, window screenshot capture functionality, mouse movement, mouse click, mouse drag, and typing functionality.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
You can install the package using npm:
|
|
12
12
|
|
|
13
13
|
```shell
|
|
14
|
-
|
|
15
|
-
npm install node-native-win-utils
|
|
16
|
-
|
|
14
|
+
npm install node-native-win-utils
|
|
17
15
|
```
|
|
18
16
|
|
|
19
17
|
## Usage
|
|
20
18
|
|
|
21
19
|
### Importing the Package
|
|
22
20
|
|
|
23
|
-
To use the package, import the necessary functions and
|
|
21
|
+
To use the package, import the necessary functions, types, and classes:
|
|
24
22
|
|
|
25
23
|
```javascript
|
|
26
24
|
import {
|
|
@@ -28,6 +26,10 @@ import {
|
|
|
28
26
|
keyUpHandler,
|
|
29
27
|
getWindowData,
|
|
30
28
|
captureWindow,
|
|
29
|
+
mouseMove,
|
|
30
|
+
mouseClick,
|
|
31
|
+
mouseDrag,
|
|
32
|
+
typeString,
|
|
31
33
|
KeyListener,
|
|
32
34
|
} from "node-native-win-utils";
|
|
33
35
|
```
|
|
@@ -72,6 +74,43 @@ captureWindow("Window Name", "output.png");
|
|
|
72
74
|
// Output: output.png with a screenshot of the window
|
|
73
75
|
```
|
|
74
76
|
|
|
77
|
+
### Mouse Movement
|
|
78
|
+
|
|
79
|
+
The `mouseMove` function allows you to move the mouse to a specific position on the screen. Provide the `posX` and `posY` coordinates as parameters:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
mouseMove(100, 200);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Mouse Click
|
|
86
|
+
|
|
87
|
+
The `mouseClick` function allows you to perform a mouse click event. Optionally, you can specify the mouse button as a parameter (`"left"`, `"middle"`, or `"right"`). If no button is specified, a left mouse click is performed by default:
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
mouseClick(); // Left mouse click
|
|
91
|
+
mouseClick("right"); // Right mouse click
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Mouse Drag
|
|
95
|
+
|
|
96
|
+
The `mouseDrag` function allows you to simulate dragging the mouse from one position to another. Provide the starting and ending coordinates (`startX`, `startY`, `endX`, `endY`) as parameters. Optionally, you can specify the speed at which the mouse should be dragged:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
mouseDrag(100, 200, 300, 400);
|
|
100
|
+
mouseDrag(100, 200, 300, 400, 100); // Drag with speed 100
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Typing
|
|
104
|
+
|
|
105
|
+
The `typeString` function allows you to simulate typing a string of characters. Provide the string to type as the `stringToType` parameter. Optionally, you can specify
|
|
106
|
+
|
|
107
|
+
a delay between each character (in milliseconds) using the `delay` parameter:
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
typeString("Hello, world!");
|
|
111
|
+
typeString("Hello, world!", 100); // Type with a delay of 100ms between characters
|
|
112
|
+
```
|
|
113
|
+
|
|
75
114
|
### Key Listener Class
|
|
76
115
|
|
|
77
116
|
The `KeyListener` class extends the EventEmitter class and simplifies working with the `keyDownHandler` and `keyUpHandler` functions. You can register event listeners for the "keyDown" and "keyUp" events using the `on` method:
|
|
@@ -100,6 +139,10 @@ listener.on("keyUp", (data) => {
|
|
|
100
139
|
| keyUpHandler | `callback: (keyCode: number) => void` | `void` |
|
|
101
140
|
| getWindowData | `windowName: string` | `WindowData` |
|
|
102
141
|
| captureWindow | `windowName: string, outputPath: string` | `void` |
|
|
142
|
+
| mouseMove | `posX: number, posY: number` | `boolean` |
|
|
143
|
+
| mouseClick | `button?: "left" \| "middle" \| "right"` | `boolean` |
|
|
144
|
+
| mouseDrag | `startX: number, startY: number, endX: number, endY: number, speed?: number` | `boolean` |
|
|
145
|
+
| typeString | `stringToType: string, delay?: number` | `boolean` |
|
|
103
146
|
| KeyListener.on | `event: "keyDown"`,<br>`callback: (data: { keyCode: number; keyName: string }) => void` | `this` (EventListener) |
|
|
104
147
|
| KeyListener.on | `event: "keyUp"`,<br>`callback: (data: { keyCode: number; keyName: string }) => void` | `this` (EventListener) |
|
|
105
148
|
|
|
@@ -113,6 +156,10 @@ import {
|
|
|
113
156
|
keyUpHandler,
|
|
114
157
|
getWindowData,
|
|
115
158
|
captureWindow,
|
|
159
|
+
mouseMove,
|
|
160
|
+
mouseClick,
|
|
161
|
+
mouseDrag,
|
|
162
|
+
typeString,
|
|
116
163
|
KeyListener,
|
|
117
164
|
} from "node-native-win-utils";
|
|
118
165
|
|
|
@@ -144,6 +191,25 @@ captureWindow("My Window", "output.png");
|
|
|
144
191
|
|
|
145
192
|
// Output: output.png with a screenshot of the window
|
|
146
193
|
|
|
194
|
+
// Move the mouse
|
|
195
|
+
|
|
196
|
+
mouseMove(100, 200);
|
|
197
|
+
|
|
198
|
+
// Perform mouse click
|
|
199
|
+
|
|
200
|
+
mouseClick(); // Left mouse click
|
|
201
|
+
mouseClick("right"); // Right mouse click
|
|
202
|
+
|
|
203
|
+
// Simulate mouse drag
|
|
204
|
+
|
|
205
|
+
mouseDrag(100, 200, 300, 400);
|
|
206
|
+
mouseDrag(100, 200, 300, 400, 100); // Drag with speed 100
|
|
207
|
+
|
|
208
|
+
// Simulate typing
|
|
209
|
+
|
|
210
|
+
typeString("Hello, world!");
|
|
211
|
+
typeString("Hello, world!", 100); // Type with a delay of 100ms between characters
|
|
212
|
+
|
|
147
213
|
// Use KeyListener class
|
|
148
214
|
|
|
149
215
|
const listener = new KeyListener();
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ export type GetWindowData = (windowName: string) => WindowData;
|
|
|
10
10
|
export type CaptureWindow = (windowName: string, outputPath: string) => void;
|
|
11
11
|
export type KeyDownHandler = (callback: (keyCode: number) => void) => void;
|
|
12
12
|
export type KeyUpHandler = (callback: (keyCode: number) => void) => void;
|
|
13
|
+
export type MouseMove = (posX: number, posY: number) => boolean;
|
|
14
|
+
export type MouseClick = (button?: "left" | "middle" | "right") => boolean;
|
|
15
|
+
export type TypeString = (stringToType: string, delay?: number) => boolean;
|
|
16
|
+
export type MouseDrag = (starX: number, startY: number, endX: Number, endY: number, speed?: number) => boolean;
|
|
13
17
|
export interface KeyListener extends EventEmitter {
|
|
14
18
|
on(event: "keyDown", callback: (data: {
|
|
15
19
|
keyCode: number;
|
|
@@ -20,8 +24,8 @@ export interface KeyListener extends EventEmitter {
|
|
|
20
24
|
keyName: string;
|
|
21
25
|
}) => void): this;
|
|
22
26
|
}
|
|
23
|
-
declare const keyDownHandler: KeyDownHandler, keyUpHandler: KeyUpHandler, getWindowData: GetWindowData, captureWindow: CaptureWindow;
|
|
27
|
+
declare const keyDownHandler: KeyDownHandler, keyUpHandler: KeyUpHandler, getWindowData: GetWindowData, captureWindow: CaptureWindow, mouseMove: MouseMove, mouseClick: MouseClick, mouseDrag: MouseDrag, typeString: TypeString;
|
|
24
28
|
export declare class KeyListener extends EventEmitter {
|
|
25
29
|
constructor();
|
|
26
30
|
}
|
|
27
|
-
export { keyDownHandler, keyUpHandler, getWindowData, captureWindow };
|
|
31
|
+
export { keyDownHandler, keyUpHandler, getWindowData, captureWindow, mouseMove, mouseClick, mouseDrag, typeString, };
|
package/dist/index.js
CHANGED
|
@@ -3,16 +3,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.captureWindow = exports.getWindowData = exports.keyUpHandler = exports.keyDownHandler = exports.KeyListener = void 0;
|
|
6
|
+
exports.typeString = exports.mouseDrag = exports.mouseClick = exports.mouseMove = exports.captureWindow = exports.getWindowData = exports.keyUpHandler = exports.keyDownHandler = exports.KeyListener = void 0;
|
|
7
7
|
const EventEmitter = require("events");
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
9
|
const bindings = require("node-gyp-build")(path_1.default.resolve(__dirname, ".."));
|
|
10
10
|
const keyCodes_1 = __importDefault(require("./keyCodes"));
|
|
11
|
-
const { keyDownHandler, keyUpHandler, getWindowData, captureWindow, } = bindings;
|
|
11
|
+
const { keyDownHandler, keyUpHandler, getWindowData, captureWindow, mouseMove, mouseClick, mouseDrag, typeString, } = bindings;
|
|
12
12
|
exports.keyDownHandler = keyDownHandler;
|
|
13
13
|
exports.keyUpHandler = keyUpHandler;
|
|
14
14
|
exports.getWindowData = getWindowData;
|
|
15
15
|
exports.captureWindow = captureWindow;
|
|
16
|
+
exports.mouseMove = mouseMove;
|
|
17
|
+
exports.mouseClick = mouseClick;
|
|
18
|
+
exports.mouseDrag = mouseDrag;
|
|
19
|
+
exports.typeString = typeString;
|
|
16
20
|
class KeyListener extends EventEmitter {
|
|
17
21
|
constructor() {
|
|
18
22
|
super();
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-native-win-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"author": "RynerNO",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"repository": "https://github.com/RynerNO/node-native-win-utils.git",
|
|
6
7
|
"description": "Native addon for Node.js providing utility operations on Windows systems",
|
|
7
8
|
"keywords": [
|
|
8
9
|
"node.js",
|
|
@@ -14,7 +15,12 @@
|
|
|
14
15
|
"window",
|
|
15
16
|
"screenshot",
|
|
16
17
|
"capture",
|
|
17
|
-
"listener"
|
|
18
|
+
"listener",
|
|
19
|
+
"mouse",
|
|
20
|
+
"movemouse",
|
|
21
|
+
"click",
|
|
22
|
+
"keyboard",
|
|
23
|
+
"mousedrag"
|
|
18
24
|
],
|
|
19
25
|
"main": "dist/index.js",
|
|
20
26
|
"types": "dist/index.d.ts",
|
|
Binary file
|
|
@@ -162,4 +162,44 @@ Napi::Value SetKeyUpCallback(const Napi::CallbackInfo &info)
|
|
|
162
162
|
monitorThreadRunning = true;
|
|
163
163
|
}
|
|
164
164
|
return env.Undefined();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
Napi::Value TypeString(const Napi::CallbackInfo &info)
|
|
168
|
+
{
|
|
169
|
+
Napi::Env env = info.Env();
|
|
170
|
+
|
|
171
|
+
if (info.Length() < 1 || !info[0].IsString())
|
|
172
|
+
{
|
|
173
|
+
Napi::TypeError::New(env, "You should provide a string to type").ThrowAsJavaScriptException();
|
|
174
|
+
return env.Null();
|
|
175
|
+
}
|
|
176
|
+
int delay = 15;
|
|
177
|
+
std::string text = info[0].As<Napi::String>();
|
|
178
|
+
if (info.Length() > 1 && info[1].IsNumber())
|
|
179
|
+
{
|
|
180
|
+
delay = info[1].As<Napi::Number>();
|
|
181
|
+
}
|
|
182
|
+
// Convert the string to wide string
|
|
183
|
+
std::wstring wideText(text.begin(), text.end());
|
|
184
|
+
|
|
185
|
+
// Simulate typing by sending keyboard events
|
|
186
|
+
for (const wchar_t &character : wideText)
|
|
187
|
+
{
|
|
188
|
+
INPUT keyboardInput = {0};
|
|
189
|
+
keyboardInput.type = INPUT_KEYBOARD;
|
|
190
|
+
keyboardInput.ki.wVk = 0;
|
|
191
|
+
keyboardInput.ki.wScan = character;
|
|
192
|
+
keyboardInput.ki.dwFlags = KEYEVENTF_UNICODE;
|
|
193
|
+
keyboardInput.ki.time = 0; // System will provide the timestamp
|
|
194
|
+
|
|
195
|
+
SendInput(1, &keyboardInput, sizeof(keyboardInput));
|
|
196
|
+
|
|
197
|
+
keyboardInput.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
|
|
198
|
+
SendInput(1, &keyboardInput, sizeof(keyboardInput));
|
|
199
|
+
|
|
200
|
+
// Sleep for 15 milliseconds between each character input
|
|
201
|
+
Sleep(delay);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return Napi::Boolean::New(env, true);
|
|
165
205
|
}
|
package/src/cpp/main.cpp
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
#include <helpers.cpp>
|
|
3
3
|
#include "captureWindow.cpp"
|
|
4
4
|
#include <getWindowData.cpp>
|
|
5
|
-
#include <
|
|
5
|
+
#include <keyboard.cpp>
|
|
6
|
+
#include <mouse.cpp>
|
|
6
7
|
|
|
7
8
|
Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|
8
9
|
{
|
|
@@ -10,6 +11,10 @@ Napi::Object Init(Napi::Env env, Napi::Object exports)
|
|
|
10
11
|
exports.Set("captureWindow", Napi::Function::New(env, CaptureWindow));
|
|
11
12
|
exports.Set("keyDownHandler", Napi::Function::New(env, SetKeyDownCallback));
|
|
12
13
|
exports.Set("keyUpHandler", Napi::Function::New(env, SetKeyUpCallback));
|
|
14
|
+
exports.Set("mouseMove", Napi::Function::New(env, MoveMouse));
|
|
15
|
+
exports.Set("mouseClick", Napi::Function::New(env, ClickMouse));
|
|
16
|
+
exports.Set("mouseDrag", Napi::Function::New(env, DragMouse));
|
|
17
|
+
exports.Set("typeString", Napi::Function::New(env, TypeString));
|
|
13
18
|
return exports;
|
|
14
19
|
}
|
|
15
20
|
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// patrially used code from https://github.com/octalmage/robotjs witch is under MIT License Copyright (c) 2014 Jason Stallings
|
|
2
|
+
#include <napi.h>
|
|
3
|
+
#include <windows.h>
|
|
4
|
+
/**
|
|
5
|
+
* Move the mouse to a specific point.
|
|
6
|
+
* @param point The coordinates to move the mouse to (x, y).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
Napi::Value MoveMouse(const Napi::CallbackInfo &info)
|
|
10
|
+
{
|
|
11
|
+
Napi::Env env = info.Env();
|
|
12
|
+
|
|
13
|
+
if (info.Length() < 2 || !info[0].IsNumber() || !info[1].IsNumber())
|
|
14
|
+
{
|
|
15
|
+
Napi::TypeError::New(env, "You should provide x and y position of type number").ThrowAsJavaScriptException();
|
|
16
|
+
return env.Null();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
int posX = info[0].As<Napi::Number>();
|
|
20
|
+
int posY = info[1].As<Napi::Number>();
|
|
21
|
+
|
|
22
|
+
// Get the screen metrics
|
|
23
|
+
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
24
|
+
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
25
|
+
|
|
26
|
+
// Convert coordinates to absolute values
|
|
27
|
+
int absoluteX = static_cast<int>((65536 * posX) / screenWidth);
|
|
28
|
+
int absoluteY = static_cast<int>((65536 * posY) / screenHeight);
|
|
29
|
+
|
|
30
|
+
// Move the mouse
|
|
31
|
+
INPUT mouseInput = {0};
|
|
32
|
+
mouseInput.type = INPUT_MOUSE;
|
|
33
|
+
mouseInput.mi.dx = absoluteX;
|
|
34
|
+
mouseInput.mi.dy = absoluteY;
|
|
35
|
+
mouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
|
|
36
|
+
mouseInput.mi.time = 0; // System will provide the timestamp
|
|
37
|
+
|
|
38
|
+
SendInput(1, &mouseInput, sizeof(mouseInput));
|
|
39
|
+
|
|
40
|
+
return Napi::Boolean::New(env, true);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
Napi::Value ClickMouse(const Napi::CallbackInfo &info)
|
|
44
|
+
{
|
|
45
|
+
Napi::Env env = info.Env();
|
|
46
|
+
std::string button;
|
|
47
|
+
|
|
48
|
+
if (info.Length() < 1 || !info[0].IsString())
|
|
49
|
+
button = "left";
|
|
50
|
+
else
|
|
51
|
+
button = info[0].As<Napi::String>();
|
|
52
|
+
|
|
53
|
+
WORD mouseEvent = 0;
|
|
54
|
+
|
|
55
|
+
if (button == "left")
|
|
56
|
+
{
|
|
57
|
+
mouseEvent = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP;
|
|
58
|
+
}
|
|
59
|
+
else if (button == "right")
|
|
60
|
+
{
|
|
61
|
+
mouseEvent = MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP;
|
|
62
|
+
}
|
|
63
|
+
else if (button == "middle")
|
|
64
|
+
{
|
|
65
|
+
mouseEvent = MOUSEEVENTF_MIDDLEDOWN | MOUSEEVENTF_MIDDLEUP;
|
|
66
|
+
}
|
|
67
|
+
else
|
|
68
|
+
{
|
|
69
|
+
Napi::TypeError::New(env, "Invalid button name").ThrowAsJavaScriptException();
|
|
70
|
+
return env.Null();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Perform the mouse click
|
|
74
|
+
INPUT mouseInput = {0};
|
|
75
|
+
mouseInput.type = INPUT_MOUSE;
|
|
76
|
+
mouseInput.mi.dwFlags = mouseEvent;
|
|
77
|
+
mouseInput.mi.time = 0; // System will provide the timestamp
|
|
78
|
+
|
|
79
|
+
SendInput(1, &mouseInput, sizeof(mouseInput));
|
|
80
|
+
|
|
81
|
+
return Napi::Boolean::New(env, true);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
Napi::Value DragMouse(const Napi::CallbackInfo &info)
|
|
85
|
+
{
|
|
86
|
+
Napi::Env env = info.Env();
|
|
87
|
+
|
|
88
|
+
if (info.Length() < 4 || !info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
|
89
|
+
{
|
|
90
|
+
Napi::TypeError::New(env, "You should provide startX, startY, endX, endY").ThrowAsJavaScriptException();
|
|
91
|
+
return env.Null();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
int startX = info[0].As<Napi::Number>();
|
|
95
|
+
int startY = info[1].As<Napi::Number>();
|
|
96
|
+
int endX = info[2].As<Napi::Number>();
|
|
97
|
+
int endY = info[3].As<Napi::Number>();
|
|
98
|
+
int speed = 100;
|
|
99
|
+
if (info.Length() > 4 && info[4].IsNumber())
|
|
100
|
+
{
|
|
101
|
+
speed = info[4].As<Napi::Number>();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Get the screen metrics
|
|
105
|
+
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
106
|
+
int screenHeight = GetSystemMetrics(SM_CYSCREEN);
|
|
107
|
+
|
|
108
|
+
// Convert coordinates to absolute values
|
|
109
|
+
int absoluteStartX = static_cast<int>((65536 * startX) / screenWidth);
|
|
110
|
+
int absoluteStartY = static_cast<int>((65536 * startY) / screenHeight);
|
|
111
|
+
int absoluteEndX = static_cast<int>((65536 * endX) / screenWidth);
|
|
112
|
+
int absoluteEndY = static_cast<int>((65536 * endY) / screenHeight);
|
|
113
|
+
|
|
114
|
+
// Calculate the distance and duration based on speed
|
|
115
|
+
double distanceX = absoluteEndX - absoluteStartX;
|
|
116
|
+
double distanceY = absoluteEndY - absoluteStartY;
|
|
117
|
+
double distance = sqrt(distanceX * distanceX + distanceY * distanceY);
|
|
118
|
+
double duration = distance / speed;
|
|
119
|
+
|
|
120
|
+
// Move the mouse to the starting position
|
|
121
|
+
INPUT startMouseInput = {0};
|
|
122
|
+
startMouseInput.type = INPUT_MOUSE;
|
|
123
|
+
startMouseInput.mi.dx = absoluteStartX;
|
|
124
|
+
startMouseInput.mi.dy = absoluteStartY;
|
|
125
|
+
startMouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
|
|
126
|
+
startMouseInput.mi.time = 0; // System will provide the timestamp
|
|
127
|
+
|
|
128
|
+
SendInput(1, &startMouseInput, sizeof(startMouseInput));
|
|
129
|
+
|
|
130
|
+
// Perform mouse button down event
|
|
131
|
+
INPUT mouseDownInput = {0};
|
|
132
|
+
mouseDownInput.type = INPUT_MOUSE;
|
|
133
|
+
mouseDownInput.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
|
|
134
|
+
mouseDownInput.mi.time = 0; // System will provide the timestamp
|
|
135
|
+
|
|
136
|
+
SendInput(1, &mouseDownInput, sizeof(mouseDownInput));
|
|
137
|
+
|
|
138
|
+
// Calculate the number of steps based on the duration and desired speed
|
|
139
|
+
const int steps = 100; // Adjust the number of steps for smoother movement
|
|
140
|
+
|
|
141
|
+
// Calculate the incremental values for each step
|
|
142
|
+
double stepX = distanceX / steps;
|
|
143
|
+
double stepY = distanceY / steps;
|
|
144
|
+
|
|
145
|
+
// Move the mouse in increments to simulate dragging with speed control
|
|
146
|
+
for (int i = 0; i < steps; ++i)
|
|
147
|
+
{
|
|
148
|
+
// Calculate the position for the current step
|
|
149
|
+
int currentX = static_cast<int>(absoluteStartX + (stepX * i));
|
|
150
|
+
int currentY = static_cast<int>(absoluteStartY + (stepY * i));
|
|
151
|
+
|
|
152
|
+
// Move the mouse to the current position
|
|
153
|
+
INPUT mouseMoveInput = {0};
|
|
154
|
+
mouseMoveInput.type = INPUT_MOUSE;
|
|
155
|
+
mouseMoveInput.mi.dx = currentX;
|
|
156
|
+
mouseMoveInput.mi.dy = currentY;
|
|
157
|
+
mouseMoveInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE | MOUSEEVENTF_VIRTUALDESK;
|
|
158
|
+
mouseMoveInput.mi.time = 0; // System will provide the timestamp
|
|
159
|
+
|
|
160
|
+
SendInput(1, &mouseMoveInput, sizeof(mouseMoveInput));
|
|
161
|
+
|
|
162
|
+
// Sleep for a short duration to control the speed
|
|
163
|
+
Sleep(static_cast<DWORD>(duration / steps));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Perform mouse button up event
|
|
167
|
+
INPUT mouseUpInput = {0};
|
|
168
|
+
mouseUpInput.type = INPUT_MOUSE;
|
|
169
|
+
mouseUpInput.mi.dwFlags = MOUSEEVENTF_LEFTUP;
|
|
170
|
+
mouseUpInput.mi.time = 0; // System will provide the timestamp
|
|
171
|
+
|
|
172
|
+
SendInput(1, &mouseUpInput, sizeof(mouseUpInput));
|
|
173
|
+
|
|
174
|
+
return Napi::Boolean::New(env, true);
|
|
175
|
+
}
|