Java JNA/WinAPI。模拟鼠标单击而不移动光标';我不能正常工作
编辑:对不起,我不确定我的问题是否正确结束。有人建议我这样做,但它不能回答我的问题。我能够模拟鼠标点击,但它不能像我在问题中描述的那样正常工作Java JNA/WinAPI。模拟鼠标单击而不移动光标';我不能正常工作,java,c++,c,winapi,jna,Java,C++,C,Winapi,Jna,编辑:对不起,我不确定我的问题是否正确结束。有人建议我这样做,但它不能回答我的问题。我能够模拟鼠标点击,但它不能像我在问题中描述的那样正常工作 我仍在学习JNA,并在我的Java应用程序(JNA 5.6.0和JNA平台5.6.0)中使用它,但我希望熟悉C语言的人也能理解我,因为JNA使用的是WinAPI函数。我的操作系统是Windows10 我所拥有的: 启动魔兽争霸III游戏的Swing应用程序运行游戏的exe文件 低级键盘钩子,用于拦截击键低级键盘proc()并调用单击()方法,如下所述
我仍在学习JNA,并在我的Java应用程序(JNA 5.6.0和JNA平台5.6.0)中使用它,但我希望熟悉C语言的人也能理解我,因为JNA使用的是WinAPI函数。我的操作系统是Windows10 我所拥有的:
- 启动魔兽争霸III游戏的Swing应用程序运行游戏的exe文件
- 低级键盘钩子,用于拦截击键
并调用低级键盘proc()
方法,如下所述单击()
- 在按下某些键后(如下图所示),模拟鼠标点击游戏窗口的坐标(库存、技能和控制位置)的逻辑
User32.INSTANCE.SendMessage()
同样的情况发生了,没有单击坐标,而是选择了该区域,并且在SendMessage()
的情况下,我可能不会重新附加图片两次
3.使用User32.INSTANCE.SendInput()
public void单击(KeyBindComponent KeyBindComponent){
映射跳线=获取跳线(键绑定组件);
如果(!cords.isEmpty()){
int xCord=跳线。获取(“宽度”);
int yCord=跳线。获取(“高度”);
mouseMove(xCord,yCord);
鼠标点击();
System.out.println(“x=“+xCord+”y=“+yCord”);
}
}
无效鼠标移动(整数x,整数y){
最终int MOUSEEVENTF_LEFTUP=0x0004;
最终int MOUSEEVENTF_绝对值=0x8000;
输入=新输入();
INPUT[]移动=(INPUT[])INPUT.toArray(2);
//在移动鼠标之前释放鼠标
移动[0]。类型=新DWORD(输入。输入\鼠标);
移动[0].input.setType(“mi”);
移动[0]。input.mi.dwFlags=新的DWORD(MOUSEEVENTF_LEFTUP);
移动[0]。input.mi.dwExtraInfo=new BaseTSD.ULONG_PTR(0);
移动[0]。input.mi.time=新DWORD(0);
移动[0]。input.mi.mouseData=新DWORD(0);
移动[1]。类型=新DWORD(输入。输入\鼠标);
移动[1]。input.mi.dx=新长(x);
移动[1]。input.mi.dy=新长(y);
移动[1]。input.mi.mouseData=新的DWORD(0);
move[1]。input.mi.dwFlags=新的DWORD(MOUSEEVENTF_LEFTUP+MOUSEEVENTF_ABSOLUTE);
user32Library.SendInput(新DWORD(2),move,move[0].size());
}
void mouseClick(){
最终int MOUSEEVENTF_LEFTUP=0x0004;
最终int MOUSEEVENTF_LEFTDOWN=0x0002;
输入=新输入();
INPUT[]点击=(INPUT[])INPUT.toArray(2);
单击[0]。键入=新DWORD(输入。输入\鼠标);
单击[0]。input.setType(“mi”);
单击[0]。input.mi.dwFlags=新DWORD(MOUSEEVENTF_LEFTDOWN);
单击[0]。input.mi.dwExtraInfo=new BaseTSD.ULONG_PTR(0);
单击[0]。input.mi.time=new DWORD(0);
单击[0]。input.mi.mouseData=new DWORD(0);
单击[1]。键入=新DWORD(输入。输入\鼠标);
单击[1].input.setType(“mi”);
单击[1]。input.mi.dwFlags=新DWORD(MOUSEEVENTF_LEFTUP);
单击[1]。input.mi.dwExtraInfo=new BaseTSD.ULONG_PTR(0);
单击[1]。input.mi.time=new DWORD(0);
单击[1]。input.mi.mouseData=new DWORD(0);
user32Library.SendInput(新建DWORD(2),单击,单击[0].size());
}
在这种情况下,根本不需要单击坐标点。相反,当按下某些键时,将在当前鼠标位置单击鼠标
顺便说一下,我也尝试过使用JavaRobot,但它对我不起作用。不幸的是,鼠标光标从起始位置移动(消失)了大约一毫秒,直到您需要单击并返回起始位置
void click(int xCord, int yCord) {
//mouseMove(xCord, yCord);
POINT p = {};
GetCursorPos(&p);
mouseMoveClick(xCord, yCord);
SetCursorPos(p.x, p.y);
}
谢谢你把这篇文章读到最后,我为这么麻烦的解释道歉
谁能告诉我我在代码中犯了什么和哪里的错误?因为在所有3个选项中,我没有达到预期的行为。对于第3种情况,您没有使用
MOUSEEVENTF\u MOVE
标志移动鼠标,因此鼠标实际上没有移动。并且根据:
如果指定了MOUSEEVENTF\u绝对值
,dx和dy包含
0和65535之间的标准化绝对坐标
然后使用MOUSEEVENTF_LEFTDOWN
和MOUSEEVENTF_LEFTUP
单击当前位置
或者,您可以直接将鼠标移动合并到单击事件中:
void mouseMoveClick(int x, int y) {
INPUT click[3] = {};
click[0].type = INPUT_MOUSE;
click[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;// Release the mouse before moving it
DWORD fScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
DWORD fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
click[1].type = INPUT_MOUSE;
click[1].mi.dx = click[2].mi.dx= MulDiv(x, 65535, fScreenWidth);
click[1].mi.dy = click[2].mi.dy= MulDiv(y, 65535, fScreenHeight);
click[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
click[2].type = INPUT_MOUSE;
click[2].mi.dwFlags = MOUSEEVENTF_LEFTUP | MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
SendInput(3, click, sizeof(INPUT));
}
如果要在鼠标单击后移回原始位置,可以使用在移动前记录当前位置。然后使用mouseMove事件或更简单的方法返回该位置
void click(int xCord, int yCord) {
//mouseMove(xCord, yCord);
POINT p = {};
GetCursorPos(&p);
mouseMoveClick(xCord, yCord);
SetCursorPos(p.x, p.y);
}
您的系统(或应用程序)DPI设置是否设置为默认值以外的其他值?@mni如果DPI参数在应用程序中没有更改,则在系统中也会默认配置该参数。如果我们谈论的是鼠标,那么我有一个非常简单的旧鼠标,Sven RX-160,分辨率,DPI 800。你有m吗
void mouseMove(int x, int y) {
INPUT move[2] = {};
DWORD fScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
DWORD fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
move[0].type = move[1].type = INPUT_MOUSE;
move[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;// Release the mouse before moving it
move[1].mi.dx = MulDiv(x, 65535, fScreenWidth);
move[1].mi.dy = MulDiv(y, 65535, fScreenHeight);
move[1].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
SendInput(2, move, sizeof(INPUT));
}
void mouseMoveClick(int x, int y) {
INPUT click[3] = {};
click[0].type = INPUT_MOUSE;
click[0].mi.dwFlags = MOUSEEVENTF_LEFTUP;// Release the mouse before moving it
DWORD fScreenWidth = ::GetSystemMetrics(SM_CXSCREEN);
DWORD fScreenHeight = ::GetSystemMetrics(SM_CYSCREEN);
click[1].type = INPUT_MOUSE;
click[1].mi.dx = click[2].mi.dx= MulDiv(x, 65535, fScreenWidth);
click[1].mi.dy = click[2].mi.dy= MulDiv(y, 65535, fScreenHeight);
click[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
click[2].type = INPUT_MOUSE;
click[2].mi.dwFlags = MOUSEEVENTF_LEFTUP | MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
SendInput(3, click, sizeof(INPUT));
}
void click(int xCord, int yCord) {
//mouseMove(xCord, yCord);
POINT p = {};
GetCursorPos(&p);
mouseMoveClick(xCord, yCord);
SetCursorPos(p.x, p.y);
}