Added SelectContextMenuId Command, increasing uiabridge speeds, reliability

This commit is contained in:
Edward Jakubowski
2014-05-02 22:01:43 -04:00
parent ce78f9c084
commit 4258d0977f
19 changed files with 185 additions and 65 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -24,7 +24,8 @@ using namespace uiabridge;
*/ */
JNIEXPORT void JNICALL Java_org_synthuse_UiaBridge_initialize(JNIEnv *env, jobject obj, jstring jproperties) JNIEXPORT void JNICALL Java_org_synthuse_UiaBridge_initialize(JNIEnv *env, jobject obj, jstring jproperties)
{ {
Global::AUTO_BRIDGE = gcnew AutomationBridge(); const char *properties = env->GetStringUTFChars(jproperties, 0);//convert string
Global::AUTO_BRIDGE = gcnew AutomationBridge(marshal_as<String ^>(properties));
} }
/* /*

View File

@@ -18,7 +18,14 @@ AutomationBridge::AutomationBridge()
{ {
enumFilters = gcnew Dictionary<System::String ^, System::String ^>(); enumFilters = gcnew Dictionary<System::String ^, System::String ^>();
cacheRequest = nullptr; cacheRequest = nullptr;
initializeCache(); initializeCache("");
}
AutomationBridge::AutomationBridge(System::String ^cachedProperties)
{
enumFilters = gcnew Dictionary<System::String ^, System::String ^>();
cacheRequest = nullptr;
initializeCache(cachedProperties);
} }
AutomationBridge::~AutomationBridge() AutomationBridge::~AutomationBridge()
@@ -29,7 +36,7 @@ AutomationBridge::~AutomationBridge()
//Console::WriteLine("disposing of AutomationBridge"); //Console::WriteLine("disposing of AutomationBridge");
} }
void AutomationBridge::initializeCache() void AutomationBridge::initializeCache(System::String ^cachedProperties)
{ {
cacheRequest = gcnew CacheRequest(); cacheRequest = gcnew CacheRequest();
//cacheRequest->AutomationElementMode = AutomationElementMode::Full; //cacheRequest->AutomationElementMode = AutomationElementMode::Full;
@@ -45,7 +52,11 @@ void AutomationBridge::initializeCache()
cacheRequest->Add(AutomationElement::NameProperty); cacheRequest->Add(AutomationElement::NameProperty);
cacheRequest->Add(AutomationElement::BoundingRectangleProperty); cacheRequest->Add(AutomationElement::BoundingRectangleProperty);
*/ */
System::String ^cachedPropStr = L"RuntimeIdProperty,ParentRuntimeIdProperty,NativeWindowHandleProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ControlTypeProperty,ClassNameProperty,NameProperty,BoundingRectangleProperty,ValueProperty"; System::String ^cachedPropStr = cachedProperties;
if (cachedPropStr == nullptr) // check if blank/null we need to use DEFAULT_CACHED_PROPS;
cachedPropStr = DEFAULT_CACHED_PROPS;
else if (cachedPropStr->Equals(""))
cachedPropStr = DEFAULT_CACHED_PROPS;
array<AutomationProperty^> ^rootProperties = AutomationElement::RootElement->GetSupportedProperties(); array<AutomationProperty^> ^rootProperties = AutomationElement::RootElement->GetSupportedProperties();
List<AutomationProperty^> ^cacheList = gcnew List<AutomationProperty^>(); List<AutomationProperty^> ^cacheList = gcnew List<AutomationProperty^>();
if (cachedPropStr->Contains(L"NativeWindowHandleProperty")) //special property not in the root property list if (cachedPropStr->Contains(L"NativeWindowHandleProperty")) //special property not in the root property list
@@ -244,7 +255,7 @@ array<System::String ^> ^ AutomationBridge::enumWindowInfo(System::IntPtr window
AutomationElement ^element = AutomationElement::FromHandle(windowHandle); AutomationElement ^element = AutomationElement::FromHandle(windowHandle);
List<System::String ^> ^winInfoList = gcnew List<System::String ^>(); List<System::String ^> ^winInfoList = gcnew List<System::String ^>();
if (!isElementFiltered(element)) //test parent should be filtered if (!isElementFiltered(element)) //test parent should be filtered
winInfoList->Add(getWindowInfo(element, properties)); winInfoList->Add(getWindowInfo(element, properties, nullptr));
winInfoList->AddRange(enumWindowInfo(element, properties)); winInfoList->AddRange(enumWindowInfo(element, properties));
return winInfoList->ToArray(); return winInfoList->ToArray();
} }
@@ -255,25 +266,16 @@ array<System::String ^> ^ AutomationBridge::enumWindowInfo(AutomationElement ^el
return enumWindowInfo(element, properties, filterModifierList); return enumWindowInfo(element, properties, filterModifierList);
} }
array<System::String ^> ^ AutomationBridge::enumWindowInfo(AutomationElement ^element, System::String ^properties, List<System::String ^> ^filterModifierList) array<System::String ^> ^ AutomationBridge::enumWindowInfo(AutomationElement ^parentElement, System::String ^properties, List<System::String ^> ^filterModifierList)
{ {
List<System::String ^> ^winInfoList = gcnew List<System::String ^>(); List<System::String ^> ^winInfoList = gcnew List<System::String ^>();
if (element == nullptr) if (parentElement == nullptr)
return winInfoList->ToArray(); return winInfoList->ToArray();
TreeWalker ^tw = TreeWalker::RawViewWalker; TreeWalker ^tw = TreeWalker::RawViewWalker;
//System::Console::WriteLine("get info: {0}", getWindowInfo(element, properties)); //System::Console::WriteLine("get info: {0}", getWindowInfo(element, properties));
//AutomationElement ^currentElement = tw->GetFirstChild(element, cacheRequest); //AutomationElement ^currentElement = tw->GetFirstChild(element, cacheRequest);
AutomationElement ^currentElement = nullptr; AutomationElement ^currentElement = nullptr;
/*if (element->CachedChildren != nullptr) currentElement = tw->GetFirstChild(parentElement, cacheRequest);
{
System::Console::WriteLine("using cached child");
currentElement = element->CachedChildren[0];
}
else*/
{
//System::Console::WriteLine("not cached child");
currentElement = tw->GetFirstChild(element, cacheRequest);
}
if (currentElement == nullptr) if (currentElement == nullptr)
{ {
//System::Console::WriteLine("no children {0}", element->CachedChildren->Count); //System::Console::WriteLine("no children {0}", element->CachedChildren->Count);
@@ -292,7 +294,7 @@ array<System::String ^> ^ AutomationBridge::enumWindowInfo(AutomationElement ^el
Boolean modifierChanged = fmlOriginalSize != filterModifierList->Count; Boolean modifierChanged = fmlOriginalSize != filterModifierList->Count;
if (!filtered) //not filtered so return element if (!filtered) //not filtered so return element
{ {
winInfoList->Add(getWindowInfo(currentElement, properties)); winInfoList->Add(getWindowInfo(currentElement, properties, parentElement));
winInfoList->AddRange(enumWindowInfo(currentElement, properties, filterModifierList)); winInfoList->AddRange(enumWindowInfo(currentElement, properties, filterModifierList));
} }
else //filtered, but if modifier used keep searching children else //filtered, but if modifier used keep searching children
@@ -303,16 +305,16 @@ array<System::String ^> ^ AutomationBridge::enumWindowInfo(AutomationElement ^el
processFilterModifier(filtered, modifierChanged, filterModifierList); //cleans filterModifierList processFilterModifier(filtered, modifierChanged, filterModifierList); //cleans filterModifierList
//System::Console::WriteLine("element: {0}", currentElement); //System::Console::WriteLine("element: {0}", currentElement);
//currentElement-> //currentElement->
currentElement = tw->GetNextSibling(currentElement, cacheRequest);
} catch (Exception ^ex) } catch (Exception ^ex)
{ {
System::Console::WriteLine("Exception: {0} {1}", ex->Message, ex->StackTrace); System::Console::WriteLine("Exception: {0} {1}", ex->Message, ex->StackTrace);
} }
currentElement = tw->GetNextSibling(currentElement, cacheRequest);
} }
return winInfoList->ToArray(); return winInfoList->ToArray();
} }
System::String ^ AutomationBridge::getWindowInfo(AutomationElement ^element, System::String ^properties) System::String ^ AutomationBridge::getWindowInfo(AutomationElement ^element, System::String ^properties, AutomationElement ^optionalParentElement)
{ {
System::String ^resultProperties = L""; System::String ^resultProperties = L"";
System::String ^propertyNameErrorCheck = L""; System::String ^propertyNameErrorCheck = L"";
@@ -323,16 +325,28 @@ System::String ^ AutomationBridge::getWindowInfo(AutomationElement ^element, Sys
if (properties->Equals(L"*")) if (properties->Equals(L"*"))
wildcardEnabled = true; wildcardEnabled = true;
//setup parentElement
System::String ^parentRuntimeId = L"";
if (wildcardEnabled || properties->Contains(L"ParentRuntimeIdProperty"))
{
if (optionalParentElement == nullptr)
{
TreeWalker ^tw = TreeWalker::ControlViewWalker;
parentRuntimeId = getRuntimeIdFromElement(tw->GetParent(element, cacheRequest));
}
else
parentRuntimeId = getRuntimeIdFromElement(optionalParentElement);
}
//create array for keeping order of properties //create array for keeping order of properties
System::String ^delim = L","; System::String ^delim = L",";
array<System::String ^> ^propSpltArray = properties->Split(delim->ToCharArray()); array<System::String ^> ^propSpltArray = properties->Split(delim->ToCharArray());
TreeWalker ^tw = TreeWalker::ControlViewWalker;
System::Int32 count = 0; System::Int32 count = 0;
array<AutomationProperty^> ^aps = cachedRootProperties;//element->GetSupportedProperties(); array<AutomationProperty^> ^aps = cachedRootProperties;//element->GetSupportedProperties();
array<System::String ^> ^propValues = gcnew array<System::String ^>(propSpltArray->Length);//keep order array<System::String ^> ^propValues = gcnew array<System::String ^>(propSpltArray->Length);//keep order
System::String ^wildcardProperties = L""; System::String ^wildcardProperties = L"";
if (wildcardEnabled) { if (wildcardEnabled) {
wildcardProperties += "ParentRuntimeIdProperty:" + getRuntimeIdFromElement(tw->GetParent(element, cacheRequest)) + ","; wildcardProperties += "ParentRuntimeIdProperty:" + parentRuntimeId + ",";
//propValues = gcnew array<System::String ^>(aps->Length +1 );//add one for parent property since it doesn't exist //propValues = gcnew array<System::String ^>(aps->Length +1 );//add one for parent property since it doesn't exist
} }
for(int i=0 ; i < propValues->Length ; i++) for(int i=0 ; i < propValues->Length ; i++)
@@ -340,7 +354,7 @@ System::String ^ AutomationBridge::getWindowInfo(AutomationElement ^element, Sys
propValues[i] = L""; propValues[i] = L"";
if (propSpltArray[i]->Equals("ParentRuntimeIdProperty"))//custom property for getting parent if (propSpltArray[i]->Equals("ParentRuntimeIdProperty"))//custom property for getting parent
{ {
propValues[i] = getRuntimeIdFromElement(tw->GetParent(element, cacheRequest)); propValues[i] = parentRuntimeId;
} }
} }
for each(AutomationProperty ^ap in aps) //loop through all supported Properties for a child for each(AutomationProperty ^ap in aps) //loop through all supported Properties for a child
@@ -404,13 +418,13 @@ System::String ^ AutomationBridge::getWindowInfo(AutomationElement ^element, Sys
System::String ^ AutomationBridge::getWindowInfo(System::Int32 x, System::Int32 y, System::String ^properties) System::String ^ AutomationBridge::getWindowInfo(System::Int32 x, System::Int32 y, System::String ^properties)
{ {
AutomationElement ^element = AutomationElement::FromPoint(System::Windows::Point(x, y)); AutomationElement ^element = AutomationElement::FromPoint(System::Windows::Point(x, y));
return getWindowInfo(element, properties); return getWindowInfo(element, properties, nullptr);
} }
System::String ^ AutomationBridge::getWindowInfo(System::IntPtr windowHandle, System::String ^properties) System::String ^ AutomationBridge::getWindowInfo(System::IntPtr windowHandle, System::String ^properties)
{ {
AutomationElement ^element = AutomationElement::FromHandle(windowHandle); AutomationElement ^element = AutomationElement::FromHandle(windowHandle);
return getWindowInfo(element, properties); return getWindowInfo(element, properties, nullptr);
} }
System::String ^ AutomationBridge::getWindowInfo(System::String ^runtimeIdStr, System::String ^properties) System::String ^ AutomationBridge::getWindowInfo(System::String ^runtimeIdStr, System::String ^properties)

View File

@@ -18,6 +18,7 @@ namespace uiabridge {
{ {
public: public:
AutomationBridge(void); AutomationBridge(void);
AutomationBridge(System::String ^cachedProperties);
~AutomationBridge(); ~AutomationBridge();
int addEnumFilter(System::String ^propertyName, System::String ^propertyValue); int addEnumFilter(System::String ^propertyName, System::String ^propertyValue);
void clearEnumFilters(); void clearEnumFilters();
@@ -28,7 +29,7 @@ namespace uiabridge {
array<System::String ^> ^ enumWindowInfo(System::IntPtr windowHandle, System::String ^properties); array<System::String ^> ^ enumWindowInfo(System::IntPtr windowHandle, System::String ^properties);
array<System::String ^> ^ enumWindowInfo(AutomationElement ^element, System::String ^properties); array<System::String ^> ^ enumWindowInfo(AutomationElement ^element, System::String ^properties);
array<System::String ^> ^ enumWindowInfo(AutomationElement ^element, System::String ^properties, List<System::String ^> ^filterModifierList); array<System::String ^> ^ enumWindowInfo(AutomationElement ^element, System::String ^properties, List<System::String ^> ^filterModifierList);
System::String ^ getWindowInfo(AutomationElement ^element, System::String ^properties); System::String ^ getWindowInfo(AutomationElement ^element, System::String ^properties, AutomationElement ^optionalParentElement);
System::String ^ getWindowInfo(System::Int32 x, System::Int32 y, System::String ^properties); System::String ^ getWindowInfo(System::Int32 x, System::Int32 y, System::String ^properties);
System::String ^ getWindowInfo(System::IntPtr windowHandle, System::String ^properties); System::String ^ getWindowInfo(System::IntPtr windowHandle, System::String ^properties);
System::String ^ getWindowInfo(System::String ^runtimeIdStr, System::String ^properties); System::String ^ getWindowInfo(System::String ^runtimeIdStr, System::String ^properties);
@@ -36,8 +37,9 @@ namespace uiabridge {
static System::String ^ALL_MODIFIER = L"All";// find all matching elements of this filter static System::String ^ALL_MODIFIER = L"All";// find all matching elements of this filter
static System::String ^PARENT_MODIFIER = L"Parent";//find all children of this matching parent filter static System::String ^PARENT_MODIFIER = L"Parent";//find all children of this matching parent filter
static System::String ^FIRST_MODIFIER = L"First"; //find first element matching this filter then stop static System::String ^FIRST_MODIFIER = L"First"; //find first element matching this filter then stop
static System::String ^DEFAULT_CACHED_PROPS = L"RuntimeIdProperty,ParentRuntimeIdProperty,NativeWindowHandleProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ControlTypeProperty,ClassNameProperty,NameProperty,BoundingRectangleProperty,ValueProperty";
private: private:
void initializeCache(); void initializeCache(System::String ^cachedProperties);
Dictionary<System::String ^, System::String ^> ^enumFilters; Dictionary<System::String ^, System::String ^> ^enumFilters;
void AutomationBridge::processFilterModifier(Boolean filtered, Boolean modifierChanged, List<System::String ^> ^filterModifierList); void AutomationBridge::processFilterModifier(Boolean filtered, Boolean modifierChanged, List<System::String ^> ^filterModifierList);
CacheRequest ^cacheRequest; CacheRequest ^cacheRequest;

Binary file not shown.

Binary file not shown.

View File

@@ -25,32 +25,67 @@ void outputResults(array<System::String ^> ^winInfo)
} }
void runBasicTests(AutomationBridge ^ab, System::String ^propList)
{
array<System::String ^> ^winInfo = nullptr;
System::DateTime start;
System::Double seconds = 0;
start = System::DateTime::Now;
ab->clearEnumFilters();
ab->addEnumFilter("Parent/FrameworkIdProperty", "WinForm");
winInfo = ab->enumWindowInfo(propList);
//outputResults(winInfo);
seconds = System::Math::Round(System::DateTime::Now.Subtract(start).TotalSeconds, 4);
Console::WriteLine(L"Total WinForm Elements: {0} in {1} seconds", winInfo->Length, seconds);
start = System::DateTime::Now;
ab->clearEnumFilters();
ab->addEnumFilter("Parent/FrameworkIdProperty", "WPF");
winInfo = ab->enumWindowInfo(propList);
//outputResults(winInfo);
seconds = System::Math::Round(System::DateTime::Now.Subtract(start).TotalSeconds, 4);
Console::WriteLine(L"Total WPF Elements: {0} in {1} seconds", winInfo->Length, seconds);
start = System::DateTime::Now;
ab->clearEnumFilters();
winInfo = ab->enumWindowInfo(propList);
//outputResults(winInfo);
seconds = System::Math::Round(System::DateTime::Now.Subtract(start).TotalSeconds, 4);
Console::WriteLine(L"Total All Elements: {0} in {1} seconds", winInfo->Length, seconds);
Console::WriteLine(L"---------------------------------------");
}
int main(array<System::String ^> ^args) int main(array<System::String ^> ^args)
{ {
Console::WriteLine(L"UI Automation Bridge Test"); Console::WriteLine(L"UI Automation Bridge Test");
AutomationBridge ^ab = gcnew AutomationBridge(); //System::String ^propList = L"RuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty";
System::String ^propList = L"RuntimeIdProperty,ParentRuntimeIdProperty,NativeWindowHandleProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty"; System::String ^propList = L"RuntimeIdProperty,ParentRuntimeIdProperty,NativeWindowHandleProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ControlTypeProperty,ClassNameProperty,NameProperty,BoundingRectangleProperty";
AutomationBridge ^ab = gcnew AutomationBridge(propList);
//System::String ^propList = L"RuntimeIdProperty,BoundingRectangleProperty"; //System::String ^propList = L"RuntimeIdProperty,BoundingRectangleProperty";
Console::WriteLine(propList); Console::WriteLine(propList);
//System::String ^winInfo1 = ab->getWindowInfo(System::IntPtr(3409618), propList);
System::DateTime start = System::DateTime::Now; runBasicTests(ab, propList);
runBasicTests(ab, propList);
runBasicTests(ab, propList);
//System::String ^winInfo1 = ab->getWindowInfo(System::IntPtr(3409618), propList);
//ab->addEnumFilter("Parent/ClassNameProperty", "Notepad"); //ab->addEnumFilter("Parent/ClassNameProperty", "Notepad");
//ab->addEnumFilter("First/RuntimeIdProperty", "42-4784952"); //ab->addEnumFilter("First/RuntimeIdProperty", "42-4784952");
//ab->addEnumFilter("ClassNameProperty", "Notepad"); //ab->addEnumFilter("ClassNameProperty", "Notepad");
//ab->addEnumFilter("All/ClassNameProperty", "Edit"); //ab->addEnumFilter("All/ClassNameProperty", "Edit");
//ab->addEnumFilter("All/LocalizedControlTypeProperty", "menu item"); //ab->addEnumFilter("All/LocalizedControlTypeProperty", "menu item");
ab->addEnumFilter("Parent/FrameworkIdProperty", "WinForm"); //ab->addEnumFilter("Parent/FrameworkIdProperty", "WinForm");
//ab->addEnumFilter("Parent/FrameworkIdProperty", "WPF"); //ab->addEnumFilter("Parent/FrameworkIdProperty", "WPF");
//ab->addEnumFilter("Parent/ClassNameProperty", "WindowsForms10.Window.8.app.0.2bf8098_r13_ad1"); //ab->addEnumFilter("Parent/ClassNameProperty", "WindowsForms10.Window.8.app.0.2bf8098_r13_ad1");
array<System::String ^> ^winInfo = ab->enumWindowInfo(propList); //L"*" //array<System::String ^> ^winInfo = ab->enumWindowInfo(propList); //L"*"
//ab->clearEnumFilters(); //ab->clearEnumFilters();
//ab->addEnumFilter("Parent/FrameworkIdProperty", "WinForm"); //ab->addEnumFilter("Parent/FrameworkIdProperty", "WinForm");
//array<System::String ^> ^winInfo = ab->enumWindowInfo(System::IntPtr(3409618), propList); //L"*" //array<System::String ^> ^winInfo = ab->enumWindowInfo(System::IntPtr(3409618), propList); //L"*"
//array<System::String ^> ^winInfo = ab->enumWindowInfo(System::IntPtr(12977932), propList); //L"*" //array<System::String ^> ^winInfo = ab->enumWindowInfo(System::IntPtr(12977932), propList); //L"*"
//Console::WriteLine("enumWindowInfo x,y: {0}", ab->getWindowInfo(100,100, propList); //L"*" //Console::WriteLine("enumWindowInfo x,y: {0}", ab->getWindowInfo(100,100, propList); //L"*"
outputResults(winInfo); //outputResults(winInfo);
//Globals::Global::AUTO_BRIDGE->clearEnumFilters(); //Globals::Global::AUTO_BRIDGE->clearEnumFilters();
//winInfo = nullptr; //winInfo = nullptr;
//winInfo = Globals::Global::AUTO_BRIDGE->enumWindowInfo(System::IntPtr(7603636), propList); //winInfo = Globals::Global::AUTO_BRIDGE->enumWindowInfo(System::IntPtr(7603636), propList);
@@ -64,8 +99,9 @@ int main(array<System::String ^> ^args)
//array<System::String ^> ^winInfo2 = ab->enumWindowInfo(propList); //L"*" //array<System::String ^> ^winInfo2 = ab->enumWindowInfo(propList); //L"*"
//outputResults(winInfo2); //outputResults(winInfo2);
System::Double seconds = System::Math::Round(System::DateTime::Now.Subtract(start).TotalSeconds, 4); //System::Double seconds = System::Math::Round(System::DateTime::Now.Subtract(start).TotalSeconds, 4);
Console::WriteLine(L"Total Elements: {0} in {1} seconds", winInfo->Length, seconds); //Console::WriteLine(L"Total Elements: {0} in {1} seconds", winInfo->Length, seconds);
Console::WriteLine(L"press any key to exit");
getch();//wait for user input getch();//wait for user input
return 0; return 0;
} }

View File

@@ -15,9 +15,11 @@ import com.sun.jna.Native;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.Structure; import com.sun.jna.Structure;
import com.sun.jna.platform.win32.WinDef.*; import com.sun.jna.platform.win32.WinDef.*;
import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.platform.win32.WinNT.HANDLE; 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.WinUser;
import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER; import com.sun.jna.platform.win32.WinNT.LARGE_INTEGER;
import com.sun.jna.platform.win32.WinUser.WNDENUMPROC; import com.sun.jna.platform.win32.WinUser.WNDENUMPROC;
@@ -133,6 +135,11 @@ public class Api {
return (int) (i & 0xFFFF); 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 WinDefExt extends WinDef { public interface WinDefExt extends WinDef {
//Structures //Structures
public class MENUITEMINFO extends Structure { public class MENUITEMINFO extends Structure {
@@ -235,6 +242,7 @@ public class Api {
//HWND WindowFromPoint(POINT point); //HWND WindowFromPoint(POINT point);
HMENU GetMenu(HWND hWnd); HMENU GetMenu(HWND hWnd);
HMENU GetSystemMenu(HWND hWnd, boolean bRevert);
boolean IsMenu(HMENU hMenu); boolean IsMenu(HMENU hMenu);
int GetMenuString(HMENU hMenu, int uIDItem, char[] buffer, int nMaxCount, int uFlag); int GetMenuString(HMENU hMenu, int uIDItem, char[] buffer, int nMaxCount, int uFlag);
HMENU GetSubMenu(HMENU hMenu, int nPos); HMENU GetSubMenu(HMENU hMenu, int nPos);
@@ -243,7 +251,7 @@ public class Api {
//BOOL WINAPI GetMenuItemInfo(_In_ HMENU hMenu, _In_ UINT uItem, _In_ BOOL fByPosition, _Inout_ LPMENUITEMINFO lpmii); //BOOL WINAPI GetMenuItemInfo(_In_ HMENU hMenu, _In_ UINT uItem, _In_ BOOL fByPosition, _Inout_ LPMENUITEMINFO lpmii);
boolean GetMenuItemInfoA(HMENU hMenu, int uItem, boolean fByPosition, WinDefExt.MENUITEMINFO mii); //MENUITEMINFO boolean GetMenuItemInfoA(HMENU hMenu, int uItem, boolean fByPosition, WinDefExt.MENUITEMINFO mii); //MENUITEMINFO
boolean TrackPopupMenu(HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, long prcRect); 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 GetDlgCtrlID(HWND hwndCtl);
int GetDlgItemText(HWND hDlg, int nIDDlgItem, byte[] buffer, int nMaxCount); int GetDlgItemText(HWND hDlg, int nIDDlgItem, byte[] buffer, int nMaxCount);
@@ -536,4 +544,10 @@ public class Api {
User32.instance.RedrawWindow(hwnd, 0, 0, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN); User32.instance.RedrawWindow(hwnd, 0, 0, RDW_FRAME | RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN);
} }
public static boolean isDotNet4Installed() {
int installed = Advapi32Util.registryGetIntValue(WinReg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4.0\\Client", "Install");
//System.out.println("isDotNet4Installed: " + installed);
return (installed == 1);
}
} }

View File

@@ -110,6 +110,9 @@ public class CommandPopupMenu extends JPopupMenu {
CommandMenuItem mntmSelectMenu = new CommandMenuItem("selectMenu", 2); CommandMenuItem mntmSelectMenu = new CommandMenuItem("selectMenu", 2);
mnWinMessages.add(mntmSelectMenu); mnWinMessages.add(mntmSelectMenu);
CommandMenuItem mntmSelectContextMenuId = new CommandMenuItem("selectContextMenuId", 3);
mnWinMessages.add(mntmSelectContextMenuId);
CommandMenuItem mntmSetcursorposition = new CommandMenuItem("setCursorPosition", 3); CommandMenuItem mntmSetcursorposition = new CommandMenuItem("setCursorPosition", 3);
mnWinMessages.add(mntmSetcursorposition); mnWinMessages.add(mntmSetcursorposition);

View File

@@ -205,6 +205,8 @@ public class CommandProcessor implements Runnable{
return win.cmdWindowFocus(args); return win.cmdWindowFocus(args);
if (command.equals("selectMenu")) if (command.equals("selectMenu"))
return win.cmdSelectMenu(args); return win.cmdSelectMenu(args);
if (command.equals("selectContextMenuId"))
return win.cmdSelectContextMenuId(args);
if (command.equals("windowMinimize")) if (command.equals("windowMinimize"))
return win.cmdWindowMinimize(args); return win.cmdWindowMinimize(args);
if (command.equals("windowMaximize")) if (command.equals("windowMaximize"))

View File

@@ -131,7 +131,7 @@ public class KeyboardHook implements Runnable{
} }
// search target keyboard event list for a match and return it otherwise return null if no match // search target keyboard event list for a match and return it otherwise return null if no match
public TargetKeyPress getTargetKeyPressed(int keyCode) { private TargetKeyPress getTargetKeyPressed(int keyCode) {
TargetKeyPress target = null; TargetKeyPress target = null;
for (TargetKeyPress tkp : KeyboardHook.targetList) { for (TargetKeyPress tkp : KeyboardHook.targetList) {
if (tkp.targetKeyCode != keyCode) if (tkp.targetKeyCode != keyCode)
@@ -159,6 +159,7 @@ public class KeyboardHook implements Runnable{
@Override @Override
public void run() { public void run() {
createGlobalKeyboardHook(); createGlobalKeyboardHook();
System.out.println("Unhooking Global Keyboard Hook");
unhook();//wait for quit == true then unhook unhook();//wait for quit == true then unhook
} }

View File

@@ -10,7 +10,7 @@ package org.synthuse;
import java.math.BigInteger; import java.math.BigInteger;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinDef.HMENU; import com.sun.jna.platform.win32.WinDef.*;
public class MenuInfo { public class MenuInfo {
public HMENU hmenu = null; public HMENU hmenu = null;
@@ -25,12 +25,15 @@ public class MenuInfo {
public HMENU submenu = null; public HMENU submenu = null;
public String submenuStr = ""; public String submenuStr = "";
public int submenuCount = 0; public int submenuCount = 0;
public String center = "";
public MenuInfo(HMENU hmenu) { public MenuInfo(String hwndStr, HMENU hmenu) {
this.hwndStr = hwndStr;
loadMenuBase(hmenu); loadMenuBase(hmenu);
} }
public MenuInfo(HMENU hmenu, int position) { public MenuInfo(String hwndStr, HMENU hmenu, int position) {
this.hwndStr = hwndStr;
loadMenuBase(hmenu); loadMenuBase(hmenu);
if (this.menuCount > 0) if (this.menuCount > 0)
loadMenuDetails(hmenu, position); loadMenuDetails(hmenu, position);
@@ -52,6 +55,14 @@ public class MenuInfo {
this.text = this.text.substring(0, this.text.indexOf("\t")); this.text = this.text.substring(0, this.text.indexOf("\t"));
this.text = text.replaceAll("[^a-zA-Z0-9.,\\+ ]", ""); this.text = text.replaceAll("[^a-zA-Z0-9.,\\+ ]", "");
this.id = api.user32.GetMenuItemID(hmenu, position); 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); HMENU submenu = api.user32.GetSubMenu(hmenu, position);
if (submenu != null) { if (submenu != null) {
int subCount = api.user32.GetMenuItemCount(submenu); int subCount = api.user32.GetMenuItemCount(submenu);

View File

@@ -68,7 +68,7 @@ public class RobotMacro {
public static void rightClickMouse() { public static void rightClickMouse() {
try { try {
System.out.println("rightClickMouse"); //System.out.println("rightClickMouse");
Robot robot = new Robot(); Robot robot = new Robot();
//robot.mouseMove(200, 200); //robot.mouseMove(200, 200);
//robot.delay(1000); //robot.delay(1000);

View File

@@ -71,7 +71,7 @@ public class SynthuseDlg extends JFrame {
/** /**
* *
*/ */
public static String VERSION_STR = "1.1.3"; public static String VERSION_STR = "1.1.4";
public static String RES_STR_MAIN_ICON = "/org/synthuse/img/gnome-robots.png"; 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_REFRESH_IMG = "/org/synthuse/img/rapidsvn.png";

View File

@@ -6,8 +6,13 @@ import java.io.*;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
public class UiaBridge { public class UiaBridge {
public static String CACHED_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty,BoundingRectangleProperty";
static static
{ {
if (!Api.isDotNet4Installed()) //if .net 4.0 isn't installed don't use uiabridge
SynthuseDlg.config.disableUiaBridge = "true";
if (!SynthuseDlg.config.isUiaBridgeDisabled()) { if (!SynthuseDlg.config.isUiaBridgeDisabled()) {
//System.out.println("SynthuseDlg.config.disableUiaBridge: " + SynthuseDlg.config.disableUiaBridge); //System.out.println("SynthuseDlg.config.disableUiaBridge: " + SynthuseDlg.config.disableUiaBridge);
String archDataModel = System.getProperty("sun.arch.data.model");//32 or 64 bit String archDataModel = System.getProperty("sun.arch.data.model");//32 or 64 bit
@@ -78,7 +83,7 @@ public class UiaBridge {
public UiaBridge () public UiaBridge ()
{ {
if (!SynthuseDlg.config.isUiaBridgeDisabled()) if (!SynthuseDlg.config.isUiaBridgeDisabled())
initialize(""); initialize(CACHED_PROPERTY_LIST);
} }
public native void initialize(String properties); public native void initialize(String properties);

View File

@@ -26,6 +26,7 @@ public class WindowInfo {
public static String UIA_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty"; public static String UIA_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty";
public static String UIA_RUNTIME_ID = "RuntimeIdProperty"; public static String UIA_RUNTIME_ID = "RuntimeIdProperty";
public static String UIA_BOUNDING_RECT = "BoundingRectangleProperty";
public static int MAX_TEXT_SIZE = 200; public static int MAX_TEXT_SIZE = 200;
public HWND hwnd; public HWND hwnd;
@@ -96,23 +97,7 @@ public class WindowInfo {
extra = new LinkedHashMap<String, String>(); extra = new LinkedHashMap<String, String>();
extra.put("tvCount", tvCount.intValue() + ""); extra.put("tvCount", tvCount.intValue() + "");
} }
/*
//check if window has a menu
HMENU hmenu = Api.User32.instance.GetMenu(hWnd);
if (hmenu != null) { //menu item count
int menuCount = Api.User32.instance.GetMenuItemCount(hmenu);
if (menuCount > 0) {
this.menus = menuCount;
this.menu = hmenu;
}
else
{
LRESULT result = Api.User32.instance.PostMessage(hWnd, Api.MN_GETHMENU, new WPARAM(0), new LPARAM());
if (result.longValue() != 1)
System.out.println("MN_GETHMENU: " + result.longValue());
}
}
if (isChild) { if (isChild) {
int ctrlID = Api.User32.instance.GetDlgCtrlID(hWnd); int ctrlID = Api.User32.instance.GetDlgCtrlID(hWnd);
if (ctrlID > 0){ if (ctrlID > 0){
@@ -125,12 +110,40 @@ public class WindowInfo {
extra.put("dgText", dgText + ""); extra.put("dgText", dgText + "");
} }
} }
} }*/
char[] buffer2 = new char[1026]; char[] buffer2 = new char[1026];
User32.instance.GetClassName(hWnd, buffer2, 1026); User32.instance.GetClassName(hWnd, buffer2, 1026);
className = Native.toString(buffer2); className = Native.toString(buffer2);
//check if window has a menu
HMENU hmenu = Api.User32.instance.GetMenu(hWnd);
if (hmenu != null) { //menu item count
int menuCount = Api.User32.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.User32.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.User32.instance.GetMenuItemCount(hmenu);
if (menuCount > 0)
{
//System.out.println("Popup Win: " + menuCount);
this.menus = menuCount;
this.menu = hmenu;
}
}
}
rect = new RECT(); rect = new RECT();
User32.instance.GetWindowRect(hWnd, rect); User32.instance.GetWindowRect(hWnd, rect);

View File

@@ -249,16 +249,18 @@ public class WindowsEnumeratedXml implements Runnable{
public static Element buildMenuXmlElements(Document xmlDoc, Element xmlElement, HMENU targetMenu, String targetWin) public static Element buildMenuXmlElements(Document xmlDoc, Element xmlElement, HMENU targetMenu, String targetWin)
{ {
MenuInfo firstMi = new MenuInfo(targetMenu); MenuInfo firstMi = new MenuInfo(targetWin, targetMenu);
for (int i = 0 ; i < firstMi.menuCount ; i++ ) { for (int i = 0 ; i < firstMi.menuCount ; i++ ) {
MenuInfo menuInfo = new MenuInfo(targetMenu, i); MenuInfo menuInfo = new MenuInfo(targetWin, targetMenu, i);
Element menuElement = xmlDoc.createElement("menu"); Element menuElement = xmlDoc.createElement("menu");
menuElement.setAttribute("unaltered", menuInfo.unaltered + ""); menuElement.setAttribute("unaltered", menuInfo.unaltered + "");
menuElement.setAttribute("text", menuInfo.text + ""); menuElement.setAttribute("text", menuInfo.text + "");
menuElement.setAttribute("id", menuInfo.id + ""); menuElement.setAttribute("id", menuInfo.id + "");
menuElement.setAttribute("position", menuInfo.position + ""); menuElement.setAttribute("position", menuInfo.position + "");
menuElement.setAttribute("hmenu", menuInfo.hmenuStr + ""); menuElement.setAttribute("hmenu", menuInfo.hmenuStr + "");
menuElement.setAttribute("hwnd", targetWin + ""); menuElement.setAttribute("hwnd", menuInfo.hwndStr + "");
if (!menuInfo.center.isEmpty())
menuElement.setAttribute("center", menuInfo.center + "");
if (menuInfo.hasSubMenu) { if (menuInfo.hasSubMenu) {
buildMenuXmlElements(xmlDoc, menuElement, menuInfo.submenu, targetWin); buildMenuXmlElements(xmlDoc, menuElement, menuInfo.submenu, targetWin);
} }

View File

@@ -122,6 +122,22 @@ public class WindowsCommands extends BaseCommand {
//LRESULT result = //LRESULT result =
//System.out.println("PostMessage to " + handle.hWndStr + " for id " + id); //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.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
//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; return true;
} }
} }