Added back ValueProperty, renamed config properties

uiabridge will display ValueProperty if element supports it.
if uiabridge is disabled in synthuse.properties the native library will
not be loaded.
Added Trigger hot key Ctrl+Shift+`
Added hotkey configurations in synthuse.properties
This commit is contained in:
Edward Jakubowski
2014-04-30 22:20:52 -04:00
parent 70b885edda
commit ce78f9c084
13 changed files with 107 additions and 42 deletions

View File

@@ -299,13 +299,13 @@ public class Api {
return null;
}
public static String GetWindowClassName(HWND hWnd) {
public static String getWindowClassName(HWND hWnd) {
char[] buffer = new char[1026];
User32.instance.GetClassName(hWnd, buffer, 1026);
return Native.toString(buffer);
}
public static String GetWindowText(HWND hWnd) {
public static String getWindowText(HWND hWnd) {
String text = "";
byte[] buffer = new byte[1024];
User32.instance.GetWindowTextA(hWnd, buffer, buffer.length);
@@ -315,19 +315,26 @@ public class Api {
return text;
}
public static HWND GetWindowFromPoint(Point p) {
public static Point getCursorPos() {
long[] getPos = new long [1];
User32.instance.GetCursorPos(getPos);
return new Point(POINT_X(getPos[0]), POINT_Y(getPos[0]));
}
public static HWND getWindowFromCursorPos() {
long[] getPos = new long [1];
User32.instance.GetCursorPos(getPos);
HWND hwnd = User32.instance.WindowFromPoint(getPos[0]);
HWND childHwnd = GetHiddenChildWindowFromPoint(hwnd, getPos[0]);
HWND childHwnd = getHiddenChildWindowFromPoint(hwnd, getPos[0]);
hwnd = childHwnd;
//System.out.println(getPos[0] + "," + getPos[1] + " int: " + x + ", " + y);
//System.out.println("child: " + GetHandleAsString(childHwnd) + " " + POINT_X(getPos[0]) +", " + POINT_Y(getPos[0]));
return hwnd;
}
public static HWND GetHiddenChildWindowFromPoint(HWND inHwnd, long point)
public static HWND getHiddenChildWindowFromPoint(HWND inHwnd, long point)
{
//int x = POINT_X(point);int y = POINT_Y(point);

View File

@@ -11,8 +11,10 @@ public class Config extends PropertiesSerializer {
public static String DEFAULT_PROP_FILENAME = "synthuse.properties";
public String disableWpf = "false";
public String disableFiltersWpf = "false";
public String disableUiaBridge = "false";
public String disableFiltersUia = "false";
public String refreshKey = "3";
public String targetKey = "`";
public String urlList = "";
public String xpathList = "";
public String xpathHightlight = ".*process=\"([^\"]*)\".*";
@@ -27,17 +29,41 @@ public class Config extends PropertiesSerializer {
load(propertyFilename);
}
public boolean isWpfBridgeDisabled()
public boolean isUiaBridgeDisabled()
{
if (disableWpf == null)
if (disableUiaBridge == null)
return false;
return disableWpf.equals("true") || disableWpf.equals("True");
return disableUiaBridge.equals("true") || disableUiaBridge.equals("True");
}
public boolean isFilterWpfDisabled()
public boolean isFilterUiaDisabled()
{
if (disableFiltersWpf == null)
if (disableFiltersUia == null)
return false;
return disableFiltersWpf.equals("true") || disableFiltersWpf.equals("True");
return disableFiltersUia.equals("true") || disableFiltersUia.equals("True");
}
public int getRefreshKeyCode()
{
String keyStr = "";
if (this.refreshKey == null)
keyStr = new Config().refreshKey; //use default value
else if (this.refreshKey.isEmpty())
keyStr = new Config().refreshKey; //use default value
else
keyStr = this.refreshKey;
return RobotMacro.getKeyCode(keyStr.charAt(0))[0];
}
public int getTargetKeyCode()
{
String keyStr = "";
if (this.targetKey == null)
keyStr = new Config().targetKey; //use default value
else if (this.targetKey.isEmpty())
keyStr = new Config().targetKey; //use default value
else
keyStr = this.targetKey;
return RobotMacro.getKeyCode(keyStr.charAt(0))[0];
}
}

View File

