Java UI 的模拟点击输入
应该会有一部分小伙伴有需求使用AU3在Java UI 界面如何点击输入。查阅之后发现只有零星的一些资料。最接近可使用的也是在XP上面的一个UDF,然而此UDF并不能在Win7 64bit下使用。于是翻阅一些资料,做了一个简单的dos command下的exe 可以被AU3调用,进而模拟在Java UI上进行点击输入等。由于时间问题只有简单编写,此贴也仅仅是提供一个思路。如果有很多人有需求并且有时间的话,在考虑做出一个完整的UDF来共使用。原理是利用Oracle公司提供的Java access bridge。参考URL如下:
http://docs.oracle.com/javase/accessbridge/2.0.2/api.htm
Dos command: AutoitAccessJavaCMD.exe JavaUI_Name /button Root
For example: AutoitAccessJavaCMD.exe OfflineBuildTool-2.0.5.1 /button 0,1,0,0,0 ;点击button
AutoitAccessJavaCMD.exe OfflineBuildTool-2.0.5.1 /checkbox 0,1,0,1,0,0,0,0,0,15,0 ;选择checkbox
AutoitAccessJavaCMD.exe OfflineBuildTool-2.0.5.1 /input 0,1,0,1,0,0,0,0,0,8 abcdefg ;input窗口输入abcdefg
AutoitAccessJavaCMD.exe OfflineBuildTool-2.0.5.1 /combox 0,1,0,1,0,0,0,0,0,6 3 ;下拉list选择,3代表选择第三个
AU3调用很简单。
_RunDos(AutoitAccessJavaCMD.exe OfflineBuildTool-2.0.5.1 /button 0,1,0,0,0)
代码很凌乱,没有整理,大概贴一下主要的部分以及我觉得需要说明的部分。(其中有一些函数是直接copy的别人的,但是拿的谁的我忘记了。。。)
C++/MFC不是经常使用,使用率很低(其实是我很讨厌这两个家伙)自己也是边用边查(边抄)。所以代码质量很低,莫笑~
另外我只是写了我需要的部分,其他就没写。 对于子窗口的操作需要将FindWindow函数换成FindWindowEx,才能找到并操作子窗口。
MessageBoxTimeout(NULL,L"1",L"2",MB_OK,0,500); 这个很重要,想要成功运行必须先进行弹窗,如果你用MFC去编写的话,应该就不会需要先有窗口的创建。原因我也不知道为什么,只是猜测Java access bridge需要先创建一个窗口才能运行。需要证实。#include <objbase.h>
#include <iostream>
#include "AccessBridge.h"
#include "AccessBridgeCallbacks.h"
#include "AccessBridgeCalls.h"
#include "AccessBridgePackages.h"
#include <string.h>
#include <stdio.h>
#include "Au3AccessJava.h"
using namespace std;
BOOL main(int argc, char* argv[])
{
int flag = 0;
int g_levelOrder;
int g_nDepthOrder;
if (argc>5)
{
return FALSE;
}else
{
char dst;
//printf("%s\n", argv);
char* deep = argv;
int cnt = split(dst,deep,",");
for (int i=0; i<cnt; i++)
{
g_levelOrder = atoi(dst);
g_nDepthOrder = i+1;
}
}
if (initializeAccessBridge() == TRUE)
{
HWND Jhwnd = FindWindow(L"SunAwtFrame",c2w(argv));
printf("find windows %x\n", Jhwnd);
MessageBoxTimeout(NULL,L"1",L"2",MB_OK,0,500);
if (IsJavaWindow(Jhwnd))
{
long vmID = 0;
AccessibleContext ac = 0;
if (GetAccessibleContextFromHWND(Jhwnd, &vmID, &ac) == TRUE)
{
if (strcmp(argv,"/button")==0)
{
AccessibleContext Button_Result;
Button_Result = GetAcessContextByArray(vmID,ac,g_levelOrder, g_nDepthOrder);
ClickOneButton(vmID,Button_Result);
flag = 1;
}
else if (strcmp(argv,"/checkbox")==0)
{
AccessibleContext CheckBox_Result;
CheckBox_Result = GetAcessContextByArray(vmID, ac, g_levelOrder, g_nDepthOrder);
SelectCheckBox(vmID,CheckBox_Result);
flag = 1;
}
else if (strcmp(argv,"/combox")==0)
{
AccessibleSelection ComBox_Result;
ComBox_Result = GetAcessContextByArray(vmID, ac, g_levelOrder, g_nDepthOrder);
AddAccessibleSelectionFromContext(vmID,ComBox_Result,atoi(argv));
flag = 1;
}
else if (strcmp(argv,"/input")==0)
{
AccessibleContext Input_Result;
Input_Result = GetAcessContextByArray(vmID, ac, g_levelOrder, g_nDepthOrder);
if (setTextContents(vmID, Input_Result,c2w(argv)))
{
flag = 1;
}
else
{
flag = 0;
}
}
else
{
flag = 0;
}
}
}
shutdownAccessBridge();
}
if (flag==1)
{
return TRUE;
}
else
{
return FALSE;
}
//system("pause");
}
AccessibleContextFindAccessContext(long vmID, AccessibleContext parentAC, const wchar_t * name)
{
AccessibleContext act = 0;
AccessibleContextInfo aaci ;
GetAccessibleContextInfo(vmID, parentAC, &aaci);
for (int i = 0; i < aaci.childrenCount; i++)
{
AccessibleContext childAC = GetAccessibleChildFromContext(vmID, parentAC, i);
AccessibleContextInfo aacif;
GetAccessibleContextInfo(vmID, childAC, &aacif);
const wchar_t* Aname = aacif.name;
int childCount = aacif.childrenCount;
if (wcscmp(name,Aname) == 0)
{
act = childAC;
return act;
}
else
{
if (childCount > 0)
{
//如果有子节点 递归
AccessibleContext acTemp =FindAccessContext(vmID, childAC, name);
if (acTemp != 0)
{
//如果找到则返回,否则继续找其他兄弟路径
return acTemp;
}
}
}
}
return act;
}
void ClickOneButton(long vmID, AccessibleContext acButton)
{
//获取控件的可执行动作
AccessibleActions actionList;
getAccessibleActions(vmID, acButton, &actionList);
jint nReturn = 0;
//将要执行的动作赋值给TODO
AccessibleActionsToDo actionTodoList;
actionTodoList.actions = actionList.actionInfo;
actionTodoList.actionsCount = 1;
//执行该动作
doAccessibleActions(vmID, acButton, &actionTodoList, &nReturn);
if (nReturn < 0)
{
//成功与不成功都是返回的-1
//MessageBox("当前动作没有执行成功!");
}
}
AccessibleContext GetAcessContextByArray( long vmId, AccessibleContext rootAc, int levelArray[], int length )
{
AccessibleContext childAc = rootAc;
for (int i = 0; i < length && childAc != 0; i++)
{
childAc = GetAccessibleChildFromContext(vmId, childAc, levelArray);
//printf("%d\n", i);
}
if (childAc == 0)
{
//MessageBox("没有获取到控件ac!");
printf("can not find ac\n");
}
return childAc;
}
void SelectCheckBox(long vmID, AccessibleContext CheckBox)
{
//获取控件的可执行动作
AccessibleActions actionList;
getAccessibleActions(vmID, CheckBox, &actionList);
jint nReturn = 0;
//将要执行的动作赋值给TODO
AccessibleActionsToDo actionTodoList;
actionTodoList.actions = actionList.actionInfo;
actionTodoList.actionsCount = 1;
//执行该动作
doAccessibleActions(vmID, CheckBox, &actionTodoList, &nReturn);
if (nReturn < 0)
{
//成功与不成功都是返回的-1
//MessageBox("当前动作没有执行成功!");
}
}
int split(char dst[], char* str, const char* spl)
{
int n = 0;
char *result = NULL;
result = strtok(str, spl);
while( result != NULL )
{
strcpy(dst, result);
result = strtok(NULL, spl);
}
return n;
}
wchar_t* c2w(const char *str)
{
int length = strlen(str)+1;
wchar_t *t = (wchar_t*)malloc(sizeof(wchar_t)*length);
memset(t,0,length*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP,0,str,strlen(str),t,length);
return t;
}所需源文件均在附件中,编译软件为Vs2010.
对Root路径的说明。 感谢分享~
页:
[1]