Removed most except for core functionality code
@@ -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;
|
||||
}
|
||||
}
|
||||