主题
设置窗口光标矫正 - SetWindowCursor
函数简介
通过 识别绑定窗口内的光标图片 得到窗口内真实鼠标坐标,供 真实轨迹 MoveTo 做终点偏差矫正。适用于窗口内绘制了自定义光标、但 GetCursorPos 与游戏/窗口逻辑坐标不一致的场景。
与 SetMousePosCallback 使用 同一套矫正算法(offset = 识别坐标 - 系统坐标,corrected = MoveTo目标 - offset),但本接口 无需编写回调,由插件在 MoveTo 时自动截图并找图。
不影响 GetCursorPos。
接口名称
SetWindowCursorDLL调用
cpp
int SetWindowCursor(long ola, string cursor, double matchVal, int type, double scale, int offsetX, int offsetY);参数说明
| 参数名 | 类型 | 说明 |
|---|---|---|
| ola | 长整数型 | OLAPlug对象的指针,由 CreateCOLAPlugInterFace 接口生成。 |
| cursor | 字符串 | 光标模板图片路径;支持多图 | 分隔,如 "arrow.bmp|hand.bmp"。传 空字符串 表示清除本配置。路径相对 SetPath 或绝对路径。 |
| matchVal | 双精度浮点数 | 相似度,如 0.9,最大为 1。 |
| type | 整数型 | 匹配类型,与 MatchWindowsFromPath 一致:1 灰度;2 彩色;3 透明;4 透明彩色权重;5 普通彩色。 |
| scale | 双精度浮点数 | 窗口缩放比例,通常为 1;可通过 GetScaleFromWindows 获取。 |
| offsetX | 整数型 | 光标图片左上角到指针热点 (0,0) 的 X 偏移(像素)。 |
| offsetY | 整数型 | 光标图片左上角到指针热点 (0,0) 的 Y 偏移(像素)。 |
当 offsetX、offsetY 均为 0 时,插件根据模板 Alpha 通道 自动估算热点(非透明区域左上角),并裁剪后再参与匹配。 |
示例
SDK 调用
cpp
#include "OLAPlugServer.h"
OLAPlugServer ola;
ola.SetPath("D:/game/cursor");
// 自动估算热点,透明光标推荐 type=3
int ret = ola.SetWindowCursor("arrow.bmp|hand.bmp", 0.9, 3, 1.0, 0, 0);
if (ret == 1) {
ola.MoveTo(200, 100); // 真实轨迹下自动按识别到的光标位置矫正终点
}csharp
using OLAPlug;
var ola = new OLAPlugServer();
ola.SetPath(@"D:\game\cursor");
int ret = ola.SetWindowCursor("arrow.bmp|hand.bmp", 0.9, 3, 1.0, 0, 0);
if (ret == 1)
{
ola.MoveTo(200, 100);
}python
from OLAPlugServer import OLAPlugServer
ola = OLAPlugServer()
ola.SetPath(r"D:/game/cursor")
ret = ola.SetWindowCursor("arrow.bmp|hand.bmp", 0.9, 3, 1.0, 0, 0)
if ret == 1:
ola.MoveTo(200, 100)java
import com.olaplug.OLAPlugServer;
OLAPlugServer ola = new OLAPlugServer();
ola.SetPath("D:/game/cursor");
int ret = ola.SetWindowCursor("arrow.bmp|hand.bmp", 0.9, 3, 1.0, 0, 0);
if (ret == 1) {
ola.MoveTo(200, 100);
}cpp
var ola = com("OlaPlug.OlaSoft")
ola.SetPath("D:/game/cursor")
var ret = ola.SetWindowCursor("arrow.bmp|hand.bmp", 0.9, 3, 1.0, 0, 0)
if(ret == 1) {
ola.MoveTo(200, 100)
}vbscript
Set ola = CreateObject("OlaPlug.OlaSoft")
ola.SetPath "D:\game\cursor"
ret = ola.SetWindowCursor("arrow.bmp|hand.bmp", 0.9, 3, 1.0, 0, 0)
If ret = 1 Then
ola.MoveTo 200, 100
End Iftext
.局部变量 ola, OLAPlug
ola.创建 ()
ola.SetPath (“D:\game\cursor”)
ret = ola.SetWindowCursor (“arrow.bmp|hand.bmp”, 0.9, 3, 1.0, 0, 0)
.如果真 (ret = 1)
ola.MoveTo (200, 100)
.如果真结束aardio
import OLAPlugServer;
var ola = OLAPlugServer();
ola.SetPath("D:/game/cursor");
var ret = ola.SetWindowCursor("arrow.bmp|hand.bmp", 0.9, 3, 1.0, 0, 0);
if(ret == 1){
ola.MoveTo(200, 100);
}text
变量 ola <类型 = OLAPlugServer>
ola = 新建 OLAPlugServer
ola.SetPath (“D:\game\cursor”)
整数 ret = ola.SetWindowCursor (“arrow.bmp|hand.bmp”, 0.9, 3, 1.0, 0, 0)
如果真 (ret = 1)
{
ola.MoveTo (200, 100)
}cpp
#include "OLAPlugServer.h"
OLAPlugServer ola;
ola.SetPath("D:/game/cursor");
int32_t ret = ola.SetWindowCursor("arrow.bmp|hand.bmp", 0.9, 3, 1.0, 0, 0);
if (ret == 1) {
ola.MoveTo(200, 100);
}原生 DLL 调用
cpp
long instance = CreateCOLAPlugInterFace();
SetPath(instance, (void*)"D:/game/cursor");
SetWindowCursor(instance, (void*)"arrow.bmp", 0.9, 3, 1.0, 0, 0);
MoveTo(instance, 200, 100);csharp
using System.Runtime.InteropServices;
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern long CreateCOLAPlugInterFace();
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern int SetPath(long ola, string path);
[DllImport("OLAPlug_x64.dll", CallingConvention = CallingConvention.StdCall)]
static extern int SetWindowCursor(long ola, string cursor, double matchVal,
int type, double scale, int offsetX, int offsetY);
long instance = CreateCOLAPlugInterFace();
SetPath(instance, @"D:\game\cursor");
SetWindowCursor(instance, "arrow.bmp", 0.9, 3, 1.0, 0, 0);python
from ctypes import CDLL, c_int, c_int64, c_double, c_char_p
ola = CDLL("OLAPlug_x64.dll")
ola.CreateCOLAPlugInterFace.restype = c_int64
instance = ola.CreateCOLAPlugInterFace()
ola.SetWindowCursor(instance, b"arrow.bmp", c_double(0.9), 1, c_double(1.0), 0, 0)返回值
| 返回值 | 说明 |
|---|---|
1 | 成功(含传空 cursor 清除配置)。 |
0 | 失败(instance 无效、模板均加载失败、远程调用失败等)。 |
工作流程
设置阶段(本接口)
- 解析
cursor路径(|多模板)。 - 主线程预加载全部模板(避免并发访问图片管理器)。
- 多模板时 并行 预处理:热点估算 + 按热点裁剪模板(逻辑同 MatchImageFromPath 多图分支)。
- 缓存预处理后的模板,直至再次调用本接口或销毁 OLA 对象。
MoveTo 识别阶段(插件内部)
- 对绑定窗口 全区域 截图(
0,0,0,0)。 - 多模板时 并行 匹配,首个命中 即作为光标坐标(同
MatchImageFromPath)。 - 识别坐标与 GetCursorPos 求差,矫正 MoveTo 终点(算法见 SetMousePosCallback)。
与 SetMousePosCallback 的关系
| 项目 | 说明 |
|---|---|
| 优先级 | 若 同时 设置了本接口与 SetMousePosCallback,优先使用光标识别;识别失败时再尝试用户回调。 |
| 清除 | ClearMousePosCallback 不会 清除本配置;需调用 SetWindowCursor(ola, "", ...) 传空路径。 |
| 远程 | 本接口 支持 ConnectRemote;配置与识别均在 B 端 执行,模板路径须为 B 端可访问路径。 |
| 回调 | SetMousePosCallback 仍 仅本地 有效(函数指针无法 RPC)。 |
相关配置
| 配置项 | 类型 | 默认 | 说明 |
|---|---|---|---|
| MousePosCallbackMinOffset | 整数型 | 0 | 偏差阈值;与 SetMousePosCallback 共用。 |
| EnableRealMouse | bool | true | 须开启才会走轨迹矫正。 |
| MultiTemplateAbortOnInvalidImage | bool | true | 多模板时任一图加载失败是否整次失败(全局配置)。 |
注意事项
| 项目 | 说明 |
|---|---|
| 须先绑定窗口 | 截图与坐标系依赖 BindWindow / 截图上下文。 |
| 模板质量 | 建议使用带 Alpha 的 BMP/PNG;箭头类光标可传 offsetX/offsetY=0 自动估热点,或手动指定热点像素。 |
| 性能 | MoveTo 每次 ensureMove 可能触发一次全窗找图;模板不宜过大,matchVal 不宜过低。 |
| 识别失败 | 未找到光标时 不矫正,行为与未设置本接口时一致(可回退 SetMousePosCallback)。 |
| 非轨迹 MoveTo | 未开 EnableRealMouse 时 不 触发本矫正(与回调一致)。 |
