Extended Msg hook text limit, msg hook prompts before switching between 32 and 64 bits, optionally disable uiabridge's caches
Message Hook Viewer text limit is not set to 700,000 characters, allowing it to show many more messages/lines Message Hook Viewer will prompt user if the want to switch between 64 and 32 bits. UiaBridge has an optional flag to disable cache. This fixes an issue where caching is either slower or causes issues when using multiple threads in OASIS.
This commit is contained in:
BIN
native/MsgHook.suo
Normal file
BIN
native/MsgHook.suo
Normal file
Binary file not shown.
@@ -23,6 +23,7 @@ TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
|
|||||||
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
|
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
|
||||||
HWND mainHwnd = NULL;
|
HWND mainHwnd = NULL;
|
||||||
HMENU mainMenu = NULL;
|
HMENU mainMenu = NULL;
|
||||||
|
#define TXTBOX_LIMIT 700000
|
||||||
HWND txtbox = NULL;
|
HWND txtbox = NULL;
|
||||||
HWND targetHwnd = NULL;
|
HWND targetHwnd = NULL;
|
||||||
DWORD targetPid = 0;
|
DWORD targetPid = 0;
|
||||||
@@ -68,9 +69,9 @@ void AppendText(HWND txtHwnd, LPCTSTR newText)
|
|||||||
if (isPaused)
|
if (isPaused)
|
||||||
return;
|
return;
|
||||||
DWORD len = GetWindowTextLength(txtHwnd);
|
DWORD len = GetWindowTextLength(txtHwnd);
|
||||||
if (len > 25000)
|
if (len > (TXTBOX_LIMIT - 500))
|
||||||
{//need to truncate the beginning so the text doesn't go past it's limit
|
{//need to truncate the beginning so the text doesn't go past it's limit
|
||||||
SendMessage(txtHwnd, EM_SETSEL, 0, 10000);
|
SendMessage(txtHwnd, EM_SETSEL, 0, 20000);
|
||||||
SendMessage(txtHwnd, EM_REPLACESEL, 0, (LPARAM)_T(""));
|
SendMessage(txtHwnd, EM_REPLACESEL, 0, (LPARAM)_T(""));
|
||||||
len = GetWindowTextLength(txtHwnd);
|
len = GetWindowTextLength(txtHwnd);
|
||||||
}
|
}
|
||||||
@@ -173,7 +174,10 @@ void StartMessageHook()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_stprintf_s(tmp, _T("Target PId (%ld) is a not matching bit process\r\n"), targetPid);
|
if (current64bit)
|
||||||
|
_stprintf_s(tmp, _T("Target PId (%ld) is a not matching 64 bit process.\r\n"), targetPid);
|
||||||
|
else
|
||||||
|
_stprintf_s(tmp, _T("Target PId (%ld) is a not matching 32 bit process.\r\n"), targetPid);
|
||||||
AppendText(txtbox, tmp);
|
AppendText(txtbox, tmp);
|
||||||
TCHAR *dllname = dll32bitName;
|
TCHAR *dllname = dll32bitName;
|
||||||
TCHAR *exename = _T("SetMsgHook32.exe");
|
TCHAR *exename = _T("SetMsgHook32.exe");
|
||||||
@@ -184,12 +188,17 @@ void StartMessageHook()
|
|||||||
exename = _T("SetMsgHook64.exe");
|
exename = _T("SetMsgHook64.exe");
|
||||||
setMsgHookRes = IDR_SETMH64;
|
setMsgHookRes = IDR_SETMH64;
|
||||||
}
|
}
|
||||||
|
_tcscat_s(tmp, 500, _T("Do you wish to open a new matching Message Hook Window?"));
|
||||||
|
int mbResult = MessageBox(mainHwnd, tmp, _T("Message Hook"), MB_ICONQUESTION | MB_YESNO);
|
||||||
|
if (mbResult == IDNO)
|
||||||
|
return ;
|
||||||
_stprintf_s(tmp, _T("%s %s 0 %d"), exename, dllname, targetPid);
|
_stprintf_s(tmp, _T("%s %s 0 %d"), exename, dllname, targetPid);
|
||||||
RunResource(setMsgHookRes, tmp);
|
RunResource(setMsgHookRes, tmp);
|
||||||
//EnableMenuItem(mainMenu, ID_FILE_STOPHOOK, MF_ENABLED);
|
//EnableMenuItem(mainMenu, ID_FILE_STOPHOOK, MF_ENABLED);
|
||||||
//EnableMenuItem(mainMenu, ID_FILE_STARTHOOK, MF_DISABLED | MF_GRAYED);
|
//EnableMenuItem(mainMenu, ID_FILE_STARTHOOK, MF_DISABLED | MF_GRAYED);
|
||||||
_tcscat_s(tmp, 500, _T("\r\n"));
|
_tcscat_s(tmp, 500, _T("\r\n"));
|
||||||
AppendText(txtbox, tmp);
|
AppendText(txtbox, tmp);
|
||||||
|
PostQuitMessage(2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AppendText(txtbox, tmp);
|
AppendText(txtbox, tmp);
|
||||||
@@ -431,6 +440,7 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|||||||
if (!hWnd) {
|
if (!hWnd) {
|
||||||
DWORD lastErr = GetLastError();
|
DWORD lastErr = GetLastError();
|
||||||
printf("Error Creating Window %d\n", lastErr);
|
printf("Error Creating Window %d\n", lastErr);
|
||||||
|
_tprintf(_T("Window Class Name: %s, Instance: %ld\n"), szWindowClass, (long)hInstance);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
mainHwnd = hWnd;
|
mainHwnd = hWnd;
|
||||||
@@ -441,6 +451,7 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
|
|||||||
//WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL
|
//WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL
|
||||||
txtbox = CreateWindow(TEXT("Edit"),TEXT(""), WS_CHILD | WS_VISIBLE | ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_READONLY,
|
txtbox = CreateWindow(TEXT("Edit"),TEXT(""), WS_CHILD | WS_VISIBLE | ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_READONLY,
|
||||||
txtboxSpacing, txtboxSpacing,rect.right-(txtboxSpacing*2), rect.bottom-(txtboxSpacing*2), hWnd, NULL, NULL, NULL);
|
txtboxSpacing, txtboxSpacing,rect.right-(txtboxSpacing*2), rect.bottom-(txtboxSpacing*2), hWnd, NULL, NULL, NULL);
|
||||||
|
SendMessage(txtbox, EM_SETLIMITTEXT, (WPARAM)TXTBOX_LIMIT, 0);
|
||||||
|
|
||||||
HFONT hFont = CreateFont(14, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
|
HFONT hFont = CreateFont(14, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET,
|
||||||
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -78,11 +78,15 @@ void MsgHook_CreateMsgHookWindow(LPTSTR args)
|
|||||||
if (msgHookDll != NULL)
|
if (msgHookDll != NULL)
|
||||||
{
|
{
|
||||||
CreateMsgHookWindow = (CREATEMSGHOOKWINDOW)GetProcAddress(msgHookDll, "CreateMsgHookWindow");
|
CreateMsgHookWindow = (CREATEMSGHOOKWINDOW)GetProcAddress(msgHookDll, "CreateMsgHookWindow");
|
||||||
|
SetGlobalDLLInstance = (SETGLOBALDLLINSTANCE)GetProcAddress(msgHookDll, "SetGlobalDLLInstance");
|
||||||
if (CreateMsgHookWindow)
|
if (CreateMsgHookWindow)
|
||||||
{
|
{
|
||||||
|
SetGlobalDLLInstance(msgHookDll);
|
||||||
CreateMsgHookWindow(args);
|
CreateMsgHookWindow(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (msgHookDll != NULL)
|
||||||
|
FreeLibrary(msgHookDll);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL MsgHook_SetMsgHook(HWND hw, int threadId)
|
BOOL MsgHook_SetMsgHook(HWND hw, int threadId)
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ int _tmain(int argc, _TCHAR* argv[])
|
|||||||
TCHAR tmp[100];
|
TCHAR tmp[100];
|
||||||
_stprintf_s(tmp, _T("%ld"), (long)procId);
|
_stprintf_s(tmp, _T("%ld"), (long)procId);
|
||||||
MsgHook_CreateMsgHookWindow(tmp);
|
MsgHook_CreateMsgHookWindow(tmp);
|
||||||
|
//_getch();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -37,6 +37,16 @@ JNIEXPORT void JNICALL Java_org_synthuse_UiaBridge_shutdown(JNIEnv *env, jobject
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_synthuse_UiaBridge
|
||||||
|
* Method: useCachedRequests
|
||||||
|
* Signature: (Z)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_org_synthuse_UiaBridge_useCachedRequests(JNIEnv *env, jobject obj, jboolean jcacheRequestsFlg)
|
||||||
|
{
|
||||||
|
Global::AUTO_BRIDGE->useCachedRequests((bool)(jcacheRequestsFlg == JNI_TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_synthuse_UiaBridge
|
* Class: org_synthuse_UiaBridge
|
||||||
* Method: addEnumFilter
|
* Method: addEnumFilter
|
||||||
|
|||||||
@@ -23,6 +23,14 @@ JNIEXPORT void JNICALL Java_org_synthuse_UiaBridge_initialize
|
|||||||
JNIEXPORT void JNICALL Java_org_synthuse_UiaBridge_shutdown
|
JNIEXPORT void JNICALL Java_org_synthuse_UiaBridge_shutdown
|
||||||
(JNIEnv *, jobject);
|
(JNIEnv *, jobject);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: org_synthuse_UiaBridge
|
||||||
|
* Method: useCachedRequests
|
||||||
|
* Signature: (Z)V
|
||||||
|
*/
|
||||||
|
JNIEXPORT void JNICALL Java_org_synthuse_UiaBridge_useCachedRequests
|
||||||
|
(JNIEnv *, jobject, jboolean);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: org_synthuse_UiaBridge
|
* Class: org_synthuse_UiaBridge
|
||||||
* Method: addEnumFilter
|
* Method: addEnumFilter
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ AutomationBridge::AutomationBridge()
|
|||||||
{
|
{
|
||||||
enumFilters = gcnew Dictionary<System::String ^, System::String ^>();
|
enumFilters = gcnew Dictionary<System::String ^, System::String ^>();
|
||||||
cacheRequest = nullptr;
|
cacheRequest = nullptr;
|
||||||
|
useCache = true;
|
||||||
initializeCache("");
|
initializeCache("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ AutomationBridge::AutomationBridge(System::String ^cachedProperties)
|
|||||||
{
|
{
|
||||||
enumFilters = gcnew Dictionary<System::String ^, System::String ^>();
|
enumFilters = gcnew Dictionary<System::String ^, System::String ^>();
|
||||||
cacheRequest = nullptr;
|
cacheRequest = nullptr;
|
||||||
|
useCache = true;
|
||||||
initializeCache(cachedProperties);
|
initializeCache(cachedProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +38,11 @@ AutomationBridge::~AutomationBridge()
|
|||||||
//Console::WriteLine("disposing of AutomationBridge");
|
//Console::WriteLine("disposing of AutomationBridge");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AutomationBridge::useCachedRequests(System::Boolean cacheRequestsFlg)
|
||||||
|
{
|
||||||
|
useCache = cacheRequestsFlg;
|
||||||
|
}
|
||||||
|
|
||||||
void AutomationBridge::initializeCache(System::String ^cachedProperties)
|
void AutomationBridge::initializeCache(System::String ^cachedProperties)
|
||||||
{
|
{
|
||||||
cacheRequest = gcnew CacheRequest();
|
cacheRequest = gcnew CacheRequest();
|
||||||
@@ -158,7 +165,10 @@ Boolean AutomationBridge::isElementFiltered(System::Windows::Automation::Automat
|
|||||||
}
|
}
|
||||||
else //all other property types that are strings
|
else //all other property types that are strings
|
||||||
{
|
{
|
||||||
valStr = element->GetCachedPropertyValue(ap)->ToString();
|
if (useCache)
|
||||||
|
valStr = element->GetCachedPropertyValue(ap)->ToString();
|
||||||
|
else
|
||||||
|
valStr = element->GetCurrentPropertyValue(ap)->ToString();
|
||||||
//valStr = element->GetCurrentPropertyValue(ap)->ToString();
|
//valStr = element->GetCurrentPropertyValue(ap)->ToString();
|
||||||
}
|
}
|
||||||
//System::Console::WriteLine("test property vals: {0} , {1}", valStr, enumFilters[key]);
|
//System::Console::WriteLine("test property vals: {0} , {1}", valStr, enumFilters[key]);
|
||||||
@@ -285,7 +295,12 @@ array<System::String ^> ^ AutomationBridge::enumWindowInfo(AutomationElement ^pa
|
|||||||
//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;
|
||||||
currentElement = tw->GetFirstChild(parentElement, cacheRequest);
|
|
||||||
|
if (useCache)
|
||||||
|
currentElement = tw->GetFirstChild(parentElement, cacheRequest);
|
||||||
|
else
|
||||||
|
currentElement = tw->GetFirstChild(parentElement);
|
||||||
|
|
||||||
if (currentElement == nullptr)
|
if (currentElement == nullptr)
|
||||||
{
|
{
|
||||||
//System::Console::WriteLine("no children {0}", element->CachedChildren->Count);
|
//System::Console::WriteLine("no children {0}", element->CachedChildren->Count);
|
||||||
@@ -319,7 +334,10 @@ array<System::String ^> ^ AutomationBridge::enumWindowInfo(AutomationElement ^pa
|
|||||||
{
|
{
|
||||||
output(ex, "");
|
output(ex, "");
|
||||||
}
|
}
|
||||||
currentElement = tw->GetNextSibling(currentElement, cacheRequest);
|
if (useCache)
|
||||||
|
currentElement = tw->GetNextSibling(currentElement, cacheRequest);
|
||||||
|
else
|
||||||
|
currentElement = tw->GetNextSibling(currentElement);
|
||||||
}
|
}
|
||||||
return winInfoList->ToArray();
|
return winInfoList->ToArray();
|
||||||
}
|
}
|
||||||
@@ -387,7 +405,12 @@ System::String ^ AutomationBridge::getWindowInfo(AutomationElement ^element, Sys
|
|||||||
else
|
else
|
||||||
currentVal = element->GetCurrentPropertyValue(ap); //cached pattern was having issues;
|
currentVal = element->GetCurrentPropertyValue(ap); //cached pattern was having issues;
|
||||||
}
|
}
|
||||||
currentVal = element->GetCachedPropertyValue(ap);
|
|
||||||
|
if (useCache)
|
||||||
|
currentVal = element->GetCachedPropertyValue(ap);
|
||||||
|
else
|
||||||
|
currentVal = element->GetCurrentPropertyValue(ap);
|
||||||
|
|
||||||
if (currentVal == nullptr)
|
if (currentVal == nullptr)
|
||||||
continue;
|
continue;
|
||||||
if (ap->ProgrammaticName->Equals(L"AutomationElementIdentifiers.RuntimeIdProperty"))
|
if (ap->ProgrammaticName->Equals(L"AutomationElementIdentifiers.RuntimeIdProperty"))
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace uiabridge {
|
|||||||
AutomationBridge(void);
|
AutomationBridge(void);
|
||||||
AutomationBridge(System::String ^cachedProperties);
|
AutomationBridge(System::String ^cachedProperties);
|
||||||
~AutomationBridge();
|
~AutomationBridge();
|
||||||
|
void useCachedRequests(System::Boolean cacheRequestsFlg);
|
||||||
int addEnumFilter(System::String ^propertyName, System::String ^propertyValue);
|
int addEnumFilter(System::String ^propertyName, System::String ^propertyValue);
|
||||||
void clearEnumFilters();
|
void clearEnumFilters();
|
||||||
Boolean isElementFiltered(System::Windows::Automation::AutomationElement ^element);
|
Boolean isElementFiltered(System::Windows::Automation::AutomationElement ^element);
|
||||||
@@ -38,12 +39,14 @@ namespace uiabridge {
|
|||||||
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";
|
static System::String ^DEFAULT_CACHED_PROPS = L"RuntimeIdProperty,ParentRuntimeIdProperty,NativeWindowHandleProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ControlTypeProperty,ClassNameProperty,NameProperty,BoundingRectangleProperty,ValueProperty";
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initializeCache(System::String ^cachedProperties);
|
void initializeCache(System::String ^cachedProperties);
|
||||||
void output(Exception ^ex, System::String ^message);
|
void output(Exception ^ex, System::String ^message);
|
||||||
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;
|
||||||
|
System::Boolean useCache;
|
||||||
array<AutomationProperty^> ^cachedRootProperties;
|
array<AutomationProperty^> ^cachedRootProperties;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
5
native/uiabtest/build.bat
Normal file
5
native/uiabtest/build.bat
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
REM set path=C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\bin;%path%
|
||||||
|
|
||||||
|
%WinDir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe /p:configuration=release /p:platform=win32 %*
|
||||||
|
|
||||||
|
pause
|
||||||
@@ -60,11 +60,18 @@ int main(array<System::String ^> ^args)
|
|||||||
{
|
{
|
||||||
Console::WriteLine(L"UI Automation Bridge Test");
|
Console::WriteLine(L"UI Automation Bridge Test");
|
||||||
//System::String ^propList = L"RuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty";
|
//System::String ^propList = L"RuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty";
|
||||||
System::String ^propList = L"RuntimeIdProperty,ParentRuntimeIdProperty,NativeWindowHandleProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ControlTypeProperty,ClassNameProperty,NameProperty,BoundingRectangleProperty";
|
System::String ^propList = L"RuntimeIdProperty,ParentRuntimeIdProperty,NativeWindowHandleProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty,BoundingRectangleProperty";
|
||||||
AutomationBridge ^ab = gcnew AutomationBridge(propList);
|
AutomationBridge ^ab = gcnew AutomationBridge(propList);
|
||||||
//System::String ^propList = L"RuntimeIdProperty,BoundingRectangleProperty";
|
//System::String ^propList = L"RuntimeIdProperty,BoundingRectangleProperty";
|
||||||
Console::WriteLine(propList);
|
Console::WriteLine(propList);
|
||||||
|
Console::WriteLine(L"\nCached Requests Enabled");
|
||||||
|
ab->useCachedRequests(true);//disable cache
|
||||||
|
runBasicTests(ab, propList);
|
||||||
|
runBasicTests(ab, propList);
|
||||||
|
runBasicTests(ab, propList);
|
||||||
|
|
||||||
|
Console::WriteLine(L"Cached Requests Disabled");
|
||||||
|
ab->useCachedRequests(false);//disable cache
|
||||||
runBasicTests(ab, propList);
|
runBasicTests(ab, propList);
|
||||||
runBasicTests(ab, propList);
|
runBasicTests(ab, propList);
|
||||||
runBasicTests(ab, propList);
|
runBasicTests(ab, propList);
|
||||||
@@ -102,6 +109,6 @@ int main(array<System::String ^> ^args)
|
|||||||
//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");
|
Console::WriteLine(L"press any key to exit");
|
||||||
getch();//wait for user input
|
_getch();//wait for user input
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ public class KeyboardHook implements Runnable{
|
|||||||
public static HHOOK hHook = null;
|
public static HHOOK hHook = null;
|
||||||
public static LowLevelKeyboardProc lpfn;
|
public static LowLevelKeyboardProc lpfn;
|
||||||
public static volatile boolean quit = false;
|
public static volatile boolean quit = false;
|
||||||
|
|
||||||
|
private static Thread khThread = null;
|
||||||
|
|
||||||
|
|
||||||
public interface User32Ex extends W32APIOptions {
|
public interface User32Ex extends W32APIOptions {
|
||||||
@@ -199,6 +201,14 @@ public class KeyboardHook implements Runnable{
|
|||||||
//stops Keyboard hook and causes the unhook command to be called
|
//stops Keyboard hook and causes the unhook command to be called
|
||||||
public static void stopKeyboardHook() {
|
public static void stopKeyboardHook() {
|
||||||
quit = true;
|
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
|
// search target keyboard event list for a match and return it otherwise return null if no match
|
||||||
@@ -228,14 +238,27 @@ public class KeyboardHook implements Runnable{
|
|||||||
}
|
}
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clear all target keys to watch for
|
||||||
|
public static void clearKeyEvent() {
|
||||||
|
KeyboardHook.targetList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// add more target keys to watch for
|
// add more target keys to watch for
|
||||||
public static void addKeyEvent(int targetKeyCode, boolean withShift, boolean withCtrl, boolean withAlt) {
|
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));
|
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
|
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) {
|
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||||
//BOOL WINAPI RegisterHotKey(HWND hWnd, int id, UINT fsModifiers, UINT vk);
|
//BOOL WINAPI RegisterHotKey(HWND hWnd, int id, UINT fsModifiers, UINT vk);
|
||||||
int modifiers = User32.MOD_NOREPEAT;
|
int modifiers = User32.MOD_NOREPEAT;
|
||||||
@@ -256,6 +279,7 @@ public class KeyboardHook implements Runnable{
|
|||||||
|
|
||||||
private void unregisterAllHotKeys() // must register hot keys in the same thread that is watching for hotkey messages
|
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) {
|
for (TargetKeyPress tkp : KeyboardHook.targetList) {
|
||||||
if (!User32.INSTANCE.UnregisterHotKey(Pointer.NULL, tkp.idNumber))
|
if (!User32.INSTANCE.UnregisterHotKey(Pointer.NULL, tkp.idNumber))
|
||||||
{
|
{
|
||||||
@@ -263,12 +287,6 @@ public class KeyboardHook implements Runnable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// add more target keys to watch for
|
|
||||||
public static void addKeyEvent(int targetKeyCode) {
|
|
||||||
KeyboardHook.targetList.add(new TargetKeyPress(targetKeyCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -286,8 +304,9 @@ public class KeyboardHook implements Runnable{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void StartKeyboardHookThreaded(KeyboardEvents events) {
|
public static void StartKeyboardHookThreaded(KeyboardEvents events) {
|
||||||
Thread t = new Thread(new KeyboardHook(events));
|
quit = false;
|
||||||
t.start();
|
khThread = new Thread(new KeyboardHook(events));
|
||||||
|
khThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class SynthuseDlg extends JFrame {
|
|||||||
//private MessageHookFrame msgHook = null;
|
//private MessageHookFrame msgHook = null;
|
||||||
private int targetX;
|
private int targetX;
|
||||||
private int targetY;
|
private int targetY;
|
||||||
private UiaBridge uiabridge = new UiaBridge();
|
private UiaBridge uiabridge = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launch the application.
|
* Launch the application.
|
||||||
@@ -296,7 +296,7 @@ public class SynthuseDlg extends JFrame {
|
|||||||
|
|
||||||
btnFind = new JButton("Find");
|
btnFind = new JButton("Find");
|
||||||
btnFind.addActionListener(new ActionListener() {
|
btnFind.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent arg0) {
|
public void actionPerformed(ActionEvent arg0) {
|
||||||
String xpathItem = cmbXpath.getSelectedItem().toString();
|
String xpathItem = cmbXpath.getSelectedItem().toString();
|
||||||
int matches = XpathManager.nextXpathMatch(xpathItem, textPane, lblStatus, false);
|
int matches = XpathManager.nextXpathMatch(xpathItem, textPane, lblStatus, false);
|
||||||
if (matches < 0) //check for an error
|
if (matches < 0) //check for an error
|
||||||
@@ -427,43 +427,18 @@ public class SynthuseDlg extends JFrame {
|
|||||||
this.addWindowListener(new WindowAdapter() {
|
this.addWindowListener(new WindowAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void windowClosing(WindowEvent arg0) {
|
public void windowClosing(WindowEvent arg0) {
|
||||||
|
//System.out.println("synthuse window closed");
|
||||||
KeyboardHook.stopKeyboardHook(); //stop keyboard hook
|
KeyboardHook.stopKeyboardHook(); //stop keyboard hook
|
||||||
config.save();
|
config.save();
|
||||||
SynthuseDlg.this.dispose(); // force app to close
|
SynthuseDlg.this.dispose(); // force app to close
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
KeyboardHook.addKeyEvent(config.getRefreshKeyCode(), true, true, false);// refresh xml when CTRL+SHIFT+3 is pressed
|
initializeHotKeys();
|
||||||
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
btnRefresh.doClick();
|
btnRefresh.doClick();
|
||||||
|
//uiabridge = new UiaBridge();
|
||||||
|
//uiabridge.useCachedRequests(false);
|
||||||
refreshDatabinding();
|
refreshDatabinding();
|
||||||
super.setAlwaysOnTop(config.isAlwaysOnTop());
|
super.setAlwaysOnTop(config.isAlwaysOnTop());
|
||||||
}
|
}
|
||||||
@@ -497,7 +472,7 @@ public class SynthuseDlg extends JFrame {
|
|||||||
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
|
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/2-this.getSize().height/2);
|
||||||
this.setVisible(true);
|
this.setVisible(true);
|
||||||
return dialogResult;
|
return dialogResult;// this gets returned immediately
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshDatabinding() {
|
public void refreshDatabinding() {
|
||||||
@@ -507,6 +482,40 @@ public class SynthuseDlg extends JFrame {
|
|||||||
XmlEditorKit.TAG_HIGHLIGHTED = config.xpathHightlight;
|
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() {
|
public void targetDragged() {
|
||||||
HWND hwnd = Api.getWindowFromCursorPos();//new Point(targetX,targetY)
|
HWND hwnd = Api.getWindowFromCursorPos();//new Point(targetX,targetY)
|
||||||
String handleStr = Api.GetHandleAsString(hwnd);
|
String handleStr = Api.GetHandleAsString(hwnd);
|
||||||
@@ -518,7 +527,13 @@ public class SynthuseDlg extends JFrame {
|
|||||||
|
|
||||||
String enumProperties = "";
|
String enumProperties = "";
|
||||||
if (!SynthuseDlg.config.isUiaBridgeDisabled())
|
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);
|
enumProperties = uiabridge.getWindowInfo(targetX, targetY, WindowInfo.UIA_PROPERTY_LIST_ADV);
|
||||||
|
}
|
||||||
String runtimeId = WindowInfo.getRuntimeIdFromProperties(enumProperties);
|
String runtimeId = WindowInfo.getRuntimeIdFromProperties(enumProperties);
|
||||||
String framework = WindowInfo.getFrameworkFromProperties(enumProperties);
|
String framework = WindowInfo.getFrameworkFromProperties(enumProperties);
|
||||||
Rectangle rect = UiaBridge.getBoundaryRect(enumProperties);
|
Rectangle rect = UiaBridge.getBoundaryRect(enumProperties);
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ public class UiaBridge {
|
|||||||
|
|
||||||
public native void initialize(String properties);
|
public native void initialize(String properties);
|
||||||
public native void shutdown();
|
public native void shutdown();
|
||||||
|
public native void useCachedRequests(boolean cacheRequestsFlg);
|
||||||
public native int addEnumFilter(String propertyName, String propertyValue);
|
public native int addEnumFilter(String propertyName, String propertyValue);
|
||||||
public native void clearEnumFilters();
|
public native void clearEnumFilters();
|
||||||
public native String[] enumWindowInfo(String properties);
|
public native String[] enumWindowInfo(String properties);
|
||||||
@@ -169,10 +170,12 @@ public class UiaBridge {
|
|||||||
{
|
{
|
||||||
String[] boundarySplt = replaceEscapedCodes(propSplt[propSplt.length - 1]).split(",");
|
String[] boundarySplt = replaceEscapedCodes(propSplt[propSplt.length - 1]).split(",");
|
||||||
if (boundarySplt.length == 4 )
|
if (boundarySplt.length == 4 )
|
||||||
rect.x = Integer.parseInt(boundarySplt[0]);
|
{
|
||||||
rect.y = Integer.parseInt(boundarySplt[1]);
|
rect.x = Integer.parseInt(boundarySplt[0]);
|
||||||
rect.width = Integer.parseInt(boundarySplt[2]);
|
rect.y = Integer.parseInt(boundarySplt[1]);
|
||||||
rect.height = Integer.parseInt(boundarySplt[3]);
|
rect.width = Integer.parseInt(boundarySplt[2]);
|
||||||
|
rect.height = Integer.parseInt(boundarySplt[3]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user