有个比较奇怪的想法,windows系统通过java代码获取当前桌面的某些应用的坐标,继而利用robot来操作界面。
问题
好吧,在一番搜索之后发现java原生或许没有这个功能,只能求助于JNI,通过调用 C/C来实现。 这里记录一下JNI的生成过程以及FindWindow()方法的调用。。。(本人未使用过C/C,代码里可能有错误)。
创建Java类
public class WindowsUtil {
static {
System.loadLibrary("WindowsUtil");
}
public native String getXY(String title);
public static void main(String[] args) {
WindowsUtil util = new WindowsUtil();
System.out.println(util.getXY("123"));;
}
}
这里 WindowsUtil 是之后我们要生成的dll文件名。 getXY()是 JNI的调用方法。 这里的参数title,在后面没有用到。。。可以不写,相应的头文件和cpp文件把这个参数删去。
创建头文件
打开cmd,切换到java文件所在目录。
javac -h . WindowsUtil.java
我这里使用的是 jdk12, 如果是jdk8的话请用 javah 之后会在当前目录下生成class文件和.h头文件。
创建C/C++项目
因为本文没有从事过C/C++开发,这里应该有坑。。。。 本来是计划简单的使用VS Code和clang/mingw64来编译的,奈何基础知识不够,放弃。。。继而使用Visual Studio2019。
- 新建 《MFC动态链接库》项目,用来生成.dll文件
- 修改运行环境为x64(根据个人情况)
- 添加java 的 JNI 头文件目录(项目属性--> VC++目录-->包含目录-->添加jdk/include/win32 和 jdk/include)
- 新建 cpp文件
#include "pch.h"
#include "com_sxhjhf_robot_WindowsUtil.h"
JNIEXPORT jstring JNICALL Java_com_sxhjhf_robot_WindowsUtil_getXY
(JNIEnv* env, jobject obj, jstring str)
{
HWND hwnd;
RECT rect;
CString sstr;
CString ssstr;
char szTitle[MAX_PATH];
hwnd = FindWindow(_T("SWT_Window0"), NULL);
if (NULL != hwnd)
{
GetWindowText(hwnd, (LPWSTR)(LPCTSTR)(szTitle), MAX_PATH);
GetWindowRect(hwnd, &rect);
sstr.Format(_T("%s ??? %d %d %d %d \n"), szTitle, rect.top, rect.right, rect.bottom, rect.left);
ssstr = sstr;
while (NULL != hwnd)
{
hwnd = ::FindWindowEx(NULL, hwnd, _T("SWT_Window0"), NULL);
if (NULL != hwnd)
{
GetWindowRect(hwnd, &rect);
GetWindowText(hwnd, (LPWSTR)(LPCTSTR)(szTitle), MAX_PATH);
sstr.Format(_T("%s ??? %d %d %d %d \n"), szTitle, rect.top, rect.right, rect.bottom, rect.left);
ssstr = ssstr + sstr;
}
}
}
//int w = rect.right - rect.left, h = rect.bottom - rect.top;
//MoveWindow(hwnd, 100, 100, w, h, false);
USES_CONVERSION;
char* chars = T2A(ssstr);
return env->NewStringUTF(chars);
}
- 生成dll
- 将生成的dll文件放入jdk/bin下面
- 运行java程序 输出结果如下
e_space - robot/src/main/java/com/sxhjhf/robot/WindowsUtil.java - Eclipse IDE ??? -8 3848 1048 1912
e_space2 - Eclipse IDE ??? 89 2939 818 1915
PartRenderingEngine's limbo ??? 10000 1440 10759 0
SWT_Window_Eclipse ??? 0 136 39 0
PartRenderingEngine's limbo ??? 10000 1440 10759 0
SWT_Window_Eclipse ??? 0 136 39 0