Removed most except for core functionality code
@@ -1,11 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
@@ -1,8 +0,0 @@
|
||||
synthuse-src
|
||||
============
|
||||
|
||||
Synthuse (Synthetic-User) is a portable java base software testing framework for desktop windows applications. This framework has a built-in object spy and automation Test IDE. What makes this different from other frameworks is that it shares similar command syntax as Selenium. It also utilizes Xpath statements to locate target windows/objects The familiar syntax makes it easier to train automation tester in this frameworks.
|
||||
|
||||
Synthuse can also be incorporated in to the fitnesse platform as a test fixture.
|
||||
|
||||
<a href="https://github.com/Synthuse/synthuse-src/wiki"> Click here for Wiki and Screenshots </a>
|
||||
90
build.xml
@@ -1,90 +0,0 @@
|
||||
<project name="Synthuse" default="dist" basedir="." xmlns:ivy="antlib:org.apache.ivy.ant">
|
||||
<description> Simple build file for Synthuse </description>
|
||||
<!-- set global properties for this build -->
|
||||
<property name="src" location="src"/>
|
||||
<property name="build" location="build"/>
|
||||
<property name="lib" location="lib"/>
|
||||
<property name="dist" location="dist"/>
|
||||
<property name="main.class" value="org.synthuse.SynthuseDlg"/>
|
||||
<property name="jarname" value="synthuse.jar"/>
|
||||
|
||||
<target name="bootstrap" description="Installs apche ivy">
|
||||
<mkdir dir="${user.home}/.ant/lib"/>
|
||||
<get dest="${user.home}/.ant/lib/ivy.jar" src="http://search.maven.org/remotecontent?filepath=org/apache/ivy/ivy/2.3.0/ivy-2.3.0.jar"/>
|
||||
</target>
|
||||
|
||||
<target name="init">
|
||||
<!-- Create the time stamp -->
|
||||
<tstamp/>
|
||||
<!-- Create the build directory structure used by compile -->
|
||||
<mkdir dir="${build}"/>
|
||||
<mkdir dir="${lib}"/>
|
||||
<echo>basedir: ${basedir}</echo>
|
||||
<echo>VM: ${java.vm.name}</echo>
|
||||
<echo>VM Version: ${java.vm.specification.version}</echo>
|
||||
<echo>VM Vendor: ${java.vm.vendor}</echo>
|
||||
<echo>VM Build: ${java.vm.version}</echo>
|
||||
<echo>Username: ${user.name}</echo>
|
||||
</target>
|
||||
|
||||
<!-- downloadable dependencies are listed in ivy.xml file and are downloaded to the lib/ivy directory. -->
|
||||
<target name="resolve" depends="init" description="--> retreive dependencies with ivy">
|
||||
<ivy:retrieve pattern="${lib}/[artifact]-[revision].[ext]"/>
|
||||
<ivy:report todir="${build}"/>
|
||||
</target>
|
||||
|
||||
<target name="clean" description="clean up" >
|
||||
<!-- Delete the ${build} and ${dist} directory trees -->
|
||||
<delete dir="${build}"/>
|
||||
<delete dir="${dist}"/>
|
||||
<!-- <delete dir="${lib}"/> -->
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="init" description="compile the source including jars from lib directory" >
|
||||
<!-- Compile the java code from ${src} into ${build} -->
|
||||
<javac srcdir="${src}" destdir="${build}" includeantruntime="false" source="1.6" target="1.6">
|
||||
<classpath>
|
||||
<pathelement path="${classpath}"/>
|
||||
<fileset dir="${lib}">
|
||||
<include name="**/*.jar"/>
|
||||
</fileset>
|
||||
</classpath>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<target name="dist" depends="compile" description="generate the DISTribution jar file" >
|
||||
<!-- Create the distribution directory -->
|
||||
<mkdir dir="${dist}"/>
|
||||
<!-- Put everything from ${build} and ${lib} into the output .jar file -->
|
||||
<jar jarfile="${dist}/${jarname}" basedir="${build}">
|
||||
<zipgroupfileset dir="${lib}" includes="*.jar"/> <!-- includes lib jars -->
|
||||
<fileset dir="${src}"> <!-- includes images -->
|
||||
<include name="**/*.png" />
|
||||
</fileset>
|
||||
<fileset dir="native/uiabridge/bin"> <!-- includes native jni dlls -->
|
||||
<include name="**/*.dll" />
|
||||
</fileset>
|
||||
<fileset dir="native/MsgHook/bin"> <!-- includes native jni dlls -->
|
||||
<include name="**/*.dll" />
|
||||
</fileset>
|
||||
<manifest>
|
||||
<attribute name="Main-Class" value="${main.class}"/>
|
||||
<attribute name="Class-Path" value="${mf.classpath}"/>
|
||||
</manifest>
|
||||
</jar>
|
||||
</target>
|
||||
|
||||
<target name="run" depends="dist" description="runs our generated jar file">
|
||||
<java jar="${dist}/${jarname}" fork="true"/>
|
||||
</target>
|
||||
|
||||
<target name="jni" depends="dist" description="compile the source including jars from lib directory" >
|
||||
<!-- makes a JNI header of the named class -->
|
||||
<javah destdir="${build}" verbose="yes" classpath="${dist}/${jarname}">
|
||||
<class name="org.synthuse.UiaBridge"/>
|
||||
</javah>
|
||||
<javah destdir="${build}" verbose="yes" classpath="${dist}/${jarname}">
|
||||
<class name="org.synthuse.MsgHook"/>
|
||||
</javah>
|
||||
</target>
|
||||
</project>
|
||||
12
ivy.xml
@@ -1,12 +0,0 @@
|
||||
<ivy-module version="2.0">
|
||||
<info organisation="org.synthuse" module="Synthuse"/>
|
||||
<configurations defaultconfmapping="runtime->*,!sources,!javadoc">
|
||||
<conf name="runtime"/>
|
||||
<conf name="test"/>
|
||||
</configurations>
|
||||
<dependencies>
|
||||
<dependency org="net.java.dev.jna" name="jna" rev="3.4.0"/>
|
||||
<dependency org="net.java.dev.jna" name="platform" rev="3.4.0"/>
|
||||
<dependency org="junit" name="junit" rev="4.11" conf="test->*,!sources,!javadoc"/>
|
||||
</dependencies>
|
||||
</ivy-module>
|
||||
35
readme.txt
@@ -1,35 +0,0 @@
|
||||
Synthuse
|
||||
|
||||
Version 1.0.6 released on 2-17-2014
|
||||
By Edward Jakubowski ejakubowski7@gmail.com
|
||||
|
||||
Description:
|
||||
Synthuse is a portable java base software testing framework for desktop windows
|
||||
applications. This framework has a built-in object spy and automation Test IDE.
|
||||
What makes this different from other frameworks is that it shares similar command
|
||||
syntax as Selenium. It also utilizes Xpath statements to locate target windows/objects
|
||||
The familar syntaxes makes it easier to train automation tester in this frameworks.
|
||||
|
||||
|
||||
Configurations:
|
||||
All configurable settings are stored in the following file: synthuse.properties
|
||||
Changes to this file will not take affect until you restart the application.
|
||||
Example synthuse.properties file below:
|
||||
urlList=
|
||||
xpathList=//win[@class\='Notepad']\u00BA
|
||||
xpathHightlight=.*process\="([^"]*)".*
|
||||
|
||||
|
||||
Software Requirements:
|
||||
- Java 1.6 or greater
|
||||
|
||||
|
||||
Release Notes:
|
||||
4-8-2014 version 1.0.9
|
||||
- Added Support for automating WPF and Silverlight applications, this requires .Net 4.0 framework
|
||||
- Added better mouse scripting support
|
||||
2-17-2014 version 1.0.6
|
||||
- fixed Test IDE window
|
||||
1-30-2014 version 1.0.5
|
||||
- Base version
|
||||
|
||||
@@ -1,802 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.synthuse.Api.WinDefEx.*;
|
||||
import com.sun.jna.Callback;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
import com.sun.jna.platform.win32.Advapi32Util;
|
||||
import com.sun.jna.platform.win32.BaseTSD.LONG_PTR;
|
||||
import com.sun.jna.platform.win32.BaseTSD.SIZE_T;
|
||||
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
|
||||
import com.sun.jna.platform.win32.WinBase.SYSTEM_INFO;
|
||||
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
import com.sun.jna.platform.win32.WinReg;
|
||||
import com.sun.jna.platform.win32.WinUser;
|
||||
import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER;
|
||||
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
import com.sun.jna.win32.StdCallLibrary.StdCallCallback;
|
||||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
public class Api {
|
||||
|
||||
// Constants
|
||||
|
||||
public static int WM_SETTEXT = 0x000c;
|
||||
public static int WM_GETTEXT = 0x000D;
|
||||
public static int WM_GETTEXTLENGTH = 0x000E;
|
||||
public static int WM_MOUSEMOVE = 0x200;
|
||||
public static int WM_LBUTTONDOWN = 0x0201;
|
||||
public static int WM_LBUTTONUP = 0x0202;
|
||||
public static int WM_LBUTTONDBLCLK = 0x203;
|
||||
public static int WM_RBUTTONDOWN = 0x0204;
|
||||
public static int WM_RBUTTONUP = 0x0205;
|
||||
public static int WM_RBUTTONDBLCLK = 0x206;
|
||||
public static int WM_MBUTTONDOWN = 0x207;
|
||||
public static int WM_MBUTTONUP = 0x208;
|
||||
public static int WM_MBUTTONDBLCLK = 0x209;
|
||||
public static int WM_MOUSEWHEEL = 0x20A;
|
||||
public static int WM_MOUSEHWHEEL = 0x20E;
|
||||
public static int WM_MOUSEHOVER = 0x2A1;
|
||||
public static int WM_NCMOUSELEAVE = 0x2A2;
|
||||
public static int WM_MOUSELEAVE = 0x2A3;
|
||||
|
||||
public static int WM_CLOSE = 0x10;
|
||||
public static int WM_DESTROY = 0x0002;
|
||||
public static int WM_NCDESTROY = 0x0082;
|
||||
public static int WM_QUIT = 0x12;
|
||||
|
||||
public static int WM_SETFOCUS = 0x0007;
|
||||
public static int WM_NEXTDLGCTL = 0x0028;
|
||||
public static int WM_ENABLE = 0x000A;
|
||||
public static int WM_KEYFIRST = 0x100;
|
||||
public static int WM_KEYDOWN = 0x100;
|
||||
public static int WM_KEYUP = 0x101;
|
||||
public static int WM_CHAR = 0x102;
|
||||
public static int WM_DEADCHAR = 0x103;
|
||||
public static int WM_SYSKEYDOWN = 0x104;
|
||||
public static int WM_SYSKEYUP = 0x105;
|
||||
public static int WM_SYSCHAR = 0x106;
|
||||
|
||||
public static int WM_CUT = 0x300;
|
||||
public static int WM_COPY = 0x301;
|
||||
public static int WM_PASTE = 0x302;
|
||||
public static int WM_CLEAR = 0x303;
|
||||
public static int WM_UNDO = 0x304;
|
||||
|
||||
|
||||
public static int PROCESS_QUERY_INFORMATION = 0x0400;
|
||||
public static int PROCESS_VM_READ = 0x0010;
|
||||
public static int PROCESS_VM_WRITE = 0x0020;
|
||||
public static int PROCESS_VM_OPERATION = 0x0008;
|
||||
|
||||
public static int PS_SOLID = 0x0;
|
||||
public static int PS_DASH = 0x1;
|
||||
public static int PS_DOT = 0x2;
|
||||
public static int PS_DASHDOT = 0x3;
|
||||
public static int PS_DASHDOTDOT = 0x4;
|
||||
public static int PS_NULL = 0x5;
|
||||
public static int PS_INSIDEFRAME = 0x6;
|
||||
|
||||
public static int HOLLOW_BRUSH = 0x5;
|
||||
|
||||
public static int WM_PAINT = 0x0F;
|
||||
public static int WM_SETREDRAW = 0x0B;
|
||||
public static int WM_ERASEBKGND = 0x14;
|
||||
|
||||
public static int RDW_FRAME = 0x0400;
|
||||
public static int RDW_INVALIDATE = 0x0001;
|
||||
public static int RDW_UPDATENOW = 0x0100;
|
||||
public static int RDW_ALLCHILDREN = 0x0080;
|
||||
|
||||
public static int TB_GETBUTTONTEXTA = (0x0400 + 45);
|
||||
public static int TB_GETBUTTONTEXTW = (0x0400 + 75);
|
||||
public static int TB_GETRECT = (0x0400 + 51);
|
||||
public static int TB_GETTOOLTIPS = (0x0400 + 35);
|
||||
public static int TB_BUTTONCOUNT = 0x0418;
|
||||
|
||||
public static int LVM_FIRST = 0x1000;
|
||||
public static int LVM_GETITEMCOUNT = LVM_FIRST + 4;
|
||||
public static int LVM_GETITEM = LVM_FIRST + 75;
|
||||
public static int LVIF_TEXT = 0x0001;
|
||||
public static int LVM_GETSELECTEDCOUNT = (LVM_FIRST + 50);
|
||||
public static int LVM_SETITEMSTATE = (LVM_FIRST + 43);
|
||||
public static int LVM_GETITEMSTATE = (LVM_FIRST + 44);
|
||||
public static int LVIS_SELECTED = 0x0002;
|
||||
public static int LVIS_FOCUSED = 0x0001;
|
||||
|
||||
public static int LB_GETCOUNT = 0x18B;
|
||||
public static int LB_GETCURSEL = 0x0188;
|
||||
public static int LB_SETCURSEL = 0x0186;
|
||||
public static int LB_GETTEXT = 0x0189;
|
||||
public static int LB_GETTEXTLEN = 0x018A;
|
||||
public static int LB_SELECTSTRING = 396;
|
||||
|
||||
public static int CB_GETCOUNT = 0x146;
|
||||
|
||||
public static int TV_FIRST = 0x1100;
|
||||
public static int TVM_GETCOUNT = TV_FIRST + 5;
|
||||
|
||||
public static int VK_SHIFT = 16;
|
||||
public static int VK_LSHIFT = 0xA0;
|
||||
public static int VK_RSHIFT = 0xA1;
|
||||
public static int VK_CONTROL = 17;
|
||||
public static int VK_LCONTROL = 0xA2;
|
||||
public static int VK_RCONTROL = 0xA3;
|
||||
public static int VK_MENU = 18;
|
||||
public static int VK_LMENU = 0xA4;
|
||||
public static int VK_RMENU = 0xA5;
|
||||
|
||||
public static int WM_COMMAND = 0x111;
|
||||
public static int MN_GETHMENU = 0x01E1;
|
||||
|
||||
public static int CWP_ALL = 0x0000; // Does not skip any child windows
|
||||
|
||||
public static int PAGE_READWRITE = 0x04;
|
||||
|
||||
public static int MEM_COMMIT = 0x1000;
|
||||
public static int MEM_RESERVE = 0x2000;
|
||||
public static int MEM_RELEASE = 0x8000;
|
||||
public static int MEM_FREE = 0x10000;
|
||||
public static int MEM_DECOMMIT = 0x4000;
|
||||
|
||||
public User32Ex user32;
|
||||
public PsapiEx psapi;
|
||||
public Kernel32Ex kernel32;
|
||||
|
||||
public static final int POINT_Y(long i)
|
||||
{
|
||||
return (int) (i >> 32);
|
||||
}
|
||||
|
||||
public static final int POINT_X(long i)
|
||||
{
|
||||
return (int) (i & 0xFFFF);
|
||||
}
|
||||
|
||||
public static long MAKELONG(int low, int high)
|
||||
{
|
||||
return ((long)(((short)((int)(low) & 0xffff)) | ((int)((short)((int)(high) & 0xffff))) << 16));
|
||||
}
|
||||
|
||||
public interface WinDefEx extends com.sun.jna.platform.win32.WinDef {
|
||||
//Structures
|
||||
public class MENUITEMINFO extends Structure {
|
||||
public static final int MFS_CHECKED = 0x00000008;
|
||||
public static final int MFS_DEFAULT = 0x00001000;
|
||||
public static final int MFS_DISABLED = 0x00000003;
|
||||
public static final int MFS_ENABLED = 0x00000000;
|
||||
public static final int MFS_GRAYED = 0x00000003;
|
||||
public static final int MFS_HILITE = 0x00000080;
|
||||
public static final int MFS_UNCHECKED = 0x00000000;
|
||||
public static final int MFS_UNHILITE = 0x00000000;
|
||||
public static final int MFT_STRING = 0x0000;
|
||||
public static final int MIIM_DATA = 0x00000020;
|
||||
public static final int MIIM_STRING = 0x0040;
|
||||
public static final int MIIM_SUBMENU = 0x0004;
|
||||
public static final int MIIM_TYPE = 0x0010;
|
||||
|
||||
public static class ByValue extends MENUITEMINFO implements Structure.ByValue {
|
||||
}
|
||||
|
||||
public static class ByReference extends MENUITEMINFO implements Structure.ByReference {
|
||||
}
|
||||
|
||||
public MENUITEMINFO() {
|
||||
cbSize = size();
|
||||
}
|
||||
|
||||
public MENUITEMINFO(Pointer p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<?> getFieldOrder() {
|
||||
return Arrays.asList(new String[] { "cbSize", "fMask", "fType", "fState", "wID", "hSubMenu", "hbmpChecked",
|
||||
"hbmpUnchecked", "dwItemData", "dwTypeData", "cch", "hbmpItem" });
|
||||
}
|
||||
|
||||
public int cbSize; //The size of the structure, in bytes. The caller must set this member to sizeof(MENUITEMINFO).
|
||||
public int fMask; //Indicates the members to be retrieved or set. MIIM_STRING or MIIM_SUBMENU or ...
|
||||
public int fType; //The menu item type. fType is used only if fMask has a value of MIIM_FTYPE.
|
||||
public int fState; //The menu item state. This member can be one or more of these values. Set fMask to MIIM_STATE to use fState.
|
||||
public int wID; //An application-defined value that identifies the menu item. Set fMask to MIIM_ID to use wID.
|
||||
public HMENU hSubMenu; //A handle to the drop-down menu or submenu associated with the menu item. Or NULL
|
||||
public HBITMAP hbmpChecked; //A handle to the bitmap to display next to the item if it is selected.
|
||||
public HBITMAP hbmpUnchecked; //A handle to the bitmap to display next to the item if it is not selected.
|
||||
public ULONG_PTR dwItemData; //An application-defined value associated with the menu item. Set fMask to MIIM_DATA
|
||||
//public byte[] dwTypeData = new byte[256];
|
||||
public String dwTypeData; //The contents of the menu item, depends on the value of fType and is used only if the MIIM_TYPE flag is set in the fMask member
|
||||
public int cch; //The length of the menu item text, in characters, when information is received about a menu item of the MFT_STRING type.
|
||||
public HBITMAP hbmpItem; //A handle to the bitmap to be displayed, or it can be one of the values in the following table.
|
||||
}
|
||||
|
||||
|
||||
//64bit LVITEM size 88
|
||||
//32bit LVITEM size 60
|
||||
public static class LVITEM_VISTA extends Structure {
|
||||
public int mask;
|
||||
public int iItem;
|
||||
public int iSubItem;
|
||||
public int state;
|
||||
public int stateMask;
|
||||
public Pointer pszText;
|
||||
public int cchTextMax;
|
||||
public int iImage;
|
||||
public LPARAM lParam;
|
||||
public int iIndent;
|
||||
public int iGoupId;
|
||||
public int cColumns;
|
||||
public Pointer puColumns;
|
||||
//NTDDI_VERSION >= NTDDI_VISTA
|
||||
public Pointer piColFmt;
|
||||
public int iGroup;
|
||||
@Override
|
||||
protected List<?> getFieldOrder() {
|
||||
return Arrays.asList(new String[] {
|
||||
"mask", "iItem", "iSubItem", "state", "stateMask", "pszText", "cchTextMax", "iImage", "lParam", "iIndent", "iGoupId", "cColumns", "puColumns", "piColFmt", "iGroup" });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static class COPYDATASTRUCT extends Structure {
|
||||
//The by-reference version of this structure.
|
||||
public static class ByReference extends COPYDATASTRUCT implements Structure.ByReference { }
|
||||
|
||||
public COPYDATASTRUCT() { }
|
||||
|
||||
//Instantiates a new COPYDATASTRUCT with existing data given the address of that data.
|
||||
public COPYDATASTRUCT(final long pointer) {
|
||||
this(new Pointer(pointer));
|
||||
}
|
||||
|
||||
//Instantiates a new COPYDATASTRUCT with existing data given a pointer to that data.
|
||||
public COPYDATASTRUCT(final Pointer memory) {
|
||||
super(memory);
|
||||
read();
|
||||
}
|
||||
|
||||
public ULONG_PTR dwData; // The data to be passed to the receiving application.
|
||||
public int cbData; //The size, in bytes, of the data pointed to by the lpData
|
||||
public Pointer lpData;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
protected final List getFieldOrder() {
|
||||
return Arrays.asList(new String[] {"dwData", "cbData", "lpData" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface WNDPROC extends StdCallCallback {
|
||||
|
||||
LRESULT callback(HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
|
||||
|
||||
}
|
||||
|
||||
public interface User32Ex extends W32APIOptions {
|
||||
User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
|
||||
|
||||
int SetWindowLongPtr(HWND hWnd, int nIndex, Callback callback);
|
||||
LRESULT CallWindowProc(LONG_PTR proc, HWND hWnd, int uMsg, WPARAM uParam, LPARAM lParam);
|
||||
|
||||
boolean ShowWindow(HWND hWnd, int nCmdShow);
|
||||
boolean SetForegroundWindow(HWND hWnd);
|
||||
void SwitchToThisWindow(HWND hWnd, boolean fAltTab);
|
||||
HWND SetFocus(HWND hWnd);
|
||||
|
||||
HWND FindWindow(String winClass, String title);
|
||||
LRESULT PostMessage(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT SendMessage(HWND hWnd, int Msg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT SendMessage(HWND hWnd, int Msg, WPARAM wParam, LVITEM_VISTA lParam);
|
||||
LRESULT SendMessageA(HWND editHwnd, int wmGettext, long l, byte[] lParamStr);
|
||||
boolean DestroyWindow(HWND hWnd);
|
||||
|
||||
boolean EnumWindows (WNDENUMPROC wndenumproc, int lParam);
|
||||
boolean EnumChildWindows(HWND hWnd, WNDENUMPROC lpEnumFunc, Pointer data);
|
||||
HWND GetParent(HWND hWnd);
|
||||
boolean IsWindowVisible(HWND hWnd);
|
||||
boolean IsWindow(HWND hWnd);
|
||||
|
||||
int GetWindowRect(HWND hWnd, RECT r);
|
||||
int MapWindowPoints(HWND hWndFrom, HWND hWndTo, RECT r, int cPoints);
|
||||
HWND GetDesktopWindow();
|
||||
HDC GetWindowDC(HWND hWnd);
|
||||
int ReleaseDC(HWND hWnd, HDC hDC);
|
||||
boolean InvalidateRect(HWND hWnd, long lpRect, boolean bErase);
|
||||
boolean UpdateWindow(HWND hWnd);
|
||||
boolean RedrawWindow(HWND hWnd, long lprcUpdate, long hrgnUpdate, int flags);
|
||||
|
||||
void GetWindowTextA(HWND hWnd, byte[] buffer, int buflen);
|
||||
int GetTopWindow(HWND hWnd);
|
||||
int GetWindow(HWND hWnd, int flag);
|
||||
final int GW_HWNDNEXT = 2;
|
||||
int GetClassName(HWND hWnd, char[] buffer2, int i);
|
||||
int GetWindowModuleFileName(HWND hWnd, char[] buffer2, int i);
|
||||
int GetWindowThreadProcessId(HWND hWnd, PointerByReference pref);
|
||||
//int GetWindowThreadProcessId(HWND hWnd, IntByReference lpdwProcessId);
|
||||
|
||||
|
||||
boolean GetCursorPos(long[] lpPoint); //use macros POINT_X() and POINT_Y() on long lpPoint[0]
|
||||
|
||||
HWND WindowFromPoint(long point);
|
||||
HWND ChildWindowFromPointEx(HWND hwndParent, long point, int uFlags);
|
||||
boolean ClientToScreen(HWND hWnd, long[] lpPoint);//use macros POINT_X() and POINT_Y() on long lpPoint[0]
|
||||
boolean ScreenToClient(HWND hWnd, long[] lpPoint);//use macros POINT_X() and POINT_Y() on long lpPoint[0]
|
||||
//HWND WindowFromPoint(int xPoint, int yPoint);
|
||||
//HWND WindowFromPoint(POINT point);
|
||||
|
||||
HMENU GetMenu(HWND hWnd);
|
||||
HMENU GetSystemMenu(HWND hWnd, boolean bRevert);
|
||||
boolean IsMenu(HMENU hMenu);
|
||||
int GetMenuString(HMENU hMenu, int uIDItem, char[] buffer, int nMaxCount, int uFlag);
|
||||
HMENU GetSubMenu(HMENU hMenu, int nPos);
|
||||
int GetMenuItemCount(HMENU hMenu);
|
||||
int GetMenuItemID(HMENU hMenu, int nPos);
|
||||
//BOOL WINAPI GetMenuItemInfo(_In_ HMENU hMenu, _In_ UINT uItem, _In_ BOOL fByPosition, _Inout_ LPMENUITEMINFO lpmii);
|
||||
boolean GetMenuItemInfoA(HMENU hMenu, int uItem, boolean fByPosition, WinDefEx.MENUITEMINFO mii); //MENUITEMINFO
|
||||
boolean TrackPopupMenu(HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, long prcRect);
|
||||
boolean GetMenuItemRect(HWND hWnd, HMENU hMenu, int uItem, RECT rect);
|
||||
|
||||
int GetDlgCtrlID(HWND hwndCtl);
|
||||
int GetDlgItemText(HWND hDlg, int nIDDlgItem, byte[] buffer, int nMaxCount);
|
||||
}
|
||||
|
||||
public interface Gdi32Ex extends W32APIOptions {
|
||||
Gdi32Ex instance = (Gdi32Ex) Native.loadLibrary("gdi32", Gdi32Ex.class, DEFAULT_OPTIONS);
|
||||
HANDLE SelectObject(HDC hdc, HANDLE hgdiobj);
|
||||
HANDLE GetStockObject(int fnObject);
|
||||
boolean Rectangle(HDC hdc, int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
|
||||
HPEN CreatePen(int fnPenStyle, int nWidth, int crColor);
|
||||
}
|
||||
|
||||
public interface PsapiEx extends W32APIOptions {
|
||||
PsapiEx instance = (PsapiEx) Native.loadLibrary("psapi", PsapiEx.class, DEFAULT_OPTIONS);
|
||||
int GetModuleBaseNameW(Pointer hProcess, Pointer hmodule, char[] lpBaseName, int size);
|
||||
}
|
||||
|
||||
public interface Kernel32Ex extends W32APIOptions {
|
||||
Kernel32Ex instance = (Kernel32Ex) Native.loadLibrary("kernel32", Kernel32Ex.class, DEFAULT_OPTIONS);
|
||||
boolean GetDiskFreeSpaceEx(String lpDirectoryName, LARGE_INTEGER.ByReference lpFreeBytesAvailable, LARGE_INTEGER.ByReference lpTotalNumberOfBytes, LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes);
|
||||
int GetLastError();
|
||||
Pointer OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer);
|
||||
//int OpenProcess(int dwDesiredAccess, boolean bInheritHandle, Pointer pointer);
|
||||
boolean CloseHandle(HANDLE hObject);
|
||||
void GetNativeSystemInfo(SYSTEM_INFO lpSystemInfo);
|
||||
boolean IsWow64Process(HANDLE hProcess, IntByReference Wow64Process);
|
||||
//LPVOID VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
|
||||
|
||||
//int VirtualAllocEx(HANDLE hProcess, int lpAddress, int dwSize, DWORD flAllocationType, DWORD flProtect);
|
||||
IntByReference VirtualAllocEx(HANDLE hProc, IntByReference addr, SIZE_T size, int allocType, int prot);
|
||||
Pointer VirtualAllocEx(HANDLE hProc, int i, int lngMemLen2, int allocType, int pAGE_READWRITE);
|
||||
boolean VirtualFreeEx(HANDLE hProcess, IntByReference lpAddress, SIZE_T dwSize, DWORD dwFreeType);
|
||||
boolean WriteProcessMemory(HANDLE hProcess, IntByReference lpBaseAddress, Pointer lpBuffer, int len, IntByReference bytesWritten);
|
||||
|
||||
//boolean WriteProcessMemory(Pointer p, long address, Pointer buffer, int size, IntByReference written);
|
||||
boolean ReadProcessMemory(Pointer hProcess, long inBaseAddress, Pointer outputBuffer, int nSize, IntByReference outNumberOfBytesRead);
|
||||
int WriteProcessMemory(HANDLE handle, Pointer lngMemVar2, LVITEM_VISTA lvi,
|
||||
int lngMemLen2, IntByReference byteIO);
|
||||
int ReadProcessMemory(HANDLE handle, Pointer lngMemVar1,
|
||||
Pointer lngVarPtr1, int lngMemLen1, IntByReference byteIO);
|
||||
int VirtualFreeEx(HANDLE hProcess, Pointer lngMemVar1, int i,
|
||||
int mEM_RELEASE);
|
||||
}
|
||||
|
||||
|
||||
public Api() {
|
||||
user32 = User32Ex.instance;
|
||||
psapi = PsapiEx.instance;
|
||||
kernel32 = Kernel32Ex.instance;
|
||||
}
|
||||
|
||||
public static Long GetHandleAsLong(HWND hWnd) {
|
||||
if (hWnd == null)
|
||||
return (long)0;
|
||||
//String longHexStr = hWnd.toString().substring("native@".length());
|
||||
String longHexStr = hWnd.getPointer().toString().substring("native@".length());
|
||||
return Long.decode(longHexStr);
|
||||
}
|
||||
|
||||
public static String GetHandleAsString(HWND hWnd) {
|
||||
return GetHandleAsLong(hWnd).toString();
|
||||
}
|
||||
|
||||
public static HWND GetHandleFromString(String hWnd) {
|
||||
if (hWnd == null)
|
||||
return null;
|
||||
if (hWnd.isEmpty())
|
||||
return null;
|
||||
String cleanNumericHandle = hWnd.replaceAll("[^\\d.]", "");
|
||||
try {
|
||||
return (new HWND(new Pointer(Long.parseLong(cleanNumericHandle))));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getWindowClassName(HWND hWnd) {
|
||||
char[] buffer = new char[1026];
|
||||
User32Ex.instance.GetClassName(hWnd, buffer, 1026);
|
||||
return Native.toString(buffer);
|
||||
}
|
||||
|
||||
public static String getWindowText(HWND hWnd) {
|
||||
String text = "";
|
||||
byte[] buffer = new byte[1024];
|
||||
User32Ex.instance.GetWindowTextA(hWnd, buffer, buffer.length);
|
||||
text = Native.toString(buffer);
|
||||
if (text.isEmpty())
|
||||
text = new Api().sendWmGetText(hWnd);
|
||||
return text;
|
||||
}
|
||||
|
||||
public static Point getCursorPos() {
|
||||
|
||||
long[] getPos = new long [1];
|
||||
User32Ex.instance.GetCursorPos(getPos);
|
||||
return new Point(POINT_X(getPos[0]), POINT_Y(getPos[0]));
|
||||
}
|
||||
|
||||
public static HWND getWindowFromCursorPos() {
|
||||
|
||||
long[] getPos = new long [1];
|
||||
User32Ex.instance.GetCursorPos(getPos);
|
||||
HWND hwnd = User32Ex.instance.WindowFromPoint(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)
|
||||
{
|
||||
//int x = POINT_X(point);int y = POINT_Y(point);
|
||||
|
||||
long[] getPos = new long [1];
|
||||
getPos[0] = point;
|
||||
//if (!User32.instance.ClientToScreen(inHwnd, getPos)) return lHWND;
|
||||
//x = POINT_X(getPos[0]);y = POINT_Y(getPos[0]);
|
||||
//System.out.println("ClientToScreen " + GetHandleAsString(inHwnd) + ", " + x + ", " + y);
|
||||
|
||||
if (!User32Ex.instance.ScreenToClient(inHwnd, getPos)) return inHwnd; // if point is not correct use original hwnd.
|
||||
//x = POINT_X(getPos[0]);y = POINT_Y(getPos[0]);
|
||||
//System.out.println("ScreenToClient " + GetHandleAsString(inHwnd) + ", " + x + ", " + y);
|
||||
|
||||
HWND childHwnd = User32Ex.instance.ChildWindowFromPointEx(inHwnd, getPos[0], CWP_ALL);
|
||||
//System.out.println("ChildWindowFromPointEx2 " + GetHandleAsString(inHwnd) + ", " + x + ", " + y + " = " + GetHandleAsString(childHwnd));
|
||||
|
||||
if (childHwnd == null) // if childHwnd is not correct use original hwnd.
|
||||
return inHwnd;
|
||||
|
||||
return childHwnd;
|
||||
}
|
||||
|
||||
public HWND findWindowByTitle(String title) {
|
||||
HWND handle = user32.FindWindow(null, title);
|
||||
return handle;
|
||||
}
|
||||
|
||||
public boolean activateWindow(HWND handle) {
|
||||
boolean result = user32.SetForegroundWindow(handle);
|
||||
user32.SetFocus(handle);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void SetDialogFocus(HWND hdlg, HWND hwndControl) {
|
||||
WPARAM wp = new WPARAM(hwndControl.getPointer().getLong(0));
|
||||
LPARAM lp = new LPARAM(1);
|
||||
user32.SendMessage(hdlg, WM_NEXTDLGCTL, wp, lp);
|
||||
}
|
||||
|
||||
public boolean showWindow(HWND handle) {
|
||||
return user32.ShowWindow(handle, WinUser.SW_SHOW);
|
||||
}
|
||||
|
||||
public boolean hideWindow(HWND handle) {
|
||||
return user32.ShowWindow(handle, WinUser.SW_HIDE);
|
||||
}
|
||||
|
||||
public boolean minimizeWindow(HWND handle) {
|
||||
return user32.ShowWindow(handle, WinUser.SW_MINIMIZE);
|
||||
}
|
||||
|
||||
public boolean maximizeWindow(HWND handle) {
|
||||
return user32.ShowWindow(handle, WinUser.SW_MAXIMIZE);
|
||||
}
|
||||
|
||||
public boolean restoreWindow(HWND handle) {
|
||||
return user32.ShowWindow(handle, WinUser.SW_RESTORE);
|
||||
}
|
||||
|
||||
public boolean closeWindow(HWND handle) {
|
||||
//return user32.DestroyWindow(handle);
|
||||
//user32.SendMessage(handle, WM_CLOSE , null, null);
|
||||
user32.PostMessage(handle, WM_CLOSE , null, null);
|
||||
//user32.SendMessage(handle, WM_NCDESTROY , null, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void switchToThisWindow(HWND handle, boolean fAltTab) {
|
||||
user32.SwitchToThisWindow(handle, fAltTab);
|
||||
}
|
||||
|
||||
public String sendWmGetText(HWND handle) {
|
||||
int bufSize = 8192;
|
||||
byte[] lParamStr = new byte[bufSize];
|
||||
user32.SendMessageA(handle, WM_GETTEXT, bufSize, lParamStr);
|
||||
return (Native.toString(lParamStr));
|
||||
}
|
||||
|
||||
public void sendWmSetText(HWND handle, String text) {
|
||||
user32.SendMessageA(handle, WM_SETTEXT, 0, Native.toByteArray(text));
|
||||
}
|
||||
|
||||
public void sendClick(HWND handle) {
|
||||
user32.SendMessageA(handle, WM_LBUTTONDOWN, 0, null);
|
||||
user32.SendMessageA(handle, WM_LBUTTONUP, 0, null);
|
||||
}
|
||||
|
||||
public void sendDoubleClick(HWND handle) {
|
||||
user32.SendMessageA(handle, WM_LBUTTONDBLCLK, 0, null);
|
||||
//user32.SendMessageA(handle, WM_LBUTTONUP, 0, null);
|
||||
}
|
||||
|
||||
public void sendRightClick(HWND handle) {
|
||||
user32.SendMessageA(handle, WM_RBUTTONDOWN, 0, null);
|
||||
user32.SendMessageA(handle, WM_RBUTTONUP, 0, null);
|
||||
}
|
||||
|
||||
public void sendKeyDown(HWND handle, int keyCode) {
|
||||
user32.SendMessageA(handle, WM_KEYDOWN, keyCode, null);
|
||||
//user32.SendMessageA(handle, WM_KEYUP, keyCode, null);
|
||||
}
|
||||
|
||||
public void sendKeyUp(HWND handle, int keyCode) {
|
||||
//user32.SendMessageA(handle, WM_KEYDOWN, keyCode, null);
|
||||
user32.SendMessageA(handle, WM_KEYUP, keyCode, null);
|
||||
}
|
||||
|
||||
public String GetMenuItemText(HMENU hmenu, int position) {
|
||||
if (user32.IsMenu(hmenu) == false)
|
||||
return "";
|
||||
char[] buffer = new char[256];
|
||||
user32.GetMenuString(hmenu, position, buffer, 256, 0x0400);
|
||||
return Native.toString(buffer);
|
||||
/*
|
||||
Api.WinDefExt.MENUITEMINFO mii = new Api.WinDefExt.MENUITEMINFO(); // = (MENUITEMINFO)Api.MENUITEMINFO.newInstance(Api.MENUITEMINFO.class);
|
||||
mii.fMask = Api.WinDefExt.MENUITEMINFO.MIIM_TYPE;
|
||||
mii.fType = Api.WinDefExt.MENUITEMINFO.MFT_STRING;
|
||||
mii.cch = 0;
|
||||
mii.dwTypeData = "";
|
||||
@SuppressWarnings("unused")
|
||||
boolean result = Api.User32.instance.GetMenuItemInfoA(hmenu, position, true, mii);
|
||||
//System.out.println(position + " GetMenuItemInfo (" + result + ") : " + mii.cch + " " + mii.dwTypeData);
|
||||
mii.fMask = Api.WinDefExt.MENUITEMINFO.MIIM_TYPE;
|
||||
mii.fType = Api.WinDefExt.MENUITEMINFO.MFT_STRING;
|
||||
mii.cch += 1;
|
||||
mii.dwTypeData = "";//new String(new char[mii.cch]).replace("\0", " "); //buffer string with spaces
|
||||
result = Api.User32.instance.GetMenuItemInfoA(hmenu, position, true, mii);
|
||||
//System.out.println(position + " GetMenuItemInfo2 (" + result + ") Text: " + mii.dwTypeData + " " + mii.cch + " " + mii.wID);
|
||||
//System.out.println("last error: " + Api.Kernel32.instance.GetLastError());
|
||||
return mii.dwTypeData;
|
||||
*/
|
||||
}
|
||||
|
||||
public Point getWindowPosition(HWND handle) {
|
||||
Point windowPoint = new Point();
|
||||
RECT rect = new RECT();
|
||||
user32.GetWindowRect(handle, 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 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);
|
||||
}
|
||||
|
||||
public int getDiskUsedPercentage(String target) {
|
||||
LARGE_INTEGER.ByReference lpFreeBytesAvailable = new LARGE_INTEGER.ByReference();
|
||||
LARGE_INTEGER.ByReference lpTotalNumberOfBytes = new LARGE_INTEGER.ByReference();
|
||||
LARGE_INTEGER.ByReference lpTotalNumberOfFreeBytes = new LARGE_INTEGER.ByReference();
|
||||
Kernel32Ex.instance.GetDiskFreeSpaceEx(target, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes);
|
||||
double freeBytes = lpTotalNumberOfFreeBytes.getValue();
|
||||
double totalBytes = lpTotalNumberOfBytes.getValue();
|
||||
//System.out.println("freespace " + humanReadableByteCount(freeBytes) + "/ totalspace " + humanReadableByteCount(totalBytes));
|
||||
return (int)(((totalBytes-freeBytes)/totalBytes) * 100.0);
|
||||
}
|
||||
|
||||
public static String humanReadableByteCount(double bytes) {
|
||||
boolean si = true;
|
||||
int unit = si ? 1000 : 1024;
|
||||
if (bytes < unit) return bytes + " B";
|
||||
int exp = (int) (Math.log(bytes) / Math.log(unit));
|
||||
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
|
||||
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
|
||||
}
|
||||
|
||||
public static void highlightWindow(HWND hwnd){
|
||||
RECT rect = new RECT();
|
||||
User32Ex.instance.GetWindowRect(hwnd, rect);
|
||||
//System.out.println("RECT: " + rect.left + "," + rect.top + "," + (rect.right - rect.left) + "," + (rect.bottom - rect.top));
|
||||
highlightWindow(hwnd, 0, 0, rect.right - rect.left, rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
// creates highlight around selected window
|
||||
public static void highlightWindow(HWND hwnd, int x, int y, int x2, int y2){
|
||||
//COLORREF i.e. 0x00804070 Red = 0x70 green = 0x40 blue = 0x80
|
||||
//g_hRectanglePen = CreatePen (PS_SOLID, 3, RGB(256, 0, 0));
|
||||
HPEN rectPen = Gdi32Ex.instance.CreatePen(PS_SOLID, 3, 0x00000099); //RGB(255, 0, 0)
|
||||
HDC dc = User32Ex.instance.GetWindowDC(hwnd);
|
||||
if (dc != null) {
|
||||
// Select our created pen into the DC and backup the previous pen.
|
||||
HANDLE prevPen = Gdi32Ex.instance.SelectObject(dc, rectPen);
|
||||
|
||||
// Select a transparent brush into the DC and backup the previous brush.
|
||||
HANDLE prevBrush = Gdi32Ex.instance.SelectObject(dc, Gdi32Ex.instance.GetStockObject(HOLLOW_BRUSH));
|
||||
|
||||
// Draw a rectangle in the DC covering the entire window area of the found window.
|
||||
Gdi32Ex.instance.Rectangle (dc, x, y, x2, y2);
|
||||
|
||||
// Reinsert the previous pen and brush into the found window's DC.
|
||||
Gdi32Ex.instance.SelectObject(dc, prevPen);
|
||||
Gdi32Ex.instance.SelectObject(dc, prevBrush);
|
||||
|
||||
// Finally release the DC.
|
||||
User32Ex.instance.ReleaseDC(hwnd, dc);
|
||||
}
|
||||
}
|
||||
|
||||
public static void refreshWindow(HWND hwnd) {
|
||||
User32Ex.instance.InvalidateRect(hwnd, 0, true);
|
||||
User32Ex.instance.UpdateWindow(hwnd);
|
||||
User32Ex.instance.RedrawWindow(hwnd, 0, 0, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
|
||||
}
|
||||
|
||||
public static boolean isDotNet4Installed() {
|
||||
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;
|
||||
}
|
||||
|
||||
public static boolean isProcess64bit(int pid)
|
||||
{
|
||||
try {
|
||||
SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO();
|
||||
Kernel32Ex.instance.GetNativeSystemInfo(lpSystemInfo);
|
||||
if (lpSystemInfo.processorArchitecture.dwOemID.intValue() == 0)
|
||||
{
|
||||
System.out.println("intel x86"); //not a 64 bit os
|
||||
return false;
|
||||
}
|
||||
|
||||
Pointer process = Kernel32Ex.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, new Pointer(pid));
|
||||
IntByReference isWow64 = new IntByReference(0);
|
||||
if (!Kernel32Ex.instance.IsWow64Process(new HANDLE(process), isWow64))
|
||||
{
|
||||
//handle error
|
||||
}
|
||||
//System.out.println("isProcess64bit " + pid + " = " + isWow64.getValue());
|
||||
Kernel32Ex.instance.CloseHandle(new HANDLE(process));
|
||||
if (isWow64.getValue() == 1)
|
||||
return false;
|
||||
return true;
|
||||
//CloseHandle()
|
||||
} catch(Exception ex)
|
||||
{
|
||||
ex.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static HWND FindMainWindowFromPid(final long targetProcessId) {
|
||||
|
||||
final List<HWND> resultList = new ArrayList<HWND>();
|
||||
class ParentWindowCallback implements WinUser.WNDENUMPROC {
|
||||
@Override
|
||||
public boolean callback(HWND hWnd, Pointer lParam) {
|
||||
PointerByReference pointer = new PointerByReference();
|
||||
User32Ex.instance.GetWindowThreadProcessId(hWnd, pointer);
|
||||
long pid = pointer.getPointer().getInt(0);
|
||||
if (pid == targetProcessId)
|
||||
if (resultList.isEmpty())
|
||||
resultList.add(hWnd);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Api.User32Ex.instance.EnumWindows(new ParentWindowCallback(), 0);
|
||||
if (!resultList.isEmpty())
|
||||
return resultList.get(0);
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void SelectListViewItemByIndex(HWND listViewHwnd, int index)
|
||||
{
|
||||
/*
|
||||
HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, 0x0000c130);
|
||||
LPVOID epLvi = VirtualAllocEx(hProcess, NULL, 4096, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
LVITEM lvi;
|
||||
lvi.state = LVIS_FOCUSED | LVIS_SELECTED;
|
||||
lvi.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
|
||||
SIZE_T cbWritten = 0;
|
||||
WriteProcessMemory(hProcess, epLvi, &lvi, sizeof(lvi), &cbWritten);
|
||||
DWORD dw = SendMessage((HWND)0x00020C4C, LVM_SETITEMSTATE, 1, (LPARAM)epLvi);
|
||||
|
||||
VirtualFreeEx(hProcess, epLvi, 4096, MEM_DECOMMIT | MEM_RELEASE);
|
||||
CloseHandle(hProcess);
|
||||
*/
|
||||
PointerByReference pointer = new PointerByReference();
|
||||
User32Ex.instance.GetWindowThreadProcessId(listViewHwnd, pointer);
|
||||
int pid = pointer.getPointer().getInt(0);
|
||||
Pointer process = Kernel32Ex.instance.OpenProcess(Api.PROCESS_VM_WRITE | Api.PROCESS_VM_OPERATION, false, new Pointer(pid));
|
||||
IntByReference addr = new IntByReference(0);
|
||||
SIZE_T size = new SIZE_T(4096);
|
||||
IntByReference epLvi = Kernel32Ex.instance.VirtualAllocEx(new HANDLE(process), addr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
|
||||
|
||||
LVITEM_VISTA lvitem = new LVITEM_VISTA();
|
||||
lvitem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
|
||||
lvitem.state = LVIS_FOCUSED | LVIS_SELECTED;
|
||||
IntByReference bytesWritten = new IntByReference();
|
||||
Api.Kernel32Ex.instance.WriteProcessMemory(new HANDLE(process), epLvi, lvitem.getPointer(), lvitem.size(),bytesWritten);
|
||||
Api.User32Ex.instance.SendMessage(listViewHwnd, LVM_SETITEMSTATE, new WPARAM(index), lvitem);
|
||||
|
||||
Api.Kernel32Ex.instance.VirtualFreeEx(new HANDLE(process), epLvi, new SIZE_T(4096), new DWORD(MEM_DECOMMIT | MEM_RELEASE));
|
||||
Api.Kernel32Ex.instance.CloseHandle(new HANDLE(process));
|
||||
}
|
||||
|
||||
public static void SelectListItemByIndex(HWND listHwnd, int index)
|
||||
{
|
||||
//com.sun.jna.platform.win32.User32.INSTANCE
|
||||
Api.User32Ex.instance.SendMessage(listHwnd, LB_SETCURSEL, new WPARAM(index), new LPARAM(0));
|
||||
SelectListViewItemByIndex(listHwnd, index);
|
||||
//GetListViewItemByIndex(listHwnd, index);
|
||||
//LVITEM lvitem = new LVITEM();
|
||||
//lvitem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
|
||||
//lvitem.state = LVIS_FOCUSED | LVIS_SELECTED;
|
||||
//JOptionPane.showMessageDialog(null, "lvitem size: " + lvitem.size());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.JMenu;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class CommandPopupMenu extends JPopupMenu {
|
||||
|
||||
public static interface menuEvents {
|
||||
void menuItemClicked(String command, int paramCount, boolean useXpath, ActionEvent e);
|
||||
}
|
||||
public menuEvents events = new menuEvents() {
|
||||
public void menuItemClicked(String command, int paramCount, boolean useXpath, ActionEvent e) {
|
||||
JOptionPane.showMessageDialog(null, command);
|
||||
}
|
||||
};
|
||||
|
||||
public CommandPopupMenu() {
|
||||
|
||||
JMenu mnKeyboard = new JMenu("Keyboard");
|
||||
add(mnKeyboard);
|
||||
|
||||
CommandMenuItem mntmSendkeys = new CommandMenuItem("sendKeys", 2, false);
|
||||
mnKeyboard.add(mntmSendkeys);
|
||||
|
||||
CommandMenuItem mntmKeydown = new CommandMenuItem("keyDown", 2, false);
|
||||
mnKeyboard.add(mntmKeydown);
|
||||
|
||||
CommandMenuItem mntmKeyup = new CommandMenuItem("keyUp", 2, false);
|
||||
mnKeyboard.add(mntmKeyup);
|
||||
|
||||
CommandMenuItem mntmKeycopy = new CommandMenuItem("keyCopy", 1);
|
||||
mnKeyboard.add(mntmKeycopy);
|
||||
|
||||
CommandMenuItem mntmKeypaste = new CommandMenuItem("keyPaste", 1);
|
||||
mnKeyboard.add(mntmKeypaste);
|
||||
|
||||
CommandMenuItem mntmKeyEsc = new CommandMenuItem("keyEscape", 1);
|
||||
mnKeyboard.add(mntmKeyEsc);
|
||||
|
||||
CommandMenuItem mntmKeyFunc = new CommandMenuItem("keyFunctionX", 2, false);
|
||||
mnKeyboard.add(mntmKeyFunc);
|
||||
|
||||
JMenu mnMouse = new JMenu("Mouse");
|
||||
add(mnMouse);
|
||||
|
||||
CommandMenuItem mntmClick = new CommandMenuItem("click", 2, true);
|
||||
mnMouse.add(mntmClick);
|
||||
|
||||
CommandMenuItem mntmDoubleclick = new CommandMenuItem("doubleClick", 2, true);
|
||||
mnMouse.add(mntmDoubleclick);
|
||||
|
||||
CommandMenuItem mntmRightclick = new CommandMenuItem("rightClick", 2, true);
|
||||
mnMouse.add(mntmRightclick);
|
||||
|
||||
CommandMenuItem mntmwinClick = new CommandMenuItem("winClick", 2);
|
||||
mnMouse.add(mntmwinClick);
|
||||
|
||||
CommandMenuItem mntmwinDoubleClick = new CommandMenuItem("winDoubleClick", 2);
|
||||
mnMouse.add(mntmwinDoubleClick);
|
||||
|
||||
CommandMenuItem mntmwinRightClick = new CommandMenuItem("winRightClick", 2);
|
||||
mnMouse.add(mntmwinRightClick);
|
||||
|
||||
CommandMenuItem mntmDraganddrop = new CommandMenuItem("dragAndDrop", 3);
|
||||
mnMouse.add(mntmDraganddrop);
|
||||
|
||||
CommandMenuItem mntmMousedown = new CommandMenuItem("mouseDown", 1, false);
|
||||
mnMouse.add(mntmMousedown);
|
||||
|
||||
CommandMenuItem mntmMouseup = new CommandMenuItem("mouseUp", 1, false);
|
||||
mnMouse.add(mntmMouseup);
|
||||
|
||||
CommandMenuItem mntmMousedownright = new CommandMenuItem("mouseDownRight", 1, false);
|
||||
mnMouse.add(mntmMousedownright);
|
||||
|
||||
CommandMenuItem mntmMouseupright = new CommandMenuItem("mouseUpRight", 1, false);
|
||||
mnMouse.add(mntmMouseupright);
|
||||
|
||||
CommandMenuItem mntmMousemove = new CommandMenuItem("mouseMove", 2, true);
|
||||
mnMouse.add(mntmMousemove);
|
||||
|
||||
CommandMenuItem mntmMousemoveXy = new CommandMenuItem("mouseMoveXy", 3, false);
|
||||
mnMouse.add(mntmMousemoveXy);
|
||||
|
||||
CommandMenuItem mntmSetTargetOffset = new CommandMenuItem("setTargetOffset", 3, false);
|
||||
mnMouse.add(mntmSetTargetOffset);
|
||||
|
||||
|
||||
JMenu mnWinMessages = new JMenu("Win Messages");
|
||||
add(mnWinMessages);
|
||||
|
||||
CommandMenuItem mntmWindowfocus = new CommandMenuItem("windowFocus", 2);
|
||||
mnWinMessages.add(mntmWindowfocus);
|
||||
|
||||
CommandMenuItem mntmWindowSwitchToThis = new CommandMenuItem("windowSwitchToThis", 2);
|
||||
mnWinMessages.add(mntmWindowSwitchToThis);
|
||||
|
||||
CommandMenuItem mntmSelectMenu = new CommandMenuItem("selectMenu", 2);
|
||||
mnWinMessages.add(mntmSelectMenu);
|
||||
|
||||
CommandMenuItem mntmSelectContextMenuId = new CommandMenuItem("selectContextMenuId", 3);
|
||||
mnWinMessages.add(mntmSelectContextMenuId);
|
||||
|
||||
CommandMenuItem mntmSendCommandMsg = new CommandMenuItem("sendCommandMsg", 4);
|
||||
mnWinMessages.add(mntmSendCommandMsg);
|
||||
|
||||
CommandMenuItem mntmSendMessage = new CommandMenuItem("sendMessage", 5);
|
||||
mnWinMessages.add(mntmSendMessage);
|
||||
|
||||
CommandMenuItem mntmSetcursorposition = new CommandMenuItem("setCursorPosition", 3);
|
||||
mnWinMessages.add(mntmSetcursorposition);
|
||||
|
||||
CommandMenuItem mntmWindowminimize = new CommandMenuItem("windowMinimize", 2);
|
||||
mnWinMessages.add(mntmWindowminimize);
|
||||
|
||||
CommandMenuItem mntmWindowmaximize = new CommandMenuItem("windowMaximize", 2);
|
||||
mnWinMessages.add(mntmWindowmaximize);
|
||||
|
||||
CommandMenuItem mntmWindowrestore = new CommandMenuItem("windowRestore", 2);
|
||||
mnWinMessages.add(mntmWindowrestore);
|
||||
|
||||
CommandMenuItem mntmWindowhide = new CommandMenuItem("windowHide", 2);
|
||||
mnWinMessages.add(mntmWindowhide);
|
||||
|
||||
CommandMenuItem mntmWindowshow = new CommandMenuItem("windowShow", 2);
|
||||
mnWinMessages.add(mntmWindowshow);
|
||||
|
||||
CommandMenuItem mntmWindowclose = new CommandMenuItem("windowClose", 2);
|
||||
mnWinMessages.add(mntmWindowclose);
|
||||
|
||||
CommandMenuItem mntmSetwindowtext = new CommandMenuItem("setWindowText", 3);
|
||||
mnWinMessages.add(mntmSetwindowtext);
|
||||
|
||||
CommandMenuItem mntmGetwindowtext = new CommandMenuItem("getWindowText", 2);
|
||||
mnWinMessages.add(mntmGetwindowtext);
|
||||
|
||||
CommandMenuItem mntmGetwindowclass = new CommandMenuItem("getWindowClass", 2);
|
||||
mnWinMessages.add(mntmGetwindowclass);
|
||||
|
||||
CommandMenuItem mntmSelectListIndex = new CommandMenuItem("selectListIndex", 3);
|
||||
mnWinMessages.add(mntmSelectListIndex);
|
||||
|
||||
CommandMenuItem mntmSelectListString = new CommandMenuItem("selectListString", 3);
|
||||
mnWinMessages.add(mntmSelectListString);
|
||||
|
||||
CommandMenuItem mntmDisplayText = new CommandMenuItem("displayText", 3, false);
|
||||
add(mntmDisplayText);
|
||||
|
||||
CommandMenuItem mntmDisableStatus = new CommandMenuItem("disableStatus", 2, false);
|
||||
add(mntmDisableStatus);
|
||||
|
||||
CommandMenuItem mntmForceRefresh = new CommandMenuItem("forceRefresh", 1, false);
|
||||
add(mntmForceRefresh);
|
||||
|
||||
CommandMenuItem mntmForcewin32Refresh = new CommandMenuItem("forceWin32Refresh", 1, false);
|
||||
add(mntmForcewin32Refresh);
|
||||
|
||||
CommandMenuItem mntmOnlyRefreshWin32 = new CommandMenuItem("onlyRefreshWin32", 2, false);
|
||||
add(mntmOnlyRefreshWin32);
|
||||
|
||||
|
||||
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 mntmTakeScreenCapture = new CommandMenuItem("takeScreenCapture", 2, false);
|
||||
add(mntmTakeScreenCapture);
|
||||
|
||||
CommandMenuItem mntmTargetRefresh = new CommandMenuItem("targetRefresh", 2);
|
||||
add(mntmTargetRefresh);
|
||||
|
||||
CommandMenuItem mntmVerifyElementNotPresent = new CommandMenuItem("verifyElementNotPresent", 2);
|
||||
add(mntmVerifyElementNotPresent);
|
||||
|
||||
CommandMenuItem mntmVerifyElementPresent = new CommandMenuItem("verifyElementPresent", 2);
|
||||
add(mntmVerifyElementPresent);
|
||||
|
||||
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 mntmWaitforvisible = new CommandMenuItem("waitForVisible", 2);
|
||||
add(mntmWaitforvisible);
|
||||
|
||||
}
|
||||
|
||||
class CommandMenuItem extends JMenuItem {
|
||||
public String commandText = "";
|
||||
public int paramCount = 2;
|
||||
public boolean useXpath = true;
|
||||
|
||||
public CommandMenuItem(String arg0, int paramCount) {
|
||||
super(arg0);
|
||||
init(arg0, paramCount, true);
|
||||
}
|
||||
|
||||
public CommandMenuItem(String arg0, int paramCount, boolean useXpath) {
|
||||
super(arg0);
|
||||
init(arg0, paramCount, useXpath);
|
||||
}
|
||||
|
||||
public void init(String arg0, int paramCount, boolean useXpath) {
|
||||
this.commandText = arg0;
|
||||
this.paramCount = paramCount;
|
||||
this.useXpath = useXpath;
|
||||
this.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
events.menuItemClicked(commandText, CommandMenuItem.this.paramCount, CommandMenuItem.this.useXpath, e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static String buildSkeletonCommand(String command, int paramCount, String xpathStr, boolean useXpath) {
|
||||
String xpathItem = xpathStr;
|
||||
if (!useXpath)
|
||||
xpathItem = "";
|
||||
String actionStr = "| do | " + command + " | ";
|
||||
if (paramCount > 1)
|
||||
actionStr += "on | " + xpathItem + " | ";
|
||||
if (paramCount > 2)
|
||||
actionStr += "with | |";
|
||||
if (paramCount > 3)
|
||||
actionStr += " and | |";
|
||||
if (paramCount > 4)
|
||||
actionStr += " and | |";
|
||||
return actionStr;
|
||||
}
|
||||
}
|
||||
@@ -1,318 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JOptionPane;
|
||||
import org.synthuse.commands.*;
|
||||
|
||||
public class CommandProcessor implements Runnable{
|
||||
|
||||
public static long SPEED = 1000; // ms
|
||||
public static double XML_UPDATE_THRESHOLD = 5.0; // seconds
|
||||
public static long WAIT_TIMEOUT_THRESHOLD = 30000; //ms
|
||||
public static AtomicBoolean STOP_PROCESSOR = new AtomicBoolean(false); //stop script from executing
|
||||
public static boolean DEFAULT_QUIET = false; //by default is quiet enabled
|
||||
|
||||
protected CommandProcessor CommandProcessor = null;
|
||||
public int executeCount = 0;
|
||||
public int executeErrorCount;
|
||||
public String lastError = "";
|
||||
public String currentCommandText = "";
|
||||
public Point targetOffset = new Point();
|
||||
public StatusWindow currentStatusWin = null;
|
||||
|
||||
public String scriptStr = "";
|
||||
public BaseCommand base = new BaseCommand(this);
|
||||
public MouseCommands mouse = new MouseCommands(this);
|
||||
public KeyboardCommands keyboard = new KeyboardCommands(this);
|
||||
public WindowsCommands win = new WindowsCommands(this);
|
||||
public MainCommands main = new MainCommands(this);
|
||||
|
||||
private boolean isQuiet = DEFAULT_QUIET;
|
||||
private int scriptErrorCount = 0;
|
||||
|
||||
public static interface Events {
|
||||
void statusChanged(String status);
|
||||
void executionCompleted();
|
||||
}
|
||||
public Events events = new Events() {
|
||||
public void statusChanged(String status){
|
||||
System.out.println(status);
|
||||
}
|
||||
public void executionCompleted(){
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public int getErrors() {
|
||||
return scriptErrorCount;
|
||||
}
|
||||
|
||||
public void setScript(String Script) {
|
||||
scriptStr = Script;
|
||||
}
|
||||
|
||||
public void setQuiet(boolean val) {
|
||||
isQuiet = val;
|
||||
if (val)
|
||||
{
|
||||
if (currentStatusWin != null)
|
||||
currentStatusWin.dispose();
|
||||
currentStatusWin = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public CommandProcessor () {
|
||||
}
|
||||
|
||||
public CommandProcessor (String scriptStr) {
|
||||
this.scriptStr = scriptStr;
|
||||
}
|
||||
|
||||
public CommandProcessor (String scriptStr, Events customEvents) { //multithreading support
|
||||
this.scriptStr = scriptStr;
|
||||
if (customEvents != null)
|
||||
this.events = customEvents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() { //multithreading support
|
||||
executeAllScriptCommands(scriptStr);
|
||||
}
|
||||
|
||||
public static CommandProcessor executeThreaded(String scriptStr, Events customEvents) { //multithreading support
|
||||
CommandProcessor cp = new CommandProcessor(scriptStr, customEvents);
|
||||
Thread t = new Thread(cp);
|
||||
t.start();
|
||||
return cp;
|
||||
}
|
||||
|
||||
public void executeAllScriptCommands(String scriptStr) {
|
||||
events.statusChanged("Executing Test Script...");
|
||||
//CommandProcessor cmdProcessor = new CommandProcessor();
|
||||
scriptErrorCount = 0;
|
||||
executeCount = 0;
|
||||
lastError = "";
|
||||
long startTime = System.nanoTime();
|
||||
String[] lines = scriptStr.split("\n");
|
||||
for (String line : lines) {
|
||||
|
||||
if (!line.trim().startsWith("|"))
|
||||
continue; //skip if it doesn't start with bar
|
||||
String[] parsed = line.trim().split("\\|");
|
||||
//
|
||||
|
||||
//System.out.println("line: " + line);
|
||||
//System.out.println("parsed len = " + parsed.length);
|
||||
//System.out.println("parsed 2 = " + parsed[2]);
|
||||
//System.out.println("parsed 4 = " + parsed[4]);
|
||||
events.statusChanged("Executing line: " + line);
|
||||
if (parsed.length == 4 || parsed.length == 3)
|
||||
execute(parsed[2].trim(), new String[] {});
|
||||
if (parsed.length == 6 || parsed.length == 5)
|
||||
execute(parsed[2].trim(), new String[] {parsed[4].trim()});
|
||||
if (parsed.length == 7)
|
||||
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim()});
|
||||
if (parsed.length == 9)
|
||||
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim(), parsed[8].trim()});
|
||||
if (parsed.length == 11)
|
||||
execute(parsed[2].trim(), new String[] {parsed[4].trim(), parsed[6].trim(), parsed[8].trim(), parsed[10].trim()});
|
||||
|
||||
if (executeErrorCount > 0) //check if any errors occurred
|
||||
++scriptErrorCount;
|
||||
|
||||
if (STOP_PROCESSOR.get())
|
||||
break;
|
||||
}
|
||||
double seconds = ((double)(System.nanoTime() - startTime) / 1000000000);
|
||||
String forcedStr = "Completed";
|
||||
if (STOP_PROCESSOR.get())
|
||||
forcedStr = "Stopped";
|
||||
events.statusChanged("Script Execution " + forcedStr + " " + executeCount + " command(s) with " + scriptErrorCount + " error(s) in " + new DecimalFormat("#.###").format(seconds) + " seconds");
|
||||
events.executionCompleted();
|
||||
if (scriptErrorCount > 0 && !isQuiet)
|
||||
{
|
||||
JOptionPane optionPane = new JOptionPane(lastError);
|
||||
JDialog dialog = optionPane.createDialog("Errors");
|
||||
dialog.setAlwaysOnTop(SynthuseDlg.config.isAlwaysOnTop());
|
||||
dialog.setVisible(true);
|
||||
dialog.dispose();
|
||||
//JOptionPane.showMessageDialog(null, lastError);
|
||||
}
|
||||
}
|
||||
|
||||
public Object execute(String command, String[] args) {
|
||||
++executeCount;
|
||||
executeErrorCount = 0;
|
||||
currentCommandText = command;
|
||||
String joinedArgs = "";
|
||||
for (String arg : args)
|
||||
joinedArgs += arg + " | ";
|
||||
if (joinedArgs.endsWith("| "))
|
||||
joinedArgs = joinedArgs.substring(0, joinedArgs.length()-2);
|
||||
//StatusWindow sw = null;
|
||||
if (!isQuiet)
|
||||
currentStatusWin = new StatusWindow(command + " " + joinedArgs, -1);
|
||||
|
||||
Object result = executeCommandSwitch(command, args);
|
||||
if (SPEED > 0)
|
||||
try { Thread.sleep(SPEED); } catch (Exception e) {e.printStackTrace();}
|
||||
|
||||
if (!isQuiet && currentStatusWin != null)
|
||||
currentStatusWin.dispose();
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object executeCommandSwitch(String command, String[] args) {
|
||||
try {
|
||||
|
||||
//Key commands
|
||||
if (command.equals("sendKeys"))
|
||||
return keyboard.cmdSendKeys(args);
|
||||
if (command.equals("keyDown"))
|
||||
return keyboard.cmdKeyDown(args);
|
||||
if (command.equals("keyUp"))
|
||||
return keyboard.cmdKeyUp(args);
|
||||
if (command.equals("keyCopy"))
|
||||
return keyboard.cmdKeyCopy(args);
|
||||
if (command.equals("keyPaste"))
|
||||
return keyboard.cmdKeyPaste(args);
|
||||
if (command.equals("keyEscape"))
|
||||
return keyboard.cmdKeyEscape(args);
|
||||
if (command.equals("keyFunctionX"))
|
||||
return keyboard.cmdKeyFunc(args);
|
||||
|
||||
|
||||
//Mouse commands
|
||||
if (command.equals("click"))
|
||||
return mouse.cmdClick(args);
|
||||
if (command.equals("doubleClick"))
|
||||
return mouse.cmdDoubleClick(args);
|
||||
if (command.equals("rightClick"))
|
||||
return mouse.cmdRightClick(args);
|
||||
if (command.equals("winClick"))
|
||||
return mouse.cmdWinClick(args);
|
||||
if (command.equals("winDoubleClick"))
|
||||
return mouse.cmdWinDoubleClick(args);
|
||||
if (command.equals("winRightClick"))
|
||||
return mouse.cmdWinRightClick(args);
|
||||
if (command.equals("dragAndDrop"))
|
||||
return mouse.cmdRightClick(args);
|
||||
if (command.equals("mouseDown"))
|
||||
return mouse.cmdMouseDown(args);
|
||||
if (command.equals("mouseUp"))
|
||||
return mouse.cmdMouseUp(args);
|
||||
if (command.equals("mouseDownRight"))
|
||||
return mouse.cmdMouseDownRight(args);
|
||||
if (command.equals("mouseUpRight"))
|
||||
return mouse.cmdMouseUpRight(args);
|
||||
if (command.equals("mouseMove"))
|
||||
return mouse.cmdMouseMove(args);
|
||||
if (command.equals("mouseMoveXy"))
|
||||
return mouse.cmdMouseMoveXy(args);
|
||||
if (command.equals("setTargetOffset"))
|
||||
return mouse.cmdSetTargetOffset(args);
|
||||
|
||||
//Windows Api Commands
|
||||
if (command.equals("windowFocus"))
|
||||
return win.cmdWindowFocus(args);
|
||||
if (command.equals("selectMenu"))
|
||||
return win.cmdSelectMenu(args);
|
||||
if (command.equals("selectContextMenuId"))
|
||||
return win.cmdSelectContextMenuId(args);
|
||||
if (command.equals("sendCommandMsg"))
|
||||
return win.cmdSendCommandMsg(args);
|
||||
if (command.equals("sendMessage"))
|
||||
return win.cmdSendMessage(args);
|
||||
if (command.equals("windowMinimize"))
|
||||
return win.cmdWindowMinimize(args);
|
||||
if (command.equals("windowMaximize"))
|
||||
return win.cmdWindowMaximize(args);
|
||||
if (command.equals("windowRestore"))
|
||||
return win.cmdWindowRestore(args);
|
||||
if (command.equals("windowShow"))
|
||||
return win.cmdWindowShow(args);
|
||||
if (command.equals("windowHide"))
|
||||
return win.cmdWindowHide(args);
|
||||
if (command.equals("windowSwitchToThis"))
|
||||
return win.cmdWindowSwitchToThis(args);
|
||||
if (command.equals("windowClose"))
|
||||
return win.cmdWindowClose(args);
|
||||
if (command.equals("setWindowText"))
|
||||
return win.cmdSetText(args);
|
||||
if (command.equals("getWindowText"))
|
||||
return win.cmdGetText(args);
|
||||
if (command.equals("selectListIndex"))
|
||||
return win.cmdSelectListIndex(args);
|
||||
if (command.equals("selectListString"))
|
||||
return win.cmdSelectListString(args);
|
||||
|
||||
// Misc Command and Test/Sample command
|
||||
if (command.equals("delay") || command.equals("pause")) {
|
||||
if (!base.checkArgumentLength(args, 1))
|
||||
return false;
|
||||
if (!base.checkFirstArgumentLength(args))
|
||||
return false;
|
||||
if (!base.checkIsNumeric(args[0]))
|
||||
return false;
|
||||
//System.out.println("sleeping for " + args[0] );
|
||||
Thread.sleep(Long.parseLong(args[0]));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (command.equals("open"))
|
||||
return main.cmdOpen(args);
|
||||
if (command.equals("displayText"))
|
||||
return main.cmdDisplayText(args);
|
||||
if (command.equals("disableStatus"))
|
||||
return main.cmdDisableStatus(args);
|
||||
if (command.equals("forceRefresh"))
|
||||
return main.cmdForceRefresh(args);
|
||||
if (command.equals("forceWin32Refresh"))
|
||||
return main.cmdForceWin32Refresh(args);
|
||||
if (command.equals("onlyRefreshWin32"))
|
||||
return main.cmdOnlyRefreshWin32(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("verifyElementNotPresent"))
|
||||
return main.cmdVerifyElementNotPresent(args);
|
||||
if (command.equals("verifyElementPresent"))
|
||||
return main.cmdVerifyElementPresent(args);
|
||||
if (command.equals("takeScreenCapture"))
|
||||
return main.cmdTakeScreenCapture(args);
|
||||
if (command.equals("targetRefresh"))
|
||||
return main.cmdTargetRefresh(args);
|
||||
if (command.equals("waitForTitle"))
|
||||
return main.cmdWaitForTitle(args);
|
||||
if (command.equals("waitForText"))
|
||||
return main.cmdWaitForText(args);
|
||||
if (command.equals("waitForClass"))
|
||||
return main.cmdWaitForClass(args);
|
||||
if (command.equals("waitForVisible"))
|
||||
return main.cmdWaitForVisible(args);
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
base.appendError(e);
|
||||
return false;
|
||||
}
|
||||
base.appendError("Error: Command '" + command + "' not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
public class Config extends PropertiesSerializer {
|
||||
|
||||
public static String DEFAULT_PROP_FILENAME = "synthuse.properties";
|
||||
|
||||
public String disableUiaBridge = "false";
|
||||
public String disableFiltersUia = "false";
|
||||
public String alwaysOnTop = "true";
|
||||
public String refreshKey = "3";
|
||||
public String targetKey = "`";
|
||||
public String urlList = "";
|
||||
public String xpathList = "";
|
||||
public String xpathHightlight = ".*process=\"([^\"]*)\".*";
|
||||
|
||||
public boolean useStrongTextMatching = false;
|
||||
|
||||
|
||||
public Config() //needed for cloning
|
||||
{
|
||||
}
|
||||
|
||||
public Config(String propertyFilename)
|
||||
{
|
||||
super(propertyFilename);
|
||||
load(propertyFilename);
|
||||
}
|
||||
|
||||
public boolean isUiaBridgeDisabled()
|
||||
{
|
||||
if (disableUiaBridge == null)
|
||||
return false;
|
||||
return disableUiaBridge.equals("true") || disableUiaBridge.equals("True");
|
||||
}
|
||||
|
||||
|
||||
public void setDisableUiaBridge(boolean aNewValue) {
|
||||
disableUiaBridge=aNewValue?"true":"false";
|
||||
}
|
||||
|
||||
|
||||
public boolean isFilterUiaDisabled()
|
||||
{
|
||||
if (disableFiltersUia == null)
|
||||
return false;
|
||||
return disableFiltersUia.equals("true") || disableFiltersUia.equals("True");
|
||||
}
|
||||
|
||||
public void setDisableFiltersUia(boolean aNewValue) {
|
||||
disableFiltersUia=aNewValue?"true":"false";
|
||||
}
|
||||
|
||||
|
||||
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 void setAlwaysOnTop(boolean aNewValue)
|
||||
{
|
||||
alwaysOnTop=aNewValue?"true":"false";
|
||||
}
|
||||
|
||||
public char getRefreshKey()
|
||||
{
|
||||
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 keyStr.charAt(0);
|
||||
}
|
||||
|
||||
public int getRefreshKeyCode()
|
||||
{
|
||||
return RobotMacro.getKeyCode(this.getRefreshKey())[0];
|
||||
}
|
||||
|
||||
public void setRefreshKey(String aText) {
|
||||
this.refreshKey=aText;
|
||||
}
|
||||
|
||||
public char getTargetKey()
|
||||
{
|
||||
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 keyStr.charAt(0);
|
||||
}
|
||||
|
||||
public int getTargetKeyCode()
|
||||
{
|
||||
return RobotMacro.getKeyCode(this.getTargetKey())[0];
|
||||
}
|
||||
|
||||
public void setTargetKey(String aText) {
|
||||
this.targetKey=aText;
|
||||
}
|
||||
|
||||
public boolean isUseStrongTextMatching() {
|
||||
return useStrongTextMatching;
|
||||
}
|
||||
|
||||
public void setUseStrongTextMatching(boolean useStrongTextMatching) {
|
||||
this.useStrongTextMatching = useStrongTextMatching;
|
||||
}
|
||||
|
||||
public String getXpathList() {
|
||||
return xpathList;
|
||||
}
|
||||
|
||||
public void setXPathList(String aText) {
|
||||
xpathList=aText;
|
||||
}
|
||||
|
||||
public String getXpathHighlight() {
|
||||
return xpathHightlight;
|
||||
}
|
||||
|
||||
public void setXPathHighlight(String aText) {
|
||||
xpathHightlight=aText;
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.Cursor;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.dnd.DragSource;
|
||||
import java.awt.dnd.DragSourceAdapter;
|
||||
import java.awt.dnd.DragSourceDragEvent;
|
||||
import java.awt.dnd.DragSourceMotionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import javax.activation.ActivationDataFlavor;
|
||||
import javax.activation.DataHandler;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.TransferHandler;
|
||||
|
||||
|
||||
public class DragTarget extends JLabel {
|
||||
|
||||
public static String CUSTOM_ICON_RESOURCE = "/org/synthuse/img/bullseye-logo-th32x32.png";
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public static interface dragEvents {
|
||||
void dragStarted(JComponent c);
|
||||
void dragMouseMoved(int x, int y);
|
||||
void dropped(JComponent c);
|
||||
}
|
||||
public dragEvents events = new dragEvents() {
|
||||
public void dragStarted(JComponent c) {
|
||||
|
||||
}
|
||||
public void dragMouseMoved(int x, int y) {
|
||||
|
||||
}
|
||||
public void dropped(JComponent c) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public DragTarget() {
|
||||
|
||||
this.setTransferHandler(new CustomTransferHandler());
|
||||
|
||||
this.addMouseListener(new MouseAdapter(){
|
||||
public void mousePressed(MouseEvent e)
|
||||
{
|
||||
JComponent comp = (JComponent)e.getSource();
|
||||
TransferHandler handler = comp.getTransferHandler();
|
||||
//c.setOpaque(true);
|
||||
handler.exportAsDrag(comp, e, TransferHandler.MOVE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
class CustomTransferHandler extends TransferHandler {
|
||||
//private final JWindow window = new JWindow();
|
||||
private final DataFlavor localObjectFlavor;
|
||||
private final JLabel label = new JLabel();
|
||||
//public Cursor blankCursor = null;
|
||||
public Cursor customCursor = null;
|
||||
|
||||
public CustomTransferHandler () {
|
||||
//System.out.println("CustomTransferHandler");
|
||||
localObjectFlavor = new ActivationDataFlavor(DragTarget.class, DataFlavor.javaJVMLocalObjectMimeType, "JLabel");
|
||||
//label = DragTarget.this;
|
||||
//window.add(label);
|
||||
//window.setAlwaysOnTop(true);
|
||||
//window.setBackground(new Color(0,true));
|
||||
// Create a new blank cursor.
|
||||
//BufferedImage cursorImg = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);
|
||||
//blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(SynthuseDlg.class.getResourceAsStream(CUSTOM_ICON_RESOURCE));
|
||||
customCursor = Toolkit.getDefaultToolkit().createCustomCursor(image, new Point(15, 16), "custom cursor");
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
DragSource.getDefaultDragSource().addDragSourceMotionListener(new DragSourceMotionListener() {
|
||||
@Override
|
||||
public void dragMouseMoved(DragSourceDragEvent e) {
|
||||
events.dragMouseMoved(e.getLocation().x, e.getLocation().y);
|
||||
//Point pt = e.getLocation();
|
||||
//pt.translate(-9, -9); // offset
|
||||
//window.setLocation(pt);
|
||||
//e.getDragSourceContext().setCursor(customCursor);//DragSource.DefaultLinkDrop
|
||||
}
|
||||
});
|
||||
|
||||
DragSource.getDefaultDragSource().addDragSourceListener(new DragSourceAdapter() {
|
||||
@Override
|
||||
public void dragEnter(DragSourceDragEvent e) {
|
||||
e.getDragSourceContext().setCursor(customCursor);//DragSource.DefaultLinkDrop
|
||||
//System.out.println("dragEnter");
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Transferable createTransferable(JComponent c) {
|
||||
//System.out.println("createTransferable");
|
||||
//JLabel l = (JLabel)c;
|
||||
//String text = l.getText();
|
||||
final DataHandler dh = new DataHandler(c, localObjectFlavor.getMimeType());
|
||||
return dh;
|
||||
//return new StringSelection("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canImport(TransferSupport support) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean importData(TransferSupport support) {
|
||||
//System.out.println("importData");
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSourceActions(JComponent c) {
|
||||
//System.out.println("getSourceActions");
|
||||
events.dragStarted(c);
|
||||
JLabel p = (JLabel)c;
|
||||
label.setIcon(p.getIcon());
|
||||
//label.setText(p.draggingLabel.getText());
|
||||
//window.pack();
|
||||
//Point pt = p.getLocation();
|
||||
//SwingUtilities.convertPointToScreen(pt, p);
|
||||
//window.setLocation(pt);
|
||||
//window.setVisible(true);
|
||||
return MOVE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void exportDone(JComponent c, Transferable data, int action) {
|
||||
//System.out.println("exportDone");
|
||||
events.dropped(c);
|
||||
JLabel src = (JLabel)c;
|
||||
if(action == TransferHandler.MOVE) {
|
||||
src.remove(src);
|
||||
src.revalidate();
|
||||
src.repaint();
|
||||
}
|
||||
src = null;
|
||||
//window.setVisible(false);
|
||||
//window.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,334 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
//import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.sun.jna.*;
|
||||
import com.sun.jna.platform.win32.User32;
|
||||
import com.sun.jna.platform.win32.WinDef;
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import com.sun.jna.platform.win32.WinUser.*;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
import com.sun.jna.win32.W32APIOptions;
|
||||
|
||||
public class KeyboardHook implements Runnable{
|
||||
|
||||
|
||||
// Keyboard event class, interface, and array list
|
||||
public static class TargetKeyPress {
|
||||
int idNumber;
|
||||
int targetKeyCode;
|
||||
boolean withShift, withCtrl, withAlt;
|
||||
public TargetKeyPress (int targetKeyCode) {
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = false;
|
||||
this.withCtrl = false;
|
||||
this.withAlt = false;
|
||||
}
|
||||
public TargetKeyPress (int idNumber, int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
this.idNumber = idNumber;
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = withShift;
|
||||
this.withCtrl = withCtrl;
|
||||
this.withAlt = withAlt;
|
||||
}
|
||||
public TargetKeyPress (int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
this.targetKeyCode = targetKeyCode;
|
||||
this.withShift = withShift;
|
||||
this.withCtrl = withCtrl;
|
||||
this.withAlt = withAlt;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<TargetKeyPress> targetList = Collections.synchronizedList(new ArrayList<TargetKeyPress>());// all keys we want to throw events on
|
||||
|
||||
public static interface KeyboardEvents {
|
||||
void keyPressed(TargetKeyPress target);
|
||||
}
|
||||
public KeyboardEvents events = new KeyboardEvents() {
|
||||
public void keyPressed(TargetKeyPress target) {
|
||||
//System.out.println("target key pressed: " + target.targetKeyCode);
|
||||
}
|
||||
};
|
||||
|
||||
// JNA constants and functions
|
||||
public static final int WH_KEYBOARD_LL = 13;
|
||||
//Modifier key vkCode constants
|
||||
public static final int VK_SHIFT = 0x10;
|
||||
public static final int VK_CONTROL = 0x11;
|
||||
public static final int VK_MENU = 0x12;
|
||||
public static final int VK_CAPITAL = 0x14;
|
||||
|
||||
public static final int MOD_ALT = 0x0001;
|
||||
public static final int MOD_CONTROL = 0x0002;
|
||||
public static final int MOD_NOREPEAT = 0x4000;
|
||||
public static final int MOD_SHIFT = 0x0004;
|
||||
public static final int MOD_WIN = 0x0008;
|
||||
|
||||
public static final int QS_HOTKEY = 0x0080;
|
||||
public static final int INFINITE = 0xFFFFFFFF;
|
||||
|
||||
public static HHOOK hHook = null;
|
||||
public static LowLevelKeyboardProc lpfn;
|
||||
public static volatile boolean quit = false;
|
||||
|
||||
private static Thread khThread = null;
|
||||
|
||||
|
||||
public interface User32Ex extends W32APIOptions {
|
||||
User32Ex instance = (User32Ex) Native.loadLibrary("user32", User32Ex.class, DEFAULT_OPTIONS);
|
||||
|
||||
LRESULT LowLevelKeyboardProc(int nCode,WPARAM wParam,LPARAM lParam);
|
||||
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HMODULE hMod, int dwThreadId);
|
||||
LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT CallNextHookEx(HHOOK idHook, int nCode, WPARAM wParam, Pointer lParam);
|
||||
boolean PeekMessage(MSG lpMsg, HWND hWnd, int wMsgFilterMin, int wMsgFilterMax, int wRemoveMsg);
|
||||
boolean UnhookWindowsHookEx(HHOOK idHook);
|
||||
short GetKeyState(int nVirtKey);
|
||||
short GetAsyncKeyState(int nVirtKey);
|
||||
|
||||
/*
|
||||
DWORD WINAPI MsgWaitForMultipleObjects(
|
||||
__in DWORD nCount, //The number of object handles in the array pointed to by pHandles.
|
||||
__in const HANDLE *pHandles, //An array of object handles.
|
||||
__in BOOL bWaitAll, //If this parameter is TRUE, the function returns when the states of all objects in the pHandles array have been set to signaled and an input event has been received.
|
||||
__in DWORD dwMilliseconds, //if dwMilliseconds is INFINITE, the function will return only when the specified objects are signaled.
|
||||
__in DWORD dwWakeMask //The input types for which an input event object handle will be added to the array of object handles.
|
||||
);*/
|
||||
int MsgWaitForMultipleObjects(int nCount, Pointer pHandles, boolean bWaitAll, int dwMilliSeconds, int dwWakeMask);
|
||||
boolean RegisterHotKey(Pointer hWnd, int id, int fsModifiers, int vk);
|
||||
|
||||
//public static interface HOOKPROC extends StdCallCallback {
|
||||
// LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam);
|
||||
//}
|
||||
}
|
||||
|
||||
public interface Kernel32 extends W32APIOptions {
|
||||
Kernel32 instance = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class, DEFAULT_OPTIONS);
|
||||
|
||||
HMODULE GetModuleHandle(String name);
|
||||
}
|
||||
|
||||
// Create Global Windows Keyboard hook and wait until quit == true
|
||||
public void createGlobalKeyboardHook() {
|
||||
|
||||
if (hHook != null)
|
||||
return; //hook already running don't add anymore
|
||||
System.out.println("starting global keyboard hook");
|
||||
HMODULE hMod = Kernel32.instance.GetModuleHandle(null);
|
||||
HOOKPROC lpfn = new HOOKPROC() {
|
||||
@SuppressWarnings("unused")
|
||||
public LRESULT callback(int nCode, WPARAM wParam, KBDLLHOOKSTRUCT lParam) {
|
||||
//System.out.println("here " + lParam.vkCode);
|
||||
TargetKeyPress target = getTargetKeyPressed(lParam.vkCode); //find if this is a target key pressed
|
||||
if (target != null)
|
||||
events.keyPressed(target);
|
||||
//if (lParam.vkCode == 87) //w
|
||||
// quit = true;
|
||||
return User32.INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam.getPointer());
|
||||
}
|
||||
};
|
||||
|
||||
hHook = User32.INSTANCE.SetWindowsHookEx(WH_KEYBOARD_LL, lpfn, hMod, 0);
|
||||
if (hHook == null)
|
||||
return;
|
||||
|
||||
//System.out.println("starting message loop");
|
||||
MSG msg = new MSG();
|
||||
try {
|
||||
|
||||
while (!quit) {
|
||||
User32.INSTANCE.PeekMessage(msg, null, 0, 0, 1);
|
||||
if (msg.message == User32.WM_HOTKEY){ // && msg.wParam.intValue() == 1
|
||||
//System.out.println("Hot key pressed!");
|
||||
msg = new MSG(); //must clear msg so it doesn't repeat
|
||||
}
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//System.out.println("message loop stopped");
|
||||
}
|
||||
|
||||
// Create HotKeys Windows hook and wait until quit == true
|
||||
public void createHotKeysHook() {
|
||||
registerAllHotKeys();
|
||||
//User32Ex.instance.MsgWaitForMultipleObjects(0, Pointer.NULL, true, INFINITE, QS_HOTKEY);
|
||||
|
||||
//System.out.println("starting message loop");
|
||||
MSG msg = new MSG();
|
||||
try {
|
||||
|
||||
while (!quit) {
|
||||
User32.INSTANCE.PeekMessage(msg, null, 0, 0, 1);
|
||||
if (msg.message == User32.WM_HOTKEY){ // && msg.wParam.intValue() == 1
|
||||
//System.out.println("Hot key pressed " + msg.wParam);
|
||||
TargetKeyPress target = findTargetKeyPressById(msg.wParam.intValue());
|
||||
if (target != null)
|
||||
events.keyPressed(target);
|
||||
msg = new MSG(); //must clear msg so it doesn't repeat
|
||||
}
|
||||
Thread.sleep(10);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
unregisterAllHotKeys();
|
||||
//System.out.println("message loop stopped");
|
||||
}
|
||||
|
||||
//unhook the Global Windows Keyboard hook
|
||||
public void unhook() {
|
||||
if (hHook == null)
|
||||
return;
|
||||
if (!User32.INSTANCE.UnhookWindowsHookEx(hHook))
|
||||
System.out.println("Failed to unhook");
|
||||
//System.out.println("Unhooked");
|
||||
hHook = null;
|
||||
}
|
||||
|
||||
//stops Keyboard hook and causes the unhook command to be called
|
||||
public static void stopKeyboardHook() {
|
||||
quit = true;
|
||||
if (khThread != null)
|
||||
{
|
||||
try {
|
||||
khThread.join();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// search target keyboard event list for a match and return it otherwise return null if no match
|
||||
|
||||
private TargetKeyPress getTargetKeyPressed(int keyCode) {
|
||||
TargetKeyPress target = null;
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (tkp.targetKeyCode != keyCode)
|
||||
continue;
|
||||
if (!tkp.withShift || ((User32Ex.instance.GetKeyState(VK_SHIFT) & 0x8000) != 0)) {
|
||||
if (!tkp.withCtrl || ((User32Ex.instance.GetKeyState(VK_CONTROL) & 0x8000) != 0)) {
|
||||
if (!tkp.withAlt || ((User32Ex.instance.GetKeyState(VK_MENU) & 0x8000) != 0)) {
|
||||
return tkp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
private TargetKeyPress findTargetKeyPressById(int idNumber)
|
||||
{
|
||||
TargetKeyPress target = null;
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (tkp.idNumber == idNumber)
|
||||
return tkp;
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
// clear all target keys to watch for
|
||||
public static void clearKeyEvent() {
|
||||
KeyboardHook.targetList.clear();
|
||||
}
|
||||
|
||||
|
||||
// add more target keys to watch for
|
||||
public static void addKeyEvent(int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
||||
KeyboardHook.targetList.add(new TargetKeyPress(KeyboardHook.targetList.size() + 1 , targetKeyCode, withShift, withCtrl, withAlt));
|
||||
}
|
||||
|
||||
// add more target keys to watch for
|
||||
public static void addKeyEvent(int targetKeyCode) {
|
||||
KeyboardHook.targetList.add(new TargetKeyPress(targetKeyCode));
|
||||
}
|
||||
|
||||
|
||||
private void registerAllHotKeys() // must register hot keys in the same thread that is watching for hotkey messages
|
||||
{
|
||||
//System.out.println("registering hotkeys");
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
//BOOL WINAPI RegisterHotKey(HWND hWnd, int id, UINT fsModifiers, UINT vk);
|
||||
int modifiers = User32.MOD_NOREPEAT;
|
||||
if (tkp.withShift)
|
||||
modifiers = modifiers | User32.MOD_SHIFT;
|
||||
if (tkp.withCtrl)
|
||||
modifiers = modifiers | User32.MOD_CONTROL;
|
||||
if (tkp.withAlt)
|
||||
modifiers = modifiers | User32.MOD_ALT;
|
||||
//System.out.println("RegisterHotKey " + tkp.idNumber + "," + modifiers + ", " + tkp.targetKeyCode);
|
||||
|
||||
if (!User32.INSTANCE.RegisterHotKey(new WinDef.HWND(Pointer.NULL), tkp.idNumber, modifiers, tkp.targetKeyCode))
|
||||
{
|
||||
System.out.println("Couldn't register hotkey " + tkp.targetKeyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterAllHotKeys() // must register hot keys in the same thread that is watching for hotkey messages
|
||||
{
|
||||
//System.out.println("unregistering hotkeys");
|
||||
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||
if (!User32.INSTANCE.UnregisterHotKey(Pointer.NULL, tkp.idNumber))
|
||||
{
|
||||
System.out.println("Couldn't unregister hotkey " + tkp.targetKeyCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
//createGlobalKeyboardHook();
|
||||
createHotKeysHook();
|
||||
//System.out.println("Unhooking Global Keyboard Hook");
|
||||
unhook();//wait for quit == true then unhook
|
||||
}
|
||||
|
||||
public KeyboardHook() {
|
||||
}
|
||||
|
||||
public KeyboardHook(KeyboardEvents events) {
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
public static void StartKeyboardHookThreaded(KeyboardEvents events) {
|
||||
quit = false;
|
||||
khThread = new Thread(new KeyboardHook(events));
|
||||
khThread.start();
|
||||
}
|
||||
|
||||
/*
|
||||
// testing
|
||||
public static void main(String[] args) throws Exception {
|
||||
//add target keys
|
||||
KeyboardHook.addKeyEvent(KeyEvent.VK_3, true, true, false);
|
||||
KeyboardHook.addKeyEvent(KeyEvent.VK_5, false, true, false);
|
||||
KeyboardHook.addKeyEvent(KeyEvent.VK_Q);
|
||||
|
||||
//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_Q){ // if Q was pressed then unhook
|
||||
KeyboardHook.stopGlobalKeyboardHook();
|
||||
System.out.println("unhooking");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
|
||||
public class MenuInfo {
|
||||
public HMENU hmenu = null;
|
||||
public String hmenuStr = "";
|
||||
public String hwndStr = "";
|
||||
public int menuCount = 0;
|
||||
public String text = "";
|
||||
public String unaltered = "";
|
||||
public int id = 0;
|
||||
public int position = 0;
|
||||
public boolean hasSubMenu = false;
|
||||
public HMENU submenu = null;
|
||||
public String submenuStr = "";
|
||||
public int submenuCount = 0;
|
||||
public String center = "";
|
||||
|
||||
public MenuInfo(String hwndStr, HMENU hmenu) {
|
||||
this.hwndStr = hwndStr;
|
||||
loadMenuBase(hmenu);
|
||||
}
|
||||
|
||||
public MenuInfo(String hwndStr, HMENU hmenu, int position) {
|
||||
this.hwndStr = hwndStr;
|
||||
loadMenuBase(hmenu);
|
||||
if (this.menuCount > 0)
|
||||
loadMenuDetails(hmenu, position);
|
||||
}
|
||||
|
||||
public void loadMenuBase(HMENU hmenu) {
|
||||
Api api = new Api();
|
||||
this.hmenu = hmenu;
|
||||
this.hmenuStr = GetHandleMenuAsString(hmenu);
|
||||
this.menuCount = api.user32.GetMenuItemCount(hmenu);
|
||||
}
|
||||
|
||||
public void loadMenuDetails(HMENU hmenu, int position) {
|
||||
Api api = new Api();
|
||||
this.position = position;
|
||||
this.unaltered = api.GetMenuItemText(hmenu, position);
|
||||
this.text = unaltered;
|
||||
if (this.unaltered.contains("\t"))
|
||||
this.text = this.text.substring(0, this.text.indexOf("\t"));
|
||||
this.text = text.replaceAll("[^a-zA-Z0-9.,\\+ ]", "");
|
||||
this.id = api.user32.GetMenuItemID(hmenu, position);
|
||||
/*
|
||||
HWND hWnd = Api.GetHandleFromString(hwndStr);
|
||||
RECT rect = new RECT();
|
||||
api.user32.GetMenuItemRect(hWnd, hmenu, position, rect);
|
||||
int centerX = ((rect.right - rect.left) / 2) + rect.left;
|
||||
int centerY = ((rect.bottom - rect.top) / 2) + rect.top;
|
||||
this.center = centerX + "," + centerY;
|
||||
*/
|
||||
HMENU submenu = api.user32.GetSubMenu(hmenu, position);
|
||||
if (submenu != null) {
|
||||
int subCount = api.user32.GetMenuItemCount(submenu);
|
||||
if (subCount > 0) {
|
||||
this.hasSubMenu = true;
|
||||
this.submenu = submenu;
|
||||
this.submenuStr = GetHandleMenuAsString(submenu);
|
||||
this.submenuCount = subCount;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String GetHandleMenuAsString(HMENU hmenu) {
|
||||
if (hmenu == null)
|
||||
return "0";
|
||||
//String longHexStr = hWnd.toString().substring("native@".length());
|
||||
//String longHexStr = hmenu.getPointer()
|
||||
String longHexStr = hmenu.getPointer().toString().substring("native@0x".length());
|
||||
long l = new BigInteger(longHexStr, 16).longValue();
|
||||
return l + "";
|
||||
}
|
||||
|
||||
public static HMENU GetHandleMenuFromString(String hmenu) {
|
||||
if (hmenu == null)
|
||||
return null;
|
||||
if (hmenu.isEmpty())
|
||||
return null;
|
||||
String cleanNumericHandle = hmenu.replaceAll("[^\\d.]", "");
|
||||
try {
|
||||
return (new HMENU(new Pointer(Long.parseLong(cleanNumericHandle))));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
// This class is not actually used and is only here as a reference
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JToolBar;
|
||||
import java.awt.BorderLayout;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
import com.sun.jna.platform.win32.User32;
|
||||
import com.sun.jna.platform.win32.WinDef.*;
|
||||
import com.sun.jna.platform.win32.BaseTSD.LONG_PTR;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTextField;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Component;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.Box;
|
||||
|
||||
|
||||
public class MessageHookFrame extends JFrame {
|
||||
|
||||
private static final long serialVersionUID = -5863279004595502801L;
|
||||
|
||||
public static final String newLine = System.getProperty("line.separator");
|
||||
|
||||
public static final int WH_CALLWNDPROC = 4;
|
||||
public static final int WH_GETMESSAGE = 3;
|
||||
public static final int WH_KEYBOARD_LL = 13;
|
||||
|
||||
public static final int WM_COPYDATA = 74;
|
||||
public static final int GWLP_WNDPROC = -4;
|
||||
|
||||
private JTextArea textArea;
|
||||
private JButton btnSave;
|
||||
private JButton btnStartMsgHook;
|
||||
private JButton btnPause;
|
||||
private JButton btnClear;
|
||||
private LONG_PTR oldWndProc;
|
||||
private MsgHook msgHook = null;
|
||||
|
||||
public static volatile boolean quit = false;
|
||||
private JLabel lblTargetHwnd;
|
||||
public JTextField txtTarget;
|
||||
private Component horizontalStrut;
|
||||
|
||||
public MessageHookFrame() {
|
||||
setTitle("Message Hook");
|
||||
setBounds(100, 100, 700, 367);
|
||||
|
||||
JToolBar toolBar = new JToolBar();
|
||||
getContentPane().add(toolBar, BorderLayout.NORTH);
|
||||
|
||||
btnStartMsgHook = new JButton("Start Hook");
|
||||
btnStartMsgHook.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (btnStartMsgHook.getText().equals("Start Hook"))
|
||||
{ //start Message Hook
|
||||
btnStartMsgHook.setText("Stop Hook");
|
||||
createMessageHook();
|
||||
}
|
||||
else
|
||||
{ //stop message hook
|
||||
btnStartMsgHook.setText("Start Hook");
|
||||
stopMessageHook();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
lblTargetHwnd = new JLabel("Target HWND: ");
|
||||
toolBar.add(lblTargetHwnd);
|
||||
|
||||
txtTarget = new JTextField();
|
||||
txtTarget.setMaximumSize(new Dimension(70, 2147483647));
|
||||
txtTarget.setText("0");
|
||||
toolBar.add(txtTarget);
|
||||
txtTarget.setColumns(10);
|
||||
|
||||
horizontalStrut = Box.createHorizontalStrut(20);
|
||||
toolBar.add(horizontalStrut);
|
||||
toolBar.add(btnStartMsgHook);
|
||||
|
||||
btnPause = new JButton("Pause");
|
||||
btnPause.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
|
||||
final HWND myHwnd = new HWND(Native.getWindowPointer(MessageHookFrame.this));
|
||||
oldWndProc = User32.INSTANCE.GetWindowLongPtr(myHwnd, GWLP_WNDPROC);
|
||||
|
||||
Api.WNDPROC wndProc = new Api.WNDPROC() {
|
||||
public LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
if (uMsg == WM_COPYDATA){
|
||||
System.out.println("WM_COPYDATA");
|
||||
//handle the window message here
|
||||
}
|
||||
else
|
||||
System.out.println("MESSAGE: " + uMsg);
|
||||
return Api.User32Ex.instance.CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
|
||||
//return new LRESULT(0);
|
||||
//return User32.INSTANCE.DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
};
|
||||
|
||||
Api.User32Ex.instance.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, wndProc);
|
||||
}
|
||||
});
|
||||
toolBar.add(btnPause);
|
||||
|
||||
btnSave = new JButton("Save");
|
||||
btnSave.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
}
|
||||
});
|
||||
toolBar.add(btnSave);
|
||||
|
||||
btnClear = new JButton("Clear");
|
||||
btnClear.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
textArea.setText("");
|
||||
}
|
||||
});
|
||||
toolBar.add(btnClear);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
getContentPane().add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
textArea = new JTextArea();
|
||||
scrollPane.setViewportView(textArea);
|
||||
|
||||
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
this.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
//TestIdeFrame.this.setVisible(false);
|
||||
MessageHookFrame.this.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
super.setAlwaysOnTop(SynthuseDlg.config.isAlwaysOnTop());
|
||||
|
||||
}
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
HWND hWnd;
|
||||
int nCode;
|
||||
DWORD dwHookType;
|
||||
WPARAM wParam;
|
||||
LPARAM lParam;
|
||||
TCHAR wParamStr[25];
|
||||
TCHAR lParamStr[25];
|
||||
}HEVENT;
|
||||
*/
|
||||
|
||||
public static class HEVENT extends Structure {
|
||||
//The by-reference version of this structure.
|
||||
public static class ByReference extends HEVENT implements Structure.ByReference { }
|
||||
|
||||
public HEVENT() { }
|
||||
|
||||
//Instantiates a new COPYDATASTRUCT with existing data given the address of that data.
|
||||
public HEVENT(final long pointer) {
|
||||
this(new Pointer(pointer));
|
||||
}
|
||||
|
||||
//Instantiates a new COPYDATASTRUCT with existing data given a pointer to that data.
|
||||
public HEVENT(final Pointer memory) {
|
||||
super(memory);
|
||||
read();
|
||||
}
|
||||
|
||||
public WORD hWnd;
|
||||
public WORD nCode;
|
||||
public DWORD dwHookType;
|
||||
public DWORD wParam;
|
||||
public DWORD lParam;
|
||||
//public TCHAR wParamStr[25];
|
||||
//public TCHAR lParamStr[25];
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Override
|
||||
protected final List getFieldOrder() {
|
||||
return Arrays.asList(new String[] {"hWnd", "nCode", "dwHookType", "wParam", "lParam" });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void createMessageHook() {
|
||||
|
||||
quit = false; //don't quit
|
||||
|
||||
//find the HWND and current WNDPROC on this java window
|
||||
final HWND myHwnd = new HWND(Native.getWindowPointer(MessageHookFrame.this));
|
||||
oldWndProc = User32.INSTANCE.GetWindowLongPtr(myHwnd, GWLP_WNDPROC);
|
||||
|
||||
Api.WNDPROC wndProc = new Api.WNDPROC() {
|
||||
public LRESULT callback(HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
if (uMsg == WM_COPYDATA){
|
||||
//(COPYDATASTRUCT *) lParam
|
||||
//if( pCopyDataStruct->cbData == sizeof(HEVENT)) {
|
||||
// HEVENT Event;
|
||||
// memcpy(&Event, (HEVENT*)pCopyDataStruct->lpData, sizeof(HEVENT)); // transfer data to internal variable
|
||||
//}
|
||||
|
||||
Api.WinDefEx.COPYDATASTRUCT cds = new Api.WinDefEx.COPYDATASTRUCT(lParam.longValue());
|
||||
HEVENT he = new HEVENT(cds.lpData);
|
||||
appendLine("msg: WM_COPYDATA" + cds.cbData);
|
||||
appendLine("hwnd: " + he.hWnd + ", msg: " + he.nCode + ", wParam: " + he.wParam + ", lParam: " + he.lParam);
|
||||
//System.out.println("WM_COPYDATA");
|
||||
//handle the window message here
|
||||
}
|
||||
//else
|
||||
// System.out.println("MESSAGE: " + uMsg);
|
||||
|
||||
return Api.User32Ex.instance.CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam);
|
||||
//return User32.INSTANCE.DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
};
|
||||
|
||||
//Set the wndproc callback on this MessageHookFrame so we can process Windows Messages
|
||||
Api.User32Ex.instance.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, wndProc);
|
||||
|
||||
IntByReference intByRef = new IntByReference(0);
|
||||
final int threadId = User32.INSTANCE.GetWindowThreadProcessId(Api.GetHandleFromString(txtTarget.getText()), intByRef);
|
||||
|
||||
//int myPid = Kernel32.INSTANCE.GetCurrentProcessId();
|
||||
//HWND myHwnd = Api.FindMainWindowFromPid(myPid);
|
||||
final long myHwndLong = Api.GetHandleAsLong(myHwnd);
|
||||
|
||||
//System.out.println("Starting Msg Hook for " + myHwndLong + " on id " + threadId);
|
||||
if (threadId == 0 ) // don't allow global
|
||||
{
|
||||
System.out.println("Not allowing global message hook " + threadId);
|
||||
User32.INSTANCE.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, oldWndProc); //restore default WNDPROC
|
||||
quit = true;
|
||||
return;
|
||||
}
|
||||
|
||||
msgHook = new MsgHook();
|
||||
if (!msgHook.setMessageHook((int) myHwndLong, threadId))
|
||||
appendLine("Error setting message hook");
|
||||
else
|
||||
appendLine("Message hook started");
|
||||
|
||||
}
|
||||
|
||||
public void unhook(MsgHook msgHook) {
|
||||
msgHook.removeMessageHook();
|
||||
}
|
||||
|
||||
//stops Keyboard hook and causes the unhook command to be called
|
||||
public void stopMessageHook() {
|
||||
//if (!quit) //if not hooked skip
|
||||
// return;
|
||||
quit = true;
|
||||
appendLine("Message hook stopped");
|
||||
final HWND myHwnd = new HWND(Native.getWindowPointer(MessageHookFrame.this));
|
||||
User32.INSTANCE.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, oldWndProc); //restore default WNDPROC
|
||||
unhook(msgHook);
|
||||
}
|
||||
|
||||
public void appendLine(String txt)
|
||||
{
|
||||
textArea.append(txt + newLine);
|
||||
textArea.setCaretPosition(textArea.getDocument().getLength());
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
public class MsgHook {
|
||||
|
||||
public static String targetdllName = "";
|
||||
public static String dll64bitName = "";
|
||||
public static String dll32bitName = "";
|
||||
static
|
||||
{
|
||||
String loadFailedMsg = "Failed to load MsgHook library.\n";
|
||||
//System.out.println("SynthuseDlg.config.disableUiaBridge: " + SynthuseDlg.config.disableUiaBridge);
|
||||
String archDataModel = System.getProperty("sun.arch.data.model");//32 or 64 bit
|
||||
try {
|
||||
targetdllName = "/MsgHook" + archDataModel + ".dll";
|
||||
dll64bitName = SaveNativeLibraryFromJar("/MsgHook64.dll"); //need to save both 32 and 64 bit dlls for hooking both types
|
||||
dll32bitName = SaveNativeLibraryFromJar("/MsgHook32.dll");
|
||||
if (archDataModel.equals("32"))
|
||||
System.load(dll32bitName);
|
||||
else
|
||||
System.load(dll64bitName);
|
||||
|
||||
} catch (Exception ex) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
ex.printStackTrace(pw);
|
||||
System.out.println(sw.toString());
|
||||
JOptionPane.showMessageDialog(null, loadFailedMsg + sw.toString() , "Native Library Load Error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
||||
public static String SaveNativeLibraryFromJar(String path) {
|
||||
// Obtain filename from path
|
||||
String[] parts = path.split("/");
|
||||
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
|
||||
// Split filename to prexif and suffix (extension)
|
||||
String prefix = "";
|
||||
String suffix = null;
|
||||
if (filename != null) {
|
||||
parts = filename.split("\\.", 2);
|
||||
prefix = parts[0];
|
||||
suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null;
|
||||
}
|
||||
File temp = null;
|
||||
try {
|
||||
// Prepare temporary file
|
||||
temp = File.createTempFile(prefix, suffix);
|
||||
temp.deleteOnExit();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!temp.exists()) { //some reason the temp file wasn't create so abort
|
||||
System.out.println("File " + temp.getAbsolutePath() + " does not exist.");
|
||||
return "";
|
||||
}
|
||||
|
||||
// Prepare buffer for data copying
|
||||
byte[] buffer = new byte[1024];
|
||||
int readBytes;
|
||||
// Open and check input stream
|
||||
InputStream is = MsgHook.class.getResourceAsStream(path);
|
||||
if (is == null) { //check if valid
|
||||
System.out.println("File " + path + " was not found inside JAR.");
|
||||
return "";
|
||||
}
|
||||
// Open output stream and copy data between source file in JAR and the temporary file
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(temp);
|
||||
while ((readBytes = is.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, readBytes);
|
||||
}
|
||||
os.close();
|
||||
is.close();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Finally, load the library
|
||||
return temp.getAbsolutePath();
|
||||
}
|
||||
|
||||
public native boolean initialize(String dll32bitName, String dll64bitName);
|
||||
public native boolean createMsgHookWindow();
|
||||
public native boolean setMsgHookWindowTargetHwnd(int hwnd);
|
||||
public native boolean setMsgHookWindowTargetPid(int pid);
|
||||
public native boolean setMessageHook(int hwnd, int threadId);
|
||||
public native boolean removeMessageHook();
|
||||
//public native boolean shutdown();
|
||||
|
||||
public static Thread createMsgHookWinThread(final long targetHwnd, final int targetPid)
|
||||
{
|
||||
Thread t = new Thread() {
|
||||
public void run() {
|
||||
MsgHook mh = new MsgHook();
|
||||
mh.initialize(dll32bitName, dll64bitName);
|
||||
if (targetPid != 0)
|
||||
mh.setMsgHookWindowTargetPid(targetPid);
|
||||
if (targetHwnd != 0)
|
||||
mh.setMsgHookWindowTargetHwnd((int)targetHwnd);
|
||||
mh.createMsgHookWindow();
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
return t;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Properties;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
|
||||
/*
|
||||
|
||||
// example class for PropertiesSerializer
|
||||
public class Configuration extends PropertiesSerializer{
|
||||
|
||||
public static final String DEFAULT_PROP_FILENAME = "./ctf.properties";
|
||||
|
||||
// General Settings
|
||||
public String tests_dir = "./tests";
|
||||
public String logs_dir = "./logs";
|
||||
public int statusTimer = 2000;
|
||||
|
||||
public Configuration() //needed for cloning
|
||||
{
|
||||
}
|
||||
|
||||
public Configuration(String propertyFilename)
|
||||
{
|
||||
super(propertyFilename);
|
||||
load(propertyFilename);
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
public class PropertiesSerializer {
|
||||
|
||||
protected Properties prop = new Properties();
|
||||
protected String propertyFilename = null;
|
||||
|
||||
public PropertiesSerializer()
|
||||
{
|
||||
}
|
||||
|
||||
public PropertiesSerializer(String propertyFilename)
|
||||
{
|
||||
this.propertyFilename = propertyFilename;
|
||||
}
|
||||
|
||||
public void load(String propertyFilename)
|
||||
{
|
||||
try
|
||||
{
|
||||
prop.load(new FileInputStream(propertyFilename));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.out.println("Unable to load properties from file: "+propertyFilename+". Default values will be used.");
|
||||
return;
|
||||
}
|
||||
|
||||
Field[] fields = this.getClass().getFields();
|
||||
for (int i = 0 ; i < fields.length; i++)
|
||||
{
|
||||
String pName = fields[i].getName();
|
||||
String pType = "String";
|
||||
try
|
||||
{
|
||||
pType = fields[i].get(this).getClass().getSimpleName();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
final Object myProperty = prop.get(pName);
|
||||
try
|
||||
{
|
||||
if(myProperty==null) {
|
||||
// System.out.println("Property "+pName+"["+pType+"] not set; input was null");
|
||||
} else {
|
||||
if (pType.equalsIgnoreCase("integer"))
|
||||
fields[i].set(this, Integer.parseInt(myProperty + ""));
|
||||
if (pType.equalsIgnoreCase("boolean"))
|
||||
fields[i].set(this, Boolean.parseBoolean(myProperty + ""));
|
||||
else
|
||||
fields[i].set(this, myProperty);
|
||||
System.out.println("Property "+pName+"["+pType+"] set to: "+myProperty);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
Field[] fields = this.getClass().getFields();
|
||||
for (int i = 0 ; i < fields.length; i++)
|
||||
{
|
||||
//fields[i].get(this);
|
||||
try {
|
||||
String pName = fields[i].getName();
|
||||
//String pType = fields[i].get(this).getClass().getSimpleName();
|
||||
if (fields[i].get(this) == null)
|
||||
prop.setProperty(pName, "");
|
||||
else
|
||||
prop.setProperty(pName, fields[i].get(this) + "");
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
FileOutputStream fos = new FileOutputStream(propertyFilename);
|
||||
prop.store(fos, "");
|
||||
fos.flush();
|
||||
fos.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
Object newObject = null;
|
||||
try {
|
||||
newObject = (Object)this.getClass().newInstance();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
Field[] fields = this.getClass().getFields();
|
||||
for (int i = 0 ; i < fields.length; i++)
|
||||
{
|
||||
try {
|
||||
//fields[i].get(this);
|
||||
//String pName = fields[i].getName();
|
||||
fields[i].set(newObject, fields[i].get(this));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return newObject;
|
||||
}
|
||||
|
||||
public boolean hasChanged()
|
||||
{
|
||||
boolean changes = false;
|
||||
Field[] fields = this.getClass().getFields();
|
||||
for (int i = 0 ; i < fields.length; i++)
|
||||
{
|
||||
//fields[i].get(this);
|
||||
try {
|
||||
String pName = fields[i].getName();
|
||||
//String pType = fields[i].get(this).getClass().getSimpleName();
|
||||
if (prop.getProperty(pName).compareTo(fields[i].get(this)+"") != 0)
|
||||
changes = true;
|
||||
|
||||
} catch (Exception e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return changes;
|
||||
}
|
||||
|
||||
public String getPropertyFilename()
|
||||
{
|
||||
return this.propertyFilename;
|
||||
}
|
||||
|
||||
public void setPropertyFilename(String filename)
|
||||
{
|
||||
this.propertyFilename = filename;
|
||||
}
|
||||
|
||||
public String readValue(String propertyName)
|
||||
{
|
||||
String val = "";
|
||||
val = prop.getProperty(propertyName);
|
||||
return val;
|
||||
}
|
||||
|
||||
public void writeValue(String propertyName, String propertValue)
|
||||
{
|
||||
prop.setProperty(propertyName, propertValue);
|
||||
try {
|
||||
prop.store(new FileOutputStream(propertyFilename), null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,631 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class RobotMacro {
|
||||
|
||||
public static Exception lastException = null;
|
||||
|
||||
public static boolean executeCommand(String cmd) {
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
try {
|
||||
runtime.exec(cmd);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void delay(int time) {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.delay(time);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void moveMouse(int x, int y) {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mouseMove(x, y);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void leftClickMouse() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void doubleClickMouse() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
robot.delay(100);
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void rightClickMouse() {
|
||||
try {
|
||||
//System.out.println("rightClickMouse");
|
||||
Robot robot = new Robot();
|
||||
//robot.mouseMove(200, 200);
|
||||
//robot.delay(1000);
|
||||
robot.mousePress(InputEvent.BUTTON3_MASK);
|
||||
robot.mouseRelease(InputEvent.BUTTON3_MASK);
|
||||
//System.out.println("rightClickMouse good");
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void leftMouseDown() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mousePress(InputEvent.BUTTON1_MASK);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void leftMouseUp() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mouseRelease(InputEvent.BUTTON1_MASK);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void rightMouseDown() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mousePress(InputEvent.BUTTON3_MASK);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void rightMouseUp() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mouseRelease(InputEvent.BUTTON3_MASK);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void mouseMove(int x, int y) {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.mouseMove(x, y);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyKey() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_C);
|
||||
robot.keyRelease(KeyEvent.VK_C);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void pasteKey() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
robot.keyPress(KeyEvent.VK_V);
|
||||
robot.keyRelease(KeyEvent.VK_V);
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void escapeKey() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
robot.keyPress(KeyEvent.VK_ESCAPE);
|
||||
robot.keyRelease(KeyEvent.VK_ESCAPE);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void functionKey(int functionNum) {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
int keyCode = 0;
|
||||
switch (functionNum) {
|
||||
case 1: keyCode = KeyEvent.VK_F1; break;
|
||||
case 2: keyCode = KeyEvent.VK_F2; break;
|
||||
case 3: keyCode = KeyEvent.VK_F3; break;
|
||||
case 4: keyCode = KeyEvent.VK_F4; break;
|
||||
case 5: keyCode = KeyEvent.VK_F5; break;
|
||||
case 6: keyCode = KeyEvent.VK_F6; break;
|
||||
case 7: keyCode = KeyEvent.VK_F7; break;
|
||||
case 8: keyCode = KeyEvent.VK_F8; break;
|
||||
case 9: keyCode = KeyEvent.VK_F9; break;
|
||||
case 10: keyCode = KeyEvent.VK_F10; break;
|
||||
case 11: keyCode = KeyEvent.VK_F11; break;
|
||||
case 12: keyCode = KeyEvent.VK_F12; break;
|
||||
}
|
||||
robot.keyPress(keyCode);
|
||||
robot.keyRelease(keyCode);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
|
||||
public static void tildeKey() {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_QUOTE});
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
}
|
||||
}
|
||||
/* SendKeys Special Keys List
|
||||
{BACKSPACE}, {BS}, or {BKSP}
|
||||
{BREAK}
|
||||
{CAPSLOCK}
|
||||
{DELETE} or {DEL}
|
||||
{DOWN}
|
||||
{END}
|
||||
{ENTER} or ~
|
||||
{ESC}
|
||||
{HELP}
|
||||
{HOME}
|
||||
{INSERT} or {INS}
|
||||
{LEFT}
|
||||
{NUMLOCK}
|
||||
{PGDN}
|
||||
{PGUP}
|
||||
{PRTSC} (reserved for future use)
|
||||
{RIGHT}
|
||||
{SCROLLLOCK}
|
||||
{TAB}
|
||||
{UP}
|
||||
{F1}
|
||||
{F2}
|
||||
{F3}
|
||||
{F4}
|
||||
{F5}
|
||||
{F6}
|
||||
{F7}
|
||||
{F8}
|
||||
{F9}
|
||||
{F10}
|
||||
{F11}
|
||||
{F12}
|
||||
{F13}
|
||||
{F14}
|
||||
{F15}
|
||||
{F16}
|
||||
{ADD}
|
||||
{SUBTRACT}
|
||||
{MULTIPLY}
|
||||
{DIVIDE}
|
||||
{{}
|
||||
{}}
|
||||
SHIFT +
|
||||
CTRL ^
|
||||
ALT %
|
||||
|
||||
*/
|
||||
|
||||
public static boolean sendKeys(String keyCommands) {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
boolean specialKeyFlag = false;
|
||||
String specialKey = "";
|
||||
boolean modifierKeyFlag = false;
|
||||
String modifierKeys = "";
|
||||
for (int i = 0; i < keyCommands.length(); i++) {
|
||||
char key = keyCommands.charAt(i);
|
||||
if (specialKeyFlag)
|
||||
specialKey += key;
|
||||
if (key == '{' && specialKeyFlag == false) {
|
||||
specialKeyFlag = true;
|
||||
specialKey = "{";
|
||||
}
|
||||
|
||||
if (!specialKeyFlag) { //not special key(tab,enter,...) just press normal keys and modifiers
|
||||
// Modifier key logic
|
||||
if (key == '+' || key == '^' || key == '%') { //shift alt or ctrl
|
||||
if (!modifierKeyFlag) {
|
||||
modifierKeys = key + "";
|
||||
modifierKeyFlag = true;
|
||||
}
|
||||
else
|
||||
modifierKeys += key + ""; //append multiple modifiers
|
||||
if (key == '+')
|
||||
robot.keyPress(KeyEvent.VK_SHIFT);
|
||||
if (key == '^')
|
||||
robot.keyPress(KeyEvent.VK_CONTROL);
|
||||
if (key == '%')
|
||||
robot.keyPress(KeyEvent.VK_ALT);
|
||||
continue; //skip to next key
|
||||
}
|
||||
pressKeyCodes(robot, getKeyCode(key));
|
||||
}
|
||||
if (specialKeyFlag) {
|
||||
if (specialKey.equals("{ENTER}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_ENTER} );
|
||||
}
|
||||
else if (specialKey.equals("{ESC}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_ESCAPE} );
|
||||
}
|
||||
else if (specialKey.equals("{HOME}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_HOME} );
|
||||
}
|
||||
else if (specialKey.equals("{END}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_END} );
|
||||
}
|
||||
else if (specialKey.equals("{PGDN}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_PAGE_DOWN} );
|
||||
}
|
||||
else if (specialKey.equals("{PGUP}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_PAGE_UP} );
|
||||
}
|
||||
else if (specialKey.equals("{TAB}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_TAB} );
|
||||
}
|
||||
else if (specialKey.equals("{UP}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_UP} );
|
||||
}
|
||||
else if (specialKey.equals("{DOWN}")) {
|
||||
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("{PERCENT}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_5} );
|
||||
}
|
||||
else if (specialKey.equals("{CARROT}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_6} );
|
||||
}
|
||||
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("{BAR}")) {
|
||||
specialKeyFlag = false;
|
||||
pressKeyCodes(robot, new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_SLASH});
|
||||
}
|
||||
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
|
||||
modifierKeyFlag = false;
|
||||
for (int m = 0; m < modifierKeys.length(); m++) {
|
||||
char mkey = modifierKeys.charAt(m);
|
||||
if (mkey == '+')
|
||||
robot.keyRelease(KeyEvent.VK_SHIFT);
|
||||
if (mkey == '^')
|
||||
robot.keyRelease(KeyEvent.VK_CONTROL);
|
||||
if (mkey == '%')
|
||||
robot.keyRelease(KeyEvent.VK_ALT);
|
||||
}
|
||||
modifierKeys = "";
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean pressKey(char key) {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
int[] keyCode = getKeyCode(key);
|
||||
pressKeyCodes(robot, keyCode);
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean keyDown(char key) {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
int[] keyCodes = getKeyCode(key);
|
||||
for (int i = 0; i < keyCodes.length; i++) {
|
||||
robot.keyPress(keyCodes[i]);
|
||||
//System.out.println("pressed: " + keyCodes[i]);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean keyUp(char key) {
|
||||
try {
|
||||
Robot robot = new Robot();
|
||||
int[] keyCodes = getKeyCode(key);
|
||||
for (int i = keyCodes.length - 1; i >= 0; i--) {
|
||||
robot.keyRelease(keyCodes[i]);
|
||||
//System.out.println("released: " + keyCodes[i]);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void pressKeyCodes(Robot robot, int[] keyCodes) {
|
||||
for (int i = 0; i < keyCodes.length; i++) {
|
||||
robot.keyPress(keyCodes[i]);
|
||||
//System.out.println("pressed: " + keyCodes[i]);
|
||||
}
|
||||
//robot.delay(50);
|
||||
for (int i = keyCodes.length - 1; i >= 0; i--) {
|
||||
robot.keyRelease(keyCodes[i]);
|
||||
//System.out.println("released: " + keyCodes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static int[] getKeyCode(char key) {
|
||||
switch (key) {
|
||||
case 'a': return(new int[]{KeyEvent.VK_A});
|
||||
case 'b': return(new int[]{KeyEvent.VK_B});
|
||||
case 'c': return(new int[]{KeyEvent.VK_C});
|
||||
case 'd': return(new int[]{KeyEvent.VK_D});
|
||||
case 'e': return(new int[]{KeyEvent.VK_E});
|
||||
case 'f': return(new int[]{KeyEvent.VK_F});
|
||||
case 'g': return(new int[]{KeyEvent.VK_G});
|
||||
case 'h': return(new int[]{KeyEvent.VK_H});
|
||||
case 'i': return(new int[]{KeyEvent.VK_I});
|
||||
case 'j': return(new int[]{KeyEvent.VK_J});
|
||||
case 'k': return(new int[]{KeyEvent.VK_K});
|
||||
case 'l': return(new int[]{KeyEvent.VK_L});
|
||||
case 'm': return(new int[]{KeyEvent.VK_M});
|
||||
case 'n': return(new int[]{KeyEvent.VK_N});
|
||||
case 'o': return(new int[]{KeyEvent.VK_O});
|
||||
case 'p': return(new int[]{KeyEvent.VK_P});
|
||||
case 'q': return(new int[]{KeyEvent.VK_Q});
|
||||
case 'r': return(new int[]{KeyEvent.VK_R});
|
||||
case 's': return(new int[]{KeyEvent.VK_S});
|
||||
case 't': return(new int[]{KeyEvent.VK_T});
|
||||
case 'u': return(new int[]{KeyEvent.VK_U});
|
||||
case 'v': return(new int[]{KeyEvent.VK_V});
|
||||
case 'w': return(new int[]{KeyEvent.VK_W});
|
||||
case 'x': return(new int[]{KeyEvent.VK_X});
|
||||
case 'y': return(new int[]{KeyEvent.VK_Y});
|
||||
case 'z': return(new int[]{KeyEvent.VK_Z});
|
||||
case 'A': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_A});
|
||||
case 'B': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_B});
|
||||
case 'C': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_C});
|
||||
case 'D': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_D});
|
||||
case 'E': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_E});
|
||||
case 'F': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_F});
|
||||
case 'G': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_G});
|
||||
case 'H': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_H});
|
||||
case 'I': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_I});
|
||||
case 'J': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_J});
|
||||
case 'K': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_K});
|
||||
case 'L': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_L});
|
||||
case 'M': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_M});
|
||||
case 'N': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_N});
|
||||
case 'O': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_O});
|
||||
case 'P': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_P});
|
||||
case 'Q': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_Q});
|
||||
case 'R': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_R});
|
||||
case 'S': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_S});
|
||||
case 'T': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_T});
|
||||
case 'U': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_U});
|
||||
case 'V': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_V});
|
||||
case 'W': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_W});
|
||||
case 'X': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_X});
|
||||
case 'Y': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_Y});
|
||||
case 'Z': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_Z});
|
||||
case '`': return(new int[]{KeyEvent.VK_BACK_QUOTE});
|
||||
case '0': return(new int[]{KeyEvent.VK_0});
|
||||
case '1': return(new int[]{KeyEvent.VK_1});
|
||||
case '2': return(new int[]{KeyEvent.VK_2});
|
||||
case '3': return(new int[]{KeyEvent.VK_3});
|
||||
case '4': return(new int[]{KeyEvent.VK_4});
|
||||
case '5': return(new int[]{KeyEvent.VK_5});
|
||||
case '6': return(new int[]{KeyEvent.VK_6});
|
||||
case '7': return(new int[]{KeyEvent.VK_7});
|
||||
case '8': return(new int[]{KeyEvent.VK_8});
|
||||
case '9': return(new int[]{KeyEvent.VK_9});
|
||||
case '-': return(new int[]{KeyEvent.VK_MINUS});
|
||||
case '=': return(new int[]{KeyEvent.VK_EQUALS});
|
||||
case '~': return(new int[]{KeyEvent.VK_ENTER});//return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_QUOTE});
|
||||
case '!': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_1});
|
||||
case '@': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_2});
|
||||
case '#': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_3});
|
||||
case '$': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_4});
|
||||
case '%': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_5});
|
||||
case '^': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_6});
|
||||
case '&': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_7});
|
||||
case '*': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_8});
|
||||
case '(': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_9});
|
||||
case ')': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_0});
|
||||
case '_': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_MINUS});
|
||||
case '+': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_EQUALS});
|
||||
case '\t': return(new int[]{KeyEvent.VK_TAB});
|
||||
case '\n': return(new int[]{KeyEvent.VK_ENTER});
|
||||
case '[': return(new int[]{KeyEvent.VK_OPEN_BRACKET});
|
||||
case ']': return(new int[]{KeyEvent.VK_CLOSE_BRACKET});
|
||||
case '\\': return(new int[]{KeyEvent.VK_BACK_SLASH});
|
||||
case '{': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_OPEN_BRACKET});
|
||||
case '}': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_CLOSE_BRACKET});
|
||||
case '|': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_BACK_SLASH});
|
||||
case ';': return(new int[]{KeyEvent.VK_SEMICOLON});
|
||||
case ':': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_SEMICOLON});
|
||||
case '\'': return(new int[]{KeyEvent.VK_QUOTE});
|
||||
case '"': return(new int[]{KeyEvent.VK_QUOTEDBL});
|
||||
case ',': return(new int[]{KeyEvent.VK_COMMA});
|
||||
case '<': return(new int[]{KeyEvent.VK_LESS});
|
||||
case '.': return(new int[]{KeyEvent.VK_PERIOD});
|
||||
case '>': return(new int[]{KeyEvent.VK_GREATER});
|
||||
case '/': return(new int[]{KeyEvent.VK_SLASH});
|
||||
case '?': return(new int[]{KeyEvent.VK_SHIFT, KeyEvent.VK_SLASH}); // needs Shift
|
||||
case ' ': return(new int[]{KeyEvent.VK_SPACE});
|
||||
default:
|
||||
throw new IllegalArgumentException("Cannot find Key Code for character " + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.Toolkit;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JWindow;
|
||||
|
||||
|
||||
public class StatusWindow extends JWindow {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
public static int FONT_SIZE = 14;
|
||||
public static int FONT_BOLD = Font.BOLD; //Font.PLAIN
|
||||
public static int Y_BOTTOM_OFFSET = -100;
|
||||
public static Color BACKGROUND_COLOR = Color.yellow;
|
||||
public static Color FOREGROUND_COLOR = Color.black;
|
||||
//private int displayTime = -1;
|
||||
//private String displayText = "";
|
||||
public StatusWindow(String lblText, int displayTime) {
|
||||
super();
|
||||
//this.displayTime = displayTime;
|
||||
//this.displayText = lblText;
|
||||
//this.setLayout(new FlowLayout());
|
||||
JLabel lbl = new JLabel(lblText);
|
||||
lbl.setFont(new Font(lbl.getName(), FONT_BOLD, FONT_SIZE));
|
||||
lbl.setOpaque(true); //background isn't painted without this
|
||||
lbl.setBackground(BACKGROUND_COLOR);
|
||||
lbl.setForeground(FOREGROUND_COLOR);
|
||||
this.getContentPane().setLayout(new FlowLayout());
|
||||
this.getContentPane().add(lbl);
|
||||
this.pack();
|
||||
this.setVisible(true);
|
||||
//
|
||||
if (displayTime > 0) {
|
||||
Timer timer = new Timer(true);
|
||||
timer.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
StatusWindow.this.dispose();
|
||||
}
|
||||
}, displayTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setVisible(final boolean visible) {
|
||||
super.setVisible(visible);
|
||||
// ...and bring window to the front.. in a strange and weird way
|
||||
if (visible) {
|
||||
super.setAlwaysOnTop(true);
|
||||
super.toFront();
|
||||
super.requestFocus();
|
||||
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
//this.setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2);
|
||||
this.setLocation(dim.width/2-this.getSize().width/2, dim.height + Y_BOTTOM_OFFSET );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package org.synthuse;
|
||||
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.synthuse.controllers.SynthuseConfigDialogControllers;
|
||||
import org.synthuse.views.SynthuseConfigPanel;
|
||||
|
||||
public class SynthuseConfigDialog extends JDialog {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = -4877764256323621418L;
|
||||
|
||||
private Config theConfig; //Model
|
||||
private final SynthuseConfigPanel theSynthuseConfigPanel; //View
|
||||
|
||||
public SynthuseConfigDialog(JFrame aParentFrame, Config aConfig) {
|
||||
super(aParentFrame);
|
||||
|
||||
this.setConfig(aConfig);
|
||||
|
||||
this.setTitle("Synthuse Properties");
|
||||
|
||||
theSynthuseConfigPanel = new SynthuseConfigPanel();
|
||||
|
||||
SynthuseConfigDialogControllers.bindActionControllers(theSynthuseConfigPanel,theConfig);
|
||||
|
||||
this.getContentPane().add(theSynthuseConfigPanel);
|
||||
this.setSize(492, 260);
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SynthuseConfigDialogControllers.initializeUI(theSynthuseConfigPanel,theConfig);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
synchronized private void setConfig(Config aConfig) {
|
||||
theConfig = aConfig;
|
||||
}
|
||||
}
|
||||
@@ -1,579 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.*;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
|
||||
/*
|
||||
import com.jgoodies.forms.layout.FormLayout;
|
||||
import com.jgoodies.forms.layout.ColumnSpec;
|
||||
import com.jgoodies.forms.layout.RowSpec;
|
||||
import com.jgoodies.forms.factories.FormFactory;
|
||||
*/
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.synthuse.Api.User32Ex;
|
||||
import org.synthuse.DragTarget.dragEvents;
|
||||
|
||||
|
||||
//public class SynthuseDlg extends JDialog {
|
||||
public class SynthuseDlg extends JFrame {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public static String VERSION_STR = "1.2.4";
|
||||
|
||||
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";
|
||||
public static String RES_STR_TESTIDE_IMG = "/org/synthuse/img/applications-education.png";
|
||||
public static String RES_STR_HELP_IMG = "/org/synthuse/img/help-3.png";
|
||||
public static String RES_STR_TARGET_IMG = "/org/synthuse/img/bullseye-logo-th18x18.png";
|
||||
public static String RES_STR_FIND_IMG = "/org/synthuse/img/edit-find-3.png";
|
||||
public static String RES_STR_SETACTION_IMG = "/org/synthuse/img/document-new-5.png";
|
||||
public static String RES_STR_CANCEL_IMG = "/org/synthuse/img/document-close-2.png";
|
||||
public static String RES_STR_PREFERENCES_IMG = "/org/synthuse/img/preferences-desktop.png";
|
||||
|
||||
private static final int STRUT_WIDTH = 10;
|
||||
|
||||
public static List<String> actionListQueue = new ArrayList<String>();
|
||||
private static final long serialVersionUID = 1L;
|
||||
private XpathManager.Events xpathEvents = null;
|
||||
private JPanel contentPane;
|
||||
private JLabel lblStatus;
|
||||
private JButton btnRefresh;
|
||||
private JTextPane textPane;
|
||||
private JButton btnSetAction;
|
||||
private JButton btnCancel;
|
||||
private JButton btnFind;
|
||||
public static Config config = new Config(Config.DEFAULT_PROP_FILENAME);
|
||||
private String dialogResult = "";
|
||||
private String lastDragHwnd = "";
|
||||
private int lastDragPid = 0;
|
||||
private String lastRuntimeId ="";
|
||||
private JComboBox<String> cmbXpath;
|
||||
private JButton btnTestIde;
|
||||
private JButton btnAdvanced;
|
||||
|
||||
private TestIdeFrame testIde = null;
|
||||
protected SynthuseConfigDialog configDialog=null;
|
||||
//private MessageHookFrame msgHook = null;
|
||||
private int targetX;
|
||||
private int targetY;
|
||||
private UiaBridge uiabridge = null;
|
||||
|
||||
/**
|
||||
* Launch the application.
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
SynthuseDlg frame = new SynthuseDlg();
|
||||
frame.setVisible(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the frame.
|
||||
*/
|
||||
public SynthuseDlg() {
|
||||
setIconImage(Toolkit.getDefaultToolkit().getImage(SynthuseDlg.class.getResource(RES_STR_MAIN_ICON)));
|
||||
//setModal(true);
|
||||
setTitle("Synthuse");
|
||||
setBounds(100, 100, 827, 420);
|
||||
contentPane = new JPanel();
|
||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
contentPane.setLayout(new BorderLayout(0, 0));
|
||||
setContentPane(contentPane);
|
||||
|
||||
JToolBar toolBar = new JToolBar();
|
||||
contentPane.add(toolBar, BorderLayout.NORTH);
|
||||
|
||||
JRadioButton rdbtnWindows = new JRadioButton("Windows Enumerated Xml");
|
||||
rdbtnWindows.setSelected(true);
|
||||
toolBar.add(rdbtnWindows);
|
||||
|
||||
Component horizontalStrut = Box.createHorizontalStrut(STRUT_WIDTH);
|
||||
toolBar.add(horizontalStrut);
|
||||
|
||||
JRadioButton rdbtnUrl = new JRadioButton("Url: ");
|
||||
rdbtnUrl.setEnabled(false);
|
||||
toolBar.add(rdbtnUrl);
|
||||
|
||||
// Group the radio buttons.
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
group.add(rdbtnWindows);
|
||||
group.add(rdbtnUrl);
|
||||
|
||||
JComboBox<String> cmbUrl = new JComboBox<String>();
|
||||
cmbUrl.setEnabled(false);
|
||||
cmbUrl.setEditable(true);
|
||||
toolBar.add(cmbUrl);
|
||||
|
||||
Component horizontalStrut_1 = Box.createHorizontalStrut(STRUT_WIDTH);
|
||||
toolBar.add(horizontalStrut_1);
|
||||
|
||||
btnRefresh = new JButton(" Refresh ");
|
||||
btnRefresh.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
//WindowsEnumeratedXml wex = new WindowsEnumeratedXml(textPane, lblStatus);
|
||||
//wex.run();
|
||||
WindowsEnumeratedXml.getXmlThreaded(textPane, lblStatus);
|
||||
}
|
||||
});
|
||||
btnRefresh.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_REFRESH_IMG)));
|
||||
toolBar.add(btnRefresh);
|
||||
|
||||
Component horizontalStrut_3 = Box.createHorizontalStrut(STRUT_WIDTH);
|
||||
toolBar.add(horizontalStrut_3);
|
||||
|
||||
btnTestIde = new JButton("Test IDE");
|
||||
btnTestIde.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
if (testIde == null) {
|
||||
testIde = new TestIdeFrame();
|
||||
if (SynthuseDlg.actionListQueue.size() > 0) { // if stuff is already in the queue add it to the test ide
|
||||
for (String action : SynthuseDlg.actionListQueue) {
|
||||
testIde.txtTest.append(action + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
testIde.setVisible(true);
|
||||
}
|
||||
});
|
||||
btnTestIde.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_TESTIDE_IMG)));
|
||||
toolBar.add(btnTestIde);
|
||||
|
||||
Component horizontalStrut_2 = Box.createHorizontalStrut(STRUT_WIDTH);
|
||||
toolBar.add(horizontalStrut_2);
|
||||
|
||||
btnAdvanced = new JButton("Advanced");
|
||||
btnAdvanced.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_PREFERENCES_IMG)));
|
||||
btnAdvanced.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JPopupMenu menu = new JPopupMenu();
|
||||
ActionListener menuListener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent event) {
|
||||
//System.out.println("Popup menu item [" + event.getActionCommand() + "] was pressed.");
|
||||
if (event.getActionCommand() == "Message Hook"){
|
||||
/*
|
||||
if (msgHook == null)
|
||||
msgHook = new MessageHookFrame();
|
||||
msgHook.setVisible(true);
|
||||
msgHook.txtTarget.setText(lastDragHwnd);
|
||||
*/
|
||||
long lastHwndLong = 0;
|
||||
try {
|
||||
//lastHwndLong = Long.parseLong(lastDragHwnd);
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
MsgHook.createMsgHookWinThread(lastHwndLong, lastDragPid);
|
||||
|
||||
}
|
||||
if (event.getActionCommand() == "Settings") {
|
||||
if(configDialog==null) {
|
||||
createConfigDialog();
|
||||
}
|
||||
configDialog.setVisible(true);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
JMenuItem mnMessageHook = new JMenuItem("Message Hook");
|
||||
mnMessageHook.addActionListener(menuListener);
|
||||
menu.add(mnMessageHook);
|
||||
JMenuItem mnSettings = new JMenuItem("Settings");
|
||||
mnSettings.setEnabled(true);
|
||||
mnSettings.addActionListener(menuListener);
|
||||
menu.add(mnSettings);
|
||||
|
||||
Component c = (Component) e.getSource();
|
||||
menu.show(c, -1, c.getHeight());
|
||||
}
|
||||
});
|
||||
toolBar.add(btnAdvanced);
|
||||
|
||||
Component horizontalStrut_4 = Box.createHorizontalStrut(STRUT_WIDTH);
|
||||
toolBar.add(horizontalStrut_4);
|
||||
|
||||
JButton helpBtn = new JButton("Help");
|
||||
helpBtn.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_HELP_IMG)));
|
||||
helpBtn.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
String about = "";
|
||||
about += "Synthuse Version " + VERSION_STR + " created by Edward Jakubowski ejakubowski7@gmail.com\n\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 += " Synthuse location - " + SynthuseDlg.class.getProtectionDomain().getCodeSource().getLocation().toString();
|
||||
|
||||
about += "\n\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";
|
||||
about += " OS Arch - " + System.getProperty("os.arch") + "\n";
|
||||
String jclasspath = System.getProperty("java.class.path");
|
||||
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(SynthuseDlg.this, about , "About", JOptionPane.QUESTION_MESSAGE);
|
||||
}
|
||||
});
|
||||
toolBar.add(helpBtn);
|
||||
|
||||
JSplitPane splitPane = new JSplitPane();
|
||||
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
|
||||
contentPane.add(splitPane, BorderLayout.CENTER);
|
||||
|
||||
JPanel panel = new JPanel();
|
||||
panel.setMinimumSize(new Dimension(20, 35));
|
||||
splitPane.setLeftComponent(panel);
|
||||
/*
|
||||
panel.setLayout(new FormLayout(new ColumnSpec[] {
|
||||
FormFactory.RELATED_GAP_COLSPEC,
|
||||
ColumnSpec.decode("left:max(11dlu;default)"),
|
||||
FormFactory.RELATED_GAP_COLSPEC,
|
||||
ColumnSpec.decode("left:default"),
|
||||
FormFactory.RELATED_GAP_COLSPEC,
|
||||
FormFactory.DEFAULT_COLSPEC,
|
||||
FormFactory.RELATED_GAP_COLSPEC,
|
||||
FormFactory.DEFAULT_COLSPEC,
|
||||
FormFactory.RELATED_GAP_COLSPEC,
|
||||
FormFactory.DEFAULT_COLSPEC,},
|
||||
new RowSpec[] {
|
||||
FormFactory.RELATED_GAP_ROWSPEC,
|
||||
RowSpec.decode("default:grow"),}));
|
||||
*/
|
||||
panel.setLayout(new GridBagLayout());
|
||||
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.HORIZONTAL;
|
||||
c.weightx = 0.5;
|
||||
c.gridwidth = 2;
|
||||
c.gridx = 0;
|
||||
c.gridy = 0;
|
||||
c.insets = new Insets(3,3,3,3); // add padding around objects
|
||||
|
||||
final DragTarget lblTarget = new DragTarget();
|
||||
|
||||
lblTarget.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
final ImageIcon imageIcon = new ImageIcon(SynthuseDlg.class.getResource(RES_STR_TARGET_IMG));
|
||||
lblTarget.setMinimumSize(new Dimension(imageIcon.getIconWidth(), imageIcon.getIconHeight()));
|
||||
lblTarget.setIcon(imageIcon);
|
||||
panel.add(lblTarget, c);
|
||||
|
||||
btnFind = new JButton("Find");
|
||||
btnFind.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
String xpathItem = cmbXpath.getSelectedItem().toString();
|
||||
int matches = XpathManager.nextXpathMatch(xpathItem, textPane, lblStatus, false);
|
||||
if (matches < 0) //check for an error
|
||||
return; //don't save bad xpath to combobox
|
||||
if (config.xpathList == null)
|
||||
config.xpathList = "";
|
||||
if (!config.xpathList.contains(xpathItem + "\u00ba")){
|
||||
config.xpathList += xpathItem + "\u00ba";
|
||||
refreshDatabinding();
|
||||
cmbXpath.setSelectedItem(xpathItem);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cmbXpath = new JComboBox<String>();
|
||||
cmbXpath.setPreferredSize(new Dimension(440, 20));//fix the width of the combobox
|
||||
cmbXpath.setPrototypeDisplayValue("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");//fix the width of the combobox
|
||||
cmbXpath.setEditable(true);
|
||||
cmbXpath.getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
if (event.getKeyChar() == KeyEvent.VK_ENTER) {
|
||||
btnFind.doClick();
|
||||
}
|
||||
}
|
||||
});
|
||||
c.gridwidth = 1;
|
||||
c.gridx = 3;
|
||||
panel.add(cmbXpath, c);
|
||||
btnFind.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_FIND_IMG)));
|
||||
c.gridwidth = 1;
|
||||
c.gridx = 4;
|
||||
panel.add(btnFind, c);
|
||||
|
||||
|
||||
btnSetAction = new JButton("Set Action");
|
||||
btnSetAction.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
CommandPopupMenu menu = new CommandPopupMenu();
|
||||
final String xpathItem = cmbXpath.getSelectedItem().toString();
|
||||
menu.events = new CommandPopupMenu.menuEvents() {
|
||||
@Override
|
||||
public void menuItemClicked(String command, int paramCount, boolean useXpath, ActionEvent e) {
|
||||
String actionStr = CommandPopupMenu.buildSkeletonCommand(command, paramCount, xpathItem, useXpath);
|
||||
SynthuseDlg.actionListQueue.add(actionStr);
|
||||
lblStatus.setText("Setting Action: " + actionStr);
|
||||
if (testIde != null)
|
||||
testIde.txtTest.append(actionStr + "\n");
|
||||
}
|
||||
};
|
||||
Component c = (Component) e.getSource();
|
||||
menu.show(c, -1, c.getHeight());
|
||||
}
|
||||
});
|
||||
btnSetAction.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_SETACTION_IMG)));
|
||||
c.gridwidth = 1;
|
||||
c.gridx = 5;
|
||||
panel.add(btnSetAction, c);
|
||||
|
||||
btnCancel = new JButton("Cancel");
|
||||
btnCancel.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
dialogResult = "";
|
||||
SynthuseDlg.this.disposeWindow();
|
||||
}
|
||||
});
|
||||
btnCancel.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_CANCEL_IMG)));
|
||||
c.gridwidth = 1;
|
||||
c.gridx = 6;
|
||||
panel.add(btnCancel, c);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
splitPane.setRightComponent(scrollPane);
|
||||
|
||||
textPane = new JTextPane();
|
||||
textPane.setEditable(false);
|
||||
textPane.setEditorKitForContentType("text/xml", new XmlEditorKit());
|
||||
textPane.setContentType("text/xml");
|
||||
|
||||
scrollPane.setViewportView(textPane);
|
||||
|
||||
JPanel panel_1 = new JPanel();
|
||||
FlowLayout flowLayout = (FlowLayout) panel_1.getLayout();
|
||||
flowLayout.setAlignment(FlowLayout.LEFT);
|
||||
panel_1.setMinimumSize(new Dimension(20, 20));
|
||||
contentPane.add(panel_1, BorderLayout.SOUTH);
|
||||
|
||||
lblStatus = new JLabel("Status:");
|
||||
lblStatus.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
lblStatus.setVerticalAlignment(SwingConstants.TOP);
|
||||
panel_1.add(lblStatus);
|
||||
xpathEvents = new XpathManager.Events() {
|
||||
@Override
|
||||
public void statusChanged(String status) {
|
||||
lblStatus.setText(status);
|
||||
}
|
||||
@Override
|
||||
public void executionCompleted(Object input, final String results) { //buildXpathStatementThreaded finished, with results being the xpath statement
|
||||
if (input instanceof HWND) { // in case thread takes long time to process
|
||||
lastDragHwnd = Api.GetHandleAsString((HWND)input);
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {//swing components are not thread safe, this will run on Swings event dispatch thread
|
||||
public void run() {
|
||||
XpathManager.nextXpathMatch(results, textPane, lblStatus, true);
|
||||
cmbXpath.setSelectedItem(results);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
lblTarget.events = new dragEvents() {
|
||||
public void dragStarted(JComponent c) {
|
||||
//might be nice to minimize this window, if we weren't displaying realtime information about each window
|
||||
}
|
||||
public void dragMouseMoved(int x, int y) {
|
||||
targetX = x;
|
||||
targetY = y;
|
||||
targetDragged();
|
||||
}
|
||||
public void dropped(JComponent c) {
|
||||
lastDragHwnd = ""; //sometimes with multithreaded the order becomes incorrect, so we may want to refresh this on dropped.
|
||||
targetDragged();
|
||||
}
|
||||
};
|
||||
|
||||
this.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
this.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent arg0) {
|
||||
//System.out.println("synthuse window closed");
|
||||
KeyboardHook.stopKeyboardHook(); //stop keyboard hook
|
||||
config.save();
|
||||
SynthuseDlg.this.dispose(); // force app to close
|
||||
}
|
||||
});
|
||||
|
||||
initializeHotKeys();
|
||||
|
||||
btnRefresh.doClick();
|
||||
//uiabridge = new UiaBridge();
|
||||
//uiabridge.useCachedRequests(false);
|
||||
refreshDatabinding();
|
||||
super.setAlwaysOnTop(config.isAlwaysOnTop());
|
||||
}
|
||||
|
||||
/*
|
||||
@Override
|
||||
public void setVisible(final boolean visible) {
|
||||
// make sure that frame is marked as not disposed if it is asked to be visible
|
||||
if (visible) {
|
||||
//setDisposed(false);
|
||||
}
|
||||
// let's handle visibility...
|
||||
if (!visible || !isVisible()) { // have to check this condition simply because super.setVisible(true) invokes toFront if frame was already visible
|
||||
super.setVisible(visible);
|
||||
}
|
||||
// ...and bring frame to the front.. in a strange and weird way
|
||||
if (visible) {
|
||||
int state = super.getExtendedState();
|
||||
state &= ~JFrame.ICONIFIED;
|
||||
super.setExtendedState(state);
|
||||
super.setAlwaysOnTop(true);
|
||||
super.toFront();
|
||||
super.requestFocus();
|
||||
super.setAlwaysOnTop(false);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
public String showDialog() {
|
||||
//this.setModal(true);
|
||||
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
this.setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2);
|
||||
this.setVisible(true);
|
||||
return dialogResult;// this gets returned immediately
|
||||
}
|
||||
|
||||
public void refreshDatabinding() {
|
||||
if (config.xpathList != null)
|
||||
cmbXpath.setModel(new DefaultComboBoxModel<String>(config.xpathList.split("\u00ba")));
|
||||
if (config.xpathHightlight != null)
|
||||
XmlEditorKit.TAG_HIGHLIGHTED = config.xpathHightlight;
|
||||
}
|
||||
|
||||
private void initializeHotKeys()
|
||||
{
|
||||
KeyboardHook.clearKeyEvent();
|
||||
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.StartKeyboardHookThreaded(new KeyboardHook.KeyboardEvents() {
|
||||
@Override
|
||||
public void keyPressed(KeyboardHook.TargetKeyPress target) {
|
||||
//System.out.println("target key pressed " + target.targetKeyCode);
|
||||
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()){
|
||||
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();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void targetDragged() {
|
||||
HWND hwnd = Api.getWindowFromCursorPos();//new Point(targetX,targetY)
|
||||
String handleStr = Api.GetHandleAsString(hwnd);
|
||||
String classStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.getWindowClassName(hwnd));
|
||||
String parentStr = Api.GetHandleAsString(User32Ex.instance.GetParent(hwnd));
|
||||
PointerByReference pointer = new PointerByReference();
|
||||
User32Ex.instance.GetWindowThreadProcessId(hwnd, pointer);
|
||||
int pid = pointer.getPointer().getInt(0);
|
||||
|
||||
String enumProperties = "";
|
||||
if (!SynthuseDlg.config.isUiaBridgeDisabled())
|
||||
{
|
||||
//System.out.println("useCachedRequests false");
|
||||
if (uiabridge == null)
|
||||
uiabridge = new UiaBridge();
|
||||
uiabridge.useCachedRequests(false);
|
||||
enumProperties = uiabridge.getWindowInfo(targetX, targetY, WindowInfo.UIA_PROPERTY_LIST_ADV);
|
||||
}
|
||||
String runtimeId = WindowInfo.getRuntimeIdFromProperties(enumProperties);
|
||||
String framework = WindowInfo.getFrameworkFromProperties(enumProperties);
|
||||
Rectangle rect = UiaBridge.getBoundaryRect(enumProperties);
|
||||
Point offsetPoint = WindowInfo.findOffset(rect, targetX, targetY);
|
||||
lblStatus.setText("rid:" + runtimeId + " " + framework + " class: " + classStr + " hWnd: " + handleStr + " parent: " + parentStr + " X,Y (" + targetX + ", " + targetY + ") offset: " + offsetPoint.x + ", " + offsetPoint.y);
|
||||
if (!lastDragHwnd.equals(handleStr) || !lastRuntimeId.equals(runtimeId)) {
|
||||
if (!lastDragHwnd.isEmpty()) {
|
||||
Api.refreshWindow(Api.GetHandleFromString(lastDragHwnd));
|
||||
}
|
||||
lastDragHwnd = handleStr;
|
||||
lastRuntimeId = runtimeId;
|
||||
lastDragPid = pid;
|
||||
//lastDragHwnd = (hwnd + "");
|
||||
if (framework.equals(UiaBridge.FRAMEWORK_ID_WPF) || framework.equals(UiaBridge.FRAMEWORK_ID_SILVER))
|
||||
{// WPF and Silverlight apps don't expose their child windows boundaries the same as win32 apps
|
||||
Api.highlightWindow(Api.User32Ex.instance.GetDesktopWindow(), rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
|
||||
}
|
||||
else
|
||||
Api.highlightWindow(hwnd);
|
||||
XpathManager.buildXpathStatementThreaded(hwnd, enumProperties, textPane, xpathEvents);
|
||||
}
|
||||
}
|
||||
|
||||
public void disposeWindow()
|
||||
{
|
||||
WindowEvent closingEvent = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
|
||||
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(closingEvent);
|
||||
}
|
||||
|
||||
private void createConfigDialog() {
|
||||
configDialog=new SynthuseConfigDialog(this, config);
|
||||
configDialog.setLocationRelativeTo(null);
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextArea;
|
||||
import javax.swing.WindowConstants;
|
||||
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.Toolkit;
|
||||
import java.io.*;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
||||
public class TestIdeFrame extends JFrame {
|
||||
|
||||
public static String RES_STR_MAIN_ICON = "/org/synthuse/img/applications-education.png";
|
||||
public static String RES_STR_STOP_IMG = "/org/synthuse/img/dialog-close.png";
|
||||
public static String RES_STR_RUN_IMG = "/org/synthuse/img/arrow-right-3.png";
|
||||
public static String RES_STR_CLEAR_IMG = "/org/synthuse/img/user-trash-2.png";
|
||||
public static String RES_STR_COPY_IMG = "/org/synthuse/img/edit-copy-7.png";
|
||||
public static String RES_STR_SAVE_IMG = "/org/synthuse/img/document-save-6.png";
|
||||
public static String RES_STR_OPEN_IMG = "/org/synthuse/img/document-open-folder.png";
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private JPanel contentPane;
|
||||
public JTextArea txtTest;
|
||||
private JButton btnRun;
|
||||
private JButton btnClear;
|
||||
private JButton btnCopy;
|
||||
private JButton btnSave;
|
||||
private JButton btnOpen;
|
||||
private JLabel lblStatus;
|
||||
|
||||
/**
|
||||
* Create the frame.
|
||||
*/
|
||||
|
||||
public TestIdeFrame() {
|
||||
setTitle("Test IDE - Synthuse");
|
||||
setIconImage(Toolkit.getDefaultToolkit().getImage(TestIdeFrame.class.getResource(RES_STR_MAIN_ICON)));
|
||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
setBounds(100, 100, 700, 367);
|
||||
contentPane = new JPanel();
|
||||
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
contentPane.setLayout(new BorderLayout(0, 0));
|
||||
setContentPane(contentPane);
|
||||
|
||||
JToolBar toolBar = new JToolBar();
|
||||
contentPane.add(toolBar, BorderLayout.NORTH);
|
||||
|
||||
btnRun = new JButton("Run");
|
||||
btnRun.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
runTestScript();
|
||||
}
|
||||
});
|
||||
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
|
||||
toolBar.add(btnRun);
|
||||
|
||||
btnSave = new JButton("Save");
|
||||
btnSave.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
saveTestScript();
|
||||
}
|
||||
});
|
||||
btnSave.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_SAVE_IMG)));
|
||||
toolBar.add(btnSave);
|
||||
|
||||
btnOpen = new JButton("Open");
|
||||
btnOpen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
openTestScript();
|
||||
}
|
||||
});
|
||||
btnOpen.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_OPEN_IMG)));
|
||||
toolBar.add(btnOpen);
|
||||
|
||||
btnClear = new JButton("Clear");
|
||||
btnClear.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
txtTest.setText("");
|
||||
}
|
||||
});
|
||||
btnClear.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_CLEAR_IMG)));
|
||||
toolBar.add(btnClear);
|
||||
|
||||
btnCopy = new JButton("Copy Script");
|
||||
btnCopy.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent arg0) {
|
||||
StringSelection stringSelection = new StringSelection(txtTest.getText());
|
||||
Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clpbrd.setContents(stringSelection, null);
|
||||
//StatusWindow sw = new StatusWindow("this is a test BLAH really long string goes here to test status of stuff yaya!!!!123123 123 123", 4000);
|
||||
}
|
||||
});
|
||||
btnCopy.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_COPY_IMG)));
|
||||
toolBar.add(btnCopy);
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane();
|
||||
contentPane.add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
txtTest = new JTextArea();
|
||||
txtTest.setText("Click the Run button above to test the script below...\r\n\r\n");
|
||||
scrollPane.setViewportView(txtTest);
|
||||
|
||||
lblStatus = new JLabel(" ");
|
||||
contentPane.add(lblStatus, BorderLayout.SOUTH);
|
||||
|
||||
this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
this.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
//TestIdeFrame.this.setVisible(false);
|
||||
TestIdeFrame.this.dispose();
|
||||
}
|
||||
});
|
||||
super.setAlwaysOnTop(SynthuseDlg.config.isAlwaysOnTop());
|
||||
}
|
||||
|
||||
public void runTestScript()
|
||||
{
|
||||
if (btnRun.getText().equals("Run")) {
|
||||
btnRun.setText("Stop");
|
||||
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_STOP_IMG)));
|
||||
CommandProcessor.STOP_PROCESSOR.set(false);
|
||||
CommandProcessor.executeThreaded(txtTest.getText(), new CommandProcessor.Events() {
|
||||
@Override
|
||||
public void statusChanged(String status) {
|
||||
lblStatus.setText(status);
|
||||
}
|
||||
@Override
|
||||
public void executionCompleted() {
|
||||
btnRun.setText("Run");
|
||||
btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
CommandProcessor.STOP_PROCESSOR.set(true);
|
||||
//btnRun.setText("Run");
|
||||
//btnRun.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_RUN_IMG)));
|
||||
}
|
||||
}
|
||||
|
||||
private void saveTestScript()
|
||||
{
|
||||
JFileChooser fChoose = new JFileChooser();
|
||||
fChoose.setFileFilter(new FileNameExtensionFilter("Text Files", "txt", "text"));
|
||||
int result = fChoose.showSaveDialog(this);
|
||||
if (result == JFileChooser.CANCEL_OPTION)
|
||||
return;
|
||||
File file = fChoose.getSelectedFile();
|
||||
if (fChoose.getFileFilter().getDescription().startsWith("Text") && !file.getAbsolutePath().toLowerCase().endsWith(".txt"))
|
||||
file = new File(file.getAbsolutePath() + ".txt"); //append extension if not already there
|
||||
|
||||
FileWriter fw = null;
|
||||
try {
|
||||
fw = new FileWriter(file);
|
||||
fw.write(txtTest.getText());
|
||||
fw.flush();
|
||||
fw.close();
|
||||
fw = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (fw != null)
|
||||
try { fw.close(); } catch (Exception e){ e.printStackTrace(); };
|
||||
lblStatus.setText("Script Saved: " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
private void openTestScript()
|
||||
{
|
||||
JFileChooser fChoose = new JFileChooser();
|
||||
fChoose.setFileFilter(new FileNameExtensionFilter("Text Files", "txt", "text"));
|
||||
int result = fChoose.showOpenDialog(this);
|
||||
if (result == JFileChooser.CANCEL_OPTION)
|
||||
return;
|
||||
File file = fChoose.getSelectedFile();
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader(file));
|
||||
String line = "";
|
||||
txtTest.setText("");
|
||||
while((line = br.readLine()) != null){
|
||||
txtTest.append(line + System.getProperty("line.separator"));
|
||||
//System.out.println(line);
|
||||
}
|
||||
br.close();
|
||||
br = null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (br != null)
|
||||
try { br.close(); } catch (Exception e){ e.printStackTrace(); };
|
||||
lblStatus.setText("Script Loaded: " + file.getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.io.*;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
public class UiaBridge {
|
||||
|
||||
public static String CACHED_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty,BoundingRectangleProperty";
|
||||
public static final String FRAMEWORK_ID_WPF = "WPF";
|
||||
public static final String FRAMEWORK_ID_SILVER = "Silverlight";
|
||||
public static final String FRAMEWORK_ID_WINFORM = "WinForm";
|
||||
public static final String FRAMEWORK_ID_WIN = "Win32";
|
||||
|
||||
static
|
||||
{
|
||||
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
|
||||
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, loadFailedMsg + sw.toString() , "Native Library Load Error", JOptionPane.ERROR_MESSAGE);
|
||||
SynthuseDlg.config.disableUiaBridge = "true";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadNativeLibraryFromJar(String path) {
|
||||
// Obtain filename from path
|
||||
String[] parts = path.split("/");
|
||||
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
|
||||
// Split filename to prexif and suffix (extension)
|
||||
String prefix = "";
|
||||
String suffix = null;
|
||||
if (filename != null) {
|
||||
parts = filename.split("\\.", 2);
|
||||
prefix = parts[0];
|
||||
suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null;
|
||||
}
|
||||
File temp = null;
|
||||
try {
|
||||
// Prepare temporary file
|
||||
temp = File.createTempFile(prefix, suffix);
|
||||
temp.deleteOnExit();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!temp.exists()) { //some reason the temp file wasn't create so abort
|
||||
System.out.println("File " + temp.getAbsolutePath() + " does not exist.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare buffer for data copying
|
||||
byte[] buffer = new byte[1024];
|
||||
int readBytes;
|
||||
// Open and check input stream
|
||||
InputStream is = UiaBridge.class.getResourceAsStream(path);
|
||||
if (is == null) { //check if valid
|
||||
System.out.println("File " + path + " was not found inside JAR.");
|
||||
return;
|
||||
}
|
||||
// Open output stream and copy data between source file in JAR and the temporary file
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(temp);
|
||||
while ((readBytes = is.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, readBytes);
|
||||
}
|
||||
os.close();
|
||||
is.close();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Finally, load the library
|
||||
System.load(temp.getAbsolutePath());
|
||||
}
|
||||
|
||||
public UiaBridge ()
|
||||
{
|
||||
if (!SynthuseDlg.config.isUiaBridgeDisabled())
|
||||
initialize(CACHED_PROPERTY_LIST);
|
||||
}
|
||||
|
||||
public native void initialize(String properties);
|
||||
public native void shutdown();
|
||||
public native void useCachedRequests(boolean cacheRequestsFlg);
|
||||
public native int addEnumFilter(String propertyName, String propertyValue);
|
||||
public native void clearEnumFilters();
|
||||
public native String[] enumWindowInfo(String properties);
|
||||
public native String[] enumWindowInfo(int windowHandle, String properties);
|
||||
//native String[] enumWindowInfo(AutomationElement ^element, String properties);
|
||||
//native String[] enumWindowInfo(AutomationElement ^element, String properties, String[] filterModifierList);
|
||||
//native String getWindowInfo(AutomationElement ^element, String properties);
|
||||
public native String getWindowInfo(int x, int y, String properties);
|
||||
public native String getWindowInfo(int windowHandle, String properties);
|
||||
public native String getWindowInfo(String runtimeId, String properties);
|
||||
|
||||
|
||||
/*
|
||||
public native void setFrameworkId(String propertyValue); //default is WPF, but also accepts Silverlight, Win32
|
||||
public native void setTouchableOnly(boolean val); //default is true
|
||||
|
||||
//Descendants will walk the full tree of windows, NOT just one level of children
|
||||
public native int countDescendantWindows();
|
||||
public native int countDescendantWindows(String runtimeIdValue);
|
||||
|
||||
public native int countChildrenWindows();
|
||||
public native int countChildrenWindows(String runtimeIdValue);
|
||||
|
||||
public String[] enumChildrenWindowIds(String runtimeIdValue); //if runtimeIdValue is null will start at desktop
|
||||
public native String[] enumDescendantWindowIds(String runtimeIdValue); //if runtimeIdValue is null will start at desktop
|
||||
public native String[] enumDescendantWindowIds(long processId);
|
||||
//In all the above Enumerate methods will return a list of Runtime Ids for all related windows.
|
||||
public native String[] enumDescendantWindowInfo(String runtimeIdValue, String properties); //returns properties comma separated
|
||||
|
||||
public native String getRuntimeIdFromHandle(long windowHandle);
|
||||
public native String getRuntimeIdFromPoint(int x, int y);
|
||||
public native String getParentRuntimeId(String runtimeIdValue);
|
||||
public native String getProperty(String propertyName, String runtimeIdValue);
|
||||
public native String[] getProperties(String runtimeIdValue);
|
||||
public native String[] getPropertiesAndValues(String runtimeIdValue);
|
||||
*/
|
||||
|
||||
public static String replaceEscapedCodes(String input) {
|
||||
//, is a comma ,
|
||||
String result = input;
|
||||
result = result.replaceAll(",", ",");
|
||||
result = result.replaceAll("<", "<");
|
||||
result = result.replaceAll(">", ">");
|
||||
result = result.replaceAll("'", "'");
|
||||
result = result.replaceAll(""", "\"");
|
||||
result = result.replaceAll("&", "&");
|
||||
return result;
|
||||
}
|
||||
|
||||
public Point getCenterOfElement(String runtimeIdValue) {
|
||||
Point p = new Point();
|
||||
String boundaryProperty = getWindowInfo(runtimeIdValue, "BoundingRectangleProperty");
|
||||
Rectangle rect = getBoundaryRect(boundaryProperty);
|
||||
p.x = ((rect.width) /2) + rect.x;
|
||||
p.y = ((rect.height) /2) + rect.y;
|
||||
return p;
|
||||
}
|
||||
|
||||
//BoundingRectangleProperty is the last property listed in comma separated properties string
|
||||
public static Rectangle getBoundaryRect(String properties) {
|
||||
Rectangle rect = new Rectangle();
|
||||
String[] propSplt = properties.split(",");
|
||||
if (propSplt.length > 0)
|
||||
{
|
||||
String[] boundarySplt = replaceEscapedCodes(propSplt[propSplt.length - 1]).split(",");
|
||||
if (boundarySplt.length == 4 )
|
||||
{
|
||||
rect.x = Integer.parseInt(boundarySplt[0]);
|
||||
rect.y = Integer.parseInt(boundarySplt[1]);
|
||||
rect.width = Integer.parseInt(boundarySplt[2]);
|
||||
rect.height = Integer.parseInt(boundarySplt[3]);
|
||||
}
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski7@gmail.com
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
|
||||
public class WinPtr {
|
||||
|
||||
public HWND hWnd = null;
|
||||
public String hWndStr = "";
|
||||
public String runtimeId = "";
|
||||
|
||||
public String hmenuStr = "";//store menu handle
|
||||
public int hmenuPos = -1;//store menu position or id
|
||||
|
||||
public WinPtr() {
|
||||
}
|
||||
|
||||
public WinPtr(HWND hWnd) {
|
||||
this.hWnd = hWnd;
|
||||
this.hWndStr = Api.GetHandleAsString(hWnd);
|
||||
}
|
||||
|
||||
public WinPtr(String runtimeId) {
|
||||
this.runtimeId = runtimeId;
|
||||
}
|
||||
|
||||
public boolean isWin32() {
|
||||
return (hWnd != null || !hWndStr.equals(""));
|
||||
}
|
||||
|
||||
public boolean isWpf() {
|
||||
return (!runtimeId.equals(""));
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (hWnd == null && hWndStr.equals("") && runtimeId.equals(""));
|
||||
}
|
||||
|
||||
public static boolean isWpfRuntimeIdFormat(String runtimeIdTest) {
|
||||
return (runtimeIdTest.contains("-"));
|
||||
}
|
||||
|
||||
public void convertToNativeHwnd()
|
||||
{
|
||||
if (isWpfRuntimeIdFormat(runtimeId)){
|
||||
hWndStr = runtimeId.split("-")[1];
|
||||
hWnd = Api.GetHandleFromString(hWndStr);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (isWin32() && !hWndStr.equals(""))
|
||||
return hWndStr;
|
||||
else if (isWin32() && hWnd != null)
|
||||
{
|
||||
hWndStr = Api.GetHandleAsString(hWnd);
|
||||
return hWndStr;
|
||||
}
|
||||
else if (isWpf())
|
||||
return runtimeId;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.synthuse.Api.*;
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import com.sun.jna.platform.win32.WinDef.LRESULT;
|
||||
import com.sun.jna.platform.win32.WinDef.RECT;
|
||||
import com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
|
||||
public class WindowInfo {
|
||||
|
||||
public static String UIA_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty";
|
||||
public static String UIA_PROPERTY_LIST_ADV = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty,BoundingRectangleProperty";
|
||||
public static String UIA_RUNTIME_ID = "RuntimeIdProperty";
|
||||
public static String UIA_BOUNDING_RECT = "BoundingRectangleProperty";
|
||||
public static int MAX_TEXT_SIZE = 200;
|
||||
|
||||
public HWND hwnd;
|
||||
public String hwndStr = "";
|
||||
public HWND parent = null;
|
||||
public String parentStr = "";
|
||||
public RECT rect;
|
||||
public String text;
|
||||
public String value;
|
||||
public String controlType = "";
|
||||
public String className = "";
|
||||
public boolean isChild = false;
|
||||
public String processName = "";
|
||||
public long pid = 0;
|
||||
public Object xmlObj = null;
|
||||
public String framework = "win32";//default as win32
|
||||
public String runtimeId = "";
|
||||
public int menus = 0;
|
||||
public HMENU menu = null;
|
||||
public boolean useUiaBridge = false;
|
||||
public boolean is64bit = false;
|
||||
|
||||
public Map<String, String> extra = null;
|
||||
|
||||
//Default Win32 support
|
||||
public WindowInfo(HWND hWnd, boolean isChild) {
|
||||
this.framework = "win32";
|
||||
byte[] buffer = new byte[1024];
|
||||
User32Ex.instance.GetWindowTextA(hWnd, buffer, buffer.length);
|
||||
text = Native.toString(buffer);
|
||||
if (text.isEmpty())
|
||||
text = new Api().sendWmGetText(hWnd);
|
||||
//if (text.isEmpty()) {
|
||||
//System.out.println("getting toolbar text");
|
||||
//}
|
||||
if (text.length() > MAX_TEXT_SIZE) //if text is too large it will slow down xml display
|
||||
text = text.substring(0, MAX_TEXT_SIZE);
|
||||
|
||||
//Get item count depending on what type of control it is
|
||||
LRESULT tbCount = Api.User32Ex.instance.SendMessage(hWnd, Api.TB_BUTTONCOUNT, new WPARAM(0), new LPARAM(0));
|
||||
if (tbCount.intValue() > 0) { // toolbar button count
|
||||
//System.out.println("TB_BUTTONCOUNT: " + tbCount.intValue());
|
||||
if (extra == null)
|
||||
extra = new LinkedHashMap<String, String>();
|
||||
extra.put("tbCount", tbCount.intValue() + "");
|
||||
//Api.User32.instance.SendMessageA(hWnd, Api.TB_GETTOOLTIPS, 0, buffer);
|
||||
//text = Native.toString(buffer);
|
||||
}
|
||||
LRESULT lvCount = Api.User32Ex.instance.SendMessage(hWnd, Api.LVM_GETITEMCOUNT, new WPARAM(0), new LPARAM(0));
|
||||
if (lvCount.intValue() > 0) { // listview item count
|
||||
if (extra == null)
|
||||
extra = new LinkedHashMap<String, String>();
|
||||
extra.put("lvCount", lvCount.intValue() + "");
|
||||
}
|
||||
LRESULT lbCount = Api.User32Ex.instance.SendMessage(hWnd, Api.LB_GETCOUNT, new WPARAM(0), new LPARAM(0));
|
||||
if (lbCount.intValue() > 0) { // listbox item count
|
||||
if (extra == null)
|
||||
extra = new LinkedHashMap<String, String>();
|
||||
extra.put("lbCount", lbCount.intValue() + "");
|
||||
}
|
||||
LRESULT cbCount = Api.User32Ex.instance.SendMessage(hWnd, Api.CB_GETCOUNT, new WPARAM(0), new LPARAM(0));
|
||||
if (cbCount.intValue() > 0) { // listbox item count
|
||||
if (extra == null)
|
||||
extra = new LinkedHashMap<String, String>();
|
||||
extra.put("cbCount", cbCount.intValue() + "");
|
||||
}
|
||||
LRESULT tvCount = Api.User32Ex.instance.SendMessage(hWnd, Api.TVM_GETCOUNT, new WPARAM(0), new LPARAM(0));
|
||||
if (tvCount.intValue() > 0) { //treeview node count
|
||||
if (extra == null)
|
||||
extra = new LinkedHashMap<String, String>();
|
||||
extra.put("tvCount", tvCount.intValue() + "");
|
||||
}
|
||||
|
||||
char[] buffer2 = new char[1026];
|
||||
User32Ex.instance.GetClassName(hWnd, buffer2, 1026);
|
||||
className = Native.toString(buffer2);
|
||||
|
||||
//check if window has a menu
|
||||
HMENU hmenu = null;
|
||||
try {
|
||||
hmenu = Api.User32Ex.instance.GetMenu(hWnd);
|
||||
} catch(Exception ex) {
|
||||
//ex.printStackTrace();
|
||||
}
|
||||
if (hmenu != null) { //menu item count
|
||||
int menuCount = Api.User32Ex.instance.GetMenuItemCount(hmenu);
|
||||
if (menuCount > 0) {
|
||||
this.menus = menuCount;
|
||||
this.menu = hmenu;
|
||||
}
|
||||
}
|
||||
else // if (className.equals("#32768")) //check if its a popup menu window
|
||||
{
|
||||
//LRESULT result = Api.User32.instance.PostMessage(hWnd, Api.MN_GETHMENU, new WPARAM(0), new LPARAM(0));
|
||||
LRESULT result = Api.User32Ex.instance.SendMessage(hWnd, Api.MN_GETHMENU, new WPARAM(0), new LPARAM(0));
|
||||
if (result.longValue() != 1)
|
||||
{
|
||||
//System.out.println("MN_GETHMENU: " + result.longValue());
|
||||
hmenu = new HMENU(new Pointer(result.longValue()));
|
||||
int menuCount = Api.User32Ex.instance.GetMenuItemCount(hmenu);
|
||||
if (menuCount > 0)
|
||||
{
|
||||
//System.out.println("Popup Win: " + menuCount);
|
||||
this.menus = menuCount;
|
||||
this.menu = hmenu;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
rect = new RECT();
|
||||
User32Ex.instance.GetWindowRect(hWnd, rect);
|
||||
|
||||
this.isChild = isChild;
|
||||
if (isChild) {
|
||||
parent = User32Ex.instance.GetParent(hWnd);
|
||||
parentStr = Api.GetHandleAsString(parent);
|
||||
// test to see if uiaBridge should be used on this child
|
||||
if (this.className.startsWith("HwndWrapper") || this.className.startsWith("MicrosoftSilverlight") || this.className.startsWith("GeckoPluginWindow"))
|
||||
useUiaBridge = true;
|
||||
}
|
||||
else {
|
||||
PointerByReference pointer = new PointerByReference();
|
||||
User32Ex.instance.GetWindowThreadProcessId(hWnd, pointer);
|
||||
pid = pointer.getPointer().getInt(0);
|
||||
getProcessInfo();
|
||||
//test to see if uiaBridge should be used on this parent
|
||||
if (this.className.startsWith("HwndWrapper") || this.className.startsWith("WindowsForms"))
|
||||
useUiaBridge = true;
|
||||
}
|
||||
this.hwnd = hWnd;
|
||||
hwndStr = Api.GetHandleAsString(hWnd);
|
||||
if (this.hwndStr == null)
|
||||
this.hwndStr = "";
|
||||
}
|
||||
|
||||
//support for WPF, Silverlight, WinForms
|
||||
public WindowInfo(String enumProperties, boolean isChild) {
|
||||
//WPF_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty";
|
||||
String[] spltProperties = enumProperties.split(",");
|
||||
this.isChild = isChild;
|
||||
this.useUiaBridge = true;
|
||||
if (SynthuseDlg.config.isFilterUiaDisabled()) { //use wildcard mode
|
||||
extra = new LinkedHashMap<String, String>();
|
||||
for(String prop: spltProperties) {
|
||||
String[] propertyNameAndValue = prop.split(":", 2);
|
||||
if (propertyNameAndValue.length < 2)
|
||||
continue;
|
||||
|
||||
if (propertyNameAndValue[0].equals("RuntimeIdProperty"))
|
||||
this.runtimeId = propertyNameAndValue[1];
|
||||
else if (propertyNameAndValue[0].equals("ParentRuntimeIdProperty"))
|
||||
this.parentStr = propertyNameAndValue[1];
|
||||
else if (propertyNameAndValue[0].equals("ProcessIdProperty"))
|
||||
this.pid = Long.parseLong(propertyNameAndValue[1]);
|
||||
else if (propertyNameAndValue[0].equals("FrameworkIdProperty"))
|
||||
this.framework = propertyNameAndValue[1];
|
||||
else if (propertyNameAndValue[0].equals("LocalizedControlTypeProperty"))
|
||||
this.controlType = propertyNameAndValue[1];
|
||||
else if (propertyNameAndValue[0].equals("ClassNameProperty"))
|
||||
this.className = propertyNameAndValue[1];
|
||||
else if (propertyNameAndValue[0].equals("NameProperty"))
|
||||
this.text = propertyNameAndValue[1];
|
||||
else if (propertyNameAndValue[0].equals("ValueProperty"))
|
||||
this.value = propertyNameAndValue[1];
|
||||
else{
|
||||
extra.put(propertyNameAndValue[0], propertyNameAndValue[1]);
|
||||
}
|
||||
}
|
||||
this.hwndStr = this.runtimeId;
|
||||
if (text != null)
|
||||
if (text.length() > MAX_TEXT_SIZE)
|
||||
text = text.substring(0, MAX_TEXT_SIZE);
|
||||
if (this.hwndStr == null)
|
||||
this.hwndStr = "";
|
||||
//if (this.framework == null)
|
||||
// this.framework = "na";
|
||||
if(this.controlType.equals("window"))
|
||||
this.isChild = false;
|
||||
return;
|
||||
}
|
||||
// non-wildcard mode
|
||||
if (spltProperties.length > 0)
|
||||
this.runtimeId = spltProperties[0];
|
||||
this.hwndStr = this.runtimeId;
|
||||
if (spltProperties.length > 1 && isChild)
|
||||
this.parentStr = spltProperties[1];
|
||||
if (spltProperties.length > 2)
|
||||
this.pid = Long.parseLong(spltProperties[2]);
|
||||
if (spltProperties.length > 3)
|
||||
this.framework = spltProperties[3];
|
||||
if (spltProperties.length > 4)
|
||||
this.controlType = UiaBridge.replaceEscapedCodes(spltProperties[4]);
|
||||
if (spltProperties.length > 5)
|
||||
this.className = UiaBridge.replaceEscapedCodes(spltProperties[5]);
|
||||
if (spltProperties.length > 6)
|
||||
this.text = UiaBridge.replaceEscapedCodes(spltProperties[6]);
|
||||
if (spltProperties.length > 7)
|
||||
this.value = UiaBridge.replaceEscapedCodes(spltProperties[7]);
|
||||
if (this.className == "")
|
||||
this.className = this.controlType;
|
||||
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 = "";
|
||||
getProcessInfo();
|
||||
if(this.controlType.equals("window"))
|
||||
this.isChild = false;
|
||||
/*
|
||||
this.rect = new RECT();
|
||||
try {
|
||||
String rectStr = wb.getProperty("BoundingRectangleProperty", runtimeId);
|
||||
String[] rectSplt = rectStr.split(",");
|
||||
this.rect.right = Integer.parseInt(rectSplt[0]);
|
||||
this.rect.bottom = Integer.parseInt(rectSplt[1]);
|
||||
this.rect.left = Integer.parseInt(rectSplt[2]);
|
||||
this.rect.top = Integer.parseInt(rectSplt[3]);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void getProcessInfo()
|
||||
{
|
||||
if (pid == 0)
|
||||
return;
|
||||
char[] buffer = new char[1026];
|
||||
Pointer process = Kernel32Ex.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, new Pointer(pid));
|
||||
PsapiEx.instance.GetModuleBaseNameW(process, null, buffer, 512);
|
||||
processName = Native.toString(buffer);
|
||||
Kernel32Ex.instance.CloseHandle(new HANDLE(process));
|
||||
is64bit = Api.isProcess64bit((int)pid);
|
||||
}
|
||||
|
||||
|
||||
public static String getRuntimeIdFromProperties(String enumProperties)
|
||||
{
|
||||
String[] spltProperties = enumProperties.split(",");
|
||||
if (spltProperties.length > 0)
|
||||
return spltProperties[0];
|
||||
return "";
|
||||
}
|
||||
|
||||
public static String getFrameworkFromProperties(String enumProperties)
|
||||
{
|
||||
String[] spltProperties = enumProperties.split(",");
|
||||
if (spltProperties.length > 3)
|
||||
return spltProperties[3];
|
||||
return "";
|
||||
}
|
||||
|
||||
public static Point findOffset(Rectangle rect, int xPos, int yPos)
|
||||
{
|
||||
Point offset = new Point();
|
||||
int x = ((rect.width) /2) + rect.x;
|
||||
int y = ((rect.height) /2) + rect.y;
|
||||
|
||||
offset.x = xPos - x;
|
||||
offset.y = yPos - y;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.format("%s \"%s\" [%s] (%s) {%s}", framework, text, className, controlType, hwndStr);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,421 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.sql.Timestamp;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpression;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import com.sun.jna.platform.win32.WinUser;
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
|
||||
public class WindowsEnumeratedXml implements Runnable{
|
||||
|
||||
public static Exception lastException = null;
|
||||
public static AtomicBoolean enumeratingXmlFlag = new AtomicBoolean(false);
|
||||
public JTextPane outputPane = null;
|
||||
public JLabel lblStatus = null;
|
||||
public WindowsEnumeratedXml() {
|
||||
}
|
||||
|
||||
public WindowsEnumeratedXml(JTextPane outputPane, JLabel lblStatus) {
|
||||
this.outputPane = outputPane;
|
||||
this.lblStatus = lblStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
lblStatus.setText("Loading Windows Enumerated Xml...");
|
||||
long startTime = System.nanoTime();
|
||||
outputPane.setText(getXml());
|
||||
outputPane.setCaretPosition(0);
|
||||
double seconds = ((double)(System.nanoTime() - startTime) / 1000000000);
|
||||
lblStatus.setText("Windows Enumerated Xml loaded in " + new DecimalFormat("#.###").format(seconds) + " seconds");
|
||||
enumeratingXmlFlag.set(false);
|
||||
}
|
||||
|
||||
public static void getXmlThreaded(JTextPane outputPane, JLabel lblStatus) {
|
||||
if (enumeratingXmlFlag.get())
|
||||
return; //something is already running
|
||||
enumeratingXmlFlag.set(true); //if we don't do this the multiple xml's could get combined on the textpane
|
||||
Thread t = new Thread(new WindowsEnumeratedXml(outputPane, lblStatus));
|
||||
t.start();
|
||||
}
|
||||
|
||||
public static String getXml() {
|
||||
final Map<String, WindowInfo> infoList = getWin32XmlMap();
|
||||
|
||||
//process all windows that have been flagged for uiaBridge (useUiaBridge == true)
|
||||
appendUiaBridgeWindows(infoList);
|
||||
|
||||
return generateWindowsXml(infoList, "EnumeratedWindows");
|
||||
}
|
||||
|
||||
public static String getWin32Xml() {
|
||||
final Map<String, WindowInfo> infoList = getWin32XmlMap();
|
||||
return generateWindowsXml(infoList, "EnumeratedWindows");
|
||||
}
|
||||
|
||||
public static Map<String, WindowInfo> getWin32XmlMap() {
|
||||
final Map<String, WindowInfo> infoList = new LinkedHashMap<String, WindowInfo>();
|
||||
|
||||
HWND desktopRootHwnd = Api.User32Ex.instance.GetDesktopWindow();
|
||||
WindowInfo wi = new WindowInfo(desktopRootHwnd, false);
|
||||
wi.controlType = "DesktopRoot";
|
||||
infoList.put(wi.hwndStr, wi);
|
||||
|
||||
class ParentWindowCallback implements WinUser.WNDENUMPROC {
|
||||
@Override
|
||||
public boolean callback(HWND hWnd, Pointer lParam) {
|
||||
WindowInfo wi = new WindowInfo(hWnd, false);
|
||||
infoList.put(wi.hwndStr, wi);
|
||||
infoList.putAll(EnumerateWin32ChildWindows(hWnd));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Api.User32Ex.instance.EnumWindows(new ParentWindowCallback(), 0);
|
||||
return infoList;
|
||||
}
|
||||
|
||||
public static void appendUiaBridgeWindows(Map<String, WindowInfo> infoList)
|
||||
{
|
||||
//Enumerate WPF, WinForm, Silverlight windows and add to list
|
||||
if (!SynthuseDlg.config.isUiaBridgeDisabled())
|
||||
{
|
||||
UiaBridge uiabridge = new UiaBridge();
|
||||
Map<String, WindowInfo> uiaInfoList = new LinkedHashMap<String, WindowInfo>();
|
||||
for (String handle : infoList.keySet()) {
|
||||
if (infoList.get(handle).useUiaBridge) {
|
||||
uiaInfoList.putAll(EnumerateWindowsWithUiaBridge(uiabridge, handle, "*"));
|
||||
}
|
||||
}
|
||||
infoList.putAll(uiaInfoList);
|
||||
}
|
||||
//return infoList;
|
||||
}
|
||||
|
||||
public static Map<String, WindowInfo> EnumerateWin32ChildWindows(HWND parentHwnd)
|
||||
{
|
||||
final Map<String, WindowInfo> infoList = new LinkedHashMap<String, WindowInfo>();
|
||||
|
||||
class ChildWindowCallback implements WinUser.WNDENUMPROC {
|
||||
@Override
|
||||
public boolean callback(HWND hWnd, Pointer lParam) {
|
||||
WindowInfo wi = new WindowInfo(hWnd, true);
|
||||
infoList.put(wi.hwndStr, wi);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Api.User32Ex.instance.EnumChildWindows(parentHwnd, new ChildWindowCallback(), new Pointer(0));
|
||||
|
||||
return infoList;
|
||||
}
|
||||
|
||||
public static String generateWindowsXml(Map<String, WindowInfo> infoList, String rootElementName)
|
||||
{
|
||||
final Map<String, String> processList = new LinkedHashMap<String, String>();
|
||||
int wpfCount = 0;
|
||||
int winFormCount = 0;
|
||||
int silverlightCount = 0;
|
||||
int menuCount = 0;
|
||||
// convert window info list to xml dom
|
||||
try {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
|
||||
// root elements
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element rootElement = doc.createElement(rootElementName);
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
long parentCount = 0;
|
||||
long childCount = 0;
|
||||
for (String handle : infoList.keySet()) {
|
||||
WindowInfo w = infoList.get(handle);
|
||||
//System.out.println(w);
|
||||
// create new win xml element
|
||||
Element win = null;
|
||||
if (w.framework.equals("win32"))
|
||||
win = doc.createElement("win");
|
||||
else if (w.framework.equals(UiaBridge.FRAMEWORK_ID_WPF))
|
||||
{
|
||||
win = doc.createElement("wpf");
|
||||
++wpfCount;
|
||||
}
|
||||
else if (w.framework.equals(UiaBridge.FRAMEWORK_ID_WINFORM))
|
||||
{
|
||||
win = doc.createElement("winfrm");
|
||||
++winFormCount;
|
||||
}
|
||||
else if (w.framework.equals(UiaBridge.FRAMEWORK_ID_SILVER))
|
||||
{
|
||||
win = doc.createElement("silver");
|
||||
++silverlightCount;
|
||||
}
|
||||
else
|
||||
win = doc.createElement("win");
|
||||
//System.out.println(w.toString());
|
||||
|
||||
win.setAttribute("hwnd", w.hwndStr);
|
||||
win.setAttribute("text", w.text);
|
||||
if (w.value != "" && w.value != null)
|
||||
win.setAttribute("value", w.value);
|
||||
if (w.text != null)
|
||||
win.setAttribute("TEXT", w.text.toUpperCase());
|
||||
win.setAttribute("class", w.className);
|
||||
if (w.className != null)
|
||||
win.setAttribute("CLASS", w.className.toUpperCase());
|
||||
if (w.controlType != null)
|
||||
if (!w.controlType.isEmpty())
|
||||
win.setAttribute("type", w.controlType);
|
||||
if (!w.isChild) {
|
||||
//win.setAttribute("parent", "yes");
|
||||
parentCount++;
|
||||
if (w.processName != null && !w.processName.isEmpty()) {
|
||||
if (!processList.containsKey(w.pid+""))
|
||||
processList.put(w.pid+"", w.hwndStr);
|
||||
win.setAttribute("process", w.processName);
|
||||
if (w.processName != null)
|
||||
win.setAttribute("PROCESS", w.processName.toUpperCase());
|
||||
}
|
||||
if (w.pid != 0)
|
||||
{
|
||||
if (w.is64bit)
|
||||
win.setAttribute("bits", "64");
|
||||
else
|
||||
win.setAttribute("bits", "32");
|
||||
}
|
||||
}
|
||||
if (w.pid != 0)
|
||||
win.setAttribute("pid", w.pid+"");
|
||||
//else
|
||||
//win.setAttribute("parent", w.parent + ""); // not really needed since child node is append to parent node
|
||||
|
||||
|
||||
if (w.extra != null) {
|
||||
for(String extraName: w.extra.keySet()) {
|
||||
win.setAttribute(extraName, w.extra.get(extraName)+"");
|
||||
}
|
||||
}
|
||||
|
||||
if (w.menus > 0) {
|
||||
win.setAttribute("menus", w.menus+"");
|
||||
//String menuStr = MenuInfo.GetHandleMenuAsString(w.menu);
|
||||
buildMenuXmlElements(doc, win, w.menu, w.hwndStr);
|
||||
++menuCount;
|
||||
}
|
||||
|
||||
if (w.isChild && infoList.containsKey(w.parentStr)) {
|
||||
childCount++;
|
||||
WindowInfo parentWi = infoList.get(w.parentStr);
|
||||
if (parentWi.xmlObj != null)
|
||||
((Element)parentWi.xmlObj).appendChild(win);
|
||||
else
|
||||
rootElement.appendChild(win);
|
||||
}
|
||||
else
|
||||
rootElement.appendChild(win);
|
||||
w.xmlObj = win;
|
||||
|
||||
}
|
||||
|
||||
// calculate totals on various windows.
|
||||
Element totals = doc.createElement("totals");
|
||||
totals.setAttribute("parentCount", parentCount+"");
|
||||
totals.setAttribute("childCount", childCount+"");
|
||||
totals.setAttribute("windowCount", infoList.size()+"");
|
||||
//totals.setAttribute("wpfWrapperCount", wpfParentList.size()+"");
|
||||
totals.setAttribute("wpfCount", wpfCount+"");
|
||||
totals.setAttribute("winFormCount", winFormCount+"");
|
||||
totals.setAttribute("silverlightCount", silverlightCount+"");
|
||||
totals.setAttribute("menuCount", menuCount+"");
|
||||
totals.setAttribute("processCount", processList.size()+"");
|
||||
totals.setAttribute("updatedLast", new Timestamp((new Date()).getTime()) + "");
|
||||
rootElement.appendChild(totals);
|
||||
String output = nodeToString(rootElement);
|
||||
//System.out.println("count - " + infoList.size() + "\r\n");
|
||||
return output;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
lastException = e;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static Element buildMenuXmlElements(Document xmlDoc, Element xmlElement, HMENU targetMenu, String targetWin)
|
||||
{
|
||||
MenuInfo firstMi = new MenuInfo(targetWin, targetMenu);
|
||||
for (int i = 0 ; i < firstMi.menuCount ; i++ ) {
|
||||
MenuInfo menuInfo = new MenuInfo(targetWin, targetMenu, i);
|
||||
Element menuElement = xmlDoc.createElement("menu");
|
||||
menuElement.setAttribute("unaltered", menuInfo.unaltered + "");
|
||||
menuElement.setAttribute("text", menuInfo.text + "");
|
||||
menuElement.setAttribute("id", menuInfo.id + "");
|
||||
menuElement.setAttribute("position", menuInfo.position + "");
|
||||
menuElement.setAttribute("hmenu", menuInfo.hmenuStr + "");
|
||||
menuElement.setAttribute("hwnd", menuInfo.hwndStr + "");
|
||||
if (!menuInfo.center.isEmpty())
|
||||
menuElement.setAttribute("center", menuInfo.center + "");
|
||||
if (menuInfo.hasSubMenu) {
|
||||
buildMenuXmlElements(xmlDoc, menuElement, menuInfo.submenu, targetWin);
|
||||
}
|
||||
xmlElement.appendChild(menuElement);
|
||||
}
|
||||
return xmlElement;
|
||||
}
|
||||
|
||||
public static Map<String, WindowInfo> EnumerateWindowsWithUiaBridge(UiaBridge uiabridge, String parentHwndStr, String frameworkType) {
|
||||
final Map<String, WindowInfo> infoList = new LinkedHashMap<String, WindowInfo>();
|
||||
//WpfBridge wb = new WpfBridge();
|
||||
//wpf.setFrameworkId(frameworkType);
|
||||
long hwnd = Long.parseLong(parentHwndStr);
|
||||
//System.out.println("getRuntimeIdFromHandle of " + hwnd);
|
||||
String parentRuntimeId = uiabridge.getWindowInfo((int) hwnd, WindowInfo.UIA_RUNTIME_ID);
|
||||
//System.out.println("runtimeId=" + runtimeId);
|
||||
String[] allIds = null;
|
||||
if (SynthuseDlg.config.isFilterUiaDisabled())
|
||||
allIds = uiabridge.enumWindowInfo((int) hwnd, "*");
|
||||
else
|
||||
allIds = uiabridge.enumWindowInfo((int) hwnd, WindowInfo.UIA_PROPERTY_LIST);
|
||||
if (allIds == null)
|
||||
return infoList; //empty list
|
||||
//System.out.println("enumDescendantWindowIds " + allIds.length);
|
||||
for(String runtimeIdAndInfo : allIds) {
|
||||
//System.out.println("getting window info for: " + runtimeIdAndInfo);
|
||||
WindowInfo wi = new WindowInfo(runtimeIdAndInfo, true);
|
||||
if (wi.parentStr.equals(parentRuntimeId))
|
||||
wi.parentStr = parentHwndStr;
|
||||
//System.out.println("is parent? " + onlyRuntimeId);
|
||||
infoList.put(wi.runtimeId, wi);
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
|
||||
public static String escapeXmlAttributeValue(String unescapedStr) {
|
||||
String result = "";
|
||||
try {
|
||||
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
|
||||
// root elements
|
||||
Document doc = docBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("temp");
|
||||
doc.appendChild(rootElement);
|
||||
Attr attribute = doc.createAttribute("attrib");
|
||||
attribute.setNodeValue(unescapedStr);
|
||||
rootElement.setAttributeNode(attribute);
|
||||
result = nodeToString(rootElement);
|
||||
result = result.replaceAll("[^\"]*\"([^\"]*)\"[^\"]*", "$1"); // keep the string within quotes.
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
//lastException = e;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String nodeToString(Node node) {
|
||||
StringWriter sw = new StringWriter();
|
||||
try {
|
||||
Transformer t = TransformerFactory.newInstance().newTransformer();
|
||||
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
t.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
|
||||
t.transform(new DOMSource(node), new StreamResult(sw));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
lastException = e;
|
||||
}
|
||||
return sw.toString();
|
||||
}
|
||||
|
||||
public static String queryWindowInfoXml(String xpathExpr) {
|
||||
String nl = System.getProperty("line.separator");
|
||||
String result = "<result>" + nl;
|
||||
String xml = getXml();
|
||||
List<String> resultList = evaluateXpathGetValues(xml, xpathExpr);
|
||||
for(String item: resultList) {
|
||||
result += " " + item;
|
||||
}
|
||||
result += "</result>" + nl;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static HWND queryHandleWindowInfoXml(String xpathExpr) {
|
||||
String xml = getXml();
|
||||
String result = "";
|
||||
List<String> resultList = evaluateXpathGetValues(xml, xpathExpr);
|
||||
for(String item: resultList) {
|
||||
if (item.contains("hwnd")) {
|
||||
List<String> hwndList = evaluateXpathGetValues(item, "//@hwnd");
|
||||
result = hwndList.get(0);
|
||||
}
|
||||
else
|
||||
result = item;
|
||||
break;
|
||||
}
|
||||
return Api.GetHandleFromString(result);
|
||||
}
|
||||
|
||||
|
||||
public static List<String> evaluateXpathGetValues(String xml, String xpathExpr) {
|
||||
List<String> resultLst = new ArrayList<String>();
|
||||
try {
|
||||
InputSource inSource = new InputSource(new StringReader(xml));
|
||||
XPathFactory factory = XPathFactory.newInstance();
|
||||
XPath xpath = factory.newXPath();
|
||||
XPathExpression expr = xpath.compile(xpathExpr);
|
||||
|
||||
Object result = expr.evaluate(inSource, XPathConstants.NODESET);
|
||||
NodeList nodes = (NodeList) result;
|
||||
for (int i = 0; i < nodes.getLength(); i++) {
|
||||
String val = nodes.item(i).getNodeValue();
|
||||
if (val == null) // if we can't get a string value try to transform the xml node to a string
|
||||
val = nodeToString(nodes.item(i));
|
||||
else
|
||||
val += System.getProperty("line.separator");
|
||||
resultLst.add(val);
|
||||
//System.out.println("match " + i + ": " + val);
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
lastException = e;
|
||||
}
|
||||
return resultLst;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,209 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
/* Example:
|
||||
|
||||
// Set editor kit
|
||||
jtextpane.setEditorKitForContentType("text/xml", new XmlEditorKit());
|
||||
jtextpane.setContentType("text/xml");
|
||||
|
||||
*/
|
||||
|
||||
public class XmlEditorKit extends StyledEditorKit {
|
||||
|
||||
private static final long serialVersionUID = 2969169649596107757L;
|
||||
private ViewFactory xmlViewFactory;
|
||||
|
||||
private static HashMap<Pattern, Color> patternColors;
|
||||
private static String TAG_PATTERN = "(</?[a-z]*)\\s?>?";
|
||||
private static String TAG_END_PATTERN = "(/>)";
|
||||
private static String TAG_ATTRIBUTE_PATTERN = "\\s([a-zA-Z0-9]*)\\s*?\\=\\s*?\\\"";
|
||||
private static String TAG_ATTRIBUTE_VALUE = "[a-zA-Z0-9]*\\=(\"[^\"]*\")";
|
||||
private static String TAG_COMMENT = "(<!--.*-->)";
|
||||
private static String TAG_CDATA_START = "(\\<!\\[CDATA\\[).*";
|
||||
private static String TAG_CDATA_END = ".*(]]>)";
|
||||
|
||||
//public static String TAG_HIGHLIGHTED = ".*hwnd=\"([^\"]*)\".*";
|
||||
public static String TAG_HIGHLIGHTED = "";
|
||||
public static Color TAG_HIGHLIGHTED_COLOR = new Color(170, 255, 48);
|
||||
|
||||
public static int HIGHLIGHTED_START = 0;
|
||||
public static int HIGHLIGHTED_END = 0;
|
||||
public static Color HIGHLIGHTED_COLOR = new Color(240, 255, 112);
|
||||
|
||||
static {
|
||||
// NOTE: the order is important!
|
||||
patternColors = new HashMap<Pattern, Color>();
|
||||
patternColors.put(Pattern.compile(TAG_CDATA_START), new Color(128, 128, 128));
|
||||
patternColors.put(Pattern.compile(TAG_CDATA_END), new Color(128, 128, 128));
|
||||
patternColors.put(Pattern.compile(TAG_PATTERN), new Color(63, 127, 127));
|
||||
patternColors.put(Pattern.compile(TAG_ATTRIBUTE_PATTERN), new Color(127, 0, 127));
|
||||
patternColors.put(Pattern.compile(TAG_END_PATTERN), new Color(63, 127, 127));
|
||||
patternColors.put(Pattern.compile(TAG_ATTRIBUTE_VALUE), new Color(42, 0, 255));
|
||||
patternColors.put(Pattern.compile(TAG_COMMENT), new Color(63, 95, 191));
|
||||
}
|
||||
|
||||
|
||||
class XmlView extends PlainView {
|
||||
|
||||
|
||||
public XmlView(Element element) {
|
||||
|
||||
super(element);
|
||||
|
||||
// Set tabsize to 4 (instead of the default 8)
|
||||
getDocument().putProperty(PlainDocument.tabSizeAttribute, 4);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int drawUnselectedText(Graphics graphics, int x, int y, int p0, int p1) throws BadLocationException {
|
||||
try {
|
||||
|
||||
Document doc = getDocument();
|
||||
String text = doc.getText(p0, p1 - p0);
|
||||
|
||||
Segment segment = getLineBuffer();
|
||||
int initialXpos = x;
|
||||
|
||||
SortedMap<Integer, Integer> startMap = new TreeMap<Integer, Integer>();
|
||||
SortedMap<Integer, Color> colorMap = new TreeMap<Integer, Color>();
|
||||
|
||||
// Match all regexes on this snippet, store positions
|
||||
for (Map.Entry<Pattern, Color> entry : patternColors.entrySet()) {
|
||||
|
||||
Matcher matcher = entry.getKey().matcher(text);
|
||||
|
||||
while (matcher.find()) {
|
||||
startMap.put(matcher.start(1), matcher.end(1));
|
||||
colorMap.put(matcher.start(1), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check the map for overlapping parts
|
||||
|
||||
int i = 0;
|
||||
//add tag highlighted background colors
|
||||
if (!TAG_HIGHLIGHTED.isEmpty()) {
|
||||
Matcher highlightMatcher = Pattern.compile(TAG_HIGHLIGHTED).matcher(text);
|
||||
while(highlightMatcher.find()) {
|
||||
int start = highlightMatcher.start(1);
|
||||
int end = highlightMatcher.end(1);
|
||||
if (i < start) {
|
||||
graphics.setColor(Color.black);
|
||||
doc.getText(p0 + i, start - i, segment);
|
||||
x = Utilities.drawTabbedText(segment, x, y, graphics, this, i);
|
||||
}
|
||||
graphics.setColor(TAG_HIGHLIGHTED_COLOR);
|
||||
i = end;
|
||||
doc.getText(p0 + start, i - start, segment);
|
||||
int width = Utilities.getTabbedTextWidth(segment, graphics.getFontMetrics(), x, this, p0 + start);
|
||||
//graphics.drawLine(x, y, width, y);graphics.getFontMetrics()
|
||||
graphics.fillRect(x, y - graphics.getFontMetrics().getHeight() + 2, width, graphics.getFontMetrics().getHeight());
|
||||
graphics.setColor(Color.black);
|
||||
doc.getText(p0 + start, i - start, segment);
|
||||
x = Utilities.drawTabbedText(segment, x, y, graphics, this, start);
|
||||
}
|
||||
}
|
||||
x = initialXpos;
|
||||
i=0;
|
||||
//add highlighted background colors based on position
|
||||
//String textx = doc.getText(p0, p1 - p0);
|
||||
if ((HIGHLIGHTED_START < p1 && HIGHLIGHTED_START >= p0) || (HIGHLIGHTED_END <= p1 && HIGHLIGHTED_END > p0) || ( HIGHLIGHTED_START < p1 && HIGHLIGHTED_END > p0)) {
|
||||
//select whole line
|
||||
int start = 0;
|
||||
int end = text.length();
|
||||
// test to see if only partial line is needed.
|
||||
if (HIGHLIGHTED_START > p0)
|
||||
start = HIGHLIGHTED_START - p0;
|
||||
if (HIGHLIGHTED_END < p1)
|
||||
end -= p1 - HIGHLIGHTED_END;
|
||||
if (i < start) { // fill in normal color if start highlight isn't at the beginning
|
||||
graphics.setColor(Color.black);
|
||||
doc.getText(p0 + i, start - i, segment);
|
||||
x = Utilities.drawTabbedText(segment, x, y, graphics, this, i);
|
||||
}
|
||||
graphics.setColor(HIGHLIGHTED_COLOR);// fill in the highlight color
|
||||
i = end;
|
||||
if (i - start > 0) {
|
||||
doc.getText(p0 + start, i - start, segment);
|
||||
int width = Utilities.getTabbedTextWidth(segment, graphics.getFontMetrics(), x, this, p0 + start);
|
||||
//graphics.drawLine(x, y, width, y);graphics.getFontMetrics()
|
||||
graphics.fillRect(x, y - graphics.getFontMetrics().getHeight() + 2, width, graphics.getFontMetrics().getHeight());
|
||||
graphics.setColor(Color.black);
|
||||
doc.getText(p0 + start, i - start, segment);
|
||||
x = Utilities.drawTabbedText(segment, x, y, graphics, this, start);
|
||||
}
|
||||
//else
|
||||
// System.out.println("invalid highlighting " + (i - start) + " is <= 0 (" + p0 + "-" + p1 + "=" + (p1 - p0) +") " + start + ", " + end + " len=" + text.length());
|
||||
}
|
||||
|
||||
x = initialXpos;
|
||||
i=0;
|
||||
// Color the parts of xml foreground font
|
||||
for (Map.Entry<Integer, Integer> entry : startMap.entrySet()) {
|
||||
int start = entry.getKey();
|
||||
int end = entry.getValue();
|
||||
|
||||
if (i < start) {
|
||||
graphics.setColor(Color.black);
|
||||
doc.getText(p0 + i, start - i, segment);
|
||||
x = Utilities.drawTabbedText(segment, x, y, graphics, this, i);
|
||||
}
|
||||
|
||||
graphics.setColor(colorMap.get(start));
|
||||
i = end;
|
||||
doc.getText(p0 + start, i - start, segment);
|
||||
x = Utilities.drawTabbedText(segment, x, y, graphics, this, start);
|
||||
}
|
||||
|
||||
|
||||
// Paint possible remaining text black
|
||||
if (i < text.length()) {
|
||||
graphics.setColor(Color.black);
|
||||
doc.getText(p0 + i, text.length() - i, segment);
|
||||
x = Utilities.drawTabbedText(segment, x, y, graphics, this, i);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class XmlViewFactory extends Object implements ViewFactory {
|
||||
/**
|
||||
* @see javax.swing.text.ViewFactory#create(javax.swing.text.Element)
|
||||
*/
|
||||
public View create(Element element) {
|
||||
|
||||
return new XmlView(element);
|
||||
}
|
||||
}
|
||||
|
||||
public XmlEditorKit() {
|
||||
xmlViewFactory = new XmlViewFactory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ViewFactory getViewFactory() {
|
||||
return xmlViewFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getContentType() {
|
||||
return "text/xml";
|
||||
}
|
||||
}
|
||||
@@ -1,292 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JTextPane;
|
||||
|
||||
import org.synthuse.Api.User32Ex;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
|
||||
public class XpathManager implements Runnable{
|
||||
|
||||
private HWND hwnd = null;
|
||||
private String enumProperties = null;
|
||||
private JTextPane windowsXmlTextPane = null;
|
||||
|
||||
public static interface Events {
|
||||
void statusChanged(String status);
|
||||
void executionCompleted(Object input, String results);
|
||||
}
|
||||
public Events events = new Events() {
|
||||
public void statusChanged(String status){
|
||||
System.out.println(status);
|
||||
}
|
||||
public void executionCompleted(Object input, String results){
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
public XpathManager(HWND hwnd, JTextPane windowsXmlTextPane, Events events) {
|
||||
this.events = events;
|
||||
this.hwnd = hwnd;
|
||||
this.windowsXmlTextPane = windowsXmlTextPane;
|
||||
}
|
||||
|
||||
public XpathManager(HWND hwnd, String enumProperties, JTextPane windowsXmlTextPane, Events events) {
|
||||
this.events = events;
|
||||
this.hwnd = hwnd;
|
||||
this.enumProperties = enumProperties;
|
||||
this.windowsXmlTextPane = windowsXmlTextPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String results = SynthuseDlg.config.isUseStrongTextMatching()?buildXpathStatement(true,50,50):buildXpathStatement();
|
||||
events.executionCompleted(hwnd, results);
|
||||
}
|
||||
|
||||
public static void buildXpathStatementThreaded(HWND hwnd, JTextPane windowsXmlTextPane, Events events) {
|
||||
Thread t = new Thread(new XpathManager(hwnd, windowsXmlTextPane, events));
|
||||
t.start();
|
||||
}
|
||||
|
||||
public static void buildXpathStatementThreaded(HWND hwnd, String runtimeId, JTextPane windowsXmlTextPane, Events events) {
|
||||
Thread t = new Thread(new XpathManager(hwnd, runtimeId, windowsXmlTextPane, events));
|
||||
t.start();
|
||||
}
|
||||
|
||||
public String compareLongTextString(String rawText) {
|
||||
String escapedTxtStr = WindowsEnumeratedXml.escapeXmlAttributeValue(rawText);
|
||||
if (!escapedTxtStr.isEmpty()) {
|
||||
if (rawText.length() > 20) {// if the raw text is too long only test the first 20 characters
|
||||
escapedTxtStr = WindowsEnumeratedXml.escapeXmlAttributeValue(rawText.substring(0, 20));
|
||||
}
|
||||
}
|
||||
return escapedTxtStr;
|
||||
}
|
||||
|
||||
public String buildUiaXpathStatement() {
|
||||
if (enumProperties == null)
|
||||
return "";
|
||||
if (enumProperties.isEmpty())
|
||||
return "";
|
||||
String builtXpath = "";
|
||||
String xml = this.windowsXmlTextPane.getText();
|
||||
|
||||
WindowInfo wi = new WindowInfo(enumProperties, true);
|
||||
String onlyRuntimeIdXpath = "//*[@hwnd='" + wi.runtimeId + "']";
|
||||
List<String> wpfResultList = WindowsEnumeratedXml.evaluateXpathGetValues(xml, onlyRuntimeIdXpath);
|
||||
//System.out.println("evaluateXpathGetValues1: " + onlyRuntimeIdXpath + " = " + wpfResultList.size());
|
||||
if (wpfResultList.size() == 0)
|
||||
return"";
|
||||
//System.out.println("enumProperties: " + enumProperties);
|
||||
String typeStr = wi.controlType;
|
||||
String txtOrig = wi.text;
|
||||
//String winValueOrig = wpf.getWindowValue(runtimeId);
|
||||
//System.out.println("text: " + txtOrig);
|
||||
String txtStr = compareLongTextString(txtOrig);
|
||||
|
||||
builtXpath = "//*[@type='" + typeStr + "' and starts-with(@text,'" + txtStr + "')" + "]";
|
||||
|
||||
//builtXpath = "//*[@hwnd='" + runtimeId + "']";
|
||||
wpfResultList = WindowsEnumeratedXml.evaluateXpathGetValues(xml, builtXpath);
|
||||
//System.out.println("evaluateXpathGetValues2: " + builtXpath + " = " + wpfResultList.size());
|
||||
if (wpfResultList.size() == 1)
|
||||
return builtXpath;
|
||||
return onlyRuntimeIdXpath;
|
||||
}
|
||||
|
||||
public String buildXpathStatement() {
|
||||
return buildXpathStatement(false, 20, 30);
|
||||
}
|
||||
|
||||
public String buildXpathStatement(boolean useFullTextMatching, int maxParentTextLength, int maxTextLength) {
|
||||
String builtXpath = "";
|
||||
try {
|
||||
String xml = this.windowsXmlTextPane.getText();
|
||||
if (enumProperties != null && !SynthuseDlg.config.isUiaBridgeDisabled()) {
|
||||
if (!enumProperties.isEmpty()) {
|
||||
builtXpath = buildUiaXpathStatement();
|
||||
}
|
||||
}
|
||||
if (builtXpath != "")
|
||||
return builtXpath;
|
||||
String classStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.getWindowClassName(hwnd));
|
||||
String handleStr = Api.GetHandleAsString(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 = User32Ex.instance.GetParent(hwnd);
|
||||
String parentClassStr = WindowsEnumeratedXml.escapeXmlAttributeValue(Api.getWindowClassName(parent));
|
||||
String parentTxtOrig = Api.getWindowText(parent);
|
||||
String parentTxtStr = WindowsEnumeratedXml.escapeXmlAttributeValue(parentTxtOrig);
|
||||
if (!parentTxtStr.isEmpty()) {
|
||||
if (parentTxtOrig.length() > maxParentTextLength) {// if the parent text is too long only test the first maxParentTextLength characters
|
||||
parentTxtStr = WindowsEnumeratedXml.escapeXmlAttributeValue(parentTxtOrig.substring(0, maxParentTextLength));
|
||||
parentTxtStr = " and starts-with(@text,'" + parentTxtStr + "')";
|
||||
}
|
||||
else
|
||||
parentTxtStr = " and @text='" + parentTxtStr + "'";
|
||||
}
|
||||
if (!parentClassStr.isEmpty())
|
||||
{
|
||||
if (!txtStr.isEmpty()&&useFullTextMatching) {
|
||||
String copyOfTxtStr = txtStr;
|
||||
if (copyOfTxtStr.length() > maxTextLength) {// if the text is too long only test the first maxTextLength characters
|
||||
copyOfTxtStr = WindowsEnumeratedXml.escapeXmlAttributeValue(copyOfTxtStr.substring(0, maxTextLength));
|
||||
copyOfTxtStr = " and starts-with(@text,'" + copyOfTxtStr + "')";
|
||||
}
|
||||
else
|
||||
copyOfTxtStr = " and @text='" + copyOfTxtStr + "'";
|
||||
builtXpath = "//win[@class='" + parentClassStr + "'" + parentTxtStr + "]/win[@class='" + classStr + "'" + copyOfTxtStr + "]";
|
||||
}
|
||||
else
|
||||
{
|
||||
builtXpath = "//win[@class='" + parentClassStr + "'" + parentTxtStr + "]/win[@class='" + classStr + "']";
|
||||
}
|
||||
}
|
||||
System.out.println(builtXpath);
|
||||
resultList = WindowsEnumeratedXml.evaluateXpathGetValues(xml, builtXpath);
|
||||
if (resultList.size() > 1) { // if there are still multiple results add position to the xpath
|
||||
int position = 1;
|
||||
for (String result : resultList) {
|
||||
if (result.contains(handleStr)) {
|
||||
builtXpath += "[" + position + "]";
|
||||
break;
|
||||
}
|
||||
++position;
|
||||
}
|
||||
}
|
||||
if (resultList.size() == 0) { //some reason a window might have a parent window that is not associated with it's child (orphans!!)
|
||||
if (!txtStr.isEmpty()) {
|
||||
if (txtStr.length() > maxTextLength) {// if the text is too long only test the first maxTextLength characters
|
||||
txtStr = WindowsEnumeratedXml.escapeXmlAttributeValue(txtStr.substring(0, maxTextLength));
|
||||
txtStr = " and starts-with(@text,'" + txtStr + "')";
|
||||
}
|
||||
else
|
||||
txtStr = " and @text='" + txtStr + "'";
|
||||
}
|
||||
builtXpath = "//win[@class='" + classStr + "'" + txtStr + "]";
|
||||
}
|
||||
resultList = WindowsEnumeratedXml.evaluateXpathGetValues(xml, builtXpath);
|
||||
if (resultList.size() > 1) //still too many matched, only use hwnd
|
||||
builtXpath = "//win[@hwnd='" + handleStr + "']";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return builtXpath;
|
||||
}
|
||||
|
||||
public static int nextXpathMatch(String xpathExpr, JTextPane targetText, JLabel lblStatus, boolean alwaysFromTop) {
|
||||
int results = 0;
|
||||
try {
|
||||
if (xpathExpr.length() == 0)
|
||||
return results;
|
||||
|
||||
if (targetText instanceof JTextPane) {
|
||||
final JTextPane target = (JTextPane)targetText;
|
||||
target.requestFocus();
|
||||
int cPos = 0;
|
||||
try {
|
||||
cPos = target.getCaretPosition();
|
||||
} catch(Exception ex) {
|
||||
//return 0;//something is throwing nullpointer exception
|
||||
}
|
||||
if (alwaysFromTop)
|
||||
cPos = 0;
|
||||
int len = target.getStyledDocument().getLength();
|
||||
String xml = target.getText(0, len);
|
||||
WindowsEnumeratedXml.lastException = null;
|
||||
List<String> resultList = WindowsEnumeratedXml.evaluateXpathGetValues(xml, xpathExpr);
|
||||
if (resultList.size() == 0 && WindowsEnumeratedXml.lastException != null) {
|
||||
String errMsg = WindowsEnumeratedXml.lastException.getCause().getMessage();
|
||||
JOptionPane.showMessageDialog(target.getTopLevelAncestor(), "Exception: " + errMsg, "Error", JOptionPane.ERROR_MESSAGE);
|
||||
return -1;
|
||||
}
|
||||
results = resultList.size();
|
||||
String txt = "";
|
||||
String targetStr = target.getText(cPos, (len - cPos));
|
||||
int matches = 0;
|
||||
int mPos = 0;
|
||||
target.select(cPos, cPos); //clear selection
|
||||
for (int i = 0; i < resultList.size(); i++) {
|
||||
txt = resultList.get(i).trim();
|
||||
if (txt.length() == 0)
|
||||
continue;
|
||||
//if (txt.endsWith("\r\n"))
|
||||
// txt = txt.substring(0, txt.length() - 2).trim();
|
||||
txt = txt.replaceAll("\r\n", "\n").trim();
|
||||
while ((mPos = targetStr.indexOf(txt)) != -1) {
|
||||
if (matches == 0){
|
||||
if (!alwaysFromTop)
|
||||
flashMatchingWindow(txt);
|
||||
//target.setCaretPosition(cPos + mPos);
|
||||
//target.select(cPos + mPos, cPos + mPos + txt.length());
|
||||
XmlEditorKit.HIGHLIGHTED_START = cPos + mPos;
|
||||
XmlEditorKit.HIGHLIGHTED_END = cPos + mPos + txt.length();
|
||||
//System.out.println("HIGHLIGHTED_START = " + (cPos + mPos));
|
||||
//System.out.println("HIGHLIGHTED_END = " + (cPos + mPos + txt.length()));
|
||||
final int cpos = cPos + mPos +2;
|
||||
EventQueue.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
target.updateUI();
|
||||
target.setCaretPosition(cpos);
|
||||
}
|
||||
});
|
||||
}
|
||||
targetStr = targetStr.substring(mPos + txt.length());
|
||||
++matches;
|
||||
}
|
||||
}
|
||||
lblStatus.setText(results + " match(es)");
|
||||
if (cPos > 0 && matches == 0 && !alwaysFromTop) { //ask if user wants to search from top
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
XmlEditorKit.HIGHLIGHTED_START = 0;
|
||||
XmlEditorKit.HIGHLIGHTED_END = 0;
|
||||
e.printStackTrace();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
public static void flashMatchingWindow(String txtXml) {
|
||||
if (txtXml.contains("hwnd")) {
|
||||
List<String> hwndList = WindowsEnumeratedXml.evaluateXpathGetValues(txtXml, "//@hwnd");
|
||||
if (hwndList.size() > 0) {
|
||||
String hwndStr = hwndList.get(0);
|
||||
HWND tHwnd = Api.GetHandleFromString(hwndStr);
|
||||
Api.highlightWindow(tHwnd);
|
||||
try { Thread.sleep(100); } catch (Exception e) {e.printStackTrace();}
|
||||
Api.refreshWindow(tHwnd);
|
||||
try { Thread.sleep(100); } catch (Exception e) {e.printStackTrace();}
|
||||
Api.highlightWindow(tHwnd);
|
||||
try { Thread.sleep(100); } catch (Exception e) {e.printStackTrace();}
|
||||
Api.refreshWindow(tHwnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,311 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse.commands;
|
||||
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.synthuse.*;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
|
||||
public class BaseCommand {
|
||||
|
||||
static String WIN_XML = "";
|
||||
static long LAST_UPDATED_XML = 0;
|
||||
|
||||
protected Api api = new Api();
|
||||
protected UiaBridge uiabridge = new UiaBridge();
|
||||
protected CommandProcessor parentProcessor = null;
|
||||
|
||||
protected int getExecuteErrorCount() {
|
||||
return parentProcessor.executeErrorCount;
|
||||
}
|
||||
|
||||
protected void setExecuteErrorCount(int val) {
|
||||
parentProcessor.executeErrorCount = val;
|
||||
}
|
||||
|
||||
protected String getCurrentCommand() {
|
||||
return parentProcessor.currentCommandText;
|
||||
}
|
||||
|
||||
protected void setCurrentCommand(String val) {
|
||||
parentProcessor.currentCommandText = val;
|
||||
}
|
||||
|
||||
protected boolean isProcessorStopped() {
|
||||
return CommandProcessor.STOP_PROCESSOR.get();
|
||||
}
|
||||
|
||||
public BaseCommand(CommandProcessor cp) { // should pass in the parent command processor
|
||||
parentProcessor = cp;
|
||||
}
|
||||
|
||||
public void appendError(Exception e) {
|
||||
setExecuteErrorCount(getExecuteErrorCount() + 1);
|
||||
StringWriter sw = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(sw));
|
||||
parentProcessor.lastError += new Timestamp((new Date()).getTime()) + " - " + sw.toString() + "\n";
|
||||
try {
|
||||
sw.close();
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void appendError(String msg) {
|
||||
setExecuteErrorCount(getExecuteErrorCount() + 1);
|
||||
parentProcessor.lastError += new Timestamp((new Date()).getTime()) + " - " + msg + "\n";
|
||||
}
|
||||
|
||||
public boolean checkArgumentLength(String[] args, int expectedLength) {
|
||||
if (args.length < expectedLength) {
|
||||
appendError("Error: expected at least " + expectedLength + " arguments (" + getCurrentCommand() + "[" + args.length + "])");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean checkFirstArgumentLength(String[] args) {
|
||||
if (args[0].length() <= 0) {
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed, expected first argument length > 0");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean checkIsNumeric(String val) {
|
||||
try {
|
||||
Long.parseLong(val);
|
||||
} catch(NumberFormatException e) {
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed, was expecting a numeric value instead '" + val + "'");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean whenFalseAppendError(boolean cmdResult) {
|
||||
if (!cmdResult)
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed");
|
||||
return cmdResult;
|
||||
}
|
||||
|
||||
public void forceXmlRefresh() {
|
||||
WIN_XML = WindowsEnumeratedXml.getXml();
|
||||
LAST_UPDATED_XML = System.nanoTime();
|
||||
}
|
||||
|
||||
public void forceWin32OnlyXmlRefresh() {
|
||||
WIN_XML = WindowsEnumeratedXml.getWin32Xml();
|
||||
LAST_UPDATED_XML = System.nanoTime();
|
||||
}
|
||||
|
||||
public void onlyRefreshWin32(boolean flg) {
|
||||
SynthuseDlg.config.disableUiaBridge = flg + "";
|
||||
}
|
||||
|
||||
public void targetXmlRefresh(String xpath) {
|
||||
if (WIN_XML.isEmpty()) //can't target refresh unless there is XML to start with
|
||||
{
|
||||
forceXmlRefresh();
|
||||
return;
|
||||
}
|
||||
//WIN_XML = WindowsEnumeratedXml.getXml();
|
||||
LAST_UPDATED_XML = System.nanoTime();
|
||||
|
||||
String resultStr = "";
|
||||
String resultHwndStr = "";
|
||||
List<String> resultList = WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath);
|
||||
for(String item: resultList) {
|
||||
//System.out.println("xpath result item: " + item);
|
||||
resultStr = item;
|
||||
if (item.contains("hwnd=")) {
|
||||
List<String> hwndList = WindowsEnumeratedXml.evaluateXpathGetValues(item, "//@hwnd");
|
||||
if (hwndList.size() > 0)
|
||||
resultHwndStr = hwndList.get(0).replaceAll("[^\\d-.]", ""); //get first hwnd;
|
||||
}
|
||||
else
|
||||
resultStr = item;
|
||||
break;
|
||||
}
|
||||
String newXml = "";
|
||||
Map<String, WindowInfo> infoList;
|
||||
if (resultHwndStr.contains("-")) { //uiabridge target refresh
|
||||
resultHwndStr = resultHwndStr.split("-")[1];
|
||||
infoList = WindowsEnumeratedXml.EnumerateWindowsWithUiaBridge(uiabridge, resultHwndStr, "*");
|
||||
newXml = WindowsEnumeratedXml.generateWindowsXml(infoList, "updates");
|
||||
//System.out.println("newXml: " + newXml);
|
||||
}
|
||||
else
|
||||
{ // native target refresh
|
||||
infoList = new LinkedHashMap<String, WindowInfo>();
|
||||
HWND parentHwnd = Api.GetHandleFromString(resultHwndStr);
|
||||
WindowInfo wi = new WindowInfo(parentHwnd, false);
|
||||
infoList.put(wi.hwndStr, wi);
|
||||
infoList.putAll(WindowsEnumeratedXml.EnumerateWin32ChildWindows(parentHwnd));
|
||||
//WindowsEnumeratedXml.appendUiaBridgeWindows(infoList); //if we need this we should specify a runtimeID handle instead
|
||||
newXml = WindowsEnumeratedXml.generateWindowsXml(infoList, "updates");
|
||||
System.out.println("newNativeXml: " + newXml);
|
||||
}
|
||||
|
||||
int pos = WIN_XML.indexOf(resultStr);
|
||||
WIN_XML = WIN_XML.substring(0, pos) + newXml + WIN_XML.substring(pos + resultStr.length());
|
||||
|
||||
}
|
||||
|
||||
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<String> resultList = WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath);
|
||||
if (resultList.size() > 0)
|
||||
{
|
||||
resultStr = resultList.get(0).trim();
|
||||
if (resultStr.startsWith("<winfrm "))
|
||||
result = "winfrm";
|
||||
else if(resultStr.startsWith("<win "))
|
||||
result = "win";
|
||||
else if(resultStr.startsWith("<wpf "))
|
||||
result = "wpf";
|
||||
else if(resultStr.startsWith("<silver "))
|
||||
result = "silver";
|
||||
else if(resultStr.startsWith("<menu "))
|
||||
result = "menu";
|
||||
else
|
||||
result = "other";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public WinPtr findHandleWithXpath(String xpath) {
|
||||
return findHandleWithXpath(xpath, false);
|
||||
}
|
||||
|
||||
public WinPtr findHandleWithXpath(String xpath, boolean ignoreFailedFind) {
|
||||
WinPtr result = new WinPtr();
|
||||
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();
|
||||
}
|
||||
//WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath);
|
||||
String resultStr = "";
|
||||
List<String> resultList = WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath);
|
||||
for(String item: resultList) {
|
||||
//System.out.println("xpath result item: " + item);
|
||||
if (item.contains("hwnd=")) {
|
||||
List<String> hwndList = WindowsEnumeratedXml.evaluateXpathGetValues(item, "//@hwnd");
|
||||
if (hwndList.size() > 0)
|
||||
resultStr = hwndList.get(0); //get first hwnd;
|
||||
}
|
||||
else
|
||||
resultStr = item;
|
||||
if (item.contains("hmenu=")) { //get menu information, useful for getting center of menu
|
||||
List<String> hmenuList = WindowsEnumeratedXml.evaluateXpathGetValues(item, "//@hmenu");
|
||||
if (hmenuList.size() > 0)
|
||||
result.hmenuStr = hmenuList.get(0).replaceAll("[^\\d-.]", ""); //get first hmenu;
|
||||
if (item.contains("id=")) {
|
||||
List<String> 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;
|
||||
if (!ignoreFailedFind && result.isEmpty())
|
||||
appendError("Error: Failed to find window handle matching: " + xpath);
|
||||
}
|
||||
else {
|
||||
result.hWnd = Api.GetHandleFromString(resultStr);
|
||||
if (!ignoreFailedFind && !api.user32.IsWindow(result.hWnd))
|
||||
appendError("Error: Failed to locate window HWND(" + resultStr + ") from : " + xpath);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int findMenuIdWithXpath(String xpath) {
|
||||
int result = 0;
|
||||
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();
|
||||
}
|
||||
//WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath);
|
||||
String resultStr = "";
|
||||
List<String> resultList = WindowsEnumeratedXml.evaluateXpathGetValues(WIN_XML, xpath);
|
||||
for(String item: resultList) {
|
||||
if (item.contains("hmenu=")) {
|
||||
List<String> list = WindowsEnumeratedXml.evaluateXpathGetValues(item, "//@id");
|
||||
if (list.size() > 0)
|
||||
resultStr = list.get(0); //get first id
|
||||
}
|
||||
else
|
||||
resultStr = item;
|
||||
break;
|
||||
}
|
||||
resultStr = resultStr.replaceAll("[^\\d.]", ""); //remove all non-numeric values
|
||||
//System.out.println("findMenuIdWithXpath: " + resultStr);
|
||||
if (resultStr.isEmpty())
|
||||
appendError("Error: Failed to find window handle matching: " + xpath);
|
||||
else
|
||||
result = Integer.parseInt(resultStr);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public Point getCenterWindowPosition(WinPtr handle) {
|
||||
Point p = null;
|
||||
if (handle.isWin32())
|
||||
p = api.getWindowPosition(handle.hWnd);
|
||||
else
|
||||
p = uiabridge.getCenterOfElement(handle.runtimeId);
|
||||
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<String> listStr, String delimiter) {
|
||||
StringBuilder result = new StringBuilder("");
|
||||
for (String item: listStr) {
|
||||
result.append(item + delimiter);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public void killStatusWindow() {
|
||||
parentProcessor.currentStatusWin.dispose();
|
||||
parentProcessor.currentStatusWin = null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse.commands;
|
||||
|
||||
import java.io.*;
|
||||
import org.synthuse.*;
|
||||
|
||||
public class FileCommands extends BaseCommand {
|
||||
|
||||
public FileCommands(CommandProcessor cp) {
|
||||
super(cp);
|
||||
}
|
||||
|
||||
public String cmdGrepFile(String[] args) throws Exception {
|
||||
if (!checkArgumentLength(args, 2))
|
||||
return null;
|
||||
String filename = args[0];
|
||||
String pattern = args[1];
|
||||
StringBuilder result = new StringBuilder("");
|
||||
FileInputStream fis = null;
|
||||
BufferedReader br = null;
|
||||
try {
|
||||
fis = new FileInputStream(filename);
|
||||
DataInputStream dis = new DataInputStream(fis);
|
||||
br = new BufferedReader(new InputStreamReader(dis));
|
||||
String strLine = "";
|
||||
while ((strLine = br.readLine()) != null) {
|
||||
if (strLine.matches(pattern))
|
||||
result.append(strLine + "\n");
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw ex;
|
||||
}
|
||||
finally {
|
||||
if (fis != null)
|
||||
fis.close();
|
||||
if (br != null)
|
||||
br.close();
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public String cmdFileSearch(String[] args) {
|
||||
if (!checkArgumentLength(args, 2))
|
||||
return null;
|
||||
String path = args[0];
|
||||
String filenamePattern = args[1];
|
||||
StringBuilder result = new StringBuilder("");
|
||||
File parent = new File(path);
|
||||
for(File child : parent.listFiles()) {
|
||||
if (child.isFile() && child.getName().matches(filenamePattern))
|
||||
result.append(child.getAbsolutePath() + "\n");
|
||||
else if (child.isDirectory()) {
|
||||
result.append(cmdFileSearch(new String[] {child.getAbsolutePath(), filenamePattern}));
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse.commands;
|
||||
|
||||
import org.synthuse.*;
|
||||
|
||||
public class KeyboardCommands extends BaseCommand {
|
||||
|
||||
public KeyboardCommands(CommandProcessor commandProcessor) {
|
||||
super(commandProcessor);
|
||||
}
|
||||
|
||||
public boolean cmdSendKeys(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
return whenFalseAppendError(RobotMacro.sendKeys(args[0]));
|
||||
}
|
||||
|
||||
public boolean cmdKeyDown(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
if (!checkFirstArgumentLength(args))
|
||||
return false;
|
||||
char keyChar = args[0].charAt(0);
|
||||
return RobotMacro.keyDown(keyChar);
|
||||
}
|
||||
|
||||
public boolean cmdKeyUp(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
if (!checkFirstArgumentLength(args))
|
||||
return false;
|
||||
char keyChar = args[0].charAt(0);
|
||||
return RobotMacro.keyUp(keyChar);
|
||||
}
|
||||
|
||||
public boolean cmdKeyCopy(String[] args) {
|
||||
RobotMacro.copyKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdKeyPaste(String[] args) {
|
||||
RobotMacro.pasteKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdKeyEscape(String[] args) {
|
||||
RobotMacro.escapeKey();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdKeyFunc(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
if (!checkFirstArgumentLength(args))
|
||||
return false;
|
||||
int fNum = Integer.parseInt(args[0]);
|
||||
RobotMacro.functionKey(fNum);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse.commands;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Robot;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.synthuse.*;
|
||||
|
||||
public class MainCommands extends BaseCommand {
|
||||
|
||||
public MainCommands(CommandProcessor cp) {
|
||||
super(cp);
|
||||
}
|
||||
|
||||
public boolean cmdOpen(String[] args) throws IOException {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
runtime.exec(args[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdDisplayText(String[] args) throws IOException {
|
||||
if (!checkArgumentLength(args, 2))
|
||||
return false;
|
||||
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 );
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSetSpeed(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
long speed = Long.parseLong(args[0]);
|
||||
CommandProcessor.SPEED = speed;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSetTimeout(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
long timeout = Long.parseLong(args[0]);
|
||||
CommandProcessor.WAIT_TIMEOUT_THRESHOLD = timeout;
|
||||
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 cmdForceWin32Refresh(String[] args) {
|
||||
if (!checkArgumentLength(args, 0))
|
||||
return false;
|
||||
forceWin32OnlyXmlRefresh();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdOnlyRefreshWin32(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
boolean flg = Boolean.parseBoolean(args[0]);
|
||||
onlyRefreshWin32(flg);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdTargetRefresh(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
targetXmlRefresh(args[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWaitForTitle(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
long totalAttempts = (long) (CommandProcessor.WAIT_TIMEOUT_THRESHOLD / (CommandProcessor.XML_UPDATE_THRESHOLD * 1000));
|
||||
long attemptCount = 0;
|
||||
String xpath = "/EnumeratedWindows/*[@TEXT='" + WindowsEnumeratedXml.escapeXmlAttributeValue(args[0].toUpperCase()) + "']";
|
||||
WinPtr handle = findHandleWithXpath(xpath, true);
|
||||
if (!handle.isEmpty())// first test without a timeout
|
||||
return true;
|
||||
while (attemptCount < totalAttempts) {
|
||||
handle = findHandleWithXpath(xpath, true);
|
||||
if (!handle.isEmpty())
|
||||
break;
|
||||
try {Thread.sleep((long)(CommandProcessor.XML_UPDATE_THRESHOLD * 1000));} catch (Exception e) {e.printStackTrace();}
|
||||
++attemptCount;
|
||||
if (isProcessorStopped())
|
||||
break;
|
||||
}
|
||||
if (handle.isEmpty())
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed to find element matching " + args[0]);
|
||||
return (!handle.isEmpty());
|
||||
}
|
||||
|
||||
public boolean cmdWaitForText(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
long totalAttempts = (long) (CommandProcessor.WAIT_TIMEOUT_THRESHOLD / (CommandProcessor.XML_UPDATE_THRESHOLD * 1000));
|
||||
long attemptCount = 0;
|
||||
String xpath = "//[@TEXT='" + WindowsEnumeratedXml.escapeXmlAttributeValue(args[0].toUpperCase()) + "']";
|
||||
WinPtr handle = findHandleWithXpath(xpath, true);
|
||||
if (!handle.isEmpty())// first test without a timeout
|
||||
return true;
|
||||
while (attemptCount < totalAttempts) {
|
||||
handle = findHandleWithXpath(xpath, true);
|
||||
if (!handle.isEmpty())
|
||||
break;
|
||||
try {Thread.sleep((long)(CommandProcessor.XML_UPDATE_THRESHOLD * 1000));} catch (Exception e) {e.printStackTrace();}
|
||||
++attemptCount;
|
||||
if (isProcessorStopped())
|
||||
break;
|
||||
}
|
||||
if (handle.isEmpty())
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed to find element matching " + args[0]);
|
||||
return (!handle.isEmpty());
|
||||
}
|
||||
|
||||
public boolean cmdWaitForClass(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
long totalAttempts = (long) (CommandProcessor.WAIT_TIMEOUT_THRESHOLD / (CommandProcessor.XML_UPDATE_THRESHOLD * 1000));
|
||||
long attemptCount = 0;
|
||||
String xpath = "//[@CLASS='" + WindowsEnumeratedXml.escapeXmlAttributeValue(args[0].toUpperCase()) + "']";
|
||||
WinPtr handle = findHandleWithXpath(xpath, true);
|
||||
if (!handle.isEmpty())// first test without a timeout
|
||||
return true;
|
||||
while (attemptCount < totalAttempts) {
|
||||
handle = findHandleWithXpath(xpath, true);
|
||||
if (!handle.isEmpty())
|
||||
break;
|
||||
try {Thread.sleep((long)(CommandProcessor.XML_UPDATE_THRESHOLD * 1000));} catch (Exception e) {e.printStackTrace();}
|
||||
++attemptCount;
|
||||
if (isProcessorStopped())
|
||||
break;
|
||||
}
|
||||
if (handle.isEmpty())
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed to find element matching " + args[0]);
|
||||
return (!handle.isEmpty());
|
||||
}
|
||||
|
||||
public boolean cmdWaitForVisible(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
long totalAttempts = (long) (CommandProcessor.WAIT_TIMEOUT_THRESHOLD / (CommandProcessor.XML_UPDATE_THRESHOLD * 1000));
|
||||
long attemptCount = 0;
|
||||
WinPtr handle = findHandleWithXpath(args[0], true);
|
||||
if (!handle.isEmpty())// first test without a timeout
|
||||
return true;
|
||||
while (attemptCount < totalAttempts) {
|
||||
handle = findHandleWithXpath(args[0], true);
|
||||
if (!handle.isEmpty())
|
||||
break;
|
||||
try {Thread.sleep((long)(CommandProcessor.XML_UPDATE_THRESHOLD * 1000));} catch (Exception e) {e.printStackTrace();}
|
||||
++attemptCount;
|
||||
if (isProcessorStopped())
|
||||
break;
|
||||
}
|
||||
if (handle.isEmpty())
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed to find element matching " + args[0]);
|
||||
return (!handle.isEmpty());
|
||||
}
|
||||
|
||||
public boolean cmdVerifyElementNotPresent(String[] args)
|
||||
{
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0], true);
|
||||
if (!handle.isEmpty())
|
||||
{
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed to NOT find element matching " + args[0]);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdVerifyElementPresent(String[] args)
|
||||
{
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0], true);
|
||||
if (!handle.isEmpty())
|
||||
return true;
|
||||
else
|
||||
{
|
||||
appendError("Error: command '" + getCurrentCommand() + "' failed to find element matching " + args[0]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean cmdDisableStatus(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
boolean val = args[0].toUpperCase().equals("TRUE");
|
||||
parentProcessor.setQuiet(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdTakeScreenCapture(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
try {
|
||||
String saveName = args[0];
|
||||
if (!saveName.toLowerCase().endsWith(".png"))
|
||||
saveName += ".png";
|
||||
//LOG.debug("take Screen Capture " + new File(saveName).getAbsolutePath());
|
||||
Robot robot = new Robot();
|
||||
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
BufferedImage image = robot.createScreenCapture(new Rectangle(screenSize));
|
||||
ImageIO.write(image, "png", new File(saveName));
|
||||
}
|
||||
catch(Exception e) {
|
||||
//e.printStackTrace();
|
||||
appendError(e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse.commands;
|
||||
|
||||
import java.awt.Point;
|
||||
|
||||
import org.synthuse.*;
|
||||
|
||||
public class MouseCommands extends BaseCommand {
|
||||
|
||||
public MouseCommands(CommandProcessor commandProcessor) {
|
||||
super(commandProcessor);
|
||||
}
|
||||
|
||||
public boolean cmdClick(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
//System.out.println("cmdClick1: " + args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean cmdDoubleClick(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean cmdRightClick(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean cmdMouseDown(String[] args) {
|
||||
RobotMacro.leftMouseDown();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdMouseUp(String[] args) {
|
||||
RobotMacro.leftMouseUp();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdMouseDownRight(String[] args) {
|
||||
RobotMacro.rightMouseDown();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdMouseUpRight(String[] args) {
|
||||
RobotMacro.rightMouseUp();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdMouseMove(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean cmdSetTargetOffset(String[] args) {
|
||||
if (!checkArgumentLength(args, 2))
|
||||
return false;
|
||||
int x = Integer.parseInt(args[0]);
|
||||
int y = Integer.parseInt(args[1]);
|
||||
parentProcessor.targetOffset.x = x;
|
||||
parentProcessor.targetOffset.y = y;
|
||||
return true;
|
||||
}
|
||||
public boolean cmdMouseMoveXy(String[] args) {
|
||||
if (!checkArgumentLength(args, 2))
|
||||
return false;
|
||||
int x = Integer.parseInt(args[0]);
|
||||
int y = Integer.parseInt(args[1]);
|
||||
RobotMacro.mouseMove(x, y);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWinClick(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
api.sendClick(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWinDoubleClick(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
api.sendDoubleClick(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWinRightClick(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
api.sendRightClick(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
/*
|
||||
* Copyright 2014, Synthuse.org
|
||||
* Released under the Apache Version 2.0 License.
|
||||
*
|
||||
* last modified by ejakubowski
|
||||
*/
|
||||
|
||||
package org.synthuse.commands;
|
||||
|
||||
import org.synthuse.*;
|
||||
|
||||
import com.sun.jna.platform.win32.WinDef.LPARAM;
|
||||
import com.sun.jna.platform.win32.WinDef.WPARAM;
|
||||
|
||||
public class WindowsCommands extends BaseCommand {
|
||||
|
||||
public WindowsCommands(CommandProcessor cp) {
|
||||
super(cp);
|
||||
}
|
||||
|
||||
public boolean cmdWindowFocus(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.activateWindow(handle.hWnd);
|
||||
//api.showWindow(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWindowMinimize(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.minimizeWindow(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWindowMaximize(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.maximizeWindow(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWindowRestore(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.restoreWindow(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWindowHide(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.hideWindow(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWindowShow(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.showWindow(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdWindowSwitchToThis(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.switchToThisWindow(handle.hWnd, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public boolean cmdWindowClose(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.closeWindow(handle.hWnd);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSetText(String[] args) {
|
||||
if (!checkArgumentLength(args, 2))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
api.sendWmSetText(handle.hWnd, args[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
public String cmdGetText(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return "";
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return "";
|
||||
handle.convertToNativeHwnd();
|
||||
return api.sendWmGetText(handle.hWnd);
|
||||
}
|
||||
|
||||
public boolean cmdSelectMenu(String[] args) {
|
||||
if (!checkArgumentLength(args, 1))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]);
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
int id = findMenuIdWithXpath(args[0]);
|
||||
handle.convertToNativeHwnd();
|
||||
//LRESULT result =
|
||||
//System.out.println("PostMessage to " + handle.hWndStr + " for id " + id);
|
||||
api.user32.PostMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0));
|
||||
//api.user32.SendMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSelectContextMenuId(String[] args) {
|
||||
if (!checkArgumentLength(args, 2))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]); //xpath to HWND is first argument
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
int id = Integer.parseInt(args[1]); //context menu id is supplied as second argument
|
||||
handle.convertToNativeHwnd();
|
||||
//LRESULT result =
|
||||
System.out.println("PostMessage to " + handle.toString() + " for id " + id + " - " + Api.MAKELONG(id, 0));
|
||||
//api.user32.PostMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0));
|
||||
api.user32.SendMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(Api.MAKELONG(id, 0)), new LPARAM(0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSendCommandMsg(String[] args) {
|
||||
if (!checkArgumentLength(args, 3))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]); //xpath to HWND is first argument
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
int id = Integer.parseInt(args[1]); //context menu id is supplied as second argument
|
||||
int idLparam = Integer.parseInt(args[2]); //context menu id is supplied as second argument
|
||||
handle.convertToNativeHwnd();
|
||||
//LRESULT result =
|
||||
//System.out.println("Send Message WM_COMMAND to " + handle.toString() + " PARAMS: " + id + ", " + idLparam);
|
||||
//api.user32.PostMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0));
|
||||
api.user32.SendMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(idLparam));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSendMessage(String[] args) {
|
||||
if (!checkArgumentLength(args, 4))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]); //xpath to HWND is first argument
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
int msg = Integer.parseInt(args[1]);
|
||||
int id = Integer.parseInt(args[2]); //context menu id is supplied as second argument
|
||||
int idLparam = Integer.parseInt(args[3]); //context menu id is supplied as second argument
|
||||
handle.convertToNativeHwnd();
|
||||
//LRESULT result =
|
||||
//System.out.println("Send Message WM_COMMAND to " + handle.toString() + " PARAMS: " + id + ", " + idLparam);
|
||||
//api.user32.PostMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0));
|
||||
api.user32.SendMessage(handle.hWnd, msg, new WPARAM(id), new LPARAM(idLparam));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSelectListIndex(String[] args) {
|
||||
if (!checkArgumentLength(args, 2))
|
||||
return false;
|
||||
WinPtr handle = findHandleWithXpath(args[0]); //xpath to HWND is first argument
|
||||
if (handle.isEmpty())
|
||||
return false;
|
||||
handle.convertToNativeHwnd();
|
||||
int index = Integer.parseInt(args[1]);
|
||||
Api.SelectListItemByIndex(handle.hWnd, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean cmdSelectListString(String[] args) {
|
||||
//CB_SELECTSTRING
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package org.synthuse.controllers;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
import org.synthuse.Config;
|
||||
import org.synthuse.views.SynthuseConfigPanel;
|
||||
|
||||
public class SynthuseConfigDialogControllers {
|
||||
|
||||
public static void initializeUI(SynthuseConfigPanel aSynthuseConfigPanel, Config aConfig) {
|
||||
aSynthuseConfigPanel.getAlwaysOnTopCheckBox().setSelected(aConfig.isAlwaysOnTop());
|
||||
aSynthuseConfigPanel.getDisableFiltersUiaCheckBox().setSelected(aConfig.isFilterUiaDisabled());
|
||||
aSynthuseConfigPanel.getDisableUiaBridgeCheckBox().setSelected(aConfig.isUiaBridgeDisabled());
|
||||
aSynthuseConfigPanel.getRefreshKeyTextField().setText(Character.toString(aConfig.getRefreshKey()));
|
||||
aSynthuseConfigPanel.getStrongTextMatchingCheckBox().setSelected(aConfig.isUseStrongTextMatching());
|
||||
aSynthuseConfigPanel.getTargetKeyTextField().setText(Character.toString(aConfig.getTargetKey()));
|
||||
aSynthuseConfigPanel.getXPathHighlightTextField().setText(aConfig.getXpathHighlight());
|
||||
aSynthuseConfigPanel.getXPathListTextField().setText(aConfig.getXpathList());
|
||||
}
|
||||
|
||||
public static void bindActionControllers(final SynthuseConfigPanel aSynthuseConfigPanel, final Config aConfig) {
|
||||
aSynthuseConfigPanel.getAlwaysOnTopCheckBox().addActionListener(alwaysOnTopCheckboxActionHandler(aSynthuseConfigPanel, aConfig));
|
||||
aSynthuseConfigPanel.getDisableFiltersUiaCheckBox().addActionListener(disableFiltersUiaCheckboxActionHandler(aSynthuseConfigPanel, aConfig));
|
||||
aSynthuseConfigPanel.getDisableUiaBridgeCheckBox().addActionListener(disableUiaBridgeCheckboxActionHandler(aSynthuseConfigPanel, aConfig));
|
||||
aSynthuseConfigPanel.getRefreshKeyTextField().addActionListener(refreshKeyCodeTextFieldActionHandler(aSynthuseConfigPanel, aConfig));
|
||||
aSynthuseConfigPanel.getStrongTextMatchingCheckBox().addActionListener(strongTextMatchingCheckboxActionHandler(aSynthuseConfigPanel, aConfig));
|
||||
aSynthuseConfigPanel.getTargetKeyTextField().addActionListener(targetKeyCodeTextFieldActionHandler(aSynthuseConfigPanel, aConfig));
|
||||
aSynthuseConfigPanel.getXPathHighlightTextField().addActionListener(xpathHighlightTextFieldActionHandler(aSynthuseConfigPanel, aConfig));
|
||||
aSynthuseConfigPanel.getXPathListTextField().addActionListener(xpathListTextFieldActionHandler(aSynthuseConfigPanel, aConfig));
|
||||
}
|
||||
|
||||
private static ActionListener xpathListTextFieldActionHandler(final SynthuseConfigPanel aSynthuseConfigPanel,
|
||||
final Config aConfig) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aE) {
|
||||
aConfig.setXPathList(aSynthuseConfigPanel.getXPathListTextField().getText());
|
||||
JOptionPane.showMessageDialog(aSynthuseConfigPanel, "May require restart to be effective");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionListener xpathHighlightTextFieldActionHandler(final SynthuseConfigPanel aSynthuseConfigPanel,
|
||||
final Config aConfig) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aE) {
|
||||
aConfig.setXPathHighlight(aSynthuseConfigPanel.getXPathHighlightTextField().getText());
|
||||
JOptionPane.showMessageDialog(aSynthuseConfigPanel, "May require restart to be effective");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionListener targetKeyCodeTextFieldActionHandler(final SynthuseConfigPanel aSynthuseConfigPanel,
|
||||
final Config aConfig) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aE) {
|
||||
aConfig.setTargetKey(aSynthuseConfigPanel.getTargetKeyTextField().getText());
|
||||
JOptionPane.showMessageDialog(aSynthuseConfigPanel, "May require restart to be effective");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionListener strongTextMatchingCheckboxActionHandler(
|
||||
final SynthuseConfigPanel aSynthuseConfigPanel, final Config aConfig) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aE) {
|
||||
aConfig.setUseStrongTextMatching(aSynthuseConfigPanel.getStrongTextMatchingCheckBox().isSelected());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionListener refreshKeyCodeTextFieldActionHandler(final SynthuseConfigPanel aSynthuseConfigPanel,
|
||||
final Config aConfig) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aE) {
|
||||
aConfig.setRefreshKey(aSynthuseConfigPanel.getRefreshKeyTextField().getText());
|
||||
JOptionPane.showMessageDialog(aSynthuseConfigPanel, "May require restart to be effective");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionListener disableUiaBridgeCheckboxActionHandler(final SynthuseConfigPanel aSynthuseConfigPanel,
|
||||
final Config aConfig) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aE) {
|
||||
aConfig.setDisableUiaBridge(aSynthuseConfigPanel.getDisableUiaBridgeCheckBox().isSelected());
|
||||
JOptionPane.showMessageDialog(aSynthuseConfigPanel, "May require restart to be effective");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionListener disableFiltersUiaCheckboxActionHandler(final SynthuseConfigPanel aSynthuseConfigPanel,
|
||||
final Config aConfig) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aE) {
|
||||
aConfig.setDisableFiltersUia(aSynthuseConfigPanel.getDisableFiltersUiaCheckBox().isSelected());
|
||||
JOptionPane.showMessageDialog(aSynthuseConfigPanel, "May require restart to be effective");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static ActionListener alwaysOnTopCheckboxActionHandler(final SynthuseConfigPanel aSynthuseConfigPanel,
|
||||
final Config aConfig) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aE) {
|
||||
aConfig.setAlwaysOnTop(aSynthuseConfigPanel.getAlwaysOnTopCheckBox().isSelected());
|
||||
JOptionPane.showMessageDialog(aSynthuseConfigPanel, "May require restart to be effective");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 951 B |
|
Before Width: | Height: | Size: 610 B |
|
Before Width: | Height: | Size: 333 B |
|
Before Width: | Height: | Size: 991 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 852 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
@@ -1,122 +0,0 @@
|
||||
package org.synthuse.test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.synthuse.*;
|
||||
|
||||
public class CommandProcessorTest {
|
||||
|
||||
String goodTestScript1 = "| do | pause | on | 10 |";
|
||||
String goodTestScript2 = "| do | pause | on | 10 |\n| do | pause | on | 20 |\n";
|
||||
String goodTestScript3 = "|do|pause|on|8|\n|do|pause|on|16|\n";
|
||||
String goodTestScript4 = "| do|pause|on|8|\r\n|do|pause|on|16|\r\n";
|
||||
|
||||
String badTestScript1 = "| do | pause | on | bob |\n";
|
||||
String badTestScript2 = "| do | pause | on | bob |\n| do | pause | on | joe |\n";
|
||||
|
||||
CommandProcessor.Events testEvents = new CommandProcessor.Events() {
|
||||
@Override
|
||||
public void statusChanged(String status) {
|
||||
}
|
||||
@Override
|
||||
public void executionCompleted() {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
CommandProcessor.DEFAULT_QUIET = true;
|
||||
CommandProcessor.SPEED = 0;
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initCommandProcessor() {
|
||||
CommandProcessor commandProcessor = null;
|
||||
|
||||
commandProcessor = new CommandProcessor("");
|
||||
assertEquals(commandProcessor.scriptStr, "");
|
||||
|
||||
commandProcessor = new CommandProcessor(goodTestScript1);
|
||||
assertEquals(commandProcessor.scriptStr, goodTestScript1);
|
||||
|
||||
//this script will be initialized and executed too
|
||||
commandProcessor = CommandProcessor.executeThreaded(goodTestScript2, testEvents);
|
||||
assertEquals(commandProcessor.scriptStr, goodTestScript2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ExecuteSingleThreadedValidScripts() {
|
||||
CommandProcessor commandProcessor = new CommandProcessor("", testEvents);
|
||||
commandProcessor.run();
|
||||
assertEquals(commandProcessor.getErrors(), 0);
|
||||
|
||||
commandProcessor.setScript(goodTestScript1);
|
||||
assertEquals(commandProcessor.scriptStr, goodTestScript1);
|
||||
commandProcessor.run();
|
||||
assertEquals(commandProcessor.getErrors(), 0);
|
||||
|
||||
commandProcessor.setScript(goodTestScript2);
|
||||
assertEquals(commandProcessor.scriptStr, goodTestScript2);
|
||||
commandProcessor.run();
|
||||
assertEquals(commandProcessor.getErrors(), 0);
|
||||
|
||||
commandProcessor = new CommandProcessor(goodTestScript3, testEvents);
|
||||
commandProcessor.run();
|
||||
assertEquals(commandProcessor.getErrors(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ExecuteMultiThreadedValidScripts() {
|
||||
CommandProcessor.executeThreaded("", testEvents);
|
||||
CommandProcessor commandProcessor = null;
|
||||
commandProcessor = CommandProcessor.executeThreaded(goodTestScript1, testEvents);
|
||||
assertEquals(commandProcessor.getErrors(), 0);
|
||||
commandProcessor = CommandProcessor.executeThreaded(goodTestScript2, testEvents);
|
||||
assertEquals(commandProcessor.getErrors(), 0);
|
||||
commandProcessor = CommandProcessor.executeThreaded(goodTestScript3, testEvents);
|
||||
assertEquals(commandProcessor.getErrors(), 0);
|
||||
//CommandProcessor.executeThreaded(goodTestScript3, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ExecuteSingleThreadedBadScripts() {
|
||||
//undefined command
|
||||
CommandProcessor commandProcessor = new CommandProcessor("| do | xasdffds |", testEvents);
|
||||
commandProcessor.setQuiet(true);
|
||||
commandProcessor.run();
|
||||
//System.out.println(commandProcessor.lastError);
|
||||
//2014-03-25 10:19:37.54 - Error: Command 'xasdffds' not found.
|
||||
assertEquals(commandProcessor.getErrors(), 1);
|
||||
|
||||
commandProcessor.setScript(badTestScript1);
|
||||
commandProcessor.setQuiet(true);
|
||||
commandProcessor.run();
|
||||
//System.out.println(commandProcessor.lastError);
|
||||
assertEquals(commandProcessor.getErrors(), 1);
|
||||
assertTrue(commandProcessor.lastError.length() > 1);
|
||||
|
||||
commandProcessor.setScript(badTestScript2);
|
||||
commandProcessor.setQuiet(true);
|
||||
assertEquals(commandProcessor.scriptStr, badTestScript2);
|
||||
commandProcessor.run();
|
||||
//System.out.println(commandProcessor.lastError);
|
||||
assertEquals(commandProcessor.getErrors(), 2);
|
||||
assertTrue(commandProcessor.lastError.length() > 1);
|
||||
|
||||
}
|
||||
|
||||
// test running mulithreaded bad scripts
|
||||
|
||||
// test parsing bars, and arguments that contain values with bars
|
||||
|
||||
// test command sections ie keyboard, mouse, win, main, base
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" >
|
||||
|
||||
<head>
|
||||
<title>SilverlightMockTestApp</title>
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
#silverlightControlHost {
|
||||
height: 100%;
|
||||
text-align:center;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="Silverlight.js"></script>
|
||||
<script type="text/javascript">
|
||||
function onSilverlightError(sender, args) {
|
||||
var appSource = "";
|
||||
if (sender != null && sender != 0) {
|
||||
appSource = sender.getHost().Source;
|
||||
}
|
||||
|
||||
var errorType = args.ErrorType;
|
||||
var iErrorCode = args.ErrorCode;
|
||||
|
||||
if (errorType == "ImageError" || errorType == "MediaError") {
|
||||
return;
|
||||
}
|
||||
|
||||
var errMsg = "Unhandled Error in Silverlight Application " + appSource + "\n" ;
|
||||
|
||||
errMsg += "Code: "+ iErrorCode + " \n";
|
||||
errMsg += "Category: " + errorType + " \n";
|
||||
errMsg += "Message: " + args.ErrorMessage + " \n";
|
||||
|
||||
if (errorType == "ParserError") {
|
||||
errMsg += "File: " + args.xamlFile + " \n";
|
||||
errMsg += "Line: " + args.lineNumber + " \n";
|
||||
errMsg += "Position: " + args.charPosition + " \n";
|
||||
}
|
||||
else if (errorType == "RuntimeError") {
|
||||
if (args.lineNumber != 0) {
|
||||
errMsg += "Line: " + args.lineNumber + " \n";
|
||||
errMsg += "Position: " + args.charPosition + " \n";
|
||||
}
|
||||
errMsg += "MethodName: " + args.methodName + " \n";
|
||||
}
|
||||
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<form id="form1" runat="server" style="height:100%">
|
||||
<div id="silverlightControlHost">
|
||||
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
|
||||
<param name="source" value="SilverlightMockTestApp.xap"/>
|
||||
<param name="onError" value="onSilverlightError" />
|
||||
<param name="background" value="white" />
|
||||
<param name="minRuntimeVersion" value="4.0.50826.0" />
|
||||
<param name="autoUpgrade" value="true" />
|
||||
<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50826.0" style="text-decoration:none">
|
||||
<img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style:none"/>
|
||||
</a>
|
||||
</object><iframe id="_sl_historyFrame" style="visibility:hidden;height:0px;width:0px;border:0px"></iframe></div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,79 +0,0 @@
|
||||
package org.synthuse.test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
// This class doesn't contain Test, only some methods that are used by the unit tests
|
||||
public class UnitTestHelper {
|
||||
|
||||
static Process runningApp = null;
|
||||
public static void RunApp(String ResourceFilePath) {
|
||||
String tempFilename = ExtractFileFromJar(ResourceFilePath);
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
try {
|
||||
runningApp = runtime.exec(tempFilename);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void DestroyApp() {
|
||||
if (runningApp != null)
|
||||
runningApp.destroy();
|
||||
}
|
||||
|
||||
public static String ExtractFileFromJar(String path) {
|
||||
// Obtain filename from path
|
||||
String[] parts = path.split("/");
|
||||
String filename = (parts.length > 1) ? parts[parts.length - 1] : null;
|
||||
// Split filename to prexif and suffix (extension)
|
||||
String prefix = "";
|
||||
String suffix = null;
|
||||
if (filename != null) {
|
||||
parts = filename.split("\\.", 2);
|
||||
prefix = parts[0];
|
||||
suffix = (parts.length > 1) ? "."+parts[parts.length - 1] : null;
|
||||
}
|
||||
File temp = null;
|
||||
try {
|
||||
// Prepare temporary file
|
||||
temp = File.createTempFile(prefix, suffix);
|
||||
temp.deleteOnExit();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (!temp.exists()) { //some reason the temp file wasn't create so abort
|
||||
System.out.println("File " + temp.getAbsolutePath() + " does not exist.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Prepare buffer for data copying
|
||||
byte[] buffer = new byte[1024];
|
||||
int readBytes;
|
||||
// Open and check input stream
|
||||
InputStream is = UnitTestHelper.class.getResourceAsStream(path);
|
||||
if (is == null) { //check if valid
|
||||
System.out.println("File " + path + " was not found inside JAR.");
|
||||
return null;
|
||||
}
|
||||
// Open output stream and copy data between source file in JAR and the temporary file
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(temp);
|
||||
while ((readBytes = is.read(buffer)) != -1) {
|
||||
os.write(buffer, 0, readBytes);
|
||||
}
|
||||
os.close();
|
||||
is.close();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return temp.getAbsolutePath();
|
||||
// Finally, load the library
|
||||
//System.load(temp.getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
package org.synthuse.test;
|
||||
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.synthuse.Api;
|
||||
import org.synthuse.WindowInfo;
|
||||
import org.synthuse.WindowsEnumeratedXml;
|
||||
import org.synthuse.Api.Kernel32Ex;
|
||||
import org.synthuse.Api.PsapiEx;
|
||||
import org.synthuse.Api.User32Ex;
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.WinUser;
|
||||
import com.sun.jna.platform.win32.WinDef.HMENU;
|
||||
import com.sun.jna.platform.win32.WinDef.HWND;
|
||||
import com.sun.jna.platform.win32.WinDef.RECT;
|
||||
import com.sun.jna.ptr.PointerByReference;
|
||||
|
||||
public class WinApiTest {
|
||||
Api api = new Api();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
|
||||
}
|
||||
|
||||
public static void output(String val) {
|
||||
//System.out.println(val);
|
||||
}
|
||||
|
||||
//copied and modified slightly from WindowInfo class
|
||||
public String getWindow32Information(HWND hWnd, boolean isChild) {
|
||||
String hwndStr = "";
|
||||
HWND parent = null;
|
||||
String parentStr = "";
|
||||
RECT rect;
|
||||
String text;
|
||||
String className = "";
|
||||
String processName = "";
|
||||
long pid = 0;
|
||||
|
||||
Map<String, String> extra = null;
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
output("Calling GetWindowTextA");
|
||||
User32Ex.instance.GetWindowTextA(hWnd, buffer, buffer.length);
|
||||
text = Native.toString(buffer);
|
||||
output("GetWindowTextA returned: " + text);
|
||||
if (text.isEmpty()) {
|
||||
output("Calling sendWmGetText");
|
||||
text = new Api().sendWmGetText(hWnd);
|
||||
output("sendWmGetText returned: " + text);
|
||||
}
|
||||
|
||||
char[] buffer2 = new char[1026];
|
||||
output("Calling GetClassName");
|
||||
User32Ex.instance.GetClassName(hWnd, buffer2, 1026);
|
||||
className = Native.toString(buffer2);
|
||||
output("GetClassName returned: " + className);
|
||||
|
||||
HMENU hmenu = Api.User32Ex.instance.GetMenu(hWnd);
|
||||
//hmenu = Api.User32.instance.GetSubMenu(hmenu, 0);
|
||||
if (hmenu != null) { //menu item count
|
||||
int menuCount = Api.User32Ex.instance.GetMenuItemCount(hmenu);
|
||||
if (menuCount > 0) {
|
||||
if (extra == null)
|
||||
extra = new LinkedHashMap<String, String>();
|
||||
extra.put("menuCount", menuCount + "");
|
||||
System.out.println("className: " + className);
|
||||
System.out.println("text: " + text);
|
||||
System.out.println("menuCount: " + menuCount);
|
||||
|
||||
for (int m = 0 ; m < menuCount ; m++) {
|
||||
String menuTxt = api.GetMenuItemText(hmenu, m);
|
||||
System.out.println("Menu Text: " + menuTxt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rect = new RECT();
|
||||
output("Calling GetWindowRect");
|
||||
User32Ex.instance.GetWindowRect(hWnd, rect);
|
||||
output("GetWindowRect returned: " + rect.toString());
|
||||
|
||||
if (isChild) {
|
||||
output("Calling GetParent");
|
||||
parent = User32Ex.instance.GetParent(hWnd);
|
||||
parentStr = Api.GetHandleAsString(parent);
|
||||
output("GetParent returned: " + parentStr);
|
||||
}
|
||||
else {
|
||||
//User32.instance.GetWindowModuleFileName(hWnd, path, 512);
|
||||
//IntByReference pointer = new IntByReference();
|
||||
PointerByReference pointer = new PointerByReference();
|
||||
output("Calling GetWindowThreadProcessId");
|
||||
User32Ex.instance.GetWindowThreadProcessId(hWnd, pointer);
|
||||
pid = pointer.getPointer().getInt(0);
|
||||
output("GetWindowThreadProcessId returned: " + pid);
|
||||
Pointer process = Kernel32Ex.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, pointer.getPointer());
|
||||
//output("OpenProcess returned: " + process.getLong(0));
|
||||
output("Calling GetModuleBaseNameW");
|
||||
PsapiEx.instance.GetModuleBaseNameW(process, null, buffer2, 512);
|
||||
processName = Native.toString(buffer2);
|
||||
output("GetModuleBaseNameW returned: " + processName);
|
||||
//processName = Native.toString(path);
|
||||
}
|
||||
hwndStr = Api.GetHandleAsString(hWnd);
|
||||
output("GetHandleAsString returned: " + hwndStr);
|
||||
return hwndStr;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enumerateParentWindowsTest() {
|
||||
final Map<String, WindowInfo> infoList = new LinkedHashMap<String, WindowInfo>();
|
||||
|
||||
class ParentWindowCallback implements WinUser.WNDENUMPROC {
|
||||
@Override
|
||||
public boolean callback(HWND hWnd, Pointer lParam) {
|
||||
output("Getting window info " + Api.GetHandleAsString(hWnd));
|
||||
//WindowInfo wi = new WindowInfo(hWnd, false);
|
||||
infoList.put(getWindow32Information(hWnd, false), null);
|
||||
//Api.User32.instance.EnumChildWindows(hWnd, new ChildWindowCallback(), new Pointer(0));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Api.User32Ex.instance.EnumWindows(new ParentWindowCallback(), 0);
|
||||
output("enumerateParentWindowsTest size: " + infoList.size());
|
||||
assertTrue(infoList.size() > 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getXmlTest() {
|
||||
String xml = WindowsEnumeratedXml.getXml();
|
||||
output("getXmlTest len: " + xml.length());
|
||||
assertTrue(xml.length() > 500);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
output("WinApiTest");
|
||||
WinApiTest wat = new WinApiTest();
|
||||
wat.enumerateParentWindowsTest();
|
||||
wat.getXmlTest();
|
||||
output("done.");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,225 +0,0 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package org.synthuse.views;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JTextField;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author ux29sy
|
||||
*/
|
||||
public class SynthuseConfigPanel extends javax.swing.JPanel {
|
||||
|
||||
/**
|
||||
* Creates new form SynthuseConfigPanel
|
||||
*/
|
||||
public SynthuseConfigPanel() {
|
||||
initComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
java.awt.GridBagConstraints gridBagConstraints;
|
||||
|
||||
theStrongTextMatchingCheckBox = new javax.swing.JCheckBox();
|
||||
theAlwaysOnTopCheckBox = new javax.swing.JCheckBox();
|
||||
theDisableUiaBridgeCheckBox = new javax.swing.JCheckBox();
|
||||
theDisableFiltersUiaCheckBox = new javax.swing.JCheckBox();
|
||||
jLabel1 = new javax.swing.JLabel();
|
||||
jLabel2 = new javax.swing.JLabel();
|
||||
jLabel3 = new javax.swing.JLabel();
|
||||
jLabel4 = new javax.swing.JLabel();
|
||||
filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 32767));
|
||||
filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(90, 0), new java.awt.Dimension(90, 0), new java.awt.Dimension(32767, 0));
|
||||
theRefreshKeyTextField = new javax.swing.JTextField();
|
||||
theTargetKeyTextField = new javax.swing.JTextField();
|
||||
theXPathListTextField = new javax.swing.JTextField();
|
||||
theXPathHighlightTextField = new javax.swing.JTextField();
|
||||
filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(50, 0), new java.awt.Dimension(50, 0), new java.awt.Dimension(50, 32767));
|
||||
|
||||
setLayout(new java.awt.GridBagLayout());
|
||||
|
||||
theStrongTextMatchingCheckBox.setText("Use Strong Text Matching");
|
||||
theStrongTextMatchingCheckBox.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
|
||||
add(theStrongTextMatchingCheckBox, gridBagConstraints);
|
||||
|
||||
theAlwaysOnTopCheckBox.setText("Always On Top");
|
||||
theAlwaysOnTopCheckBox.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 1;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
|
||||
add(theAlwaysOnTopCheckBox, gridBagConstraints);
|
||||
|
||||
theDisableUiaBridgeCheckBox.setText("Disable Uia Bridge");
|
||||
theDisableUiaBridgeCheckBox.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
|
||||
add(theDisableUiaBridgeCheckBox, gridBagConstraints);
|
||||
|
||||
theDisableFiltersUiaCheckBox.setText("Disable Filters Uia");
|
||||
theDisableFiltersUiaCheckBox.setHorizontalTextPosition(javax.swing.SwingConstants.LEADING);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 3;
|
||||
gridBagConstraints.gridwidth = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
|
||||
add(theDisableFiltersUiaCheckBox, gridBagConstraints);
|
||||
|
||||
jLabel1.setText("Refresh Key:");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.gridheight = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
|
||||
add(jLabel1, gridBagConstraints);
|
||||
|
||||
jLabel2.setText("Target Key:");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 4;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.gridheight = 2;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(3, 3, 3, 3);
|
||||
add(jLabel2, gridBagConstraints);
|
||||
|
||||
jLabel3.setText("XPath List:");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 6, 6, 6);
|
||||
add(jLabel3, gridBagConstraints);
|
||||
|
||||
jLabel4.setText("XPath Highlight:");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 6, 6, 6);
|
||||
add(jLabel4, gridBagConstraints);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 0;
|
||||
gridBagConstraints.gridy = 4;
|
||||
add(filler1, gridBagConstraints);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 2;
|
||||
gridBagConstraints.gridy = 0;
|
||||
add(filler2, gridBagConstraints);
|
||||
|
||||
theRefreshKeyTextField.setText("XXXX");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 5;
|
||||
gridBagConstraints.gridy = 0;
|
||||
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
|
||||
gridBagConstraints.gridheight = 2;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
add(theRefreshKeyTextField, gridBagConstraints);
|
||||
|
||||
theTargetKeyTextField.setText("XXXX");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 5;
|
||||
gridBagConstraints.gridy = 2;
|
||||
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
|
||||
gridBagConstraints.gridheight = 2;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
add(theTargetKeyTextField, gridBagConstraints);
|
||||
|
||||
theXPathListTextField.setText("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 5;
|
||||
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 6, 6, 6);
|
||||
add(theXPathListTextField, gridBagConstraints);
|
||||
|
||||
theXPathHighlightTextField.setText("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 1;
|
||||
gridBagConstraints.gridy = 6;
|
||||
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
|
||||
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
|
||||
gridBagConstraints.insets = new java.awt.Insets(6, 6, 6, 6);
|
||||
add(theXPathHighlightTextField, gridBagConstraints);
|
||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||
gridBagConstraints.gridx = 5;
|
||||
gridBagConstraints.gridy = 4;
|
||||
add(filler3, gridBagConstraints);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.Box.Filler filler1;
|
||||
private javax.swing.Box.Filler filler2;
|
||||
private javax.swing.Box.Filler filler3;
|
||||
private javax.swing.JLabel jLabel1;
|
||||
private javax.swing.JLabel jLabel2;
|
||||
private javax.swing.JLabel jLabel3;
|
||||
private javax.swing.JLabel jLabel4;
|
||||
private javax.swing.JCheckBox theAlwaysOnTopCheckBox;
|
||||
private javax.swing.JCheckBox theDisableFiltersUiaCheckBox;
|
||||
private javax.swing.JCheckBox theDisableUiaBridgeCheckBox;
|
||||
private javax.swing.JTextField theRefreshKeyTextField;
|
||||
private javax.swing.JCheckBox theStrongTextMatchingCheckBox;
|
||||
private javax.swing.JTextField theTargetKeyTextField;
|
||||
private javax.swing.JTextField theXPathHighlightTextField;
|
||||
private javax.swing.JTextField theXPathListTextField;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
public JCheckBox getAlwaysOnTopCheckBox() {
|
||||
return theAlwaysOnTopCheckBox;
|
||||
}
|
||||
|
||||
public JCheckBox getDisableFiltersUiaCheckBox() {
|
||||
return theDisableFiltersUiaCheckBox;
|
||||
}
|
||||
|
||||
public JCheckBox getDisableUiaBridgeCheckBox() {
|
||||
return theDisableUiaBridgeCheckBox;
|
||||
}
|
||||
|
||||
public JTextField getRefreshKeyTextField() {
|
||||
return theRefreshKeyTextField;
|
||||
}
|
||||
|
||||
public JCheckBox getStrongTextMatchingCheckBox() {
|
||||
return theStrongTextMatchingCheckBox;
|
||||
}
|
||||
|
||||
public JTextField getTargetKeyTextField() {
|
||||
return theTargetKeyTextField;
|
||||
}
|
||||
|
||||
public JTextField getXPathHighlightTextField() {
|
||||
return theXPathHighlightTextField;
|
||||
}
|
||||
|
||||
public JTextField getXPathListTextField() {
|
||||
return theXPathListTextField;
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
#
|
||||
#Tue Sep 22 12:05:52 CEST 2015
|
||||
targetKey=`
|
||||
useStrongTextMatching=true
|
||||
disableUiaBridge=false
|
||||
disableFiltersUia=false
|
||||
alwaysOnTop=false
|
||||
refreshKey=3
|
||||
DEFAULT_PROP_FILENAME=
|
||||
xpathHightlight=
|
||||
xpathList=
|
||||
urlList=
|
||||