From 1a6bbe480bcaf544ff90a35b4db51f74231c12fb Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:03:36 +0000 Subject: [PATCH 01/15] =?UTF-8?q?=E5=A2=9E=E6=B7=BBlsnput=E7=9A=84?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matriller <11452290+matriller@user.noreply.gitee.com> --- source/remote.lspro | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/source/remote.lspro b/source/remote.lspro index 18d49408..8bc93e2c 100755 --- a/source/remote.lspro +++ b/source/remote.lspro @@ -473,3 +473,29 @@ lpt.remote.rtt_w601_iot = { } } +# lsnput + +lpt.remote.lsnput = { + info = { + name = "lsnput", + text = "为洛书而编写的键盘鼠标控制库", + release = "1.7.0.0" + }, + source = { + all = { + "lsnput.h", + "lsnput.c", + "lsnput.els", + "readme.md", + "ELS_lsnput.h", + "ELS_lsnput.c", + "lsnput_script.h" + }, + Ubuntu = { + "makefile", + }, + Windows = { + "makefile", + } + } +} -- Gitee From 52e0c617d18eccb07a733b5adc3d499d08a44cab Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:04:03 +0000 Subject: [PATCH 02/15] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20lsnput?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/lsnput/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/lsnput/.keep diff --git a/source/lsnput/.keep b/source/lsnput/.keep new file mode 100644 index 00000000..e69de29b -- Gitee From fa0c36899667c4eedee05d5fc0ddb0d1fd2b2fa4 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:06:08 +0000 Subject: [PATCH 03/15] =?UTF-8?q?=E5=A2=9E=E5=8A=A0lsnpu=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matriller <11452290+matriller@user.noreply.gitee.com> --- source/lsnput/ELS_lsnput.c | 63 +++++++++++++ source/lsnput/ELS_lsnput.h | 27 ++++++ source/lsnput/lsnput.c | 172 ++++++++++++++++++++++++++++++++++ source/lsnput/lsnput.els | 24 +++++ source/lsnput/lsnput.h | 36 +++++++ source/lsnput/lsnput_script.h | 30 ++++++ source/lsnput/reame.md | 84 +++++++++++++++++ 7 files changed, 436 insertions(+) create mode 100644 source/lsnput/ELS_lsnput.c create mode 100644 source/lsnput/ELS_lsnput.h create mode 100644 source/lsnput/lsnput.c create mode 100644 source/lsnput/lsnput.els create mode 100644 source/lsnput/lsnput.h create mode 100644 source/lsnput/lsnput_script.h create mode 100644 source/lsnput/reame.md diff --git a/source/lsnput/ELS_lsnput.c b/source/lsnput/ELS_lsnput.c new file mode 100644 index 00000000..e82f6321 --- /dev/null +++ b/source/lsnput/ELS_lsnput.c @@ -0,0 +1,63 @@ +#include "ELS_lsnput.h" +#include "lsnput.h" + +#include + +int ELSAPI_lsnput_GetMousePosition(els_VmObj* vm) +{ + LosuObj output = obj_newunit(vm); + MousePosition p; + + //获取鼠标位置 + GetMousePosition(&p); + obj_setunit(vm, output, obj_newstr(vm, "x"), obj_newnum(vm, p.x)); + obj_setunit(vm, output, obj_newstr(vm, "y"), obj_newnum(vm, p.y)); + + arg_return(vm, output); + return 1; +} + +int ELSAPI_lsnput_SetMousePosition(els_VmObj* vm) +{ + MousePosition p; + + //获取要设置的坐标 + p.x = arg_getnum(vm, 2); + p.y = arg_getnum(vm, 3); + + //设置鼠标位置 + if (SetMousePosition(&p)) + arg_returnnum(vm, 1); + else + arg_returnnull(vm); + + return 1; +} + +int ELSAPI_lsnput_MouseAct(els_VmObj* vm) +{ + MouseEvent e; + + e.type = (uint32_t)arg_getnum(vm, 2) | (uint32_t)arg_getnum(vm, 3); //获取鼠标事件的类型 + e.slide = arg_getnum(vm, 4); //获取滑轮滚动的距离 + + if (MouseAct(&e)) + arg_returnnum(vm, 1); + else + arg_returnnull(vm); + + return 1; +} + +int ELSAPI_lsnput_click(els_VmObj *vm) +{ + MousePosition p; + uint8_t type = arg_getnum(vm, 2); + + GetMousePosition(&p); + if (MouseClick(&p, type)) + arg_returnnum(vm, 1); + else + arg_returnnull(vm); + return 1; +} diff --git a/source/lsnput/ELS_lsnput.h b/source/lsnput/ELS_lsnput.h new file mode 100644 index 00000000..57ae55eb --- /dev/null +++ b/source/lsnput/ELS_lsnput.h @@ -0,0 +1,27 @@ +#ifndef ELS_LSINPUT_H_ +#define ELS_LSINPUT_H_ + +#include "els.h" +#include "lsnput_script.h" + +int ELSAPI_lsnput_GetMousePosition(els_VmObj* vm); +int ELSAPI_lsnput_SetMousePosition(els_VmObj* vm); +int ELSAPI_lsnput_MouseAct(els_VmObj* vm); +int ELSAPI_lsnput_click(els_VmObj *vm); + +void ElsLib_lsnput_libinit(els_VmObj *vm) +{ + LosuObj lib = obj_newunit(vm); + + vm_setval(vm, "lsnput", &lib); + + obj_setunit(vm, lib, obj_newstr(vm, "get_mouse_position"), obj_newfunction(vm, ELSAPI_lsnput_GetMousePosition)); + obj_setunit(vm, lib, obj_newstr(vm, "set_mouse_position"), obj_newfunction(vm, ELSAPI_lsnput_SetMousePosition)); + obj_setunit(vm, lib, obj_newstr(vm, "mouse_act"), obj_newfunction(vm, ELSAPI_lsnput_MouseAct)); + obj_setunit(vm, lib, obj_newstr(vm, "click"), obj_newfunction(vm, ELSAPI_lsnput_click)); + //obj_setunit(vm, lib, obj_newstr(vm, ""), obj_newfunction(vm, ELSAPI_lsnput_)); + + vm_dostring(vm, lsnput_script); +} + +#endif diff --git a/source/lsnput/lsnput.c b/source/lsnput/lsnput.c new file mode 100644 index 00000000..8ac98226 --- /dev/null +++ b/source/lsnput/lsnput.c @@ -0,0 +1,172 @@ +#include "lsnput.h" + +/* + Windows系统实现 +*/ +#ifdef LOSU_WINDOWS + +#include + +inline bool GetMousePosition(MousePosition *position) +{ + /* + BOOL GetCursorPos( + [out] LPPOINT lpPoint + ); + + 检索鼠标光标的位置(以屏幕坐标为单位)。 + + 参数 + [out] lpPoint + 类型: LPPOINT + 指向接收光标屏幕坐标的 POINT 结构的指针。 + + 返回值 + 类型: BOOL + 如果成功,则返回非零值,否则返回零。 要获得更多的错误信息,请调用 GetLastError。 + + 注解 + 光标位置始终在屏幕坐标中指定,不受包含光标的窗口的映射模式的影响。 + 调用进程必须具有对窗口工作站 WINSTA_READATTRIBUTES 访问权限。 + 调用 GetCursorPos 时,输入桌面必须是当前桌面。 调用 OpenInputDesktop 以确定当前桌面是否为输入桌面。 + 如果不是,请使用 OpenInputDesktop 返回的 HDESK 调用 SetThreadDesktop 以切换到该桌面。 + */ + + bool output; + POINT pt; + + output = GetCursorPos(&pt); + position->x = pt.x; + position->y = pt.y; + + return output; +} + +inline bool SetMousePosition(MousePosition *position) +{ + /* + BOOL SetCursorPos( + [in] int X, + [in] int Y + ); + + 将光标移动到指定的屏幕坐标。 如果新坐标不在由最近的 ClipCursor 函数调用设置的屏幕矩形内,则系统会自动调整坐标,使光标停留在矩形内。 + + 参数 + [in] X + 类型: int + 光标的新 x 坐标(以屏幕坐标为单位)。 + + [in] Y + 类型: int + 光标的新 y 坐标(以屏幕坐标为单位)。 + + 返回值 + 类型: BOOL + 如果成功,则返回非零值,否则返回零。 要获得更多的错误信息,请调用 GetLastError。 + + 注解 + 游标是共享资源。 仅当光标位于窗口工作区时,窗口才应移动光标。 + 调用进程必须具有对窗口工作站 WINSTA_WRITEATTRIBUTES 访问权限。 + 调用 SetCursorPos 时,输入桌面必须是当前桌面。 调用 OpenInputDesktop 以确定当前桌面是否为输入桌面。 + 如果不是,请使用 OpenInputDesktop 返回的 HDESK 调用 SetThreadDesktop 以切换到该桌面。 + */ + return SetCursorPos(position->x, position->y); +} + +bool MouseAct(MouseEvent *event) +{ + /* + void mouse_event( + [in] DWORD dwFlags, + [in] DWORD dx, + [in] DWORD dy, + [in] DWORD dwData, + [in] ULONG_PTR dwExtraInfo + ); + + mouse_event 函数合成鼠标运动和按钮单击。 + + + */ + DWORD dwFlags, dwData; + + switch (event->type) + { + case LSNPUT_MOUSE_LEFT | LSNPUT_MOUSE_DOWN: + //左键向下 + dwFlags = MOUSEEVENTF_LEFTDOWN; + break; + case LSNPUT_MOUSE_LEFT | LSNPUT_MOUSE_UP: + //左键向上 + dwFlags = MOUSEEVENTF_LEFTUP; + break; + case LSNPUT_MOUSE_RIGHT | LSNPUT_MOUSE_DOWN: + //右键向下 + dwFlags = MOUSEEVENTF_RIGHTDOWN; + break; + case LSNPUT_MOUSE_RIGHT | LSNPUT_MOUSE_UP: + //右键向上 + dwFlags = MOUSEEVENTF_RIGHTUP; + break; + case LSNPUT_MOUSE_MID | LSNPUT_MOUSE_DOWN: + //中键向下 + if (event->slide == 0) + { + //纯向下 + dwFlags = MOUSEEVENTF_MIDDLEDOWN; + dwData = 0; + } + else + { + //滚轮滑动 + dwFlags = MOUSEEVENTF_WHEEL; + dwData = event->slide; + } + break; + case LSNPUT_MOUSE_MID | LSNPUT_MOUSE_UP: + //中键向上 + dwFlags = MOUSEEVENTF_MIDDLEUP; + break; + default: + return false; + } + + mouse_event(dwFlags, 0, 0, dwData, 0); + + return true; +} + +#endif + +/* + Linux系统实现 +*/ + +#ifdef LOSU_LINUX + +#endif + + +/* + 通用操作系统实现 +*/ + +bool MouseClick(MousePosition *p, uint64_t type) +{ + MouseEvent e; + + e.slide = 0; + SetMousePosition(p); + + if (type & 0b00000111) + { + e.type = type | LSNPUT_MOUSE_DOWN; + MouseAct(&e); + e.type = type | LSNPUT_MOUSE_UP; + MouseAct(&e); + return true; + } + return false; +} + diff --git a/source/lsnput/lsnput.els b/source/lsnput/lsnput.els new file mode 100644 index 00000000..f827efbd --- /dev/null +++ b/source/lsnput/lsnput.els @@ -0,0 +1,24 @@ +import('stdlib') + +lsnput.mouse = {} + +lsnput.mouse.LEFT = 1 +lsnput.mouse.RIGHT = 2 +lsnput.mouse.MID = 4 +lsnput.mouse.UP = 8 +lsnput.mouse.DOWN = 16 + +键鼠事件 = {} + +键鼠事件.鼠标 = {} + +键鼠事件.获取鼠标坐标 = lsnput.get_mouse_position +键鼠事件.设置鼠标坐标 = lsnput.set_mouse_position +键鼠事件.鼠标操作 = lsnput.mouse_act +键鼠事件.点击 = lsnput.click + +键鼠事件.鼠标.左 = 1 +键鼠事件.鼠标.右 = 2 +键鼠事件.鼠标.中 = 4 +键鼠事件.鼠标.抬起 = 8 +键鼠事件.鼠标.摁下 = 16 diff --git a/source/lsnput/lsnput.h b/source/lsnput/lsnput.h new file mode 100644 index 00000000..916bab81 --- /dev/null +++ b/source/lsnput/lsnput.h @@ -0,0 +1,36 @@ +#ifndef LSNPUT_H_ +#define LSNPUT_H_ + +/* + 洛书的监听、操作鼠标和键盘的模块 + 作者:Matriller + 立项时间:2023-9-29 + 历史维护者:Matriller + 版本:1.7.0.1 +*/ + +#include +#include + +#define LSNPUT_MOUSE_LEFT 0b00000001 +#define LSNPUT_MOUSE_RIGHT 0b00000010 +#define LSNPUT_MOUSE_MID 0b00000100 +#define LSNPUT_MOUSE_UP 0b00001000 +#define LSNPUT_MOUSE_DOWN 0b00010000 + +typedef struct { + uint32_t x; //鼠标的x轴坐标 + uint32_t y; //鼠标的y轴坐标 +} MousePosition; + +typedef struct { + uint8_t type; //鼠标事件的类型 + uint8_t slide; //鼠标中键滑动的距离。当type为LSNPUT_MOUSE_MID | LSNPUT_MOUSE_DOWN此值才有效。 +} MouseEvent; + +bool GetMousePosition(MousePosition *position); //获取鼠标位置 +bool SetMousePosition(MousePosition *position); //设置鼠标位置 +bool MouseAct(MouseEvent *event); //设置鼠标事件 +bool MouseClick(MousePosition *p, uint64_t type); //将鼠标移到指定位置,并点击相应的键 + +#endif \ No newline at end of file diff --git a/source/lsnput/lsnput_script.h b/source/lsnput/lsnput_script.h new file mode 100644 index 00000000..3f079bec --- /dev/null +++ b/source/lsnput/lsnput_script.h @@ -0,0 +1,30 @@ +#ifndef LSINPUT_SCRIPT_H_ +#define LSINPUT_SCRIPT_H_ + +const char lsnput_script[] = { +105, 109, 112, 111, 114, 116, 40, 39, 115, 116, 100, 108, 105, 98, 39, 41, 10, 10, 108, 115, 110, 112, 117, 116, +46, 109, 111, 117, 115, 101, 32, 61, 32, 123, 125, 10, 10, 108, 115, 110, 112, 117, 116, 46, 109, 111, 117, 115, +101, 46, 76, 69, 70, 84, 32, 61, 32, 49, 10, 108, 115, 110, 112, 117, 116, 46, 109, 111, 117, 115, 101, 46, +82, 73, 71, 72, 84, 32, 61, 32, 50, 10, 108, 115, 110, 112, 117, 116, 46, 109, 111, 117, 115, 101, 46, 77, +73, 68, 32, 61, 32, 52, 10, 108, 115, 110, 112, 117, 116, 46, 109, 111, 117, 115, 101, 46, 85, 80, 32, 61, +32, 56, 10, 108, 115, 110, 112, 117, 116, 46, 109, 111, 117, 115, 101, 46, 68, 79, 87, 78, 32, 61, 32, 49, +54, 10, 10, 233, 148, 174, 233, 188, 160, 228, 186, 139, 228, 187, 182, 32, 61, 32, 123, 125, 10, 10, 233, 148, +174, 233, 188, 160, 228, 186, 139, 228, 187, 182, 46, 233, 188, 160, 230, 160, 135, 32, 61, 32, 123, 125, 10, 10, +233, 148, 174, 233, 188, 160, 228, 186, 139, 228, 187, 182, 46, 232, 142, 183, 229, 143, 150, 233, 188, 160, 230, 160, +135, 229, 157, 144, 230, 160, 135, 32, 61, 32, 108, 115, 110, 112, 117, 116, 46, 103, 101, 116, 95, 109, 111, 117, +115, 101, 95, 112, 111, 115, 105, 116, 105, 111, 110, 10, 233, 148, 174, 233, 188, 160, 228, 186, 139, 228, 187, 182, +46, 232, 174, 190, 231, 189, 174, 233, 188, 160, 230, 160, 135, 229, 157, 144, 230, 160, 135, 32, 61, 32, 108, 115, +110, 112, 117, 116, 46, 115, 101, 116, 95, 109, 111, 117, 115, 101, 95, 112, 111, 115, 105, 116, 105, 111, 110, 10, +233, 148, 174, 233, 188, 160, 228, 186, 139, 228, 187, 182, 46, 233, 188, 160, 230, 160, 135, 230, 147, 141, 228, 189, +156, 32, 61, 32, 108, 115, 110, 112, 117, 116, 46, 109, 111, 117, 115, 101, 95, 97, 99, 116, 10, 233, 148, 174, +233, 188, 160, 228, 186, 139, 228, 187, 182, 46, 231, 130, 185, 229, 135, 187, 32, 61, 32, 108, 115, 110, 112, 117, +116, 46, 99, 108, 105, 99, 107, 10, 10, 233, 148, 174, 233, 188, 160, 228, 186, 139, 228, 187, 182, 46, 233, 188, +160, 230, 160, 135, 46, 229, 183, 166, 32, 61, 32, 49, 10, 233, 148, 174, 233, 188, 160, 228, 186, 139, 228, 187, +182, 46, 233, 188, 160, 230, 160, 135, 46, 229, 143, 179, 32, 61, 32, 50, 10, 233, 148, 174, 233, 188, 160, 228, +186, 139, 228, 187, 182, 46, 233, 188, 160, 230, 160, 135, 46, 228, 184, 173, 32, 61, 32, 52, 10, 233, 148, 174, +233, 188, 160, 228, 186, 139, 228, 187, 182, 46, 233, 188, 160, 230, 160, 135, 46, 230, 138, 172, 232, 181, 183, 32, +61, 32, 56, 10, 233, 148, 174, 233, 188, 160, 228, 186, 139, 228, 187, 182, 46, 233, 188, 160, 230, 160, 135, 46, +230, 145, 129, 228, 184, 139, 32, 61, 32, 49, 54, 10 +}; + +#endif \ No newline at end of file diff --git a/source/lsnput/reame.md b/source/lsnput/reame.md new file mode 100644 index 00000000..9d7cbba7 --- /dev/null +++ b/source/lsnput/reame.md @@ -0,0 +1,84 @@ +# lsnput脚本层文档 + +本模块提供了监听、操作键盘和鼠标的功能。目前仅实现Windows平台下鼠标的监听和操作。计划在2.0.0.1版本发布Windows平台下键盘的监听和操作功能。 + +## 获取鼠标位置 + +要获取鼠标位置,可以使用lsnput.get_mouse_position或“键鼠事件.获取鼠标坐标”来实现. + +该函数的返回值是一个单元,x轴值储存在x成员中,y轴值储存在y成员中. + +下面是例程 + +```c +引("lsnput") + +令 鼠标位置 = 键鼠事件.获取鼠标坐标() + +打印(鼠标位置.x) +打印(鼠标位置.y) + +``` + +## 更改鼠标位置 + +要更改鼠标位置,可以使用lsnput.set_mouse_position或“键鼠事件.设置鼠标坐标”. + +下面是例程 + +```c +引('lsnput') + +键鼠事件.设置鼠标坐标(0, 0) #鼠标会被设置到0, 0处 +``` + +## 设置鼠标事件 + +要设置鼠标事件,可以使用lsnput.mouse_act或“键鼠事件.鼠标操作” +这两个函数都对应同一个C接口函数。函数接受两个参数, + +下面是例程 + +```c +引("lsnput") + +#鼠标要摁下后抬起才算完成一次点击 +键鼠事件.鼠标操作(键鼠事件.鼠标.左, 键鼠事件.鼠标.摁下) +键鼠事件.鼠标操作(键鼠事件.鼠标.左, 键鼠事件.鼠标.抬起) + +``` + +## 控制鼠标点击 + +一次完整的鼠标点击包括鼠标摁下和抬起。lsnput封装了这两个操作。 +该函数名为lsnput.click或“键鼠事件.点击”. + +下面是例程 + +```c +引("lsnput") + +鼠标事件.点击(键鼠事件.鼠标.左) #会点击一下左键 + +``` + +## 关于鼠标事件类型 + +鼠标事件类型用于lsnput.mouse_act和lsnput.click中,有如下值 + +```c + +lsnput.mouse.LEFT = 1 +lsnput.mouse.RIGHT = 2 +lsnput.mouse.MID = 4 +lsnput.mouse.UP = 8 +lsnput.mouse.DOWN = 16 + +键鼠事件.鼠标.左 = 1 +键鼠事件.鼠标.右 = 2 +键鼠事件.鼠标.中 = 4 +键鼠事件.鼠标.抬起 = 8 +键鼠事件.鼠标.摁下 = 16 + +``` + -- Gitee From 76119cdfb54716a0c341c0e2a5fabd4f98a3cbc0 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:06:19 +0000 Subject: [PATCH 04/15] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20BIN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/lsnput/BIN/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/lsnput/BIN/.keep diff --git a/source/lsnput/BIN/.keep b/source/lsnput/BIN/.keep new file mode 100644 index 00000000..e69de29b -- Gitee From 2c9363d070dc85a54736e3136bc22a4c83371e08 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:06:31 +0000 Subject: [PATCH 05/15] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20Windows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/lsnput/Windows/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/lsnput/Windows/.keep diff --git a/source/lsnput/Windows/.keep b/source/lsnput/Windows/.keep new file mode 100644 index 00000000..e69de29b -- Gitee From 86596533e37a5e4b7a8e24c3681c02a3339bc9b9 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:06:43 +0000 Subject: [PATCH 06/15] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20Ubuntu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/lsnput/Ubuntu/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/lsnput/Ubuntu/.keep diff --git a/source/lsnput/Ubuntu/.keep b/source/lsnput/Ubuntu/.keep new file mode 100644 index 00000000..e69de29b -- Gitee From 36598bc83d0e999c37b0a74bcf47f921aa247631 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:06:55 +0000 Subject: [PATCH 07/15] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20WIKI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/lsnput/WIKI/.keep | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/lsnput/WIKI/.keep diff --git a/source/lsnput/WIKI/.keep b/source/lsnput/WIKI/.keep new file mode 100644 index 00000000..e69de29b -- Gitee From 6866649f7904d571aed0794d1067ead3f7980e25 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:07:21 +0000 Subject: [PATCH 08/15] =?UTF-8?q?=E6=96=B0=E5=BB=BA=20=E5=8E=86=E5=8F=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "source/lsnput/WIKI/\345\216\206\345\217\262/.keep" | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 "source/lsnput/WIKI/\345\216\206\345\217\262/.keep" diff --git "a/source/lsnput/WIKI/\345\216\206\345\217\262/.keep" "b/source/lsnput/WIKI/\345\216\206\345\217\262/.keep" new file mode 100644 index 00000000..e69de29b -- Gitee From 40949ccdae3e6c67bb90969496f9a53c71d77fa0 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:07:48 +0000 Subject: [PATCH 09/15] =?UTF-8?q?lsnput=E7=9A=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matriller <11452290+matriller@user.noreply.gitee.com> --- source/lsnput/WIKI/c.md | 114 +++++++++++++++++++++++++++++++++++ source/lsnput/WIKI/script.md | 84 ++++++++++++++++++++++++++ 2 files changed, 198 insertions(+) create mode 100644 source/lsnput/WIKI/c.md create mode 100644 source/lsnput/WIKI/script.md diff --git a/source/lsnput/WIKI/c.md b/source/lsnput/WIKI/c.md new file mode 100644 index 00000000..77d03135 --- /dev/null +++ b/source/lsnput/WIKI/c.md @@ -0,0 +1,114 @@ +# lsnput C层文档 + +lsnput的C层被设计为是平台无关的,但是目前只有Windows实现。 +欲使用lsnput的C层代码,可包含lsnput.h,之后编译lsnput.c。 + +## 获取和设置鼠标位置 + +想要获取鼠标位置,需要先创建一个MousePosition对象,之后将MousePosition*传递给GetMousePosition。 +想要设置鼠标位置,需要填写好MousePosition对象,之后将它的指针传递给SetMousePosion。 + +这两个函数的使用例程如下 + +```c +#include "lsnput.h" + +#include + +int main() +{ + MousePosition p; + + GetMousePosition(&p); //获取坐标 + printf("the position of mouse is x:%u, y:%u.\n", p.x, p.y); //打印坐标。中文字面量有乱码等问题,此处采用英文。 + + //将坐标都向正方形移动5个像素 + p.x += 5; + p.y += 5; + + SetMousePosition(&p); //设置新坐标。此时鼠标应向右下角移动。 + + return 0; +} + +``` + +## 设置鼠标事件 + +设置鼠标事件,需要用到MouseAct函数和MouseEvent类型。其原型如下: + +```c +typedef struct { + uint8_t type; //鼠标事件的类型 + uint8_t slide; //鼠标中键滑动的距离。当type为LSNPUT_MOUSE_MID | LSNPUT_MOUSE_DOWN此值才有效。 +} MouseEvent; + + +bool MouseAct(MouseEvent *event); //设置鼠标事件 +``` + +MouseEvent的type成员可以有以下可能值: + ++ LSNPUT_MOUSE_LEFT 鼠标的左键 ++ LSNPUT_MOUSE_RIGHT 鼠标的右键 ++ LSNPUT_MOUSE_MID 鼠标的中键 ++ LSNPUT_MOUSE_UP 鼠标向上 ++ LSNPUT_MOUSE_DOWN 鼠标向下 + +这些值直接可以通过|运算符拼接 + +下面是一个例程 + +```c +#include "lsnput.h" + +int main() +{ + MouseEvent e; + + e.type = LSNPUT_MOUSE_LEFT | LSNPUT_MOUSE_DOWN; //类型为左键向下,即摁下左键 + MouseEvent(&e); + + e.type = LSNPUT_MOUSE_LEFT | LSNPUT_MOUSE_UP; //摁下左键后,要恢复左键 + MouseEvent(&e); + + return 0; +} + +``` + +## 高层API + +lsnput封装了MouseClick函数,将鼠标移到指定位置并摁下相应的键。该函数不能处理中键的滚动。 +MouseClick函数中会调用SetMousePosition、MouseAct,将鼠标移到对应位置,将对应键摁下并抬起。 + +原型如下 + +```c + +bool MouseClick(MousePosition *p, uint64_t type); //将鼠标移到指定位置,并点击相应的键 + +``` + +下面是一个例程 + +```c +#include "lsnput.h" + +int main() +{ + MousePosition p; + + GetMousePosition(&p); //获取当前位置 + + //移动鼠标位置 + p.x += 25; + p.y += 25; + + //按下鼠标左键 + MouseClick(&p, LSNPUT_MOUSE_LEFT); + + return 0; +} + +``` diff --git a/source/lsnput/WIKI/script.md b/source/lsnput/WIKI/script.md new file mode 100644 index 00000000..9d7cbba7 --- /dev/null +++ b/source/lsnput/WIKI/script.md @@ -0,0 +1,84 @@ +# lsnput脚本层文档 + +本模块提供了监听、操作键盘和鼠标的功能。目前仅实现Windows平台下鼠标的监听和操作。计划在2.0.0.1版本发布Windows平台下键盘的监听和操作功能。 + +## 获取鼠标位置 + +要获取鼠标位置,可以使用lsnput.get_mouse_position或“键鼠事件.获取鼠标坐标”来实现. + +该函数的返回值是一个单元,x轴值储存在x成员中,y轴值储存在y成员中. + +下面是例程 + +```c +引("lsnput") + +令 鼠标位置 = 键鼠事件.获取鼠标坐标() + +打印(鼠标位置.x) +打印(鼠标位置.y) + +``` + +## 更改鼠标位置 + +要更改鼠标位置,可以使用lsnput.set_mouse_position或“键鼠事件.设置鼠标坐标”. + +下面是例程 + +```c +引('lsnput') + +键鼠事件.设置鼠标坐标(0, 0) #鼠标会被设置到0, 0处 +``` + +## 设置鼠标事件 + +要设置鼠标事件,可以使用lsnput.mouse_act或“键鼠事件.鼠标操作” +这两个函数都对应同一个C接口函数。函数接受两个参数, + +下面是例程 + +```c +引("lsnput") + +#鼠标要摁下后抬起才算完成一次点击 +键鼠事件.鼠标操作(键鼠事件.鼠标.左, 键鼠事件.鼠标.摁下) +键鼠事件.鼠标操作(键鼠事件.鼠标.左, 键鼠事件.鼠标.抬起) + +``` + +## 控制鼠标点击 + +一次完整的鼠标点击包括鼠标摁下和抬起。lsnput封装了这两个操作。 +该函数名为lsnput.click或“键鼠事件.点击”. + +下面是例程 + +```c +引("lsnput") + +鼠标事件.点击(键鼠事件.鼠标.左) #会点击一下左键 + +``` + +## 关于鼠标事件类型 + +鼠标事件类型用于lsnput.mouse_act和lsnput.click中,有如下值 + +```c + +lsnput.mouse.LEFT = 1 +lsnput.mouse.RIGHT = 2 +lsnput.mouse.MID = 4 +lsnput.mouse.UP = 8 +lsnput.mouse.DOWN = 16 + +键鼠事件.鼠标.左 = 1 +键鼠事件.鼠标.右 = 2 +键鼠事件.鼠标.中 = 4 +键鼠事件.鼠标.抬起 = 8 +键鼠事件.鼠标.摁下 = 16 + +``` + -- Gitee From 413ff545629238d76c4ba097dfff6dc5448093e4 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:08:19 +0000 Subject: [PATCH 10/15] =?UTF-8?q?Windows=E5=B9=B3=E5=8F=B0=E4=B8=8B?= =?UTF-8?q?=E7=9A=84makefile=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matriller <11452290+matriller@user.noreply.gitee.com> --- source/lsnput/Windows/makefile | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 source/lsnput/Windows/makefile diff --git a/source/lsnput/Windows/makefile b/source/lsnput/Windows/makefile new file mode 100644 index 00000000..99cdbd29 --- /dev/null +++ b/source/lsnput/Windows/makefile @@ -0,0 +1,9 @@ +OBJ = ElsLib_lsnput.lsd +BASE = Els_lsnput.o lsnput.o +CFLAGE = -O3 -std=c99 -Wall -DLOSU_WINDOWS -I ../buildenv -fPIC -L ../buildenv -l:libeasylosu.dll -lUrlmon -lUser32 -lkernel32 -lWininet -lm -static -shared -s +CC = gcc + +OBJ: + $(CC) Els_lsnput.c lsnput.c -c $(CFLAGE) + $(CC) -o $(OBJ) $(BASE) $(CFLAGE) + \ No newline at end of file -- Gitee From e00248f0d15db742a1fe08aa1f1f10d7643bc88d Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:12:38 +0000 Subject: [PATCH 11/15] =?UTF-8?q?Ubuntu=E7=B3=BB=E7=BB=9F=E4=B8=8B?= =?UTF-8?q?=E7=9A=84makefile=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matriller <11452290+matriller@user.noreply.gitee.com> --- source/lsnput/Ubuntu/makefile | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 source/lsnput/Ubuntu/makefile diff --git a/source/lsnput/Ubuntu/makefile b/source/lsnput/Ubuntu/makefile new file mode 100644 index 00000000..865925f4 --- /dev/null +++ b/source/lsnput/Ubuntu/makefile @@ -0,0 +1,14 @@ +OBJ = ElsLib_lsnput.lsd +BASE = Els_lsnput.o lsnput.o +CFLAGS= -O3 -std=c99 -Wall -DLOSU_LINUX -I ../buildenv -fPIC +CC=gcc +T=./ElsLib_lsnput.lsd + + +all: $T + +$T: $(OBJS) + $(CC) -o $@ $(OBJS) $(BASE) -shared -lm -s -lc -O3 + +clean: + rm -rf $T $(OBJS) $(BASE) core core.* \ No newline at end of file -- Gitee From 4a2d3e3f5557412533947c45bdcd1d6310207036 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:16:47 +0000 Subject: [PATCH 12/15] =?UTF-8?q?1.7.0.0=E7=89=88=E6=9C=AC=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matriller <11452290+matriller@user.noreply.gitee.com> --- "source/lsnput/WIKI/\345\216\206\345\217\262/1.7.0.0.md" | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 "source/lsnput/WIKI/\345\216\206\345\217\262/1.7.0.0.md" diff --git "a/source/lsnput/WIKI/\345\216\206\345\217\262/1.7.0.0.md" "b/source/lsnput/WIKI/\345\216\206\345\217\262/1.7.0.0.md" new file mode 100644 index 00000000..4e7886e7 --- /dev/null +++ "b/source/lsnput/WIKI/\345\216\206\345\217\262/1.7.0.0.md" @@ -0,0 +1,6 @@ +# 1.7.0.0 版本文档 + +这是lsnput的第一个发行版,只完成了Windows平台下的鼠标位置获取与设置、鼠标事件的设置。鼠标事件的监听和键盘系列的实现还在酝酿。 + +本模块在设计时的受众主要是Windows平台下的普通用户,并非开发者。但是C层代码为开发者精心设置了接口。这样lsnput的脚本层和C层都可以是一个跨平台的鼠标键盘处理模块,成为编程人员的好帮手。 + -- Gitee From 4f454bafc8c5fb6051248e8b618f3a7f6d8c03f6 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:19:20 +0000 Subject: [PATCH 13/15] =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D=20source/lsnp?= =?UTF-8?q?ut/reame.md=20=E4=B8=BA=20source/lsnput/readme.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/lsnput/{reame.md => readme.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename source/lsnput/{reame.md => readme.md} (100%) diff --git a/source/lsnput/reame.md b/source/lsnput/readme.md similarity index 100% rename from source/lsnput/reame.md rename to source/lsnput/readme.md -- Gitee From 21f9ad101c40db176bbce4416b814974ea3a52d9 Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:21:41 +0000 Subject: [PATCH 14/15] =?UTF-8?q?=E9=92=88=E5=AF=B9lsnput=E7=9A=84?= =?UTF-8?q?=E5=B0=8F=E8=A1=A5=E4=B8=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matriller <11452290+matriller@user.noreply.gitee.com> --- source/lsnput/lsnput.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/lsnput/lsnput.c b/source/lsnput/lsnput.c index 8ac98226..7e150820 100644 --- a/source/lsnput/lsnput.c +++ b/source/lsnput/lsnput.c @@ -91,6 +91,8 @@ bool MouseAct(MouseEvent *event) */ DWORD dwFlags, dwData; + dwData = 0; + switch (event->type) { case LSNPUT_MOUSE_LEFT | LSNPUT_MOUSE_DOWN: @@ -112,11 +114,8 @@ bool MouseAct(MouseEvent *event) case LSNPUT_MOUSE_MID | LSNPUT_MOUSE_DOWN: //中键向下 if (event->slide == 0) - { //纯向下 dwFlags = MOUSEEVENTF_MIDDLEDOWN; - dwData = 0; - } else { //滚轮滑动 -- Gitee From 7cc3585f458f40e2074efd987cf88bae6d1283ed Mon Sep 17 00:00:00 2001 From: Matriller <11452290+matriller@user.noreply.gitee.com> Date: Sat, 30 Sep 2023 09:23:41 +0000 Subject: [PATCH 15/15] =?UTF-8?q?Windows=E4=BA=8C=E8=BF=9B=E5=88=B6?= =?UTF-8?q?=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matriller <11452290+matriller@user.noreply.gitee.com> --- .../lsnput/BIN/ElsLib_lsnput_Windows_amd64.lsd | Bin 0 -> 22016 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source/lsnput/BIN/ElsLib_lsnput_Windows_amd64.lsd diff --git a/source/lsnput/BIN/ElsLib_lsnput_Windows_amd64.lsd b/source/lsnput/BIN/ElsLib_lsnput_Windows_amd64.lsd new file mode 100644 index 0000000000000000000000000000000000000000..4805c529d1d04083d45ca520497ea5c4a91dc099 GIT binary patch literal 22016 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 ~oOV0(_hHVmUWiYPQ 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 literal 0 HcmV?d00001 -- Gitee