From 0d5a2b5d5b47753aa7fb503dc2655bc51ab67a52 Mon Sep 17 00:00:00 2001 From: Edward Jakubowski Date: Wed, 7 May 2014 08:03:30 -0400 Subject: [PATCH] Fixed context menu click, added more sendkeys, fix for global key hook --- src/org/synthuse/Api.java | 27 +++- src/org/synthuse/CommandPopupMenu.java | 31 +++-- src/org/synthuse/CommandProcessor.java | 4 + src/org/synthuse/Config.java | 8 ++ src/org/synthuse/KeyboardHook.java | 2 +- src/org/synthuse/RobotMacro.java | 120 ++++++++++++++++++ src/org/synthuse/SynthuseDlg.java | 42 ++++-- src/org/synthuse/TestIdeFrame.java | 1 + src/org/synthuse/UiaBridge.java | 8 +- src/org/synthuse/WinPtr.java | 3 + src/org/synthuse/WindowInfo.java | 3 + src/org/synthuse/XpathManager.java | 4 +- src/org/synthuse/commands/BaseCommand.java | 63 ++++++++- src/org/synthuse/commands/MainCommands.java | 18 ++- src/org/synthuse/commands/MouseCommands.java | 15 ++- src/org/synthuse/test/WinFormsMockTestApp.exe | Bin 20480 -> 36352 bytes synthuse.properties | 11 +- 17 files changed, 315 insertions(+), 45 deletions(-) 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 64b76a949cd428ada3e76ec8fb489aa435495ac2..2b49f132085c8ab3b33e97a2bc2a6c8c6e544734 100644 GIT binary patch literal 36352 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 KzyJR{@c#gi9F6k; delta 6762 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 ZzVw9Y3+>SV-Sf;X6VcKCR^v^9{{zyqU<&{M 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=