@@ -71,7 +71,7 @@ public class SynthuseDlg extends JFrame {
/**
*
*/
public static String VERSION_STR = "1.1.2";
public static String VERSION_STR = "1.1.3";
public static String RES_STR_MAIN_ICON = "/org/synthuse/img/gnome-robots.png";
public static String RES_STR_REFRESH_IMG = "/org/synthuse/img/rapidsvn.png";
@@ -249,7 +249,7 @@ public class SynthuseDlg extends JFrame {
c.gridy = 0;
c.insets = new Insets(3,3,3,3); // add padding around objects
DragTarget lblTarget = new DragTarget();
final DragTarget lblTarget = new DragTarget();
lblTarget.setHorizontalAlignment(SwingConstants.CENTER);
lblTarget.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_TARGET_IMG)));
@@ -389,15 +389,24 @@ public class SynthuseDlg extends JFrame {
}
});
KeyboardHook.addKeyEvent(KeyEvent.VK_3, true, true, false);// refresh xml when CTRL+SHIFT+3 is pressed
KeyboardHook.addKeyEvent(config.getRefreshKeyCode(), true, true, false);// refresh xml when CTRL+SHIFT+3 is pressed
KeyboardHook.addKeyEvent(config.getTargetKeyCode(), true, true, false);// target window when CTRL+SHIFT+~ is pressed
//add global hook and event
KeyboardHook.StartGlobalKeyboardHookThreaded(new KeyboardHook.KeyboardEvents() {
@Override
public void keyPressed(KeyboardHook.TargetKeyPress target) {
//System.out.println("target key pressed " + target.targetKeyCode);
if (target.targetKeyCode == KeyEvent.VK_3){
if (target.targetKeyCode == config.getRefreshKeyCode()){
btnRefresh.doClick();
}
if (target.targetKeyCode == config.getTargetKeyCode()){
if (!SynthuseDlg.config.isUiaBridgeDisabled())
uiabridge.initialize("");//need to re-initialize because it might be in a different thread.
Point p = Api.getCursorPos();
targetX = p.x;
targetY = p.y;
targetDragged();
}
}
});
@@ -445,11 +454,13 @@ public class SynthuseDlg extends JFrame {
}
public void targetDragged() {
HWND hwnd = Api.GetWindowFromPoint(new Point(targetX,targetY));
HWND hwnd = Api.getWindowFromCursorPos();//new Point(targetX,targetY)
String handleStr = Api.GetHandleAsString(hwnd);
String classStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.GetWindowClassName(hwnd));
String classStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.getWindowClassName(hwnd));
String parentStr = Api.GetHandleAsString(User32.instance.GetParent(hwnd));
String enumProperties = uiabridge.getWindowInfo(targetX, targetY, WindowInfo.UIA_PROPERTY_LIST);
String enumProperties = "";
if (!SynthuseDlg.config.isUiaBridgeDisabled())
enumProperties = uiabridge.getWindowInfo(targetX, targetY, WindowInfo.UIA_PROPERTY_LIST);
String runtimeId = WindowInfo.getRuntimeIdFromProperties(enumProperties);
lblStatus.setText("rid:" + runtimeId + " class: " + classStr + " hWnd: " + handleStr + " parent: " + parentStr + " X,Y: " + targetX + ", " + targetY);
if (!lastDragHwnd.equals(handleStr) || !lastRuntimeId.equals(runtimeId)) {

View File

@@ -3,12 +3,26 @@ package org.synthuse;
import java.awt.Point;
import java.io.*;
import javax.swing.JOptionPane;
public class UiaBridge {
static
{
String archDataModel = System.getProperty("sun.arch.data.model");//32 or 64 bit
//System.loadLibrary("native/WpfBridge" + archDataModel); // WpfBridge32.dll (Windows) or WpfBridge32.so (Unixes)
loadNativeLibraryFromJar("/uiabridge" + archDataModel + ".dll");
if (!SynthuseDlg.config.isUiaBridgeDisabled()) {
//System.out.println("SynthuseDlg.config.disableUiaBridge: " + SynthuseDlg.config.disableUiaBridge);
String archDataModel = System.getProperty("sun.arch.data.model");//32 or 64 bit
try {
//System.loadLibrary("native/WpfBridge" + archDataModel); // WpfBridge32.dll (Windows) or WpfBridge32.so (Unixes)
loadNativeLibraryFromJar("/uiabridge" + archDataModel + ".dll");
} catch (Exception ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
System.out.println(sw.toString());
JOptionPane.showMessageDialog(null, "Failed to load uiabridge library, make sure you have .Net 4.0 already installed.\n" + sw.toString() , "Native Library Load Error", JOptionPane.ERROR_MESSAGE);
SynthuseDlg.config.disableUiaBridge = "true";
}
}
}
public static void loadNativeLibraryFromJar(String path) {
@@ -63,7 +77,8 @@ public class UiaBridge {
public UiaBridge ()
{
initialize("");
if (!SynthuseDlg.config.isUiaBridgeDisabled())
initialize("");
}
public native void initialize(String properties);

View File

@@ -172,7 +172,7 @@ public class WindowInfo {
//WPF_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty";
String[] spltProperties = enumProperties.split(",");
this.isChild = isChild;
if (SynthuseDlg.config.isFilterWpfDisabled()) { //use wildcard mode
if (SynthuseDlg.config.isFilterUiaDisabled()) { //use wildcard mode
extra = new LinkedHashMap<String, String>();
for(String prop: spltProperties) {
String[] propertyNameAndValue = prop.split(":", 2);

View File

@@ -121,7 +121,7 @@ public class WindowsEnumeratedXml implements Runnable{
Api.User32.instance.EnumWindows(new ParentWindowCallback(), 0);
//Enumerate WPF, WinForm, Silverlight windows and add to list
if (!SynthuseDlg.config.isWpfBridgeDisabled())
if (!SynthuseDlg.config.isUiaBridgeDisabled())
{
UiaBridge uiabridge = new UiaBridge();
for (String handle : wpfParentList) {
@@ -276,7 +276,7 @@ public class WindowsEnumeratedXml implements Runnable{
String parentRuntimeId = uiabridge.getWindowInfo((int) hwnd, WindowInfo.UIA_RUNTIME_ID);
//System.out.println("runtimeId=" + runtimeId);
String[] allIds = null;
if (SynthuseDlg.config.isFilterWpfDisabled())
if (SynthuseDlg.config.isFilterUiaDisabled())
allIds = uiabridge.enumWindowInfo((int) hwnd, "*");
else
allIds = uiabridge.enumWindowInfo((int) hwnd, WindowInfo.UIA_PROPERTY_LIST);

View File

@@ -94,8 +94,6 @@ public class XpathManager implements Runnable{
String typeStr = wi.controlType;
String txtOrig = wi.text;
//String winValueOrig = wpf.getWindowValue(runtimeId);
if (typeStr == null || txtOrig == null)
return "";
//System.out.println("text: " + txtOrig);
String txtStr = compareLongTextString(txtOrig);
@@ -113,24 +111,24 @@ public class XpathManager implements Runnable{
String builtXpath = "";
try {
String xml = this.windowsXmlTextPane.getText();
if (enumProperties != null && !SynthuseDlg.config.isWpfBridgeDisabled()) {
if (enumProperties != null && !SynthuseDlg.config.isUiaBridgeDisabled()) {
if (!enumProperties.isEmpty()) {
builtXpath = buildUiaXpathStatement();
}
}
if (builtXpath != "")
return builtXpath;
String classStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.GetWindowClassName(hwnd));
String classStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.getWindowClassName(hwnd));
String handleStr = Api.GetHandleAsString(hwnd);
String txtOrig = Api.GetWindowText(hwnd);
String txtOrig = Api.getWindowText(hwnd);
String txtStr = WindowsEnumeratedXml.escapeXmlAttributeValue(txtOrig);
builtXpath = "//win[@class='" + classStr + "']";
List<String> resultList = WindowsEnumeratedXml.evaluateXpathGetValues(xml, builtXpath);
//int matches = nextXpathMatch(builtXpath, textPane, true);
if (resultList.size() > 1) { // if there are multiple results with the simple xpath then include parent class and text with the xpath statement.
HWND parent = User32.instance.GetParent(hwnd);
String parentClassStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.GetWindowClassName(parent));
String parentTxtOrig = Api.GetWindowText(parent);
String parentClassStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.getWindowClassName(parent));
String parentTxtOrig = Api.getWindowText(parent);
String parentTxtStr = WindowsEnumeratedXml.escapeXmlAttributeValue(parentTxtOrig);
if (!parentTxtStr.isEmpty()) {
if (parentTxtOrig.length() > 20) {// if the parent text is too long only test the first 20 characters

View File

@@ -16,7 +16,7 @@ public class BaseCommand {
static long LAST_UPDATED_XML = 0;
protected Api api = new Api();
protected UiaBridge wpf = new UiaBridge();
protected UiaBridge uiabridge = new UiaBridge();
protected CommandProcessor parentProcessor = null;
protected int getExecuteErrorCount() {
@@ -165,7 +165,7 @@ public class BaseCommand {
if (handle.isWin32())
p = api.getWindowPosition(handle.hWnd);
else
p = wpf.getCenterOfElement(handle.runtimeId);
p = uiabridge.getCenterOfElement(handle.runtimeId);
return p;
}