diff --git a/src/org/synthuse/Api.java b/src/org/synthuse/Api.java index a5c0e79..3af52f2 100644 --- a/src/org/synthuse/Api.java +++ b/src/org/synthuse/Api.java @@ -487,6 +487,17 @@ public class Api { return windowPoint; } + public Point getMenuItemPosition(HWND handle, HMENU hMenu, int pos) { + Point windowPoint = new Point(); + RECT rect = new RECT(); + user32.GetMenuItemRect(handle, hMenu, pos, rect); + //System.out.println("rect: l" + rect.left + ",t" + rect.top + ",r" + rect.right + ",b" + rect.bottom); + //user32.MapWindowPoints(user32.GetDesktopWindow(), user32.GetParent(handle), rect, 2); + windowPoint.x = ((rect.right - rect.left) / 2) + rect.left; + windowPoint.y = ((rect.bottom - rect.top) / 2) + rect.top; + return windowPoint; + } + public int getDiskUsedPercentage() { return getDiskUsedPercentage(null); } @@ -545,9 +556,19 @@ public class Api { } public static boolean isDotNet4Installed() { - int installed = Advapi32Util.registryGetIntValue(WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4.0\\Client", "Install"); - //System.out.println("isDotNet4Installed: " + installed); - return (installed == 1); + try { + int installed = Advapi32Util.registryGetIntValue(WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4.0\\Client", "Install"); + //System.out.println("isDotNet4Installed: " + installed); + return (installed == 1); + } catch (Exception e) { + } + try { + int installed = Advapi32Util.registryGetIntValue(WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Client", "Install"); + //System.out.println("isDotNet4Installed: " + installed); + return (installed == 1); + } catch (Exception e) { + } + return false; } } diff --git a/src/org/synthuse/CommandPopupMenu.java b/src/org/synthuse/CommandPopupMenu.java index c085af7..77cb2d4 100644 --- a/src/org/synthuse/CommandPopupMenu.java +++ b/src/org/synthuse/CommandPopupMenu.java @@ -143,35 +143,42 @@ public class CommandPopupMenu extends JPopupMenu { CommandMenuItem mntmGetwindowclass = new CommandMenuItem("getWindowClass", 2); mnWinMessages.add(mntmGetwindowclass); - CommandMenuItem mntmOpen = new CommandMenuItem("open", 2, false); - add(mntmOpen); - CommandMenuItem mntmDisplayText = new CommandMenuItem("displayText", 3, false); add(mntmDisplayText); + CommandMenuItem mntmForceRefresh = new CommandMenuItem("forceRefresh", 1, false); + add(mntmForceRefresh); + + CommandMenuItem mntmOpen = new CommandMenuItem("open", 2, false); + add(mntmOpen); + //CommandMenuItem mntmOpenAndWait = new CommandMenuItem("openAndWait", 1, false); //add(mntmOpenAndWait); CommandMenuItem mntmPause = new CommandMenuItem("pause", 2, false); add(mntmPause); + + CommandMenuItem mntmSettimeout = new CommandMenuItem("setTimeout", 2, false); + add(mntmSettimeout); + + CommandMenuItem mntmSetspeed = new CommandMenuItem("setSpeed", 2, false); + add(mntmSetspeed); + + CommandMenuItem mntmSetUpdateThreshold = new CommandMenuItem("setUpdateThreshold", 2, false); + add(mntmSetUpdateThreshold); + + CommandMenuItem mntmWaitforclass = new CommandMenuItem("waitForClass", 2, false); + add(mntmWaitforclass); CommandMenuItem mntmWaitfortitle = new CommandMenuItem("waitForTitle", 2, false); add(mntmWaitfortitle); CommandMenuItem mntmWaitfortext = new CommandMenuItem("waitForText", 2, false); add(mntmWaitfortext); - - CommandMenuItem mntmWaitforclass = new CommandMenuItem("waitForClass", 2, false); - add(mntmWaitforclass); - + CommandMenuItem mntmWaitforvisible = new CommandMenuItem("waitForVisible", 2); add(mntmWaitforvisible); - CommandMenuItem mntmSettimeout = new CommandMenuItem("setTimeout", 2, false); - add(mntmSettimeout); - - CommandMenuItem mntmSetspeed = new CommandMenuItem("setSpeed", 2, false); - add(mntmSetspeed); } class CommandMenuItem extends JMenuItem { diff --git a/src/org/synthuse/CommandProcessor.java b/src/org/synthuse/CommandProcessor.java index f69d185..afea356 100644 --- a/src/org/synthuse/CommandProcessor.java +++ b/src/org/synthuse/CommandProcessor.java @@ -243,10 +243,14 @@ public class CommandProcessor implements Runnable{ return main.cmdOpen(args); if (command.equals("displayText")) return main.cmdDisplayText(args); + if (command.equals("forceRefresh")) + return main.cmdForceRefresh(args); if (command.equals("setSpeed")) return main.cmdSetSpeed(args); if (command.equals("setTimeout")) return main.cmdSetTimeout(args); + if (command.equals("setUpdateThreshold")) + return main.cmdSetUpdateThreshold(args); if (command.equals("waitForTitle")) return main.cmdWaitForTitle(args); if (command.equals("waitForText")) diff --git a/src/org/synthuse/Config.java b/src/org/synthuse/Config.java index 93dcf0c..a003d20 100644 --- a/src/org/synthuse/Config.java +++ b/src/org/synthuse/Config.java @@ -13,6 +13,7 @@ public class Config extends PropertiesSerializer { public String disableUiaBridge = "false"; public String disableFiltersUia = "false"; + public String alwaysOnTop = "true"; public String refreshKey = "3"; public String targetKey = "`"; public String urlList = ""; @@ -43,6 +44,13 @@ public class Config extends PropertiesSerializer { return disableFiltersUia.equals("true") || disableFiltersUia.equals("True"); } + public boolean isAlwaysOnTop() + { + if (alwaysOnTop == null) + return new Config().alwaysOnTop.equals("true") || new Config().alwaysOnTop.equals("True"); + return alwaysOnTop.equals("true") || alwaysOnTop.equals("True"); + } + public int getRefreshKeyCode() { String keyStr = ""; diff --git a/src/org/synthuse/KeyboardHook.java b/src/org/synthuse/KeyboardHook.java index ff3b4d9..7fc7e63 100644 --- a/src/org/synthuse/KeyboardHook.java +++ b/src/org/synthuse/KeyboardHook.java @@ -159,7 +159,7 @@ public class KeyboardHook implements Runnable{ @Override public void run() { createGlobalKeyboardHook(); - System.out.println("Unhooking Global Keyboard Hook"); + //System.out.println("Unhooking Global Keyboard Hook"); unhook();//wait for quit == true then unhook } diff --git a/src/org/synthuse/RobotMacro.java b/src/org/synthuse/RobotMacro.java index 04d7115..e9bf9fd 100644 --- a/src/org/synthuse/RobotMacro.java +++ b/src/org/synthuse/RobotMacro.java @@ -316,6 +316,126 @@ ALT % specialKeyFlag = false; pressKeyCodes(robot, new int[]{KeyEvent.VK_DOWN} ); } + else if (specialKey.equals("{LEFT}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_LEFT} ); + } + else if (specialKey.equals("{RIGHT}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_RIGHT} ); + } + else if (specialKey.equals("{PRTSC}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_PRINTSCREEN} ); + } + else if (specialKey.equals("{DELETE}") || specialKey.equals("{DEL}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_DELETE} ); + } + else if (specialKey.equals("{BACKSPACE}") || specialKey.equals("{BS}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_BACK_SPACE} ); + } + else if (specialKey.equals("{F1}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F1} ); + } + else if (specialKey.equals("{F2}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F2} ); + } + else if (specialKey.equals("{F3}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F3} ); + } + else if (specialKey.equals("{F4}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F4} ); + } + else if (specialKey.equals("{F5}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F5} ); + } + else if (specialKey.equals("{F6}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F6} ); + } + else if (specialKey.equals("{F7}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F7} ); + } + else if (specialKey.equals("{F8}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F8} ); + } + else if (specialKey.equals("{F9}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F9} ); + } + else if (specialKey.equals("{F10}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F10} ); + } + else if (specialKey.equals("{F11}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F11} ); + } + else if (specialKey.equals("{F12}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F12} ); + } + else if (specialKey.equals("{F13}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F13} ); + } + else if (specialKey.equals("{F14}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F14} ); + } + else if (specialKey.equals("{F15}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F15} ); + } + else if (specialKey.equals("{F16}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_F16} ); + } + else if (specialKey.equals("{PRTSC}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_PRINTSCREEN} ); + } + else if (specialKey.equals("{ADD}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_ADD} ); + } + else if (specialKey.equals("{SUBTRACT}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_SUBTRACT} ); + } + else if (specialKey.equals("{MULTIPLY}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_MULTIPLY} ); + } + else if (specialKey.equals("{DIVIDE}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_DIVIDE} ); + } + else if (specialKey.equals("{INSERT}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_INSERT} ); + } + else if (specialKey.equals("{BREAK}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_CANCEL} ); + } + else if (specialKey.equals("{{}")) { + specialKeyFlag = false; + pressKeyCodes(robot, new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_OPEN_BRACKET} ); + } + else if (specialKey.equals("{}}")) { + specialKeyFlag = false; + pressKeyCodes(robot,new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_CLOSE_BRACKET} ); + } } if (modifierKeyFlag) { //time to release all the modifier keys diff --git a/src/org/synthuse/SynthuseDlg.java b/src/org/synthuse/SynthuseDlg.java index 8a173f2..389356c 100644 --- a/src/org/synthuse/SynthuseDlg.java +++ b/src/org/synthuse/SynthuseDlg.java @@ -25,6 +25,7 @@ import javax.swing.JOptionPane; import javax.swing.JToolBar; import javax.swing.JSplitPane; import javax.swing.JRadioButton; +import javax.swing.SwingUtilities; import javax.swing.WindowConstants; import java.awt.Component; @@ -71,7 +72,7 @@ public class SynthuseDlg extends JFrame { /** * */ - public static String VERSION_STR = "1.1.4"; + public static String VERSION_STR = "1.1.6"; 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"; @@ -201,7 +202,14 @@ public class SynthuseDlg extends JFrame { String about = ""; about += "Synthuse Version " + VERSION_STR + " create by Edward Jakubowski ejakubowski7@gmail.com\n\n"; - about += "System information: \n"; + about += "Application information: \n"; + about += " alwaysOnTop - " + config.isAlwaysOnTop() + "\n"; + about += " refreshKey - " + config.refreshKey + "\n"; + about += " targetKey - " + config.targetKey + "\n"; + about += " disableUiaBridge - " + config.isUiaBridgeDisabled() + "\n"; + about += " disableFiltersUia - " + config.isFilterUiaDisabled() + "\n"; + + about += "\nSystem information: \n"; about += " Java version - " + System.getProperty("java.version") + "\n"; about += " Java home - " + System.getProperty("java.home") + "\n"; about += " OS Name - " + System.getProperty("os.name") + "\n"; @@ -210,8 +218,10 @@ public class SynthuseDlg extends JFrame { jclasspath = jclasspath.replaceAll(";", ";\n "); if (!System.getProperty("os.name").startsWith("Windows")) jclasspath = jclasspath.replaceAll(":", ":\n "); + if (jclasspath.length() > 500) + jclasspath = jclasspath.substring(0, 500) + "..."; about += " Java class path - " + jclasspath + "\n\n"; - JOptionPane.showMessageDialog(null, about , "About", JOptionPane.QUESTION_MESSAGE); + JOptionPane.showMessageDialog(SynthuseDlg.this, about , "About", JOptionPane.QUESTION_MESSAGE); } }); toolBar.add(helpBtn); @@ -396,22 +406,32 @@ public class SynthuseDlg extends JFrame { @Override public void keyPressed(KeyboardHook.TargetKeyPress target) { //System.out.println("target key pressed " + target.targetKeyCode); - if (target.targetKeyCode == config.getRefreshKeyCode()){ - btnRefresh.doClick(); + if (target.targetKeyCode == config.getRefreshKeyCode()){ + SwingUtilities.invokeLater(new Runnable() {//swing components are not thread safe, this will run on Swings event dispatch thread + public void run() { + 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(); + SwingUtilities.invokeLater(new Runnable() {//swing components are not thread safe, this will run on Swings event dispatch thread + public void run() { + //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(); + } + }); + } } }); btnRefresh.doClick(); refreshDatabinding(); + super.setAlwaysOnTop(config.isAlwaysOnTop()); } /* diff --git a/src/org/synthuse/TestIdeFrame.java b/src/org/synthuse/TestIdeFrame.java index b45b6cd..9bbd259 100644 --- a/src/org/synthuse/TestIdeFrame.java +++ b/src/org/synthuse/TestIdeFrame.java @@ -133,6 +133,7 @@ public class TestIdeFrame extends JFrame { TestIdeFrame.this.dispose(); } }); + super.setAlwaysOnTop(SynthuseDlg.config.isAlwaysOnTop()); } } diff --git a/src/org/synthuse/UiaBridge.java b/src/org/synthuse/UiaBridge.java index 3f84b10..8880dab 100644 --- a/src/org/synthuse/UiaBridge.java +++ b/src/org/synthuse/UiaBridge.java @@ -9,10 +9,14 @@ public class UiaBridge { public static String CACHED_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty,BoundingRectangleProperty"; + static { - if (!Api.isDotNet4Installed()) //if .net 4.0 isn't installed don't use uiabridge + String loadFailedMsg = "Failed to load uiabridge library, make sure you have .Net 4.0 already installed.\n"; + if (!Api.isDotNet4Installed()) { //if .net 4.0 isn't installed don't use uiabridge SynthuseDlg.config.disableUiaBridge = "true"; + JOptionPane.showMessageDialog(null, loadFailedMsg , "Native Library Load Error", JOptionPane.ERROR_MESSAGE); + } 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 @@ -24,7 +28,7 @@ public class UiaBridge { 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); + JOptionPane.showMessageDialog(null, loadFailedMsg + sw.toString() , "Native Library Load Error", JOptionPane.ERROR_MESSAGE); SynthuseDlg.config.disableUiaBridge = "true"; } } diff --git a/src/org/synthuse/WinPtr.java b/src/org/synthuse/WinPtr.java index c490416..75ac542 100644 --- a/src/org/synthuse/WinPtr.java +++ b/src/org/synthuse/WinPtr.java @@ -15,6 +15,9 @@ public class WinPtr { public String hWndStr = ""; public String runtimeId = ""; + public String hmenuStr = "";//store menu handle + public int hmenuPos = -1;//store menu position or id + public WinPtr() { } diff --git a/src/org/synthuse/WindowInfo.java b/src/org/synthuse/WindowInfo.java index 242b304..5076a63 100644 --- a/src/org/synthuse/WindowInfo.java +++ b/src/org/synthuse/WindowInfo.java @@ -245,6 +245,9 @@ public class WindowInfo { if (text != null) if (text.length() > MAX_TEXT_SIZE) text = text.substring(0, MAX_TEXT_SIZE); + if (value != null) + if (value.length() > MAX_TEXT_SIZE) + value = value.substring(0, MAX_TEXT_SIZE); if (this.hwndStr == null) this.hwndStr = ""; diff --git a/src/org/synthuse/XpathManager.java b/src/org/synthuse/XpathManager.java index 38bed31..d2cf170 100644 --- a/src/org/synthuse/XpathManager.java +++ b/src/org/synthuse/XpathManager.java @@ -196,7 +196,7 @@ public class XpathManager implements Runnable{ List resultList = WindowsEnumeratedXml.evaluateXpathGetValues(xml, xpathExpr); if (resultList.size() == 0 && WindowsEnumeratedXml.lastException != null) { String errMsg = WindowsEnumeratedXml.lastException.getCause().getMessage(); - JOptionPane.showMessageDialog(null, "Exception: " + errMsg, "Error", JOptionPane.ERROR_MESSAGE); + JOptionPane.showMessageDialog(target.getTopLevelAncestor(), "Exception: " + errMsg, "Error", JOptionPane.ERROR_MESSAGE); return -1; } results = resultList.size(); @@ -237,7 +237,7 @@ public class XpathManager implements Runnable{ } lblStatus.setText(results + " matches"); if (cPos > 0 && matches == 0 && !alwaysFromTop) { //ask if user wants to search from top - int result = JOptionPane.showConfirmDialog(null, "No more matches found. Do you want to search from the top of the document?", "Find", JOptionPane.YES_NO_OPTION); + int result = JOptionPane.showConfirmDialog(target.getTopLevelAncestor(), "No more matches found. Do you want to search from the top of the document?", "Find", JOptionPane.YES_NO_OPTION); if (result == JOptionPane.YES_OPTION) { target.setCaretPosition(0); nextXpathMatch(xpathExpr, targetText, lblStatus, alwaysFromTop); diff --git a/src/org/synthuse/commands/BaseCommand.java b/src/org/synthuse/commands/BaseCommand.java index 13fbf72..69fc9e7 100644 --- a/src/org/synthuse/commands/BaseCommand.java +++ b/src/org/synthuse/commands/BaseCommand.java @@ -91,6 +91,39 @@ public class BaseCommand { appendError("Error: command '" + getCurrentCommand() + "' failed"); return cmdResult; } + + public void forceXmlRefresh() { + WIN_XML = WindowsEnumeratedXml.getXml(); + LAST_UPDATED_XML = System.nanoTime(); + } + + public String getWindowTypeWithXpath(String xpath) { + String result = ""; + double secondsFromLastUpdate = ((double)(System.nanoTime() - LAST_UPDATED_XML) / 1000000000); + if (secondsFromLastUpdate > CommandProcessor.XML_UPDATE_THRESHOLD) { //default 5 second threshold + WIN_XML = WindowsEnumeratedXml.getXml(); + LAST_UPDATED_XML = System.nanoTime(); + } + String resultStr = ""; + List resultList = WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath); + if (resultList.size() > 0) + { + resultStr = resultList.get(0).trim(); + if (resultStr.startsWith(" resultList = WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath); for(String item: resultList) { + //System.out.println("xpath result item: " + item); if (item.contains("hwnd=")) { List hwndList = WindowsEnumeratedXml.evaluateXpathGetValues(item, "//@hwnd"); if (hwndList.size() > 0) @@ -114,8 +148,19 @@ public class BaseCommand { } else resultStr = item; - break; + if (item.contains("hmenu=")) { //get menu information, useful for getting center of menu + List hmenuList = WindowsEnumeratedXml.evaluateXpathGetValues(item, "//@hmenu"); + if (hmenuList.size() > 0) + result.hmenuStr = hmenuList.get(0).replaceAll("[^\\d-.]", ""); //get first hmenu; + if (item.contains("id=")) { + List menuidList = WindowsEnumeratedXml.evaluateXpathGetValues(item, "//@position"); + if (menuidList.size() > 0) + result.hmenuPos = Integer.parseInt(menuidList.get(0).replaceAll("[^\\d-.]", "")); //get first id; + } + } + break;// we only care about the first item } + resultStr = resultStr.replaceAll("[^\\d-.]", ""); //remove all non-numeric values (except dash -) if (WinPtr.isWpfRuntimeIdFormat(resultStr)) { result.runtimeId = resultStr; @@ -137,7 +182,7 @@ public class BaseCommand { WIN_XML = WindowsEnumeratedXml.getXml(); LAST_UPDATED_XML = System.nanoTime(); } - WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath); + //WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath); String resultStr = ""; List resultList = WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath); for(String item: resultList) { @@ -169,6 +214,18 @@ public class BaseCommand { return p; } + public Point getCenterWindowPosition(WinPtr handle, String windowType) { + Point p = null; + + if (handle.isWpf() || windowType.equals("winfrm") || windowType.equals("wpf") || windowType.equals("silver")) + p = uiabridge.getCenterOfElement(handle.runtimeId); + else if (windowType.equals("win")) + p = api.getWindowPosition(handle.hWnd); + else if (windowType.equals("menu")) + p = api.getMenuItemPosition(handle.hWnd, MenuInfo.GetHandleMenuFromString(handle.hmenuStr), handle.hmenuPos); + return p; + } + public String convertListToString(List listStr, String delimiter) { StringBuilder result = new StringBuilder(""); for (String item: listStr) { diff --git a/src/org/synthuse/commands/MainCommands.java b/src/org/synthuse/commands/MainCommands.java index 4570c26..1d044fa 100644 --- a/src/org/synthuse/commands/MainCommands.java +++ b/src/org/synthuse/commands/MainCommands.java @@ -23,9 +23,10 @@ public class MainCommands extends BaseCommand { public boolean cmdDisplayText(String[] args) throws IOException { if (!checkArgumentLength(args, 2)) return false; - if (!checkIsNumeric(args[1])) + if (!checkIsNumeric(args[1])) //arg[1] is in milliseconds return false; this.killStatusWindow(); + //System.out.println("StatusWindow " + args[0] + ", " + Integer.parseInt(args[1])); StatusWindow sw = new StatusWindow(args[0], Integer.parseInt(args[1])); Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); sw.setLocation(dim.width/2-sw.getSize().width/2, dim.height + StatusWindow.Y_BOTTOM_OFFSET - 80 ); @@ -48,6 +49,21 @@ public class MainCommands extends BaseCommand { return true; } + public boolean cmdSetUpdateThreshold(String[] args) { + if (!checkArgumentLength(args, 1)) + return false; + long threshold = Long.parseLong(args[0]); + CommandProcessor.XML_UPDATE_THRESHOLD = threshold; + return true; + } + + public boolean cmdForceRefresh(String[] args) { + if (!checkArgumentLength(args, 0)) + return false; + forceXmlRefresh(); + return true; + } + public boolean cmdWaitForTitle(String[] args) { if (!checkArgumentLength(args, 1)) return false; diff --git a/src/org/synthuse/commands/MouseCommands.java b/src/org/synthuse/commands/MouseCommands.java index c4f8ce7..a7dcfc6 100644 --- a/src/org/synthuse/commands/MouseCommands.java +++ b/src/org/synthuse/commands/MouseCommands.java @@ -17,8 +17,10 @@ public class MouseCommands extends BaseCommand { //System.out.println("cmdClick1: " + args[0]); if (handle.isEmpty()) return false; - Point p = getCenterWindowPosition(handle); - //System.out.println("cmdClick3: " + p.x + "," + p.y); + String wtype = getWindowTypeWithXpath(args[0]); + //System.out.println("wtype: " + wtype + " hwnd " + handle.hWnd + " hmenu " + handle.hmenuStr + " pos " + handle.hmenuPos); + Point p = getCenterWindowPosition(handle, wtype); + //System.out.println("cmdClick: " + p.x + "," + p.y); RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y); RobotMacro.leftClickMouse(); return true; @@ -30,7 +32,8 @@ public class MouseCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; - Point p = getCenterWindowPosition(handle); + String wtype = getWindowTypeWithXpath(args[0]); + Point p = getCenterWindowPosition(handle, wtype); RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y); RobotMacro.doubleClickMouse(); return true; @@ -42,7 +45,8 @@ public class MouseCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; - Point p = getCenterWindowPosition(handle); + String wtype = getWindowTypeWithXpath(args[0]); + Point p = getCenterWindowPosition(handle, wtype); RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y); RobotMacro.rightClickMouse(); return true; @@ -74,7 +78,8 @@ public class MouseCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; - Point p = getCenterWindowPosition(handle); + String wtype = getWindowTypeWithXpath(args[0]); + Point p = getCenterWindowPosition(handle, wtype); RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y); //System.out.println("point " + p.x + "," + p.y); return true; diff --git a/src/org/synthuse/test/WinFormsMockTestApp.exe b/src/org/synthuse/test/WinFormsMockTestApp.exe index 64b76a9..2b49f13 100644 Binary files a/src/org/synthuse/test/WinFormsMockTestApp.exe and b/src/org/synthuse/test/WinFormsMockTestApp.exe differ diff --git a/synthuse.properties b/synthuse.properties index 57850a8..109bb17 100644 --- a/synthuse.properties +++ b/synthuse.properties @@ -1,10 +1,11 @@ # -#Wed Apr 30 22:00:36 EDT 2014 -DEFAULT_PROP_FILENAME= +#Tue May 06 12:01:23 EDT 2014 targetKey=` -disableFiltersUia=false -urlList= disableUiaBridge=false +disableFiltersUia=false +alwaysOnTop=true refreshKey=3 -xpathList=//wpf\u00BA +DEFAULT_PROP_FILENAME= xpathHightlight= +xpathList= +urlList=