diff --git a/.classpath b/.classpath index a4a6148..1f51963 100644 --- a/.classpath +++ b/.classpath @@ -1,9 +1,10 @@ + - + diff --git a/build.xml b/build.xml index 557de61..154b8ee 100644 --- a/build.xml +++ b/build.xml @@ -61,6 +61,9 @@ + + + diff --git a/native/MsgHook.sln b/native/MsgHook.sln deleted file mode 100644 index 58c03a6..0000000 --- a/native/MsgHook.sln +++ /dev/null @@ -1,36 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MsgHook", "MsgHook\MsgHook.vcxproj", "{8E038A94-7D02-49E9-B9F6-5224D9D11225}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MsgHookTest", "MsgHookTest\MsgHookTest.vcxproj", "{E8016236-E771-4BEC-8407-6BF37C68D174}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8E038A94-7D02-49E9-B9F6-5224D9D11225}.Debug|Win32.ActiveCfg = Debug|Win32 - {8E038A94-7D02-49E9-B9F6-5224D9D11225}.Debug|Win32.Build.0 = Debug|Win32 - {8E038A94-7D02-49E9-B9F6-5224D9D11225}.Debug|x64.ActiveCfg = Debug|x64 - {8E038A94-7D02-49E9-B9F6-5224D9D11225}.Debug|x64.Build.0 = Debug|x64 - {8E038A94-7D02-49E9-B9F6-5224D9D11225}.Release|Win32.ActiveCfg = Release|Win32 - {8E038A94-7D02-49E9-B9F6-5224D9D11225}.Release|Win32.Build.0 = Release|Win32 - {8E038A94-7D02-49E9-B9F6-5224D9D11225}.Release|x64.ActiveCfg = Release|x64 - {8E038A94-7D02-49E9-B9F6-5224D9D11225}.Release|x64.Build.0 = Release|x64 - {E8016236-E771-4BEC-8407-6BF37C68D174}.Debug|Win32.ActiveCfg = Debug|Win32 - {E8016236-E771-4BEC-8407-6BF37C68D174}.Debug|Win32.Build.0 = Debug|Win32 - {E8016236-E771-4BEC-8407-6BF37C68D174}.Debug|x64.ActiveCfg = Debug|x64 - {E8016236-E771-4BEC-8407-6BF37C68D174}.Debug|x64.Build.0 = Debug|x64 - {E8016236-E771-4BEC-8407-6BF37C68D174}.Release|Win32.ActiveCfg = Release|Win32 - {E8016236-E771-4BEC-8407-6BF37C68D174}.Release|Win32.Build.0 = Release|Win32 - {E8016236-E771-4BEC-8407-6BF37C68D174}.Release|x64.ActiveCfg = Release|x64 - {E8016236-E771-4BEC-8407-6BF37C68D174}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/native/MsgHook.suo b/native/MsgHook.suo deleted file mode 100644 index e708592..0000000 Binary files a/native/MsgHook.suo and /dev/null differ diff --git a/native/MsgHook/MsgHook.cpp b/native/MsgHook/MsgHook.cpp index 5677596..2999281 100644 --- a/native/MsgHook/MsgHook.cpp +++ b/native/MsgHook/MsgHook.cpp @@ -78,11 +78,19 @@ extern "C" __declspec(dllexport) BOOL SetMsgHook(HWND callerHWnd, DWORD threadId pData->g_hWnd = callerHWnd; // remember the windows and hook handle for further instances pData->g_CwpHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CwpHookProc, (HINSTANCE)pData->g_hInstance, threadId); //pData->g_MsgHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)MsgHookProc, (HINSTANCE)pData->g_hInstance, threadId); + if (pData->g_CwpHook == NULL) { + TCHAR tmp[100]; + _stprintf_s(tmp, _T("Last Error # %ld on threadId %ld"), GetLastError(), threadId); + MessageBox(0, tmp, _T("Set Hook Error"), 0); + } return (pData->g_CwpHook != NULL); //pData->g_CwpHook != NULL && } else + { + //MessageBox(0, _T("Error: Not starting process"), _T("Set Hook Error"), 0); return false; + } } extern "C" __declspec(dllexport) BOOL RemoveHook() diff --git a/native/MsgHook/MsgHook.vcxproj b/native/MsgHook/MsgHook.vcxproj index 33a1f06..108ce52 100644 --- a/native/MsgHook/MsgHook.vcxproj +++ b/native/MsgHook/MsgHook.vcxproj @@ -64,6 +64,7 @@ true + $(JAVA_HOME)\include;$(JAVA_HOME)\include\win32;$(IncludePath) true @@ -141,10 +142,14 @@ copy /Y "$(TargetPath)" "$(ProjectDir)bin\MsgHook$(PlatformArchitecture)$(Target + + + + @@ -164,6 +169,7 @@ copy /Y "$(TargetPath)" "$(ProjectDir)bin\MsgHook$(PlatformArchitecture)$(Target + Create @@ -172,6 +178,9 @@ copy /Y "$(TargetPath)" "$(ProjectDir)bin\MsgHook$(PlatformArchitecture)$(Target Create + + + diff --git a/native/MsgHook/MsgHook.vcxproj.filters b/native/MsgHook/MsgHook.vcxproj.filters index 61ce41a..6e37813 100644 --- a/native/MsgHook/MsgHook.vcxproj.filters +++ b/native/MsgHook/MsgHook.vcxproj.filters @@ -16,6 +16,12 @@ + + Resource Files + + + Resource Files + @@ -27,6 +33,12 @@ Header Files + + Header Files + + + Header Files + @@ -41,5 +53,13 @@ Source Files + + Source Files + + + + + Resource Files + \ No newline at end of file diff --git a/native/MsgHookTest/MsgHookTest.aps b/native/MsgHook/MsgHookTest.aps similarity index 86% rename from native/MsgHookTest/MsgHookTest.aps rename to native/MsgHook/MsgHookTest.aps index b48c55d..1bcb0db 100644 Binary files a/native/MsgHookTest/MsgHookTest.aps and b/native/MsgHook/MsgHookTest.aps differ diff --git a/native/MsgHookTest/MsgHookTest.ico b/native/MsgHook/MsgHookTest.ico similarity index 100% rename from native/MsgHookTest/MsgHookTest.ico rename to native/MsgHook/MsgHookTest.ico diff --git a/native/MsgHookTest/MsgHookTest.rc b/native/MsgHook/MsgHookTest.rc similarity index 84% rename from native/MsgHookTest/MsgHookTest.rc rename to native/MsgHook/MsgHookTest.rc index 9c8e9a5..45f3912 100644 Binary files a/native/MsgHookTest/MsgHookTest.rc and b/native/MsgHook/MsgHookTest.rc differ diff --git a/native/MsgHookTest/MsgHookTest.cpp b/native/MsgHook/MsgHookWindow.cpp similarity index 75% rename from native/MsgHookTest/MsgHookTest.cpp rename to native/MsgHook/MsgHookWindow.cpp index 2db2094..cd7ed7b 100644 --- a/native/MsgHookTest/MsgHookTest.cpp +++ b/native/MsgHook/MsgHookWindow.cpp @@ -9,8 +9,10 @@ // #include "stdafx.h" -#include "MsgHookTest.h" -#include "MsgHook.h" +#include "resource.h" +#include "MsgLookup.h" +//#include "MsgHookTest.h" +//#include "MsgHook.h" #define MAX_LOADSTRING 100 @@ -19,66 +21,42 @@ HINSTANCE hInst; // current instance TCHAR szTitle[MAX_LOADSTRING]; // The title bar text TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name HWND mainHwnd = NULL; +HMENU mainMenu = NULL; HWND txtbox = NULL; HWND targetHwnd = NULL; -//TCHAR targetClassname[100] = _T("Notepad"); -TCHAR targetClassname[100] = _T("WordPadClass"); +const int txtboxSpacing = 2; + + bool filterWmCommand = true; bool filterWmNotify = false; bool filterAbove = false; -const int MAX_TEST_SIZE = 100; +//#define MAX_TEST_SIZE 100 +//TCHAR targetClassname[MAX_TEST_SIZE] = _T("Notepad"); +TCHAR targetClassname[MAX_TEST_SIZE] = _T("WordPadClass"); TCHAR testWmSettextL[MAX_TEST_SIZE] = _T("This is a test"); TCHAR testWmSettextW[MAX_TEST_SIZE] = _T("0"); TCHAR testWmCommandL[MAX_TEST_SIZE] = _T("0"); TCHAR testWmCommandW[MAX_TEST_SIZE] = _T("1"); +TCHAR targetHwndStr[MAX_TEST_SIZE] = _T(""); + +const int hotkeyIdOffset = 0; +const int pauseHotKey = 'P'; //P +bool isPaused = false; + // Forward declarations of functions included in this code module: +int APIENTRY StartWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow); ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); INT_PTR CALLBACK DlgProc(HWND, UINT, WPARAM, LPARAM); -int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) -{ - - UNREFERENCED_PARAMETER(hPrevInstance); - UNREFERENCED_PARAMETER(lpCmdLine); - - // TODO: Place code here. - MSG msg; - HACCEL hAccelTable; - - // Initialize global strings - LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); - LoadString(hInstance, IDC_MSGHOOKTEST, szWindowClass, MAX_LOADSTRING); - MyRegisterClass(hInstance); - - // Perform application initialization: - if (!InitInstance (hInstance, nCmdShow)) - { - return FALSE; - } - - hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MSGHOOKTEST)); - - // Main message loop: - while (GetMessage(&msg, NULL, 0, 0)) - { - if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - } - - return (int) msg.wParam; -} - void AppendText(HWND txtHwnd, LPCTSTR newText) { - + if (isPaused) + return; DWORD len = GetWindowTextLength(txtHwnd); if (len > 25000) {//need to truncate the beginning so the text doesn't go past it's limit @@ -125,13 +103,20 @@ void StartMessageHook() { AppendText(txtbox, _T("Starting Message Hook\r\n")); targetHwnd = FindWindow(targetClassname, NULL); + + if (_tcscmp(targetHwndStr, _T("")) != 0) //if target HWND was used then override classname hwnd + { + TCHAR *stopStr; + targetHwnd = (HWND)_tcstol(targetHwndStr, &stopStr, 10); + } + DWORD tid = GetWindowThreadProcessId(targetHwnd, NULL); InitMsgFiltersAndLookup(); //InitializeMsgLookup(); TCHAR tmp[50]; - _stprintf_s(tmp, _T("Targetting %ld, %ld\r\n"), targetHwnd, tid); + _stprintf_s(tmp, _T("Target Handle: %ld, and Thread Id: %ld\r\n"), targetHwnd, tid); AppendText(txtbox, tmp); //block self/global msg hook @@ -140,8 +125,11 @@ void StartMessageHook() return; } - if (InitMsgHook(mainHwnd, tid)) + //if (InitMsgHook(mainHwnd, tid)) + if (SetMsgHook(mainHwnd, tid)) { + EnableMenuItem(mainMenu, ID_FILE_STOPHOOK, MF_ENABLED); + EnableMenuItem(mainMenu, ID_FILE_STARTHOOK, MF_DISABLED | MF_GRAYED); AppendText(txtbox, _T("Hook successfully initialized\r\n")); } else @@ -150,8 +138,11 @@ void StartMessageHook() void StopMessageHook() { + EnableMenuItem(mainMenu, ID_FILE_STOPHOOK, MF_DISABLED | MF_GRAYED); + EnableMenuItem(mainMenu, ID_FILE_STARTHOOK, MF_ENABLED); AppendText(txtbox, TEXT("Stopping Message Hook\r\n")); - KillHook(); + //KillHook(); + RemoveHook(); } bool OnCopyData(COPYDATASTRUCT* pCopyDataStruct) // WM_COPYDATA lParam will have this struct @@ -188,7 +179,7 @@ bool OnCopyData(COPYDATASTRUCT* pCopyDataStruct) // WM_COPYDATA lParam will have if (_tcscmp(msgName, _T("")) != 0) { TCHAR tmp[200]; - _stprintf_s(tmp, _T("%d hwnd: %ld, msg: %s (%ld), wparam: '%s'[%ld], lparam: '%s'{%ld}\r\n"),Event.dwHookType, Event.hWnd, msgName, Event.nCode, Event.wParamStr, Event.wParam, Event.lParamStr,Event.lParam); + _stprintf_s(tmp, _T("hwnd: %ld, msg: %s (%ld), wparam: '%s'[%ld], lparam: '%s'{%ld}\r\n"), Event.hWnd, msgName, Event.nCode, Event.wParamStr, Event.wParam, Event.lParamStr,Event.lParam); AppendText(txtbox, tmp); } } @@ -209,9 +200,78 @@ void SendWmSettext() //ID_TESTMSGS_WM void SendWmCommand() //ID_TESTMSGS_WM { TCHAR *stopStr; + HWND sendHwnd = targetHwnd; + if (_tcscmp(targetHwndStr, _T("")) != 0) + { + sendHwnd = (HWND)_tcstol(targetHwndStr, &stopStr, 10); + } long wparam = _tcstol(testWmCommandW, &stopStr, 10); long lparam = _tcstol(testWmCommandL, &stopStr, 10); - SendMessage(targetHwnd, WM_COMMAND, wparam, lparam); + SendMessage(sendHwnd, WM_COMMAND, wparam, lparam); +} + +void HotKeyPressed(WPARAM wParam) +{ + //AppendText(txtbox, _T("hotkey test")); + if (wParam == (pauseHotKey + hotkeyIdOffset)) + { + if (!isPaused) + { + AppendText(txtbox, _T("Paused\r\n")); + isPaused = true; + } + else + { + isPaused = false; + AppendText(txtbox, _T("Unpaused\r\n")); + } + } +} + +extern "C" __declspec(dllexport) void CreateMsgHookWindow(LPTSTR lpCmdLine) +{ + //StartWinMain(GetModuleHandle(NULL), NULL, lpCmdLine, SW_SHOW); + StartWinMain((HINSTANCE)pData->g_hInstance, NULL, lpCmdLine, SW_SHOW); + +} + +int APIENTRY StartWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) +{ + + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpCmdLine); + + // TODO: Place code here. + MSG msg; + HACCEL hAccelTable; + + // Initialize global strings + LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); + LoadString(hInstance, IDC_MSGHOOKTEST, szWindowClass, MAX_LOADSTRING); + MyRegisterClass(hInstance); + + // Perform application initialization: + if (!InitInstance (hInstance, nCmdShow)) + { + return FALSE; + } + + hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MSGHOOKTEST)); + + // Main message loop: + while (GetMessage(&msg, NULL, 0, 0)) + { + //if (msg.message == WM_HOTKEY) + // HotKeyPressed(msg.wParam); + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + UnregisterHotKey(mainHwnd, pauseHotKey + hotkeyIdOffset); + + return (int) msg.wParam; } // @@ -265,10 +325,13 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) hInst = hInstance; // Store instance handle in our global variable hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); + CW_USEDEFAULT, 0, 700, 300, NULL, NULL, hInstance, NULL); - if (!hWnd) - return FALSE; + if (!hWnd) { + DWORD lastErr = GetLastError(); + printf("Error Creating Window %d\n", lastErr); + return FALSE; + } mainHwnd = hWnd; RECT rect; @@ -276,11 +339,24 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) // make the txtbox edit control almost the same size as the parent window //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, - 10, 10,rect.right - 20, rect.bottom - 20, hWnd, NULL, NULL, NULL); + txtboxSpacing, txtboxSpacing,rect.right-(txtboxSpacing*2), rect.bottom-(txtboxSpacing*2), hWnd, NULL, NULL, NULL); + + HFONT hFont = CreateFont(14, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, + OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, + DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial")); + SendMessage(txtbox, WM_SETFONT, (WPARAM)hFont, TRUE); + + mainMenu = GetMenu(mainHwnd); + EnableMenuItem(mainMenu, ID_FILE_STOPHOOK, MF_DISABLED | MF_GRAYED); + + RegisterHotKey(mainHwnd, pauseHotKey + hotkeyIdOffset, MOD_NOREPEAT | MOD_SHIFT | MOD_CONTROL, pauseHotKey); ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); + //set always on top + SetWindowPos(mainHwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE| SWP_NOMOVE); + return TRUE; } @@ -342,6 +418,9 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return DefWindowProc(hWnd, message, wParam, lParam); } break; + case WM_HOTKEY: + HotKeyPressed(wParam); + break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); // TODO: Add any drawing code here... @@ -351,7 +430,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { //resize the txtbox when the parent window size changes int nWidth = LOWORD(lParam); int nHeight = HIWORD(lParam); - SetWindowPos(txtbox, HWND_NOTOPMOST, 10, 10, nWidth-20, nHeight-20, SWP_NOZORDER|SWP_NOMOVE); + SetWindowPos(txtbox, HWND_NOTOPMOST, txtboxSpacing, txtboxSpacing, nWidth-(txtboxSpacing*2), nHeight-(txtboxSpacing*2), SWP_NOZORDER|SWP_NOMOVE); } break; case WM_DESTROY: @@ -383,6 +462,8 @@ INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) SendDlgItemMessage(hDlg, IDC_WMCOML, WM_SETTEXT, 0 , (LPARAM)testWmCommandL); SendDlgItemMessage(hDlg, IDC_WMSETW, WM_SETTEXT, 0 , (LPARAM)testWmSettextW); SendDlgItemMessage(hDlg, IDC_WMSETL, WM_SETTEXT, 0 , (LPARAM)testWmSettextL); + SendDlgItemMessage(hDlg, IDC_HWND, WM_SETTEXT, 0 , (LPARAM)targetHwndStr); + } return (INT_PTR)TRUE; @@ -394,6 +475,7 @@ INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) GetDlgItemText(hDlg, IDC_WMCOML, testWmCommandL, MAX_TEST_SIZE); GetDlgItemText(hDlg, IDC_WMSETW, testWmSettextW, MAX_TEST_SIZE); GetDlgItemText(hDlg, IDC_WMSETL, testWmSettextL, MAX_TEST_SIZE); + GetDlgItemText(hDlg, IDC_HWND, targetHwndStr, MAX_TEST_SIZE); // check filter options if (SendDlgItemMessage(hDlg, IDC_CHECK_CMD, BM_GETCHECK, 0, 0) == BST_CHECKED) // the hard way filterWmCommand = true; diff --git a/native/MsgHookTest/MsgHook.h b/native/MsgHook/MsgLookup.h similarity index 93% rename from native/MsgHookTest/MsgHook.h rename to native/MsgHook/MsgLookup.h index 792d5e6..f8413b3 100644 --- a/native/MsgHookTest/MsgHook.h +++ b/native/MsgHook/MsgLookup.h @@ -1,68 +1,5 @@ -/* - * Copyright 2014, Synthuse.org - * Released under the Apache Version 2.0 License. - * - * last modified by ejakubowski7@gmail.com -*/ -#include - -#define MSGHOOKER_FILE TEXT("MsgHook.dll") - -HINSTANCE msgHookDll; - -//BOOL SetMsgHook(HWND callerHWnd, DWORD threadId) -typedef BOOL (* SETMSGHOOK)(HWND, DWORD); -SETMSGHOOK SetMsgHook; - -//BOOL RemoveHook() -typedef BOOL (* REMOVEHOOK)(VOID); -REMOVEHOOK RemoveHook; - -typedef struct -{ - HWND hWnd; - int nCode; - DWORD dwHookType; - WPARAM wParam; - LPARAM lParam; - TCHAR wParamStr[25]; - TCHAR lParamStr[25]; -}HEVENT; - -/* -typedef struct { - DWORD vkCode; - DWORD scanCode; - DWORD flags; - DWORD time; - ULONG_PTR dwExtraInfo; -} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT; -*/ - -BOOL InitMsgHook(HWND hw, int threadId) -{ - msgHookDll = LoadLibrary(MSGHOOKER_FILE); - if (msgHookDll != NULL) - { - SetMsgHook = (SETMSGHOOK)GetProcAddress(msgHookDll, "SetMsgHook"); - RemoveHook = (REMOVEHOOK)GetProcAddress(msgHookDll, "RemoveHook"); - if (SetMsgHook) - { - return SetMsgHook(hw, threadId); - } - } - return false; -} - -void KillHook() -{ - if (RemoveHook) - RemoveHook(); - - if (msgHookDll != NULL) - FreeLibrary(msgHookDll); -} +#include "stdafx.h" // MSG Array LOOKUP const int MAX_MSG_LOOKUP = 1024; diff --git a/native/MsgHook/bin/MsgHook32.dll b/native/MsgHook/bin/MsgHook32.dll index fc01f28..e08c44d 100644 Binary files a/native/MsgHook/bin/MsgHook32.dll and b/native/MsgHook/bin/MsgHook32.dll differ diff --git a/native/MsgHook/bin/MsgHook64.dll b/native/MsgHook/bin/MsgHook64.dll index a62d705..11297ae 100644 Binary files a/native/MsgHook/bin/MsgHook64.dll and b/native/MsgHook/bin/MsgHook64.dll differ diff --git a/native/MsgHook/org_synthuse_MsgHook.cpp b/native/MsgHook/org_synthuse_MsgHook.cpp index a5665c1..3dc824b 100644 --- a/native/MsgHook/org_synthuse_MsgHook.cpp +++ b/native/MsgHook/org_synthuse_MsgHook.cpp @@ -8,12 +8,53 @@ #include "stdafx.h" #include "org_synthuse_MsgHook.h" + +/* + * Class: org_synthuse_MsgHook + * Method: createMsgHookWindow + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_createMsgHookWindow(JNIEnv *env, jobject obj) +{ + CreateMsgHookWindow(NULL); + return true; +} + +/* + * Class: org_synthuse_MsgHook + * Method: setMsgHookWindowTargetHwnd + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetHwnd(JNIEnv *env, jobject obj, jint jhwnd) +{ + _stprintf_s(targetHwndStr, _T("%ld"), (long)jhwnd); + return true; +} + +/* + * Class: org_synthuse_MsgHook + * Method: setMsgHookWindowTargetClass + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetClass(JNIEnv *env, jobject obj, jstring jclassname) +{ + const char *classname = env->GetStringUTFChars(jclassname, 0);//convert string + + memset((void *)&targetClassname, '\0', sizeof(TCHAR) * MAX_TEST_SIZE); // set TCHAR array to all 0 + int tstrLen = MultiByteToWideChar(CP_UTF8, 0, classname, (int)strlen(classname), NULL, 0); //get t len + MultiByteToWideChar(CP_UTF8, 0, classname, (int)strlen(classname), targetClassname, tstrLen); // convert char to tchar + + env->ReleaseStringUTFChars(jclassname, classname); //release string + return true; +} + /* * Class: org_synthuse_MsgHook * Method: setMessageHook * Signature: (JJ)Z */ -JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMessageHook(JNIEnv *env, jobject obj, jlong jhWnd, jlong jthreadId) +//JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMessageHook(JNIEnv *env, jobject obj, jlong jhWnd, jlong jthreadId) +JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMessageHook(JNIEnv *env, jobject obj, jint jhWnd, jint jthreadId) { return SetMsgHook((HWND)jhWnd, (DWORD)jthreadId); } diff --git a/native/MsgHook/org_synthuse_MsgHook.h b/native/MsgHook/org_synthuse_MsgHook.h index 93144b7..6e1e704 100644 --- a/native/MsgHook/org_synthuse_MsgHook.h +++ b/native/MsgHook/org_synthuse_MsgHook.h @@ -7,13 +7,37 @@ #ifdef __cplusplus extern "C" { #endif +/* + * Class: org_synthuse_MsgHook + * Method: createMsgHookWindow + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_createMsgHookWindow + (JNIEnv *, jobject); + +/* + * Class: org_synthuse_MsgHook + * Method: setMsgHookWindowTargetHwnd + * Signature: (I)Z + */ +JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetHwnd + (JNIEnv *, jobject, jint); + +/* + * Class: org_synthuse_MsgHook + * Method: setMsgHookWindowTargetClass + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMsgHookWindowTargetClass + (JNIEnv *, jobject, jstring); + /* * Class: org_synthuse_MsgHook * Method: setMessageHook - * Signature: (JJ)Z + * Signature: (II)Z */ JNIEXPORT jboolean JNICALL Java_org_synthuse_MsgHook_setMessageHook - (JNIEnv *, jobject, jlong, jlong); + (JNIEnv *, jobject, jint, jint); /* * Class: org_synthuse_MsgHook diff --git a/native/MsgHookTest/resource.h b/native/MsgHook/resource.h similarity index 95% rename from native/MsgHookTest/resource.h rename to native/MsgHook/resource.h index 596d9a1..8f5c0a2 100644 Binary files a/native/MsgHookTest/resource.h and b/native/MsgHook/resource.h differ diff --git a/native/MsgHookTest/small.ico b/native/MsgHook/small.ico similarity index 100% rename from native/MsgHookTest/small.ico rename to native/MsgHook/small.ico diff --git a/native/MsgHook/stdafx.h b/native/MsgHook/stdafx.h index 2ee36f5..d146995 100644 --- a/native/MsgHook/stdafx.h +++ b/native/MsgHook/stdafx.h @@ -9,6 +9,7 @@ #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Windows Header Files: +#include #include #include #include @@ -41,6 +42,7 @@ typedef struct #ifndef GLOBAL_VARS_H // header guards #define GLOBAL_VARS_H +extern "C" __declspec(dllexport) void CreateMsgHookWindow(LPTSTR lpCmdLine); extern "C" __declspec(dllexport) BOOL SetMsgHook(HWND callerHWnd, DWORD threadId); extern "C" __declspec(dllexport) BOOL RemoveHook(); @@ -49,4 +51,8 @@ extern HANDLE hMappedFile; extern GLOBALDATA* pData; extern bool bStartingProcess; +#define MAX_TEST_SIZE 100 +extern TCHAR targetHwndStr[MAX_TEST_SIZE]; +extern TCHAR targetClassname[MAX_TEST_SIZE]; + #endif \ No newline at end of file diff --git a/native/MsgHookTest/MsgHookTest.h b/native/MsgHookTest/MsgHookTest.h deleted file mode 100644 index d00d47e..0000000 --- a/native/MsgHookTest/MsgHookTest.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -#include "resource.h" diff --git a/native/MsgHookTest/MsgHookTest.vcxproj b/native/MsgHookTest/MsgHookTest.vcxproj deleted file mode 100644 index 677680c..0000000 --- a/native/MsgHookTest/MsgHookTest.vcxproj +++ /dev/null @@ -1,166 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {E8016236-E771-4BEC-8407-6BF37C68D174} - Win32Proj - MsgHookTest - - - - Application - true - Unicode - - - Application - true - Unicode - - - Application - false - true - Unicode - - - Application - false - true - Unicode - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - - - - - Use - Level3 - Disabled - WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - Level3 - Use - MaxSpeed - true - true - WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) - - - Windows - true - true - true - - - - - - - - - - - - - - - - - - - Create - Create - Create - Create - - - - - - - - {8e038a94-7d02-49e9-b9f6-5224d9d11225} - - - - - - \ No newline at end of file diff --git a/native/MsgHookTest/MsgHookTest.vcxproj.filters b/native/MsgHookTest/MsgHookTest.vcxproj.filters deleted file mode 100644 index 7343c35..0000000 --- a/native/MsgHookTest/MsgHookTest.vcxproj.filters +++ /dev/null @@ -1,57 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - - Resource Files - - - Resource Files - - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/native/MsgHookTest/MsgHookTest.vcxproj.user b/native/MsgHookTest/MsgHookTest.vcxproj.user deleted file mode 100644 index ace9a86..0000000 --- a/native/MsgHookTest/MsgHookTest.vcxproj.user +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/native/MsgHookTest/ReadMe.txt b/native/MsgHookTest/ReadMe.txt deleted file mode 100644 index 6d81f3a..0000000 --- a/native/MsgHookTest/ReadMe.txt +++ /dev/null @@ -1,62 +0,0 @@ -======================================================================== - WIN32 APPLICATION : MsgHookTest Project Overview -======================================================================== - -AppWizard has created this MsgHookTest application for you. - -This file contains a summary of what you will find in each of the files that -make up your MsgHookTest application. - - -MsgHookTest.vcxproj - This is the main project file for VC++ projects generated using an Application Wizard. - It contains information about the version of Visual C++ that generated the file, and - information about the platforms, configurations, and project features selected with the - Application Wizard. - -MsgHookTest.vcxproj.filters - This is the filters file for VC++ projects generated using an Application Wizard. - It contains information about the association between the files in your project - and the filters. This association is used in the IDE to show grouping of files with - similar extensions under a specific node (for e.g. ".cpp" files are associated with the - "Source Files" filter). - -MsgHookTest.cpp - This is the main application source file. - -///////////////////////////////////////////////////////////////////////////// -AppWizard has created the following resources: - -MsgHookTest.rc - This is a listing of all of the Microsoft Windows resources that the - program uses. It includes the icons, bitmaps, and cursors that are stored - in the RES subdirectory. This file can be directly edited in Microsoft - Visual C++. - -Resource.h - This is the standard header file, which defines new resource IDs. - Microsoft Visual C++ reads and updates this file. - -MsgHookTest.ico - This is an icon file, which is used as the application's icon (32x32). - This icon is included by the main resource file MsgHookTest.rc. - -small.ico - This is an icon file, which contains a smaller version (16x16) - of the application's icon. This icon is included by the main resource - file MsgHookTest.rc. - -///////////////////////////////////////////////////////////////////////////// -Other standard files: - -StdAfx.h, StdAfx.cpp - These files are used to build a precompiled header (PCH) file - named MsgHookTest.pch and a precompiled types file named StdAfx.obj. - -///////////////////////////////////////////////////////////////////////////// -Other notes: - -AppWizard uses "TODO:" comments to indicate parts of the source code you -should add to or customize. - -///////////////////////////////////////////////////////////////////////////// diff --git a/native/MsgHookTest/WinMessages.txt b/native/MsgHookTest/WinMessages.txt deleted file mode 100644 index e27e2f4..0000000 --- a/native/MsgHookTest/WinMessages.txt +++ /dev/null @@ -1,416 +0,0 @@ - -WM_NULL = 0x00 -WM_CREATE = 0x01 -WM_DESTROY = 0x02 -WM_MOVE = 0x03 -WM_SIZE = 0x05 -WM_ACTIVATE = 0x06 -WM_SETFOCUS = 0x07 -WM_KILLFOCUS = 0x08 -WM_ENABLE = 0x0A -WM_SETREDRAW = 0x0B -WM_SETTEXT = 0x0C -WM_GETTEXT = 0x0D -WM_GETTEXTLENGTH = 0x0E -WM_PAINT = 0x0F -WM_CLOSE = 0x10 -WM_QUERYENDSESSION = 0x11 -WM_QUIT = 0x12 -WM_QUERYOPEN = 0x13 -WM_ERASEBKGND = 0x14 -WM_SYSCOLORCHANGE = 0x15 -WM_ENDSESSION = 0x16 -WM_SYSTEMERROR = 0x17 -WM_SHOWWINDOW = 0x18 -WM_CTLCOLOR = 0x19 -WM_WININICHANGE = 0x1A -WM_SETTINGCHANGE = 0x1A -WM_DEVMODECHANGE = 0x1B -WM_ACTIVATEAPP = 0x1C -WM_FONTCHANGE = 0x1D -WM_TIMECHANGE = 0x1E -WM_CANCELMODE = 0x1F -WM_SETCURSOR = 0x20 -WM_MOUSEACTIVATE = 0x21 -WM_CHILDACTIVATE = 0x22 -WM_QUEUESYNC = 0x23 -WM_GETMINMAXINFO = 0x24 -WM_PAINTICON = 0x26 -WM_ICONERASEBKGND = 0x27 -WM_NEXTDLGCTL = 0x28 -WM_SPOOLERSTATUS = 0x2A -WM_DRAWITEM = 0x2B -WM_MEASUREITEM = 0x2C -WM_DELETEITEM = 0x2D -WM_VKEYTOITEM = 0x2E -WM_CHARTOITEM = 0x2F -WM_SETFONT = 0x30 -WM_GETFONT = 0x31 -WM_SETHOTKEY = 0x32 -WM_GETHOTKEY = 0x33 -WM_QUERYDRAGICON = 0x37 -WM_COMPAREITEM = 0x39 -WM_COMPACTING = 0x41 -WM_WINDOWPOSCHANGING = 0x46 -WM_WINDOWPOSCHANGED = 0x47 -WM_POWER = 0x48 -WM_COPYDATA = 0x4A -WM_CANCELJOURNAL = 0x4B -WM_NOTIFY = 0x4E -WM_INPUTLANGCHANGEREQUEST = 0x50 -WM_INPUTLANGCHANGE = 0x51 -WM_TCARD = 0x52 -WM_HELP = 0x53 -WM_USERCHANGED = 0x54 -WM_NOTIFYFORMAT = 0x55 -WM_CONTEXTMENU = 0x7B -WM_STYLECHANGING = 0x7C -WM_STYLECHANGED = 0x7D -WM_DISPLAYCHANGE = 0x7E -WM_GETICON = 0x7F -WM_SETICON = 0x80 -WM_NCCREATE = 0x81 -WM_NCDESTROY = 0x82 -WM_NCCALCSIZE = 0x83 -WM_NCHITTEST = 0x84 -WM_NCPAINT = 0x85 -WM_NCACTIVATE = 0x86 -WM_GETDLGCODE = 0x87 -WM_NCMOUSEMOVE = 0xA0 -WM_NCLBUTTONDOWN = 0xA1 -WM_NCLBUTTONUP = 0xA2 -WM_NCLBUTTONDBLCLK = 0xA3 -WM_NCRBUTTONDOWN = 0xA4 -WM_NCRBUTTONUP = 0xA5 -WM_NCRBUTTONDBLCLK = 0xA6 -WM_NCMBUTTONDOWN = 0xA7 -WM_NCMBUTTONUP = 0xA8 -WM_NCMBUTTONDBLCLK = 0xA9 -WM_KEYFIRST = 0x100 -WM_KEYDOWN = 0x100 -WM_KEYUP = 0x101 -WM_CHAR = 0x102 -WM_DEADCHAR = 0x103 -WM_SYSKEYDOWN = 0x104 -WM_SYSKEYUP = 0x105 -WM_SYSCHAR = 0x106 -WM_SYSDEADCHAR = 0x107 -WM_KEYLAST = 0x108 -WM_IME_STARTCOMPOSITION = 0x10D -WM_IME_ENDCOMPOSITION = 0x10E -WM_IME_COMPOSITION = 0x10F -WM_IME_KEYLAST = 0x10F -WM_INITDIALOG = 0x110 -WM_COMMAND = 0x111 -WM_SYSCOMMAND = 0x112 -WM_TIMER = 0x113 -WM_HSCROLL = 0x114 -WM_VSCROLL = 0x115 -WM_INITMENU = 0x116 -WM_INITMENUPOPUP = 0x117 -WM_MENUSELECT = 0x11F -WM_MENUCHAR = 0x120 -WM_ENTERIDLE = 0x121 -WM_CTLCOLORMSGBOX = 0x132 -WM_CTLCOLOREDIT = 0x133 -WM_CTLCOLORLISTBOX = 0x134 -WM_CTLCOLORBTN = 0x135 -WM_CTLCOLORDLG = 0x136 -WM_CTLCOLORSCROLLBAR = 0x137 -WM_CTLCOLORSTATIC = 0x138 -WM_MOUSEFIRST = 0x200 -WM_MOUSEMOVE = 0x200 -WM_LBUTTONDOWN = 0x201 -WM_LBUTTONUP = 0x202 -WM_LBUTTONDBLCLK = 0x203 -WM_RBUTTONDOWN = 0x204 -WM_RBUTTONUP = 0x205 -WM_RBUTTONDBLCLK = 0x206 -WM_MBUTTONDOWN = 0x207 -WM_MBUTTONUP = 0x208 -WM_MBUTTONDBLCLK = 0x209 -WM_MOUSEWHEEL = 0x20A -WM_MOUSEHWHEEL = 0x20E -WM_PARENTNOTIFY = 0x210 -WM_ENTERMENULOOP = 0x211 -WM_EXITMENULOOP = 0x212 -WM_NEXTMENU = 0x213 -WM_SIZING = 0x214 -WM_CAPTURECHANGED = 0x215 -WM_MOVING = 0x216 -WM_POWERBROADCAST = 0x218 -WM_DEVICECHANGE = 0x219 -WM_MDICREATE = 0x220 -WM_MDIDESTROY = 0x221 -WM_MDIACTIVATE = 0x222 -WM_MDIRESTORE = 0x223 -WM_MDINEXT = 0x224 -WM_MDIMAXIMIZE = 0x225 -WM_MDITILE = 0x226 -WM_MDICASCADE = 0x227 -WM_MDIICONARRANGE = 0x228 -WM_MDIGETACTIVE = 0x229 -WM_MDISETMENU = 0x230 -WM_ENTERSIZEMOVE = 0x231 -WM_EXITSIZEMOVE = 0x232 -WM_DROPFILES = 0x233 -WM_MDIREFRESHMENU = 0x234 -WM_IME_SETCONTEXT = 0x281 -WM_IME_NOTIFY = 0x282 -WM_IME_CONTROL = 0x283 -WM_IME_COMPOSITIONFULL = 0x284 -WM_IME_SELECT = 0x285 -WM_IME_CHAR = 0x286 -WM_IME_KEYDOWN = 0x290 -WM_IME_KEYUP = 0x291 -WM_MOUSEHOVER = 0x2A1 -WM_NCMOUSELEAVE = 0x2A2 -WM_MOUSELEAVE = 0x2A3 -WM_CUT = 0x300 -WM_COPY = 0x301 -WM_PASTE = 0x302 -WM_CLEAR = 0x303 -WM_UNDO = 0x304 -WM_RENDERFORMAT = 0x305 -WM_RENDERALLFORMATS = 0x306 -WM_DESTROYCLIPBOARD = 0x307 -WM_DRAWCLIPBOARD = 0x308 -WM_PAINTCLIPBOARD = 0x309 -WM_VSCROLLCLIPBOARD = 0x30A -WM_SIZECLIPBOARD = 0x30B -WM_ASKCBFORMATNAME = 0x30C -WM_CHANGECBCHAIN = 0x30D -WM_HSCROLLCLIPBOARD = 0x30E -WM_QUERYNEWPALETTE = 0x30F -WM_PALETTEISCHANGING = 0x310 -WM_PALETTECHANGED = 0x311 -WM_HOTKEY = 0x312 -WM_PRINT = 0x317 -WM_PRINTCLIENT = 0x318 -WM_HANDHELDFIRST = 0x358 -WM_HANDHELDLAST = 0x35F -WM_PENWINFIRST = 0x380 -WM_PENWINLAST = 0x38F -WM_COALESCE_FIRST = 0x390 -WM_COALESCE_LAST = 0x39F -WM_DDE_FIRST = 0x3E0 -WM_DDE_INITIATE = 0x3E0 -WM_DDE_TERMINATE = 0x3E1 -WM_DDE_ADVISE = 0x3E2 -WM_DDE_UNADVISE = 0x3E3 -WM_DDE_ACK = 0x3E4 -WM_DDE_DATA = 0x3E5 -WM_DDE_REQUEST = 0x3E6 -WM_DDE_POKE = 0x3E7 -WM_DDE_EXECUTE = 0x3E8 -WM_DDE_LAST = 0x3E8 - - - - - -WM_NULL -WM_CREATE -WM_DESTROY -WM_MOVE -WM_SIZE -WM_ACTIVATE -WM_SETFOCUS -WM_KILLFOCUS -WM_ENABLE -WM_SETREDRAW -WM_SETTEXT -WM_GETTEXT -WM_GETTEXTLENGTH -WM_PAINT -WM_CLOSE -WM_QUERYENDSESSION -WM_QUIT -WM_QUERYOPEN -WM_ERASEBKGND -WM_SYSCOLORCHANGE -WM_ENDSESSION -WM_SYSTEMERROR -WM_SHOWWINDOW -WM_CTLCOLOR -WM_WININICHANGE -WM_SETTINGCHANGE -WM_DEVMODECHANGE -WM_ACTIVATEAPP -WM_FONTCHANGE -WM_TIMECHANGE -WM_CANCELMODE -WM_SETCURSOR -WM_MOUSEACTIVATE -WM_CHILDACTIVATE -WM_QUEUESYNC -WM_GETMINMAXINFO -WM_PAINTICON -WM_ICONERASEBKGND -WM_NEXTDLGCTL -WM_SPOOLERSTATUS -WM_DRAWITEM -WM_MEASUREITEM -WM_DELETEITEM -WM_VKEYTOITEM -WM_CHARTOITEM -WM_SETFONT -WM_GETFONT -WM_SETHOTKEY -WM_GETHOTKEY -WM_QUERYDRAGICON -WM_COMPAREITEM -WM_COMPACTING -WM_WINDOWPOSCHANGING -WM_WINDOWPOSCHANGED -WM_POWER -WM_COPYDATA -WM_CANCELJOURNAL -WM_NOTIFY -WM_INPUTLANGCHANGEREQUEST -WM_INPUTLANGCHANGE -WM_TCARD -WM_HELP -WM_USERCHANGED -WM_NOTIFYFORMAT -WM_CONTEXTMENU -WM_STYLECHANGING -WM_STYLECHANGED -WM_DISPLAYCHANGE -WM_GETICON -WM_SETICON -WM_NCCREATE -WM_NCDESTROY -WM_NCCALCSIZE -WM_NCHITTEST -WM_NCPAINT -WM_NCACTIVATE -WM_GETDLGCODE -WM_NCMOUSEMOVE -WM_NCLBUTTONDOWN -WM_NCLBUTTONUP -WM_NCLBUTTONDBLCLK -WM_NCRBUTTONDOWN -WM_NCRBUTTONUP -WM_NCRBUTTONDBLCLK -WM_NCMBUTTONDOWN -WM_NCMBUTTONUP -WM_NCMBUTTONDBLCLK -WM_KEYFIRST -WM_KEYDOWN -WM_KEYUP -WM_CHAR -WM_DEADCHAR -WM_SYSKEYDOWN -WM_SYSKEYUP -WM_SYSCHAR -WM_SYSDEADCHAR -WM_KEYLAST -WM_IME_STARTCOMPOSITION -WM_IME_ENDCOMPOSITION -WM_IME_COMPOSITION -WM_IME_KEYLAST -WM_INITDIALOG -WM_COMMAND -WM_SYSCOMMAND -WM_TIMER -WM_HSCROLL -WM_VSCROLL -WM_INITMENU -WM_INITMENUPOPUP -WM_MENUSELECT -WM_MENUCHAR -WM_ENTERIDLE -WM_CTLCOLORMSGBOX -WM_CTLCOLOREDIT -WM_CTLCOLORLISTBOX -WM_CTLCOLORBTN -WM_CTLCOLORDLG -WM_CTLCOLORSCROLLBAR -WM_CTLCOLORSTATIC -WM_MOUSEFIRST -WM_MOUSEMOVE -WM_LBUTTONDOWN -WM_LBUTTONUP -WM_LBUTTONDBLCLK -WM_RBUTTONDOWN -WM_RBUTTONUP -WM_RBUTTONDBLCLK -WM_MBUTTONDOWN -WM_MBUTTONUP -WM_MBUTTONDBLCLK -WM_MOUSEWHEEL -WM_MOUSEHWHEEL -WM_PARENTNOTIFY -WM_ENTERMENULOOP -WM_EXITMENULOOP -WM_NEXTMENU -WM_SIZING -WM_CAPTURECHANGED -WM_MOVING -WM_POWERBROADCAST -WM_DEVICECHANGE -WM_MDICREATE -WM_MDIDESTROY -WM_MDIACTIVATE -WM_MDIRESTORE -WM_MDINEXT -WM_MDIMAXIMIZE -WM_MDITILE -WM_MDICASCADE -WM_MDIICONARRANGE -WM_MDIGETACTIVE -WM_MDISETMENU -WM_ENTERSIZEMOVE -WM_EXITSIZEMOVE -WM_DROPFILES -WM_MDIREFRESHMENU -WM_IME_SETCONTEXT -WM_IME_NOTIFY -WM_IME_CONTROL -WM_IME_COMPOSITIONFULL -WM_IME_SELECT -WM_IME_CHAR -WM_IME_KEYDOWN -WM_IME_KEYUP -WM_MOUSEHOVER -WM_NCMOUSELEAVE -WM_MOUSELEAVE -WM_CUT -WM_COPY -WM_PASTE -WM_CLEAR -WM_UNDO -WM_RENDERFORMAT -WM_RENDERALLFORMATS -WM_DESTROYCLIPBOARD -WM_DRAWCLIPBOARD -WM_PAINTCLIPBOARD -WM_VSCROLLCLIPBOARD -WM_SIZECLIPBOARD -WM_ASKCBFORMATNAME -WM_CHANGECBCHAIN -WM_HSCROLLCLIPBOARD -WM_QUERYNEWPALETTE -WM_PALETTEISCHANGING -WM_PALETTECHANGED -WM_HOTKEY -WM_PRINT -WM_PRINTCLIENT -WM_HANDHELDFIRST -WM_HANDHELDLAST -WM_PENWINFIRST -WM_PENWINLAST -WM_COALESCE_FIRST -WM_COALESCE_LAST -WM_DDE_FIRST -WM_DDE_INITIATE -WM_DDE_TERMINATE -WM_DDE_ADVISE -WM_DDE_UNADVISE -WM_DDE_ACK -WM_DDE_DATA -WM_DDE_REQUEST -WM_DDE_POKE -WM_DDE_EXECUTE -WM_DDE_LAST \ No newline at end of file diff --git a/native/MsgHookTest/bin/x32/MsgHook.dll b/native/MsgHookTest/bin/x32/MsgHook.dll deleted file mode 100644 index fc01f28..0000000 Binary files a/native/MsgHookTest/bin/x32/MsgHook.dll and /dev/null differ diff --git a/native/MsgHookTest/bin/x32/MsgHook.exp b/native/MsgHookTest/bin/x32/MsgHook.exp deleted file mode 100644 index a93c2a0..0000000 Binary files a/native/MsgHookTest/bin/x32/MsgHook.exp and /dev/null differ diff --git a/native/MsgHookTest/bin/x32/MsgHook.lib b/native/MsgHookTest/bin/x32/MsgHook.lib deleted file mode 100644 index 80a7bde..0000000 Binary files a/native/MsgHookTest/bin/x32/MsgHook.lib and /dev/null differ diff --git a/native/MsgHookTest/bin/x32/MsgHookTest.exe b/native/MsgHookTest/bin/x32/MsgHookTest.exe deleted file mode 100644 index a6aafd4..0000000 Binary files a/native/MsgHookTest/bin/x32/MsgHookTest.exe and /dev/null differ diff --git a/native/MsgHookTest/bin/x64/MsgHook.dll b/native/MsgHookTest/bin/x64/MsgHook.dll deleted file mode 100644 index a62d705..0000000 Binary files a/native/MsgHookTest/bin/x64/MsgHook.dll and /dev/null differ diff --git a/native/MsgHookTest/bin/x64/MsgHook.exp b/native/MsgHookTest/bin/x64/MsgHook.exp deleted file mode 100644 index 02b3396..0000000 Binary files a/native/MsgHookTest/bin/x64/MsgHook.exp and /dev/null differ diff --git a/native/MsgHookTest/bin/x64/MsgHook.lib b/native/MsgHookTest/bin/x64/MsgHook.lib deleted file mode 100644 index b3e9ccc..0000000 Binary files a/native/MsgHookTest/bin/x64/MsgHook.lib and /dev/null differ diff --git a/native/MsgHookTest/bin/x64/MsgHookTest.exe b/native/MsgHookTest/bin/x64/MsgHookTest.exe deleted file mode 100644 index 0cad9a2..0000000 Binary files a/native/MsgHookTest/bin/x64/MsgHookTest.exe and /dev/null differ diff --git a/native/MsgHookTest/stdafx.cpp b/native/MsgHookTest/stdafx.cpp deleted file mode 100644 index 56acf67..0000000 --- a/native/MsgHookTest/stdafx.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// MsgHookTest.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/native/MsgHookTest/stdafx.h b/native/MsgHookTest/stdafx.h deleted file mode 100644 index 24919b6..0000000 --- a/native/MsgHookTest/stdafx.h +++ /dev/null @@ -1,23 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#include "targetver.h" - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include - -// C RunTime Header Files -#include -#include -#include -#include -#include -#include - - -// TODO: reference additional headers your program requires here diff --git a/native/MsgHookTest/targetver.h b/native/MsgHookTest/targetver.h deleted file mode 100644 index 87c0086..0000000 --- a/native/MsgHookTest/targetver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/src/org/synthuse/Api.java b/src/org/synthuse/Api.java index 8add96b..f3d26f3 100644 --- a/src/org/synthuse/Api.java +++ b/src/org/synthuse/Api.java @@ -8,14 +8,17 @@ package org.synthuse; import java.awt.Point; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; +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.ULONG_PTR; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT.HANDLE; @@ -24,6 +27,7 @@ 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.PointerByReference; +import com.sun.jna.win32.StdCallLibrary.StdCallCallback; import com.sun.jna.win32.W32APIOptions; public class Api { @@ -198,11 +202,48 @@ public class Api { 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. } + + 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 User32 extends W32APIOptions { User32 instance = (User32) Native.loadLibrary("user32", User32.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); @@ -291,13 +332,16 @@ public class Api { kernel32 = Kernel32.instance; } - public static String GetHandleAsString(HWND hWnd) { + public static Long GetHandleAsLong(HWND hWnd) { if (hWnd == null) - return "0"; + return (long)0; //String longHexStr = hWnd.toString().substring("native@".length()); String longHexStr = hWnd.getPointer().toString().substring("native@".length()); - Long l = Long.decode(longHexStr); - return l.toString(); + return Long.decode(longHexStr); + } + + public static String GetHandleAsString(HWND hWnd) { + return GetHandleAsLong(hWnd).toString(); } public static HWND GetHandleFromString(String hWnd) { @@ -583,4 +627,26 @@ public class Api { return false; } + public static HWND FindMainWindowFromPid(final long targetProcessId) { + + final List resultList = new ArrayList(); + class ParentWindowCallback implements WinUser.WNDENUMPROC { + @Override + public boolean callback(HWND hWnd, Pointer lParam) { + PointerByReference pointer = new PointerByReference(); + User32.instance.GetWindowThreadProcessId(hWnd, pointer); + long pid = pointer.getPointer().getInt(0); + if (pid == targetProcessId) + if (resultList.isEmpty()) + resultList.add(hWnd); + return true; + } + } + + Api.User32.instance.EnumWindows(new ParentWindowCallback(), 0); + if (!resultList.isEmpty()) + return resultList.get(0); + return null; + } + } diff --git a/src/org/synthuse/CommandPopupMenu.java b/src/org/synthuse/CommandPopupMenu.java index e49f294..0bbe7b9 100644 --- a/src/org/synthuse/CommandPopupMenu.java +++ b/src/org/synthuse/CommandPopupMenu.java @@ -98,6 +98,7 @@ public class CommandPopupMenu extends JPopupMenu { CommandMenuItem mntmSetTargetOffset = new CommandMenuItem("setTargetOffset", 3, false); mnMouse.add(mntmSetTargetOffset); + JMenu mnWinMessages = new JMenu("Win Messages"); add(mnWinMessages); @@ -112,6 +113,9 @@ public class CommandPopupMenu extends JPopupMenu { CommandMenuItem mntmSelectContextMenuId = new CommandMenuItem("selectContextMenuId", 3); mnWinMessages.add(mntmSelectContextMenuId); + + CommandMenuItem mntmSendCommandMsg = new CommandMenuItem("sendCommandMsg", 4); + mnWinMessages.add(mntmSendCommandMsg); CommandMenuItem mntmSetcursorposition = new CommandMenuItem("setCursorPosition", 3); mnWinMessages.add(mntmSetcursorposition); @@ -142,7 +146,7 @@ public class CommandPopupMenu extends JPopupMenu { CommandMenuItem mntmGetwindowclass = new CommandMenuItem("getWindowClass", 2); mnWinMessages.add(mntmGetwindowclass); - + CommandMenuItem mntmDisplayText = new CommandMenuItem("displayText", 3, false); add(mntmDisplayText); @@ -226,6 +230,8 @@ public class CommandPopupMenu extends JPopupMenu { actionStr += "on | " + xpathItem + " | "; if (paramCount > 2) actionStr += "with | |"; + if (paramCount > 3) + actionStr += " and | |"; return actionStr; } } diff --git a/src/org/synthuse/CommandProcessor.java b/src/org/synthuse/CommandProcessor.java index f568651..5bfb2ac 100644 --- a/src/org/synthuse/CommandProcessor.java +++ b/src/org/synthuse/CommandProcessor.java @@ -102,6 +102,8 @@ public class CommandProcessor implements Runnable{ if (!line.trim().startsWith("|")) continue; //skip if it doesn't start with bar String[] parsed = line.split("\\|"); + // + //System.out.println("line: " + line); //System.out.println("parsed len = " + parsed.length); //System.out.println("parsed 2 = " + parsed[2]); @@ -113,6 +115,8 @@ public class CommandProcessor implements Runnable{ 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 (executeErrorCount > 0) //check if any errors occurred ++scriptErrorCount; @@ -215,6 +219,8 @@ public class CommandProcessor implements Runnable{ return win.cmdSelectMenu(args); if (command.equals("selectContextMenuId")) return win.cmdSelectContextMenuId(args); + if (command.equals("sendCommandMsg")) + return win.cmdSendCommandMsg(args); if (command.equals("windowMinimize")) return win.cmdWindowMinimize(args); if (command.equals("windowMaximize")) diff --git a/src/org/synthuse/DragTarget.java b/src/org/synthuse/DragTarget.java index ce94497..e5a36c3 100644 --- a/src/org/synthuse/DragTarget.java +++ b/src/org/synthuse/DragTarget.java @@ -130,7 +130,7 @@ public class DragTarget extends JLabel { @Override public boolean importData(TransferSupport support) { - System.out.println("importData"); + //System.out.println("importData"); return true; } diff --git a/src/org/synthuse/MessageHookFrame.java b/src/org/synthuse/MessageHookFrame.java index 887a0fb..4fef6ad 100644 --- a/src/org/synthuse/MessageHookFrame.java +++ b/src/org/synthuse/MessageHookFrame.java @@ -1,3 +1,12 @@ +/* + * 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; @@ -6,37 +15,57 @@ 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.Kernel32; -import com.sun.jna.platform.win32.WinUser.HHOOK; -import com.sun.jna.platform.win32.WinUser.HOOKPROC; -import com.sun.jna.platform.win32.WinUser.MSG; +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 HHOOK hHook = null; - //public static LowLevelKeyboardProc lpfn; public static volatile boolean quit = false; + private JLabel lblTargetHwnd; + public JTextField txtTarget; + private Component horizontalStrut; public MessageHookFrame() { setTitle("Message Hook"); @@ -60,11 +89,42 @@ public class MessageHookFrame extends JFrame { } } }); + + 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.User32.instance.CallWindowProc(oldWndProc, hWnd, uMsg, wParam, lParam); + //return new LRESULT(0); + //return User32.INSTANCE.DefWindowProc(hWnd, uMsg, wParam, lParam); + } + }; + + Api.User32.instance.SetWindowLongPtr(myHwnd, GWLP_WNDPROC, wndProc); } }); toolBar.add(btnPause); @@ -89,62 +149,142 @@ public class MessageHookFrame extends JFrame { 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() { - /* - // Below set windows hook is called from inside the native DLL - if (hHook != null) - return; //hook already running don't add anymore - System.out.println("starting global message hook"); - HMODULE hMod = Kernel32.INSTANCE.GetModuleHandle(null); - int threadId = Kernel32.INSTANCE.GetCurrentThreadId(); - HOOKPROC lpfn = new HOOKPROC() { - @SuppressWarnings("unused") - public LRESULT callback(int nCode, WPARAM wParam, LPARAM lParam) { - //System.out.println("Msg " + nCode); - - return User32.INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam); - } - }; - hHook = User32.INSTANCE.SetWindowsHookEx(WH_CALLWNDPROC, lpfn, hMod, threadId); - if (hHook == null) - return; - */ - MsgHook mh = new MsgHook(); - //mh.setMessageHook(hwnd, threadId); + quit = false; //don't quit - MSG msg = new MSG(); - try { - - while (!quit) { - User32.INSTANCE.PeekMessage(msg, null, 0, 0, 1); - if (msg.message == WM_COPYDATA){ // && msg.wParam.intValue() == 1 - System.out.println("WM_COPYDATA"); - msg = new MSG(); //must clear msg so it doesn't repeat + //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.WinDefExt.COPYDATASTRUCT cds = new Api.WinDefExt.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 } - Thread.sleep(10); - } - } catch (Exception e) { - e.printStackTrace(); + //else + // System.out.println("MESSAGE: " + uMsg); + + return Api.User32.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.User32.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; } - System.out.println("message loop stopped"); - unhook(); + + msgHook = new MsgHook(); + if (!msgHook.setMessageHook((int) myHwndLong, threadId)) + appendLine("Error setting message hook"); + else + appendLine("Message hook started"); + } - public void unhook() { - if (hHook == null) - return; - if (!User32.INSTANCE.UnhookWindowsHookEx(hHook)) - System.out.println("Failed to unhook"); - System.out.println("Unhooked"); - hHook = null; + public void unhook(MsgHook msgHook) { + msgHook.removeMessageHook(); } //stops Keyboard hook and causes the unhook command to be called - public static void stopMessageHook() { + 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()); } } diff --git a/src/org/synthuse/MsgHook.java b/src/org/synthuse/MsgHook.java index ed8228c..002b1be 100644 --- a/src/org/synthuse/MsgHook.java +++ b/src/org/synthuse/MsgHook.java @@ -1,3 +1,10 @@ +/* + * 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; @@ -7,6 +14,7 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; + import javax.swing.JOptionPane; public class MsgHook { @@ -78,7 +86,27 @@ public class MsgHook { System.load(temp.getAbsolutePath()); } - public native boolean setMessageHook(long hwnd, long threadId); + //public native boolean initialize(int hwnd); + public native boolean createMsgHookWindow(); + public native boolean setMsgHookWindowTargetHwnd(int hwnd); + public native boolean setMsgHookWindowTargetClass(String classname); + public native boolean setMessageHook(int hwnd, int threadId); public native boolean removeMessageHook(); + //public native boolean shutdown(); + + public static Thread createMsgHookWinThread(final long targetHwnd) + { + Thread t = new Thread() { + public void run() { + MsgHook mh = new MsgHook(); + mh.setMsgHookWindowTargetClass(""); + if (targetHwnd != 0) + mh.setMsgHookWindowTargetHwnd((int)targetHwnd); + mh.createMsgHookWindow(); + } + }; + t.start(); + return t; + } } diff --git a/src/org/synthuse/RobotMacro.java b/src/org/synthuse/RobotMacro.java index e9bf9fd..aeaabe9 100644 --- a/src/org/synthuse/RobotMacro.java +++ b/src/org/synthuse/RobotMacro.java @@ -428,6 +428,10 @@ ALT % 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} ); @@ -602,7 +606,7 @@ ALT % 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_COLON}); + 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}); diff --git a/src/org/synthuse/SynthuseDlg.java b/src/org/synthuse/SynthuseDlg.java index 94ec29a..228c317 100644 --- a/src/org/synthuse/SynthuseDlg.java +++ b/src/org/synthuse/SynthuseDlg.java @@ -50,7 +50,7 @@ public class SynthuseDlg extends JFrame { /** * */ - public static String VERSION_STR = "1.2.0"; + public static String VERSION_STR = "1.2.1"; 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"; @@ -83,7 +83,7 @@ public class SynthuseDlg extends JFrame { private JButton btnAdvanced; private TestIdeFrame testIde = null; - private MessageHookFrame msgHook = null; + //private MessageHookFrame msgHook = null; private int targetX; private int targetY; private UiaBridge uiabridge = new UiaBridge(); @@ -187,9 +187,19 @@ public class SynthuseDlg extends JFrame { 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); + } } }; @@ -224,7 +234,9 @@ public class SynthuseDlg extends JFrame { about += " disableUiaBridge - " + config.isUiaBridgeDisabled() + "\n"; about += " disableFiltersUia - " + config.isFilterUiaDisabled() + "\n"; - about += "\nSystem information: \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"; @@ -380,12 +392,17 @@ public class SynthuseDlg extends JFrame { lblStatus.setText(status); } @Override - public void executionCompleted(Object input, String results) { //buildXpathStatementThreaded finished, with results being the xpath statement + 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); } - XpathManager.nextXpathMatch(results, textPane, lblStatus, true); - cmbXpath.setSelectedItem(results); + 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); + } + }); + } }; diff --git a/src/org/synthuse/UiaBridge.java b/src/org/synthuse/UiaBridge.java index e049dcc..017b3e8 100644 --- a/src/org/synthuse/UiaBridge.java +++ b/src/org/synthuse/UiaBridge.java @@ -1,3 +1,10 @@ +/* + * 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; diff --git a/src/org/synthuse/commands/BaseCommand.java b/src/org/synthuse/commands/BaseCommand.java index 1d41ac9..a0080a0 100644 --- a/src/org/synthuse/commands/BaseCommand.java +++ b/src/org/synthuse/commands/BaseCommand.java @@ -1,3 +1,10 @@ +/* + * Copyright 2014, Synthuse.org + * Released under the Apache Version 2.0 License. + * + * last modified by ejakubowski +*/ + package org.synthuse.commands; diff --git a/src/org/synthuse/commands/FileCommands.java b/src/org/synthuse/commands/FileCommands.java index 3f1cb8c..46fb55b 100644 --- a/src/org/synthuse/commands/FileCommands.java +++ b/src/org/synthuse/commands/FileCommands.java @@ -1,3 +1,10 @@ +/* + * Copyright 2014, Synthuse.org + * Released under the Apache Version 2.0 License. + * + * last modified by ejakubowski +*/ + package org.synthuse.commands; import java.io.*; diff --git a/src/org/synthuse/commands/KeyboardCommands.java b/src/org/synthuse/commands/KeyboardCommands.java index 8e13835..f5f1c1a 100644 --- a/src/org/synthuse/commands/KeyboardCommands.java +++ b/src/org/synthuse/commands/KeyboardCommands.java @@ -1,3 +1,10 @@ +/* + * Copyright 2014, Synthuse.org + * Released under the Apache Version 2.0 License. + * + * last modified by ejakubowski +*/ + package org.synthuse.commands; import org.synthuse.*; diff --git a/src/org/synthuse/commands/MainCommands.java b/src/org/synthuse/commands/MainCommands.java index a12cd61..af63554 100644 --- a/src/org/synthuse/commands/MainCommands.java +++ b/src/org/synthuse/commands/MainCommands.java @@ -1,3 +1,10 @@ +/* + * Copyright 2014, Synthuse.org + * Released under the Apache Version 2.0 License. + * + * last modified by ejakubowski +*/ + package org.synthuse.commands; import java.awt.Dimension; diff --git a/src/org/synthuse/commands/MouseCommands.java b/src/org/synthuse/commands/MouseCommands.java index dd1e50a..4f90236 100644 --- a/src/org/synthuse/commands/MouseCommands.java +++ b/src/org/synthuse/commands/MouseCommands.java @@ -1,3 +1,10 @@ +/* + * Copyright 2014, Synthuse.org + * Released under the Apache Version 2.0 License. + * + * last modified by ejakubowski +*/ + package org.synthuse.commands; import java.awt.Point; @@ -18,9 +25,9 @@ public class MouseCommands extends BaseCommand { if (handle.isEmpty()) return false; String wtype = getWindowTypeWithXpath(args[0]); - System.out.println("wtype: " + wtype + " hwnd " + handle.hWnd + " hmenu " + handle.hmenuStr + " pos " + handle.hmenuPos); + //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); + //System.out.println("cmdClick: " + p.x + "," + p.y); RobotMacro.mouseMove(p.x + parentProcessor.targetOffset.x, p.y + parentProcessor.targetOffset.y); RobotMacro.leftClickMouse(); return true; diff --git a/src/org/synthuse/commands/WindowsCommands.java b/src/org/synthuse/commands/WindowsCommands.java index bc85be8..9fdf007 100644 --- a/src/org/synthuse/commands/WindowsCommands.java +++ b/src/org/synthuse/commands/WindowsCommands.java @@ -1,3 +1,10 @@ +/* + * Copyright 2014, Synthuse.org + * Released under the Apache Version 2.0 License. + * + * last modified by ejakubowski +*/ + package org.synthuse.commands; import org.synthuse.*; @@ -152,4 +159,22 @@ public class WindowsCommands extends BaseCommand { 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; + } } +