From 1721d2a130ab34d771f8b4dbfd740cc6ff8379a7 Mon Sep 17 00:00:00 2001 From: Edward Jakubowski Date: Wed, 21 May 2014 08:12:11 -0400 Subject: [PATCH] Fixed highlighting around WPF and Silverlight, fixed windows commands to use WPF runtimeIds,Adding Windows Message hook feature When targeting WPF and silverlight applications synthuse will now target each object with a red rectangle, just like it does with native win 32 applications. Windows commands like setfocus and such are now supported with UIA objects like (WPF, WinForm, Silverlight). Adding support for hooking in to the Message Queue of a target window to see what Messages are being sent, this will allow one to possible resend the messages back for automation purposes. This feature is not fully working yet, but is close. --- .gitignore | 2 + native/MsgHook.sln | 36 ++ native/MsgHook.suo | Bin 0 -> 21504 bytes native/MsgHook/MsgHook.cpp | 64 +++ native/MsgHook/MsgHook.vcxproj | 174 ++++++++ native/MsgHook/MsgHook.vcxproj.filters | 39 ++ native/MsgHook/MsgHook.vcxproj.user | 3 + native/MsgHook/ReadMe.txt | 48 ++ native/MsgHook/bin/MsgHook32.dll | Bin 0 -> 7680 bytes native/MsgHook/bin/MsgHook64.dll | Bin 0 -> 9216 bytes native/MsgHook/build.bat | 6 + native/MsgHook/dllmain.cpp | 47 ++ native/MsgHook/stdafx.cpp | 8 + native/MsgHook/stdafx.h | 43 ++ native/MsgHook/targetver.h | 8 + native/MsgHookTest/MsgHook.h | 300 +++++++++++++ native/MsgHookTest/MsgHookTest.aps | Bin 0 -> 53528 bytes native/MsgHookTest/MsgHookTest.cpp | 388 ++++++++++++++++ native/MsgHookTest/MsgHookTest.h | 3 + native/MsgHookTest/MsgHookTest.ico | Bin 0 -> 23558 bytes native/MsgHookTest/MsgHookTest.rc | Bin 0 -> 9868 bytes native/MsgHookTest/MsgHookTest.vcxproj | 166 +++++++ .../MsgHookTest/MsgHookTest.vcxproj.filters | 57 +++ native/MsgHookTest/MsgHookTest.vcxproj.user | 3 + native/MsgHookTest/ReadMe.txt | 62 +++ native/MsgHookTest/WinMessages.txt | 416 ++++++++++++++++++ native/MsgHookTest/bin/x32/MsgHook.dll | Bin 0 -> 7680 bytes native/MsgHookTest/bin/x32/MsgHook.exp | Bin 0 -> 768 bytes native/MsgHookTest/bin/x32/MsgHook.lib | Bin 0 -> 1874 bytes native/MsgHookTest/bin/x32/MsgHookTest.exe | Bin 0 -> 74240 bytes native/MsgHookTest/bin/x64/MsgHook.dll | Bin 0 -> 9216 bytes native/MsgHookTest/bin/x64/MsgHook.exp | Bin 0 -> 779 bytes native/MsgHookTest/bin/x64/MsgHook.lib | Bin 0 -> 1872 bytes native/MsgHookTest/bin/x64/MsgHookTest.exe | Bin 0 -> 75776 bytes native/MsgHookTest/resource.h | Bin 0 -> 2816 bytes native/MsgHookTest/small.ico | Bin 0 -> 23558 bytes native/MsgHookTest/stdafx.cpp | 8 + native/MsgHookTest/stdafx.h | 23 + native/MsgHookTest/targetver.h | 8 + src/org/synthuse/Api.java | 22 +- src/org/synthuse/MessageHookFrame.java | 142 ++++++ src/org/synthuse/MsgHook.java | 6 + src/org/synthuse/SynthuseDlg.java | 87 ++-- src/org/synthuse/UiaBridge.java | 49 ++- src/org/synthuse/WinPtr.java | 8 + src/org/synthuse/WindowInfo.java | 67 +-- src/org/synthuse/WindowsEnumeratedXml.java | 86 ++-- src/org/synthuse/commands/BaseCommand.java | 12 +- src/org/synthuse/commands/MouseCommands.java | 4 +- .../synthuse/commands/WindowsCommands.java | 12 + src/org/synthuse/img/preferences-desktop.png | Bin 0 -> 825 bytes 51 files changed, 2282 insertions(+), 125 deletions(-) create mode 100644 native/MsgHook.sln create mode 100644 native/MsgHook.suo create mode 100644 native/MsgHook/MsgHook.cpp create mode 100644 native/MsgHook/MsgHook.vcxproj create mode 100644 native/MsgHook/MsgHook.vcxproj.filters create mode 100644 native/MsgHook/MsgHook.vcxproj.user create mode 100644 native/MsgHook/ReadMe.txt create mode 100644 native/MsgHook/bin/MsgHook32.dll create mode 100644 native/MsgHook/bin/MsgHook64.dll create mode 100644 native/MsgHook/build.bat create mode 100644 native/MsgHook/dllmain.cpp create mode 100644 native/MsgHook/stdafx.cpp create mode 100644 native/MsgHook/stdafx.h create mode 100644 native/MsgHook/targetver.h create mode 100644 native/MsgHookTest/MsgHook.h create mode 100644 native/MsgHookTest/MsgHookTest.aps create mode 100644 native/MsgHookTest/MsgHookTest.cpp create mode 100644 native/MsgHookTest/MsgHookTest.h create mode 100644 native/MsgHookTest/MsgHookTest.ico create mode 100644 native/MsgHookTest/MsgHookTest.rc create mode 100644 native/MsgHookTest/MsgHookTest.vcxproj create mode 100644 native/MsgHookTest/MsgHookTest.vcxproj.filters create mode 100644 native/MsgHookTest/MsgHookTest.vcxproj.user create mode 100644 native/MsgHookTest/ReadMe.txt create mode 100644 native/MsgHookTest/WinMessages.txt create mode 100644 native/MsgHookTest/bin/x32/MsgHook.dll create mode 100644 native/MsgHookTest/bin/x32/MsgHook.exp create mode 100644 native/MsgHookTest/bin/x32/MsgHook.lib create mode 100644 native/MsgHookTest/bin/x32/MsgHookTest.exe create mode 100644 native/MsgHookTest/bin/x64/MsgHook.dll create mode 100644 native/MsgHookTest/bin/x64/MsgHook.exp create mode 100644 native/MsgHookTest/bin/x64/MsgHook.lib create mode 100644 native/MsgHookTest/bin/x64/MsgHookTest.exe create mode 100644 native/MsgHookTest/resource.h create mode 100644 native/MsgHookTest/small.ico create mode 100644 native/MsgHookTest/stdafx.cpp create mode 100644 native/MsgHookTest/stdafx.h create mode 100644 native/MsgHookTest/targetver.h create mode 100644 src/org/synthuse/MessageHookFrame.java create mode 100644 src/org/synthuse/MsgHook.java create mode 100644 src/org/synthuse/img/preferences-desktop.png diff --git a/.gitignore b/.gitignore index 6c8318d..4f40838 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ native/uiabridge/x64 native/uiabridge/release native/uiabridge/Debug !native/uiabridge/bin +!native/MsgHook/bin +!native/MsgHookTest/bin diff --git a/native/MsgHook.sln b/native/MsgHook.sln new file mode 100644 index 0000000..58c03a6 --- /dev/null +++ b/native/MsgHook.sln @@ -0,0 +1,36 @@ + +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 new file mode 100644 index 0000000000000000000000000000000000000000..ee98348e8ebc82b77d69436f479a05949c15d284 GIT binary patch literal 21504 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 + Event.wParam = cwps->wParam; + Event.nCode = cwps->message; + Event.dwHookType = WH_CALLWNDPROC; + + BOOL bRes = SendMessage(pData->g_hWnd, WM_COPYDATA, 0, (LPARAM)(VOID*)&CDS); // ask the controlling program if the hook should be passed + } + return CallNextHookEx(pData->g_hHook, nCode, wParam, lParam); // pass hook to next handler + //return bRes; // Don't tell the other hooks about this message. +} + +extern "C" __declspec(dllexport) BOOL SetHook(HWND callerHWnd, DWORD threadId) +{ + if(bStartingProcess) // if we're just starting the DLL for the first time, + { + pData->g_hWnd = callerHWnd; // remember the windows and hook handle for further instances + pData->g_hHook = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)HookProc, (HINSTANCE)pData->g_hInstance, threadId); + + return (pData->g_hHook != NULL); + } + else + return false; +} + +extern "C" __declspec(dllexport) BOOL RemoveHook() +{ + if (pData == NULL) + return false; + if(pData->g_hHook) // if the hook is defined + { + bool ret = UnhookWindowsHookEx(pData->g_hHook); + pData->g_hWnd = NULL; // reset data + pData->g_hHook = NULL; + return ret; + } + return false; +} \ No newline at end of file diff --git a/native/MsgHook/MsgHook.vcxproj b/native/MsgHook/MsgHook.vcxproj new file mode 100644 index 0000000..f613a06 --- /dev/null +++ b/native/MsgHook/MsgHook.vcxproj @@ -0,0 +1,174 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {8E038A94-7D02-49E9-B9F6-5224D9D11225} + Win32Proj + MsgHook + + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + DynamicLibrary + false + true + Unicode + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MSGHOOK_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;MSGHOOK_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MSGHOOK_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + mkdir "$(ProjectDir)bin" +copy /Y "$(TargetPath)" "$(ProjectDir)bin\MsgHook$(PlatformArchitecture)$(TargetExt)" + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;MSGHOOK_EXPORTS;%(PreprocessorDefinitions) + + + Windows + true + true + true + + + mkdir "$(ProjectDir)bin" +copy /Y "$(TargetPath)" "$(ProjectDir)bin\MsgHook$(PlatformArchitecture)$(TargetExt)" + + + + + + + + + + + + false + false + + + + + false + false + + + + + + + + Create + Create + Create + Create + + + + + + \ No newline at end of file diff --git a/native/MsgHook/MsgHook.vcxproj.filters b/native/MsgHook/MsgHook.vcxproj.filters new file mode 100644 index 0000000..c8c6ca7 --- /dev/null +++ b/native/MsgHook/MsgHook.vcxproj.filters @@ -0,0 +1,39 @@ + + + + + {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 + + + + + + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/native/MsgHook/MsgHook.vcxproj.user b/native/MsgHook/MsgHook.vcxproj.user new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/native/MsgHook/MsgHook.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/native/MsgHook/ReadMe.txt b/native/MsgHook/ReadMe.txt new file mode 100644 index 0000000..4420318 --- /dev/null +++ b/native/MsgHook/ReadMe.txt @@ -0,0 +1,48 @@ +======================================================================== + DYNAMIC LINK LIBRARY : MsgHook Project Overview +======================================================================== + +AppWizard has created this MsgHook DLL for you. + +This file contains a summary of what you will find in each of the files that +make up your MsgHook application. + + +MsgHook.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. + +MsgHook.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). + +MsgHook.cpp + This is the main DLL source file. + + When created, this DLL does not export any symbols. As a result, it + will not produce a .lib file when it is built. If you wish this project + to be a project dependency of some other project, you will either need to + add code to export some symbols from the DLL so that an export library + will be produced, or you can set the Ignore Input Library property to Yes + on the General propert page of the Linker folder in the project's Property + Pages dialog box. + +///////////////////////////////////////////////////////////////////////////// +Other standard files: + +StdAfx.h, StdAfx.cpp + These files are used to build a precompiled header (PCH) file + named MsgHook.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/MsgHook/bin/MsgHook32.dll b/native/MsgHook/bin/MsgHook32.dll new file mode 100644 index 0000000000000000000000000000000000000000..7aa62dd0c2a2276caf70e224bb7dd9de237e10c5 GIT binary patch literal 7680 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 = hModule; // so set the instance handle + pData->g_hWnd = NULL; // and initialize the other handles + pData->g_hHook = NULL; + } + DisableThreadLibraryCalls((HMODULE)hModule); + } + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + CloseHandle(hMappedFile); // on detaching the DLL, close the MMF + break; + } + return TRUE; +} + diff --git a/native/MsgHook/stdafx.cpp b/native/MsgHook/stdafx.cpp new file mode 100644 index 0000000..2d8db73 --- /dev/null +++ b/native/MsgHook/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// MsgHook.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 \ No newline at end of file diff --git a/native/MsgHook/stdafx.h b/native/MsgHook/stdafx.h new file mode 100644 index 0000000..bf473c9 --- /dev/null +++ b/native/MsgHook/stdafx.h @@ -0,0 +1,43 @@ +// 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 +#include +#include + +#pragma comment( lib, "psapi.lib" ) + +// TODO: reference additional headers your program requires here + +typedef struct +{ + int nCode; + DWORD dwHookType; + WPARAM wParam; + LPARAM lParam; +}HEVENT; + +typedef struct +{ + HHOOK g_hHook; + HWND g_hWnd; + HANDLE g_hInstance; +}GLOBALDATA; + +#ifndef GLOBAL_VARS_H // header guards +#define GLOBAL_VARS_H + +//Global variables , remember not to initialize here +extern HANDLE hMappedFile; +extern GLOBALDATA* pData; +extern bool bStartingProcess; + +#endif \ No newline at end of file diff --git a/native/MsgHook/targetver.h b/native/MsgHook/targetver.h new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/native/MsgHook/targetver.h @@ -0,0 +1,8 @@ +#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/native/MsgHookTest/MsgHook.h b/native/MsgHookTest/MsgHook.h new file mode 100644 index 0000000..bc22199 --- /dev/null +++ b/native/MsgHookTest/MsgHook.h @@ -0,0 +1,300 @@ +#include + +#define MSGHOOKER_FILE TEXT("MsgHook.dll") + +HINSTANCE msgHookDll; + +//BOOL SetHook(HWND callerHWnd, DWORD threadId) +typedef BOOL (* SETHOOK)(HWND, DWORD); +SETHOOK SetHook; + +//BOOL RemoveHook() +typedef BOOL (* REMOVEHOOK)(VOID); +REMOVEHOOK RemoveHook; + +typedef struct +{ + int nCode; + DWORD dwHookType; + WPARAM wParam; + LPARAM lParam; +}HEVENT; + +/* +typedef struct { + DWORD vkCode; + DWORD scanCode; + DWORD flags; + DWORD time; + ULONG_PTR dwExtraInfo; +} KBDLLHOOKSTRUCT, *PKBDLLHOOKSTRUCT; +*/ + +BOOL InitHook(HWND hw, int threadId) +{ + msgHookDll = LoadLibrary(MSGHOOKER_FILE); + if (msgHookDll != NULL) + { + SetHook = (SETHOOK)GetProcAddress(msgHookDll, "SetHook"); + RemoveHook = (REMOVEHOOK)GetProcAddress(msgHookDll, "RemoveHook"); + if (SetHook) + { + return SetHook(hw, threadId); + } + } + return false; +} + +void KillHook() +{ + if (RemoveHook) + RemoveHook(); + + if (msgHookDll != NULL) + FreeLibrary(msgHookDll); +} + +// MSG Array LOOKUP +const int MAX_MSG_LOOKUP = 1024; +const int MAX_MSG_NAME = 21; +TCHAR MSG_LOOKUP[MAX_MSG_LOOKUP][MAX_MSG_NAME] = { +}; + + +//void InitializeMsgLookup() below +void InitializeMsgLookup(int allowList[], int allowSize) +{ + for (int i = 0 ; i < MAX_MSG_LOOKUP ; i++) + { + bool allowFlg = true; + if (allowSize > 0) + allowFlg = false; + for (int a = 0 ; a < allowSize ; a++) + if (allowList[a] == i) + allowFlg = true; + if (!allowFlg) + continue; + switch (i) + { + case WM_NULL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NULL")); break; + case WM_CREATE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CREATE")); break; + case WM_DESTROY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DESTROY")); break; + case WM_MOVE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOVE")); break; + case WM_SIZE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SIZE")); break; + case WM_ACTIVATE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ACTIVATE")); break; + case WM_SETFOCUS: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SETFOCUS")); break; + case WM_KILLFOCUS: _tcscpy_s(MSG_LOOKUP[i], _T("WM_KILLFOCUS")); break; + case WM_ENABLE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ENABLE")); break; + case WM_SETREDRAW: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SETREDRAW")); break; + case WM_SETTEXT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SETTEXT")); break; + case WM_GETTEXT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_GETTEXT")); break; + case WM_GETTEXTLENGTH: _tcscpy_s(MSG_LOOKUP[i], _T("WM_GETTEXTLENGTH")); break; + case WM_PAINT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PAINT")); break; + case WM_CLOSE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CLOSE")); break; + case WM_QUERYENDSESSION: _tcscpy_s(MSG_LOOKUP[i], _T("WM_QUERYENDSESSION")); break; + case WM_QUIT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_QUIT")); break; + case WM_QUERYOPEN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_QUERYOPEN")); break; + case WM_ERASEBKGND: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ERASEBKGND")); break; + case WM_SYSCOLORCHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SYSCOLORCHANGE")); break; + case WM_ENDSESSION: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ENDSESSION")); break; + case 0x17: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SYSTEMERROR")); break; + case WM_SHOWWINDOW: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SHOWWINDOW")); break; + case 0x19: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CTLCOLOR")); break; + case WM_WININICHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_WININICHANGE")); break; + //case WM_SETTINGCHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SETTINGCHANGE")); break; + case WM_DEVMODECHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DEVMODECHANGE")); break; + case WM_ACTIVATEAPP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ACTIVATEAPP")); break; + case WM_FONTCHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_FONTCHANGE")); break; + case WM_TIMECHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_TIMECHANGE")); break; + case WM_CANCELMODE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CANCELMODE")); break; + case WM_SETCURSOR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SETCURSOR")); break; + case WM_MOUSEACTIVATE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOUSEACTIVATE")); break; + case WM_CHILDACTIVATE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CHILDACTIVATE")); break; + case WM_QUEUESYNC: _tcscpy_s(MSG_LOOKUP[i], _T("WM_QUEUESYNC")); break; + case WM_GETMINMAXINFO: _tcscpy_s(MSG_LOOKUP[i], _T("WM_GETMINMAXINFO")); break; + case WM_PAINTICON: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PAINTICON")); break; + case WM_ICONERASEBKGND: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ICONERASEBKGND")); break; + case WM_NEXTDLGCTL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NEXTDLGCTL")); break; + case WM_SPOOLERSTATUS: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SPOOLERSTATUS")); break; + case WM_DRAWITEM: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DRAWITEM")); break; + case WM_MEASUREITEM: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MEASUREITEM")); break; + case WM_DELETEITEM: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DELETEITEM")); break; + case WM_VKEYTOITEM: _tcscpy_s(MSG_LOOKUP[i], _T("WM_VKEYTOITEM")); break; + case WM_CHARTOITEM: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CHARTOITEM")); break; + case WM_SETFONT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SETFONT")); break; + case WM_GETFONT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_GETFONT")); break; + case WM_SETHOTKEY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SETHOTKEY")); break; + case WM_GETHOTKEY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_GETHOTKEY")); break; + case WM_QUERYDRAGICON: _tcscpy_s(MSG_LOOKUP[i], _T("WM_QUERYDRAGICON")); break; + case WM_COMPAREITEM: _tcscpy_s(MSG_LOOKUP[i], _T("WM_COMPAREITEM")); break; + case WM_COMPACTING: _tcscpy_s(MSG_LOOKUP[i], _T("WM_COMPACTING")); break; + case WM_WINDOWPOSCHANGING: _tcscpy_s(MSG_LOOKUP[i], _T("WM_WINDOWPOSCHANGING")); break; + case WM_WINDOWPOSCHANGED: _tcscpy_s(MSG_LOOKUP[i], _T("WM_WINDOWPOSCHANGED")); break; + case WM_POWER: _tcscpy_s(MSG_LOOKUP[i], _T("WM_POWER")); break; + case WM_COPYDATA: _tcscpy_s(MSG_LOOKUP[i], _T("WM_COPYDATA")); break; + case WM_CANCELJOURNAL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CANCELJOURNAL")); break; + case WM_NOTIFY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NOTIFY")); break; + case WM_INPUTLANGCHANGEREQUEST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_INPUTLANGCHANGERE")); break; + case WM_INPUTLANGCHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_INPUTLANGCHANGE")); break; + case WM_TCARD: _tcscpy_s(MSG_LOOKUP[i], _T("WM_TCARD")); break; + case WM_HELP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_HELP")); break; + case WM_USERCHANGED: _tcscpy_s(MSG_LOOKUP[i], _T("WM_USERCHANGED")); break; + case WM_NOTIFYFORMAT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NOTIFYFORMAT")); break; + case WM_CONTEXTMENU: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CONTEXTMENU")); break; + case WM_STYLECHANGING: _tcscpy_s(MSG_LOOKUP[i], _T("WM_STYLECHANGING")); break; + case WM_STYLECHANGED: _tcscpy_s(MSG_LOOKUP[i], _T("WM_STYLECHANGED")); break; + case WM_DISPLAYCHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DISPLAYCHANGE")); break; + case WM_GETICON: _tcscpy_s(MSG_LOOKUP[i], _T("WM_GETICON")); break; + case WM_SETICON: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SETICON")); break; + case WM_NCCREATE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCCREATE")); break; + case WM_NCDESTROY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCDESTROY")); break; + case WM_NCCALCSIZE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCCALCSIZE")); break; + case WM_NCHITTEST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCHITTEST")); break; + case WM_NCPAINT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCPAINT")); break; + case WM_NCACTIVATE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCACTIVATE")); break; + case WM_GETDLGCODE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_GETDLGCODE")); break; + case WM_NCMOUSEMOVE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCMOUSEMOVE")); break; + case WM_NCLBUTTONDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCLBUTTONDOWN")); break; + case WM_NCLBUTTONUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCLBUTTONUP")); break; + case WM_NCLBUTTONDBLCLK: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCLBUTTONDBLCLK")); break; + case WM_NCRBUTTONDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCRBUTTONDOWN")); break; + case WM_NCRBUTTONUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCRBUTTONUP")); break; + case WM_NCRBUTTONDBLCLK: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCRBUTTONDBLCLK")); break; + case WM_NCMBUTTONDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCMBUTTONDOWN")); break; + case WM_NCMBUTTONUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCMBUTTONUP")); break; + case WM_NCMBUTTONDBLCLK: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCMBUTTONDBLCLK")); break; + //case WM_KEYFIRST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_KEYFIRST")); break; + case WM_KEYDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_KEYDOWN")); break; + case WM_KEYUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_KEYUP")); break; + case WM_CHAR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CHAR")); break; + case WM_DEADCHAR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DEADCHAR")); break; + case WM_SYSKEYDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SYSKEYDOWN")); break; + case WM_SYSKEYUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SYSKEYUP")); break; + case WM_SYSCHAR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SYSCHAR")); break; + case WM_SYSDEADCHAR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SYSDEADCHAR")); break; + case WM_KEYLAST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_KEYLAST")); break; + case WM_IME_STARTCOMPOSITION: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_STARTCOMPOSIT")); break; + case WM_IME_ENDCOMPOSITION: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_ENDCOMPOSITIO")); break; + case WM_IME_COMPOSITION: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_COMPOSITION")); break; + //case WM_IME_KEYLAST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_KEYLAST")); break; + case WM_INITDIALOG: _tcscpy_s(MSG_LOOKUP[i], _T("WM_INITDIALOG")); break; + case WM_COMMAND: _tcscpy_s(MSG_LOOKUP[i], _T("WM_COMMAND")); break; + case WM_SYSCOMMAND: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SYSCOMMAND")); break; + case WM_TIMER: _tcscpy_s(MSG_LOOKUP[i], _T("WM_TIMER")); break; + case WM_HSCROLL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_HSCROLL")); break; + case WM_VSCROLL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_VSCROLL")); break; + case WM_INITMENU: _tcscpy_s(MSG_LOOKUP[i], _T("WM_INITMENU")); break; + case WM_INITMENUPOPUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_INITMENUPOPUP")); break; + case WM_MENUSELECT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MENUSELECT")); break; + case WM_MENUCHAR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MENUCHAR")); break; + case WM_ENTERIDLE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ENTERIDLE")); break; + case WM_CTLCOLORMSGBOX: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CTLCOLORMSGBOX")); break; + case WM_CTLCOLOREDIT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CTLCOLOREDIT")); break; + case WM_CTLCOLORLISTBOX: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CTLCOLORLISTBOX")); break; + case WM_CTLCOLORBTN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CTLCOLORBTN")); break; + case WM_CTLCOLORDLG: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CTLCOLORDLG")); break; + case WM_CTLCOLORSCROLLBAR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CTLCOLORSCROLLBAR")); break; + case WM_CTLCOLORSTATIC: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CTLCOLORSTATIC")); break; + case WM_MOUSEFIRST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOUSEFIRST")); break; + //case WM_MOUSEMOVE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOUSEMOVE")); break; + case WM_LBUTTONDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_LBUTTONDOWN")); break; + case WM_LBUTTONUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_LBUTTONUP")); break; + case WM_LBUTTONDBLCLK: _tcscpy_s(MSG_LOOKUP[i], _T("WM_LBUTTONDBLCLK")); break; + case WM_RBUTTONDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_RBUTTONDOWN")); break; + case WM_RBUTTONUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_RBUTTONUP")); break; + case WM_RBUTTONDBLCLK: _tcscpy_s(MSG_LOOKUP[i], _T("WM_RBUTTONDBLCLK")); break; + case WM_MBUTTONDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MBUTTONDOWN")); break; + case WM_MBUTTONUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MBUTTONUP")); break; + case WM_MBUTTONDBLCLK: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MBUTTONDBLCLK")); break; + case WM_MOUSEWHEEL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOUSEWHEEL")); break; + case WM_MOUSEHWHEEL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOUSEHWHEEL")); break; + case WM_PARENTNOTIFY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PARENTNOTIFY")); break; + case WM_ENTERMENULOOP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ENTERMENULOOP")); break; + case WM_EXITMENULOOP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_EXITMENULOOP")); break; + case WM_NEXTMENU: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NEXTMENU")); break; + case WM_SIZING: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SIZING")); break; + case WM_CAPTURECHANGED: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CAPTURECHANGED")); break; + case WM_MOVING: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOVING")); break; + case WM_POWERBROADCAST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_POWERBROADCAST")); break; + case WM_DEVICECHANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DEVICECHANGE")); break; + case WM_MDICREATE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDICREATE")); break; + case WM_MDIDESTROY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDIDESTROY")); break; + case WM_MDIACTIVATE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDIACTIVATE")); break; + case WM_MDIRESTORE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDIRESTORE")); break; + case WM_MDINEXT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDINEXT")); break; + case WM_MDIMAXIMIZE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDIMAXIMIZE")); break; + case WM_MDITILE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDITILE")); break; + case WM_MDICASCADE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDICASCADE")); break; + case WM_MDIICONARRANGE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDIICONARRANGE")); break; + case WM_MDIGETACTIVE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDIGETACTIVE")); break; + case WM_MDISETMENU: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDISETMENU")); break; + case WM_ENTERSIZEMOVE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ENTERSIZEMOVE")); break; + case WM_EXITSIZEMOVE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_EXITSIZEMOVE")); break; + case WM_DROPFILES: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DROPFILES")); break; + case WM_MDIREFRESHMENU: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MDIREFRESHMENU")); break; + case WM_IME_SETCONTEXT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_SETCONTEXT")); break; + case WM_IME_NOTIFY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_NOTIFY")); break; + case WM_IME_CONTROL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_CONTROL")); break; + case WM_IME_COMPOSITIONFULL: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_COMPOSITIONFU")); break; + case WM_IME_SELECT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_SELECT")); break; + case WM_IME_CHAR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_CHAR")); break; + case WM_IME_KEYDOWN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_KEYDOWN")); break; + case WM_IME_KEYUP: _tcscpy_s(MSG_LOOKUP[i], _T("WM_IME_KEYUP")); break; + case WM_MOUSEHOVER: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOUSEHOVER")); break; + case WM_NCMOUSELEAVE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_NCMOUSELEAVE")); break; + case WM_MOUSELEAVE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_MOUSELEAVE")); break; + case WM_CUT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CUT")); break; + case WM_COPY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_COPY")); break; + case WM_PASTE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PASTE")); break; + case WM_CLEAR: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CLEAR")); break; + case WM_UNDO: _tcscpy_s(MSG_LOOKUP[i], _T("WM_UNDO")); break; + case WM_RENDERFORMAT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_RENDERFORMAT")); break; + case WM_RENDERALLFORMATS: _tcscpy_s(MSG_LOOKUP[i], _T("WM_RENDERALLFORMATS")); break; + case WM_DESTROYCLIPBOARD: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DESTROYCLIPBOARD")); break; + case WM_DRAWCLIPBOARD: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DRAWCLIPBOARD")); break; + case WM_PAINTCLIPBOARD: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PAINTCLIPBOARD")); break; + case WM_VSCROLLCLIPBOARD: _tcscpy_s(MSG_LOOKUP[i], _T("WM_VSCROLLCLIPBOARD")); break; + case WM_SIZECLIPBOARD: _tcscpy_s(MSG_LOOKUP[i], _T("WM_SIZECLIPBOARD")); break; + case WM_ASKCBFORMATNAME: _tcscpy_s(MSG_LOOKUP[i], _T("WM_ASKCBFORMATNAME")); break; + case WM_CHANGECBCHAIN: _tcscpy_s(MSG_LOOKUP[i], _T("WM_CHANGECBCHAIN")); break; + case WM_HSCROLLCLIPBOARD: _tcscpy_s(MSG_LOOKUP[i], _T("WM_HSCROLLCLIPBOARD")); break; + case WM_QUERYNEWPALETTE: _tcscpy_s(MSG_LOOKUP[i], _T("WM_QUERYNEWPALETTE")); break; + case WM_PALETTEISCHANGING: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PALETTEISCHANGING")); break; + case WM_PALETTECHANGED: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PALETTECHANGED")); break; + case WM_HOTKEY: _tcscpy_s(MSG_LOOKUP[i], _T("WM_HOTKEY")); break; + case WM_PRINT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PRINT")); break; + case WM_PRINTCLIENT: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PRINTCLIENT")); break; + case WM_HANDHELDFIRST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_HANDHELDFIRST")); break; + case WM_HANDHELDLAST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_HANDHELDLAST")); break; + case WM_PENWINFIRST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PENWINFIRST")); break; + case WM_PENWINLAST: _tcscpy_s(MSG_LOOKUP[i], _T("WM_PENWINLAST")); break; + case 0x390: _tcscpy_s(MSG_LOOKUP[i], _T("WM_COALESCE_FIRST")); break; + case 0x39F: _tcscpy_s(MSG_LOOKUP[i], _T("WM_COALESCE_LAST")); break; + case 0x3E0: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_FIRST")); break; + //case 0x3E0: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_INITIATE")); break; + case 0x3E1: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_TERMINATE")); break; + case 0x3E2: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_ADVISE")); break; + case 0x3E3: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_UNADVISE")); break; + case 0x3E4: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_ACK")); break; + case 0x3E5: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_DATA")); break; + case 0x3E6: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_REQUEST")); break; + case 0x3E7: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_POKE")); break; + case 0x3E8: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_EXECUTE")); break; + //case 0x3E8: _tcscpy_s(MSG_LOOKUP[i], _T("WM_DDE_LAST")); break; + + //case : _tcscpy_s(MSG_LOOKUP[i], _T("")); break; + default: + memset((void *)&MSG_LOOKUP[i], '\0', sizeof(TCHAR) * MAX_MSG_NAME); + //_tcscpy_s(MSG_LOOKUP[i], 20, _T("")); + break; + } + } +} + +void InitializeMsgLookup() +{ + int allowList[1]; + allowList[0] = -1; + InitializeMsgLookup(allowList, 0); +} + diff --git a/native/MsgHookTest/MsgHookTest.aps b/native/MsgHookTest/MsgHookTest.aps new file mode 100644 index 0000000000000000000000000000000000000000..af32054611395a6bfa565aeec0e6887caf774429 GIT binary patch literal 53528 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 25000) + {//need to truncate the beginning so the text doesn't go past it's limit + SendMessage(txtHwnd, EM_SETSEL, 0, 10000); + SendMessage(txtHwnd, EM_REPLACESEL, 0, (LPARAM)_T("")); + len = GetWindowTextLength(txtHwnd); + } + //DWORD l,r; + //SendMessage(txtHwnd, EM_GETSEL,(WPARAM)&l,(LPARAM)&r); + SendMessage(txtHwnd, EM_SETSEL, len, len); + SendMessage(txtHwnd, EM_REPLACESEL, 0, (LPARAM)newText); + len = GetWindowTextLength(txtHwnd); + SendMessage(txtHwnd, EM_SETSEL, len, len); + //SendMessage(txtHwnd, EM_SETSEL,l,r); +} + +void InitMsgFiltersAndLookup() +{ + if (!filterWmCommand && !filterAbove && !filterWmNotify) + InitializeMsgLookup(); + else + { + int allowList[3]; + for (int i = 0; i < 3; i ++) + allowList[i] = -1; + + if (filterWmCommand) { + AppendText(txtbox, _T("filtering on WM_COMMAND & WM_MENUCOMMAND\r\n")); + allowList[0] = WM_COMMAND; + allowList[1] = WM_MENUCOMMAND; + } + if (filterWmNotify) + { + AppendText(txtbox, _T("filtering on WM_NOTIFY\r\n")); + allowList[2] = WM_NOTIFY; + } + //if (filterAbove) + // allowList[0] = WM_COMMAND; + InitializeMsgLookup(allowList, 3); + } +} + +void StartMessageHook() +{ + AppendText(txtbox, _T("Starting Message Hook\r\n")); + targetHwnd = FindWindow(targetClassname, NULL); + DWORD tid = GetWindowThreadProcessId(targetHwnd, NULL); + + InitMsgFiltersAndLookup(); + //InitializeMsgLookup(); + + TCHAR tmp[50]; + _stprintf_s(tmp, _T("Targetting %ld, %ld\r\n"), targetHwnd, tid); + AppendText(txtbox, tmp); + + //block self/global msg hook + if (targetHwnd == NULL || tid == 0) { + AppendText(txtbox, _T("Target window not found\r\n")); + return; + } + + if (InitHook(mainHwnd, tid)) + { + AppendText(txtbox, _T("Hook successfully initialized\r\n")); + } + else + AppendText(txtbox, _T("Hook failed to initialize\r\n")); +} + +void StopMessageHook() +{ + AppendText(txtbox, TEXT("Stopping Message Hook\r\n")); + KillHook(); +} + +bool OnCopyData(COPYDATASTRUCT* pCopyDataStruct) // WM_COPYDATA lParam will have this struct +{ + if( pCopyDataStruct->cbData!=sizeof(HEVENT)) + return false; + HEVENT Event; + memcpy(&Event, (HEVENT*)pCopyDataStruct->lpData, sizeof(HEVENT)); // transfer data to internal variable + if (Event.dwHookType == WH_KEYBOARD) + { + //KBDLLHOOKSTRUCT* pkh = (KBDLLHOOKSTRUCT*) Event.lParam; + //char tmp[50]; + //return wkvn->KeyboardData(pkh->vkCode,Event.wParam); + } + else if (Event.dwHookType == WH_MOUSE) + { + //MSLLHOOKSTRUCT* pmh = (MSLLHOOKSTRUCT*) Event.lParam; + //char tmp[50]; + //if (Event.wParam == WM_LBUTTONDOWN) + // return wkvn->MouseClickData(1,true); + // else + // return wkvn->MouseMoveData(pmh->pt.x,pmh->pt.y); + } + else if (Event.dwHookType == WH_CALLWNDPROC) + { + TCHAR *msgName = _T("unknown"); + if (Event.nCode < MAX_MSG_LOOKUP) + msgName = MSG_LOOKUP[Event.nCode]; + else + { + if (!filterAbove) + return false; + } + if (_tcscmp(msgName, _T("")) != 0) + { + TCHAR tmp[200]; + _stprintf_s(tmp, _T("msg: %s (%ld), wparam: %ld, lparam: %ld\r\n"), msgName, Event.nCode, Event.wParam, Event.lParam); + AppendText(txtbox, tmp); + } + } + return false; +} + +void SendWmSettext() //ID_TESTMSGS_WM +{ + //SetWindowText(targetHwnd, _T("This is a test")); + TCHAR txt[] = _T("This is a test"); + SendMessage(targetHwnd, WM_SETTEXT, 0 , (LPARAM)txt); + //PostMessage(targetHwnd, WM_SETTEXT, 0 , (LPARAM)txt); +} + +// +// FUNCTION: MyRegisterClass() +// +// PURPOSE: Registers the window class. +// +// COMMENTS: +// +// This function and its usage are only necessary if you want this code +// to be compatible with Win32 systems prior to the 'RegisterClassEx' +// function that was added to Windows 95. It is important to call this function +// so that the application will get 'well formed' small icons associated +// with it. +// +ATOM MyRegisterClass(HINSTANCE hInstance) +{ + WNDCLASSEX wcex; + + wcex.cbSize = sizeof(WNDCLASSEX); + + wcex.style = CS_HREDRAW | CS_VREDRAW; + wcex.lpfnWndProc = WndProc; + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = hInstance; + wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MSGHOOKTEST)); + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MSGHOOKTEST); + wcex.lpszClassName = szWindowClass; + wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); + + return RegisterClassEx(&wcex); +} + +// +// FUNCTION: InitInstance(HINSTANCE, int) +// +// PURPOSE: Saves instance handle and creates main window +// +// COMMENTS: +// +// In this function, we save the instance handle in a global variable and +// create and display the main program window. +// +BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) +{ + HWND hWnd; + + 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); + + if (!hWnd) + return FALSE; + mainHwnd = hWnd; + + RECT rect; + GetClientRect(hWnd, &rect); + // 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); + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + return TRUE; +} + +// +// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) +// +// PURPOSE: Processes messages for the main window. +// +// WM_COMMAND - process the application menu +// WM_PAINT - Paint the main window +// WM_DESTROY - post a quit message and return +// +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int wmId, wmEvent; + PAINTSTRUCT ps; + HDC hdc; + + switch (message) + { + case WM_CREATE: + //appendText(txtbox, TEXT("test\r\n")); + break; + case WM_COPYDATA: + return (OnCopyData((COPYDATASTRUCT *) lParam)); + break; + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + // Parse the menu selections: + switch (wmId) + { + case ID_FILE_STARTHOOK: + StartMessageHook(); + break; + case ID_FILE_STOPHOOK: + StopMessageHook(); + break; + case ID_TESTMSGS_WM: + SendWmSettext(); + break; + case ID_FILE_SETTINGS: + DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, About); + break; + case IDM_ABOUT: + DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); + break; + case IDM_EXIT: + DestroyWindow(hWnd); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + break; + case WM_PAINT: + hdc = BeginPaint(hWnd, &ps); + // TODO: Add any drawing code here... + EndPaint(hWnd, &ps); + break; + case WM_SIZE: + { //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); + } + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +// Message handler for about box. +INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) +{ + UNREFERENCED_PARAMETER(lParam); + switch (message) + { + case WM_INITDIALOG: + { + //IDC_EDIT1 + HWND classnameHwnd = GetDlgItem(hDlg, IDC_EDIT1); + if (classnameHwnd != NULL) + SetWindowText(classnameHwnd, targetClassname); + + if (filterWmCommand) + SendDlgItemMessage(hDlg, IDC_CHECK_CMD, BM_SETCHECK, BST_CHECKED, 0); + if (filterWmNotify) + SendDlgItemMessage(hDlg, IDC_CHECK_NOT, BM_SETCHECK, BST_CHECKED, 0); + if (filterAbove) + SendDlgItemMessage(hDlg, IDC_CHECK_ABO, BM_SETCHECK, BST_CHECKED, 0); + + } + return (INT_PTR)TRUE; + + case WM_COMMAND: + if (LOWORD(wParam) == IDOK) //only save on OK + { + HWND classnameHwnd = GetDlgItem(hDlg, IDC_EDIT1); + if (classnameHwnd != NULL) + GetWindowText(classnameHwnd, targetClassname, 100); + // check filter options + if (SendDlgItemMessage(hDlg, IDC_CHECK_CMD, BM_GETCHECK, 0, 0) == BST_CHECKED) // the hard way + filterWmCommand = true; + else + filterWmCommand = false; + if (IsDlgButtonChecked(hDlg, IDC_CHECK_NOT) == BST_CHECKED) // the easy way + filterWmNotify = true; + else + filterWmNotify = false; + if (IsDlgButtonChecked(hDlg, IDC_CHECK_ABO) == BST_CHECKED) + filterAbove = true; + else + filterAbove = false; + InitMsgFiltersAndLookup(); + } + if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) + { + EndDialog(hDlg, LOWORD(wParam)); + return (INT_PTR)TRUE; + } + break; + } + return (INT_PTR)FALSE; +} diff --git a/native/MsgHookTest/MsgHookTest.h b/native/MsgHookTest/MsgHookTest.h new file mode 100644 index 0000000..d00d47e --- /dev/null +++ b/native/MsgHookTest/MsgHookTest.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/native/MsgHookTest/MsgHookTest.ico b/native/MsgHookTest/MsgHookTest.ico new file mode 100644 index 0000000000000000000000000000000000000000..d551aa3aaf80adf9b7760e2eb8de95a5c3e53df6 GIT binary patch literal 23558 zcmeI430zgx+QuJHKtxbe5gbu*030B5$VyGcDGSFOalkY&2LuvC5pp(7&2XNl96=@z zNXGH2`|DO#nx)3nwUq43A>_N=+wHsYe$U#6ePmShD&p^B>2uySylbs@uYIPy&-w#c zpc-6UYC)x+ErDgUwQ8BlZ7hIURRB*7exZ#T}AXG2* z=^weGTI5~Inq#r?3QZRh5>Vvy7AqDy*^i;1p6BY7;LQSXZ{;g>M z?fm5AM!1uJ~14CP5-;mbWJGeF0 z_iurN!(6GBI54yo4h(CB{j~e(6Em$hj*V=Fqpvo{5$e#07L+U2`wvFkn8s8S#Efo= z^|!}o{tozLT1|Z7UlaSMxZ(5FgK^Rilm(Khv|vko7i5X}36?lI))Ggklas69 zVxSe$=33+10BfA^v%)uXY;b;dHGCaV4e6oPadwt1PEE7L#SjO4G`kKy33kG#^P1yK zcx(J^Ra<Ti+?95-JJvGIWK0JnTs;vs^DcXy)=jK$w z=lme~e0CM~SM61i7E+Zy6!Vv8(?YCpX|5H%3$bS21{dbq;8I96Tne>C8jm-9o*mM| z?2r~#1K&~U^BwT@ygK+I#1UDG8sIO%&iE*}A+E1$jbGNa!S(fRas9ovxba>)TBY{5 zxxo`Rq9|oIDtY0?rjE#1t!!u9+}s5>w|2#i&D55z%y+}h?JrQ>af9~O4zA^n9=Nr$ z7jEt9gPXg&@$23JxV49(y|Q~4emOiI-)H_6dH=qKoBYhlq5e+&PW_AegZf|U-_)N} z9@RJC3MS7vp?yXL1qC4>AOQaU{+Kjr5++WZhzS!Wz}MFoW5Wxo&I+1!G$zZHn#$;`!98-<yjHIyy#~ zd!^|5sm6LSF)_!K%8;V#rWzZU(N_%@(#Q5Ewg{KRHI95 zY?=LIo2D9@#Ky*zb^O>SmHu~IE44l?Dgh-;K81z)WLJ`;4wqn z_ZrZ%LmzL?wy3kD_lL%jZ@l`n*YIJJ=8o?=KVm^dc=tK8XTNSrUK1xwofb5!|4WPJ z4;&O=5uecStt8`&$o&U)@7lX>*XEsj-g|fBj_upFZrx%^n^vq{{r0M5OP8-%`Odni z4ek1_pUw~WS3(xf3w~KkBmDdVRSL~dfr0)bOf7sI@n%@?lm1=c0pd4Z&T02Hm@RH2 z)we;5{I7(S*0d0%twR;wLsA|##n-X4buN70s`TsBg@MbpxknH6!QPjfV-K~P+VA6v z_lLE?{$Xwi?eB?&gE}IlpC>|?5A<%2&;edpIl33d4IhkA?7Qcs#@NdnYWsbf({dao zjuAS*69M!eGt37G)4CyX#*2ub-V>ij1>vuo!mzs+z)KgL@b7{zHqOE48v-$!zJ3#Y zv6uJbc6$T6dQ*KU=65px!K_Y5n$a2Cr*_9zn`Ys&O+gqt+y{pT0q+l>1_JwOKM87w zj|1D|zXCjwI@=4Ewok|DRTFSw+Z#B)bq3CDnTav%mol33yacQq;D9qB?)YqOTV(8< zhO{02IO`82u>Hs|UYpK$#ksIn_%f8&v3sW=YtK}ip9y^Z1~r3H`B~I#;2iDQ=@jeE zsP;Kl_%^%|E=9QF`(^IPTIr6TH*`S`ui5^ww+}9?dJfr}dg8{OA;>xEhiiu?LYUzwb+T)8Ci=PAZtkjWKvm68X{|HBivlm3|Y&X;^sP6+GhB5eJk92w>5I2 z+$j(Ix}hC1827D>9dK(?2jp()h@8zG@!QT$$l2N%x3+e|?QJ|JOre?J8PhnJ%Ni~CLrzWB&44|iS%zyB8@if zn`DaR3m@|O^QyPhwX#dzrgIKY+OQIBHLeiIw|EP z&VT0+jvL~&)rdRJe}-vnAIJ6*Q-ZDH1N-*w-gRv2&ZLw99b3D3xO=#{xw*T!wQ+Oz@bGBcd0?|n&$#sN_2S8-lrFX#RqEa{~iIg60Iwp0)kazxeJo zgX#N&>G3k(9Zpk`k46?8yGp_NR9<~gx%0b2>EBc6h6N*s;*a0{2Wy6O#7ZA8q(u55 zXmAg#9`ZC+QBk9x#nSQpa4CKpR!sCp#>stnXRBl-)qQFW^fsryy=(Z?FI2AS<5;lV$HB*W zpm$$$hhFu3THa~z+qYL;AE$u>2QZl)2G;Ru)3f^vUAny3rOUHDp6~jct50i}CXE|6 zZPK7&qvp+?vT*b1+^M5y`wmZgdAPT0`%H^xiXL6DvWOu*60xx;u6V#Q2{0r8adCy( zEn;IuV&g28p4jI>W#CW53OF&!CsAr~RottogHM>&s@S>DKq|7h|3SD9 zqF9XiYwfgmNUJRFhY%(1o6xLY)@?;QKJMM%9Zv1};>0~2!r#}0zp0zW`xNH9UeDj( zg}=XRQtjm}{_d~Eq+;bB6m$ICmr^L!lH$^jp`^CQQOEr>=J>f^rrg)^KRssd^D)QI zeLuo|80KTp^Sb>{=X%)v)pLRSmCW&T|B@EJinpT1Tyzb%m&zPJ_g4w`z?hFg`Rd1_ z>Wj7&9jm;{DmLy1Gsn+8Vp@!PtSTNouWWh8cdz+W{M_4Sj-PwjDs;R>k4LR3_uiS~ z=YBll{weJklr8FC(aI`*?jJPA&pn00ytW2@1pNNmFr)z)}MRaMZIsT^P*Jr zd{v~ficiI=V%Fb3xlf-prc}}2|5bcSDrP-?@&@_Qn~c8Rs-)*Df-M*%`H0H+%lZ72 zvi{EGQOr#h;dxS84CWx2AwMJBn{b$~fyU%&3N}@!=X}9qDHtRuG5tUm68j-~fkG1sqOUyGmYlwPgb z2OYaS`ssnHnDzL{f$7y1HvU2ZvOsRl96y=1qRkb)O#V)fzZuy)A>;K#iJYK%{YIx)`7mahDM1B1t%cm9kaZNYkD4X_DC9qd+$8->B5TQhB} zPLpFP(T5^y$$V8IA1dTRh5V#84>?gGBg(O=3b|S#mnh^Cg)FI%vsB;THmdl^aSGW> zA@3;U9fcgEkcSj)tKX)y|CMyJ9 zWMGAisgNZVGNwZIRLI7bES?uKuA0cIN->306SAtME58p}SdPK5N}H!(y?QQ$SPR)# zEw=cH;9p8myVEOE~ZJrY}3iIg?0rP&%LTBp=}8h@I%TXv<9-xUO`%}-uWt5a*E=2Z6^)Nip$4?6}mrb=W3r9pMm{N(?%I<=0f{ZX!iK0oKQ1d^EdG#^%`N>O4Lp#&)lc_BC`N?cbBh&ou z$Ha>#mE4>Z3XbJ2L!+Nt++W%XmzCnEDKwe#1XEVN#&9kX7z*Ba>aDt~p(O7d58 ztNMbLMIj4qo}V1Gs?t)?V|bWl{j*<9L>}8bKN)V*HyMT)&Xn7jpKpqbGz6zmVk@{(S%;moMb= zg`B=PIy$QPUCF}>xq2agFXZoq+`W*w*DN`FAuBIr%G&-D!IW`F9}` zFJ#_@jJ%MQmz-@~sV+i3UdYL7B1xFE+kg*rC_sn}}eaYVo*?J*YFZ>$;!oOJ{ z{QCgB-)1FF4i?imzkPZz{4Rvr{h7I>sgUu{%LsSK%b0JUml0-1RnN;GSP!(-+jpO%JopO`B((dnpK-(&yRaUJ6F; zchnE_k$Wv1f4{oG;*T$8Vx5|ss!Wf01@yO_$nuNBLZ4Gvb)Vu6x9f7RD3t3{RPFna z@~=**zWfUs8kYPPZCSL4e)B1xT|TXnSM+U>y|{O?8%m4vtzIr_BVKg5vCP}`*3dR} z&a!{N#n>%>kU18z!$Q_q$meQ#RW3=oZ=knFmg=8&V&`qOUg~p1N&lWwnpHmPb9YW3 zw+z)kIP(xwOMAJX5{|A*v__uZdtvV;w2rOkgeCCc1i z#a5Q%Amc3IgIa3+fBIm(x&OWTs_~Un|HxNN{coH$#m{POUDev^Dy>e{FMhe1Y5iiu zZms`A54!#`X+2QPTVf z?Hzz(HP>z<_`pCtVkBQcYXDoj<(5>2OIWQJjknoo{cJ1lLz1e>(9E=8mgjs`uegL} zzQX5{vp*KfH*GGr#o~DjIU;vUh@T=0&Jq)gFD0c7;Ddd5*)426gntF{2EN|Mo8wO# zPliTAd7I(=L)DmRjs6(O4=GH!1jTLHLo^wdwBh+DK$Qw+?!qGvagpv{xPsh~9nd&N z>~=A#iSciB)QD?&NbUG12H=cqP`=H3>1Bsy@-SX zdOqNy2VJPA+$cAJz9;!ImDhZ60@1Rf{CjRZ)5(NY{~u-g7Oeiu@7GE<#*6DU9CnkS^jh`+UUIvzdD>k ze||28$VsM$^vrJE#YIr}L&KPc+V*k6L#e?^fgKxBv{T+4JlA0Lrc!acwP4p4BDV$I zhq4Tuxq;VQMHPjK1*G*enTm>L1ToAo_Y;m2o*tmMDd+cb-_s;9zl$2<8KES zd9OtnGfp9!2de=X6Yhz#@-fMSA!z3*TBy@mxwuDs&(DJ)OIi~hwUU$;k8fn&_+_rQ}ZKVa^NV}h&fQ`m*|4t0K{buPcGsU_@h zNj9VR4_Kj+D(j%n>MtBilrYTM1BE8qSZ{kv1K+AjeNVlMxhUDrOm>QIr1Kd+Yx|^B zlXyvr_O$|PEzH6l1Xf*fi&5}wM^4B4h8P=TN_HJ)C>+c3lj?$18@X%i8s4hMDl~l^ z`DIdLYse=h)l_!;OsmyO&@*TC$fdp+mmIeO${SCA%XnKs?=_vxBaG2w=s|jr*m>y0S^zT(77LV4ZX8g zc>^7AMMs%A8&RQ%v$A|p{+u&SmE_+(xaTT|NN{^LPT+4@eK6sje&y=(z>$q>I z=HF{%7;W>;8l>eKw5779(S&?50+aDp0yoKb+ASS_WqGeM1ekFR*K3c!$?BI9%^PnU zstbCoM_zHvJw|3XF)s_@uji=qxx0G%NP---B2&&#(^tK=>?KSGw^dYzSj5}7KHY!~eZkhOvy zRm>6saah}O*Q2k!cT&2D$GF6CrlYmk+g3c(B{jRD$h4`sgIa!$3`A^ZnmuIWJPEAN ze<8v9C=QrG=9j>7JNL8c|6G?bHd)o?Nn*9oOG{FYG6eI)rh1gilFkRT&udz55JTJW zjT-!$`whfwmw|WwxYysC>wJPcti%jrA*pf>=EUr|@+vCJtmCyU^FuPbl0%Q*Y)anB z)zBUyfziypVRA-lo2jVs-p6R?Ug2c_5_0!?<`|3J+2|7itTr)xNpi%PNy?S>G3PM5 z_W1wxQwC~nrTBM_UrIk)WBQNv6F()-ynKG!U7Y2F?fJg{nxfzHJtHALwWRF6JHcnx zv)MfZwQ_dUWuGLUA&1#&EVdNq;5q4Y<}hq3I(wsR@#*OqDv2}A&79T!B2M(tlAL<#7*NlE9Tf}|wIcCvGZ605F7GHm+ z#pj*pWpLm%MKw=gxxVH}1f%L4`y<>>9FJ?(n#^)MWw7d#8IrxSBbxcfD*G1J!d;Bv znt@|Hj?(wMJ&E+5xUVf{J)5&#o5@qWEL6$2{mYzUFSb|ElKz_)C*4;TQ$pv?@89}g eI>e&l|I%?iE~Y-n6* + + + + 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 new file mode 100644 index 0000000..7343c35 --- /dev/null +++ b/native/MsgHookTest/MsgHookTest.vcxproj.filters @@ -0,0 +1,57 @@ + + + + + {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 new file mode 100644 index 0000000..ace9a86 --- /dev/null +++ b/native/MsgHookTest/MsgHookTest.vcxproj.user @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/native/MsgHookTest/ReadMe.txt b/native/MsgHookTest/ReadMe.txt new file mode 100644 index 0000000..6d81f3a --- /dev/null +++ b/native/MsgHookTest/ReadMe.txt @@ -0,0 +1,62 @@ +======================================================================== + 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 new file mode 100644 index 0000000..e27e2f4 --- /dev/null +++ b/native/MsgHookTest/WinMessages.txt @@ -0,0 +1,416 @@ + +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 new file mode 100644 index 0000000000000000000000000000000000000000..c61865312bf68b880add7fcc9d6f77a4873396ea GIT binary patch literal 7680 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 literal 0 HcmV?d00001 diff --git a/native/MsgHookTest/bin/x32/MsgHook.lib b/native/MsgHookTest/bin/x32/MsgHook.lib new file mode 100644 index 0000000000000000000000000000000000000000..c6192c3aec1fcf3590b2717f543add945a4bd323 GIT binary patch literal 1874 zcmcIlPiqrF6#wn6Y3tTQs0u<6Rw$?lF@H9R1(A(bXy_&_oAf-5No<1+TiWPJ@Y174 zkM`(?@YXNj!Ga&adp<&;zPCHm%-Tkiq7Qc7yf<&={eOG!X=}f|^UQwiBq8T!v!!yO zkS`?pSxM$fuH0?e0A>N>1h7tlR34Z)l;4o>P>5=6V?Ah!m6wedL3N|K9*Ek(_G%cu zfe`gg-@hn;4^kpNZ?10E*ThPtS%C<;{qS8^-tP7HM1s@k4)h~MPVHZL2zPc-Ck$C=~CCYvbw+MZs@28|Gc<_)t zmU1P@#tqt>(Wm5?@4-1X2`}I}lbF|>x{sS_jy%7|z~#4iv{37{_rrtm^}u-$JaqhO zeJwiuZDD16kssjX@h(j(r+5~c7I^Kjzelz%9(~3c*%zzh8w_lm3FWc}MCR@&PUIZl zuoTB-8DijEra0m--{D09zYZ)*ijj$c)+<%g*g~;2cPFZpd{K2jSBe=`%Gby^Hu3UG z=|o4PMXQv8;&P>YQG~=?DgUJcCdunvGGgptnmTIbC+Cw=_16zl5GVQasQsb8iYicC zirim1X#M3XKFfVqgv9?ex|2q9Y#~k?QCE#-hyOj?oW8+R>rUj|Tw)4qZ|m(nQN6o4 U_3umSxlMWunvX)wVqJ;-3xum{%5tr& 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 literal 0 HcmV?d00001 diff --git a/native/MsgHookTest/bin/x64/MsgHook.dll b/native/MsgHookTest/bin/x64/MsgHook.dll new file mode 100644 index 0000000000000000000000000000000000000000..b47b70ca74c8e7f6b2a28505524468079fc5093b GIT binary patch literal 9216 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 O4&ydPkBB_Urjeg*V`Y5+ literal 0 HcmV?d00001 diff --git a/native/MsgHookTest/bin/x64/MsgHookTest.exe b/native/MsgHookTest/bin/x64/MsgHookTest.exe new file mode 100644 index 0000000000000000000000000000000000000000..17878341886b0f570a648c8bc5264077a74d26b2 GIT binary patch literal 75776 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 P^#|8u$GQEV@xcEB^kcMe literal 0 HcmV?d00001 diff --git a/native/MsgHookTest/resource.h b/native/MsgHookTest/resource.h new file mode 100644 index 0000000000000000000000000000000000000000..36293d58949b1820475d5887a36e2a4d89681685 GIT binary patch literal 2816 zcmbW3-*3|}5PG$Rg(_(6tQld3ezgBD?fzz*MaYBy0+AI zQ)ET49q04;?tFK@f3>6~KWK#vq?S}N8S)gSS4bjVMy33uJ(fqTZAm1#%w!^WGM5F< zRPLEOV{Rc!`6xGx5_w9CsBarYfVwuEf%3_SCsoTb_%bTtbMk!jN}`)D@)6$=N-Jk~=|}V|jyIW2pN6(2yHR zn4BA#SL9u}LNiK!;gwm*8FH!~LKN3GCBO8NyO47%wrfEbYkN+~CqZ%vTYaE^pwvo! zWL3o*&?K#{rr3rlfFJH==!jM%vsHzs#zQ%&;r`bK64u zMyh9Rp{S8?w=<$fk9`vKkv81Jvi&z)<=$j#>}~4ZmhHde+w4w5iLJIQ+kY3g*&3zv z#_!W~Gj@&FbxowJO%#ps!RjHlhWF^;B`37D*P8#*2SnFZ+zzuN;;E(k?Wu9v#(o=5 zG=jg!U-psp`-<+j=(g+`dudiEh+E~}9ai+PO*L!9hMMdpZl3AcUyZLTgMzI4&C~;$ z+oxpxCAnSegD<8sSeneOIe$*>j!c&R%6l#s@`-N~)-H?{ZKYvv=Zy817a`}+_{Z4X zd#zbi7iaik&%}cDAGd*jMy!n?Xg$!UHc+2C$71TwefqAbV6(E?*49cn9(#zs+}^oK z)jX&5gGyH-$(UY3zvg@zJ;(Gn^{@Rl9^{TO|?*hFX7KQV&j@<3C@hN#g(j literal 0 HcmV?d00001 diff --git a/native/MsgHookTest/small.ico b/native/MsgHookTest/small.ico new file mode 100644 index 0000000000000000000000000000000000000000..d551aa3aaf80adf9b7760e2eb8de95a5c3e53df6 GIT binary patch literal 23558 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 + +// 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 new file mode 100644 index 0000000..87c0086 --- /dev/null +++ b/native/MsgHookTest/targetver.h @@ -0,0 +1,8 @@ +#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 3af52f2..8add96b 100644 --- a/src/org/synthuse/Api.java +++ b/src/org/synthuse/Api.java @@ -77,6 +77,13 @@ public class Api { public static int PROCESS_VM_READ = 0x0010; public static int PS_SOLID = 0x0; + public static int PS_DASH = 0x1; + public static int PS_DOT = 0x2; + public static int PS_DASHDOT = 0x3; + public static int PS_DASHDOTDOT = 0x4; + public static int PS_NULL = 0x5; + public static int PS_INSIDEFRAME = 0x6; + public static int HOLLOW_BRUSH = 0x5; public static int WM_PAINT = 0x0F; @@ -521,14 +528,19 @@ public class Api { String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i"); return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre); } - - // creates highlight around selected window + public static void highlightWindow(HWND hwnd){ + RECT rect = new RECT(); + User32.instance.GetWindowRect(hwnd, rect); + //System.out.println("RECT: " + rect.left + "," + rect.top + "," + (rect.right - rect.left) + "," + (rect.bottom - rect.top)); + highlightWindow(hwnd, 0, 0, rect.right - rect.left, rect.bottom - rect.top); + } + + // creates highlight around selected window + public static void highlightWindow(HWND hwnd, int x, int y, int x2, int y2){ //COLORREF i.e. 0x00804070 Red = 0x70 green = 0x40 blue = 0x80 //g_hRectanglePen = CreatePen (PS_SOLID, 3, RGB(256, 0, 0)); HPEN rectPen = Gdi32.instance.CreatePen(PS_SOLID, 3, 0x00000099); //RGB(255, 0, 0) - RECT rect = new RECT(); - User32.instance.GetWindowRect(hwnd, rect); HDC dc = User32.instance.GetWindowDC(hwnd); if (dc != null) { // Select our created pen into the DC and backup the previous pen. @@ -538,7 +550,7 @@ public class Api { HANDLE prevBrush = Gdi32.instance.SelectObject(dc, Gdi32.instance.GetStockObject(HOLLOW_BRUSH)); // Draw a rectangle in the DC covering the entire window area of the found window. - Gdi32.instance.Rectangle (dc, 0, 0, rect.right - rect.left, rect.bottom - rect.top); + Gdi32.instance.Rectangle (dc, x, y, x2, y2); // Reinsert the previous pen and brush into the found window's DC. Gdi32.instance.SelectObject(dc, prevPen); diff --git a/src/org/synthuse/MessageHookFrame.java b/src/org/synthuse/MessageHookFrame.java new file mode 100644 index 0000000..7ce1751 --- /dev/null +++ b/src/org/synthuse/MessageHookFrame.java @@ -0,0 +1,142 @@ +package org.synthuse; + +import javax.swing.JFrame; +import javax.swing.JToolBar; +import java.awt.BorderLayout; +import javax.swing.JTextArea; +import javax.swing.JScrollPane; +import javax.swing.JButton; + + +import 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 java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +public class MessageHookFrame extends JFrame { + + private static final long serialVersionUID = -5863279004595502801L; + + public static final int WH_CALLWNDPROC = 4; + public static final int WH_GETMESSAGE = 3; + public static final int WH_KEYBOARD_LL = 13; + + private JTextArea textArea; + private JButton btnSave; + private JButton btnStartMsgHook; + private JButton btnPause; + private JButton btnClear; + + public static HHOOK hHook = null; + //public static LowLevelKeyboardProc lpfn; + public static volatile boolean quit = false; + + public MessageHookFrame() { + setTitle("Message Hook"); + setBounds(100, 100, 700, 367); + + JToolBar toolBar = new JToolBar(); + getContentPane().add(toolBar, BorderLayout.NORTH); + + btnStartMsgHook = new JButton("Start Hook"); + btnStartMsgHook.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (btnStartMsgHook.getText().equals("Start Hook")) + { //start Message Hook + btnStartMsgHook.setText("Stop Hook"); + createMessageHook(); + } + else + { //stop message hook + btnStartMsgHook.setText("Start Hook"); + stopMessageHook(); + } + } + }); + toolBar.add(btnStartMsgHook); + + btnPause = new JButton("Pause"); + btnPause.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + }); + toolBar.add(btnPause); + + btnSave = new JButton("Save"); + btnSave.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + }); + toolBar.add(btnSave); + + btnClear = new JButton("Clear"); + btnClear.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + textArea.setText(""); + } + }); + toolBar.add(btnClear); + + JScrollPane scrollPane = new JScrollPane(); + getContentPane().add(scrollPane, BorderLayout.CENTER); + + textArea = new JTextArea(); + scrollPane.setViewportView(textArea); + super.setAlwaysOnTop(SynthuseDlg.config.isAlwaysOnTop()); + } + + public void createMessageHook() { + 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; + + MSG msg = new MSG(); + try { + + while (!quit) { + User32.INSTANCE.PeekMessage(msg, null, 0, 0, 1); + if (msg.message == User32.WM_HOTKEY){ // && msg.wParam.intValue() == 1 + msg = new MSG(); //must clear msg so it doesn't repeat + } + Thread.sleep(10); + } + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("message loop stopped"); + unhook(); + } + + public void unhook() { + if (hHook == null) + return; + if (!User32.INSTANCE.UnhookWindowsHookEx(hHook)) + System.out.println("Failed to unhook"); + System.out.println("Unhooked"); + hHook = null; + } + + //stops Keyboard hook and causes the unhook command to be called + public static void stopMessageHook() { + quit = true; + } +} diff --git a/src/org/synthuse/MsgHook.java b/src/org/synthuse/MsgHook.java new file mode 100644 index 0000000..a23b374 --- /dev/null +++ b/src/org/synthuse/MsgHook.java @@ -0,0 +1,6 @@ +package org.synthuse; + +public class MsgHook { + + +} diff --git a/src/org/synthuse/SynthuseDlg.java b/src/org/synthuse/SynthuseDlg.java index 7a6adc1..c673b80 100644 --- a/src/org/synthuse/SynthuseDlg.java +++ b/src/org/synthuse/SynthuseDlg.java @@ -13,32 +13,15 @@ import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.Point; +import java.awt.Rectangle; import java.awt.Toolkit; -import javax.swing.JPanel; import javax.swing.border.EmptyBorder; -import javax.swing.DefaultComboBoxModel; -import javax.swing.ImageIcon; -import javax.swing.JComponent; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.JToolBar; -import javax.swing.JSplitPane; -import javax.swing.JRadioButton; -import javax.swing.SwingUtilities; -import javax.swing.WindowConstants; +import javax.swing.*; import java.awt.Component; - -import javax.swing.Box; -import javax.swing.ButtonGroup; -import javax.swing.JButton; - import java.awt.Dimension; -import javax.swing.JComboBox; -import javax.swing.JScrollPane; - /* import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.forms.layout.ColumnSpec; @@ -47,9 +30,6 @@ import com.jgoodies.forms.factories.FormFactory; */ import com.sun.jna.platform.win32.WinDef.HWND; -import javax.swing.JLabel; -import javax.swing.SwingConstants; - import java.awt.FlowLayout; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; @@ -60,8 +40,6 @@ import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; -import javax.swing.JTextPane; - import org.synthuse.Api.User32; import org.synthuse.DragTarget.dragEvents; @@ -72,7 +50,7 @@ public class SynthuseDlg extends JFrame { /** * */ - public static String VERSION_STR = "1.1.8"; + public static String VERSION_STR = "1.2.0"; 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"; @@ -82,6 +60,9 @@ public class SynthuseDlg extends JFrame { public static String RES_STR_FIND_IMG = "/org/synthuse/img/edit-find-3.png"; public static String RES_STR_SETACTION_IMG = "/org/synthuse/img/document-new-5.png"; public static String RES_STR_CANCEL_IMG = "/org/synthuse/img/document-close-2.png"; + public static String RES_STR_PREFERENCES_IMG = "/org/synthuse/img/preferences-desktop.png"; + + private static final int STRUT_WIDTH = 10; public static List actionListQueue = new ArrayList(); private static final long serialVersionUID = 1L; @@ -99,8 +80,10 @@ public class SynthuseDlg extends JFrame { private String lastRuntimeId =""; private JComboBox cmbXpath; private JButton btnTestIde; + private JButton btnAdvanced; private TestIdeFrame testIde = null; + private MessageHookFrame msgHook = null; private int targetX; private int targetY; private UiaBridge uiabridge = new UiaBridge(); @@ -141,7 +124,7 @@ public class SynthuseDlg extends JFrame { rdbtnWindows.setSelected(true); toolBar.add(rdbtnWindows); - Component horizontalStrut = Box.createHorizontalStrut(20); + Component horizontalStrut = Box.createHorizontalStrut(STRUT_WIDTH); toolBar.add(horizontalStrut); JRadioButton rdbtnUrl = new JRadioButton("Url: "); @@ -158,7 +141,7 @@ public class SynthuseDlg extends JFrame { cmbUrl.setEditable(true); toolBar.add(cmbUrl); - Component horizontalStrut_1 = Box.createHorizontalStrut(20); + Component horizontalStrut_1 = Box.createHorizontalStrut(STRUT_WIDTH); toolBar.add(horizontalStrut_1); btnRefresh = new JButton(" Refresh "); @@ -172,7 +155,7 @@ public class SynthuseDlg extends JFrame { btnRefresh.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_REFRESH_IMG))); toolBar.add(btnRefresh); - Component horizontalStrut_3 = Box.createHorizontalStrut(20); + Component horizontalStrut_3 = Box.createHorizontalStrut(STRUT_WIDTH); toolBar.add(horizontalStrut_3); btnTestIde = new JButton("Test IDE"); @@ -192,8 +175,40 @@ public class SynthuseDlg extends JFrame { btnTestIde.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_TESTIDE_IMG))); toolBar.add(btnTestIde); - Component horizontalStrut_2 = Box.createHorizontalStrut(20); + Component horizontalStrut_2 = Box.createHorizontalStrut(STRUT_WIDTH); toolBar.add(horizontalStrut_2); + + btnAdvanced = new JButton("Advanced"); + btnAdvanced.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_PREFERENCES_IMG))); + btnAdvanced.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + JPopupMenu menu = new JPopupMenu(); + ActionListener menuListener = new ActionListener() { + public void actionPerformed(ActionEvent event) { + //System.out.println("Popup menu item [" + event.getActionCommand() + "] was pressed."); + if (event.getActionCommand() == "Message Hook"){ + if (msgHook == null) + msgHook = new MessageHookFrame(); + msgHook.setVisible(true); + } + } + }; + JMenuItem mnMessageHook = new JMenuItem("Message Hook"); + mnMessageHook.addActionListener(menuListener); + menu.add(mnMessageHook); + JMenuItem mnSettings = new JMenuItem("Settings"); + mnSettings.setEnabled(false); + mnSettings.addActionListener(menuListener); + menu.add(mnSettings); + + Component c = (Component) e.getSource(); + menu.show(c, -1, c.getHeight()); + } + }); + toolBar.add(btnAdvanced); + + Component horizontalStrut_4 = Box.createHorizontalStrut(STRUT_WIDTH); + toolBar.add(horizontalStrut_4); JButton helpBtn = new JButton("Help"); helpBtn.setIcon(new ImageIcon(SynthuseDlg.class.getResource(RES_STR_HELP_IMG))); @@ -480,9 +495,12 @@ public class SynthuseDlg extends JFrame { String parentStr = Api.GetHandleAsString(User32.instance.GetParent(hwnd)); String enumProperties = ""; if (!SynthuseDlg.config.isUiaBridgeDisabled()) - enumProperties = uiabridge.getWindowInfo(targetX, targetY, WindowInfo.UIA_PROPERTY_LIST); + enumProperties = uiabridge.getWindowInfo(targetX, targetY, WindowInfo.UIA_PROPERTY_LIST_ADV); String runtimeId = WindowInfo.getRuntimeIdFromProperties(enumProperties); - lblStatus.setText("rid:" + runtimeId + " class: " + classStr + " hWnd: " + handleStr + " parent: " + parentStr + " X,Y: " + targetX + ", " + targetY); + String framework = WindowInfo.getFrameworkFromProperties(enumProperties); + Rectangle rect = UiaBridge.getBoundaryRect(enumProperties); + Point offsetPoint = WindowInfo.findOffset(rect, targetX, targetY); + lblStatus.setText("rid:" + runtimeId + " " + framework + " class: " + classStr + " hWnd: " + handleStr + " parent: " + parentStr + " X,Y (" + targetX + ", " + targetY + ") offset: " + offsetPoint.x + ", " + offsetPoint.y); if (!lastDragHwnd.equals(handleStr) || !lastRuntimeId.equals(runtimeId)) { if (!lastDragHwnd.isEmpty()) { Api.refreshWindow(Api.GetHandleFromString(lastDragHwnd)); @@ -490,7 +508,12 @@ public class SynthuseDlg extends JFrame { lastDragHwnd = handleStr; lastRuntimeId = runtimeId; //lastDragHwnd = (hwnd + ""); - Api.highlightWindow(hwnd); + if (framework.equals(UiaBridge.FRAMEWORK_ID_WPF) || framework.equals(UiaBridge.FRAMEWORK_ID_SILVER)) + {// WPF and Silverlight apps don't expose their child windows boundaries the same as win32 apps + Api.highlightWindow(Api.User32.instance.GetDesktopWindow(), rect.x, rect.y, rect.x + rect.width, rect.y + rect.height); + } + else + Api.highlightWindow(hwnd); XpathManager.buildXpathStatementThreaded(hwnd, enumProperties, textPane, xpathEvents); } } diff --git a/src/org/synthuse/UiaBridge.java b/src/org/synthuse/UiaBridge.java index 8880dab..e049dcc 100644 --- a/src/org/synthuse/UiaBridge.java +++ b/src/org/synthuse/UiaBridge.java @@ -1,6 +1,7 @@ package org.synthuse; import java.awt.Point; +import java.awt.Rectangle; import java.io.*; import javax.swing.JOptionPane; @@ -8,7 +9,10 @@ import javax.swing.JOptionPane; public class UiaBridge { public static String CACHED_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty,BoundingRectangleProperty"; - + public static final String FRAMEWORK_ID_WPF = "WPF"; + public static final String FRAMEWORK_ID_SILVER = "Silverlight"; + public static final String FRAMEWORK_ID_WINFORM = "WinForm"; + public static final String FRAMEWORK_ID_WIN = "Win32"; static { @@ -128,18 +132,41 @@ public class UiaBridge { public native String[] getProperties(String runtimeIdValue); public native String[] getPropertiesAndValues(String runtimeIdValue); */ + + public static String replaceEscapedCodes(String input) { + //, is a comma , + String result = input; + result = result.replaceAll(",", ","); + result = result.replaceAll("<", "<"); + result = result.replaceAll(">", ">"); + result = result.replaceAll("'", "'"); + result = result.replaceAll(""", "\""); + result = result.replaceAll("&", "&"); + return result; + } + public Point getCenterOfElement(String runtimeIdValue) { Point p = new Point(); - String boundary = getWindowInfo(runtimeIdValue, "BoundingRectangleProperty"); - boundary = WindowInfo.replaceEscapedCodes(boundary); - //System.out.println("runtimeId: " + runtimeIdValue + ", boundary: " + boundary); //boundary: 841,264,125,29 - String[] boundarySplt = boundary.split(","); - int x = Integer.parseInt(boundarySplt[0]); - int y = Integer.parseInt(boundarySplt[1]); - int width = Integer.parseInt(boundarySplt[2]); - int height = Integer.parseInt(boundarySplt[3]); - p.x = ((width) /2) + x; - p.y = ((height) /2) + y; + String boundaryProperty = getWindowInfo(runtimeIdValue, "BoundingRectangleProperty"); + Rectangle rect = getBoundaryRect(boundaryProperty); + p.x = ((rect.width) /2) + rect.x; + p.y = ((rect.height) /2) + rect.y; return p; } + + //BoundingRectangleProperty is the last property listed in comma separated properties string + public static Rectangle getBoundaryRect(String properties) { + Rectangle rect = new Rectangle(); + String[] propSplt = properties.split(","); + if (propSplt.length > 0) + { + String[] boundarySplt = replaceEscapedCodes(propSplt[propSplt.length - 1]).split(","); + if (boundarySplt.length == 4 ) + rect.x = Integer.parseInt(boundarySplt[0]); + rect.y = Integer.parseInt(boundarySplt[1]); + rect.width = Integer.parseInt(boundarySplt[2]); + rect.height = Integer.parseInt(boundarySplt[3]); + } + return rect; + } } diff --git a/src/org/synthuse/WinPtr.java b/src/org/synthuse/WinPtr.java index 75ac542..5aaeccc 100644 --- a/src/org/synthuse/WinPtr.java +++ b/src/org/synthuse/WinPtr.java @@ -46,6 +46,14 @@ public class WinPtr { return (runtimeIdTest.contains("-")); } + public void convertToNativeHwnd() + { + if (isWpfRuntimeIdFormat(runtimeId)){ + hWndStr = runtimeId.split("-")[1]; + hWnd = Api.GetHandleFromString(hWndStr); + } + } + public String toString() { if (isWin32() && !hWndStr.equals("")) return hWndStr; diff --git a/src/org/synthuse/WindowInfo.java b/src/org/synthuse/WindowInfo.java index 5076a63..eb39f49 100644 --- a/src/org/synthuse/WindowInfo.java +++ b/src/org/synthuse/WindowInfo.java @@ -7,6 +7,8 @@ package org.synthuse; +import java.awt.Point; +import java.awt.Rectangle; import java.util.LinkedHashMap; import java.util.Map; @@ -25,6 +27,7 @@ import com.sun.jna.ptr.PointerByReference; public class WindowInfo { public static String UIA_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty"; + public static String UIA_PROPERTY_LIST_ADV = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty,BoundingRectangleProperty"; public static String UIA_RUNTIME_ID = "RuntimeIdProperty"; public static String UIA_BOUNDING_RECT = "BoundingRectangleProperty"; public static int MAX_TEXT_SIZE = 200; @@ -46,6 +49,7 @@ public class WindowInfo { public String runtimeId = ""; public int menus = 0; public HMENU menu = null; + public boolean useUiaBridge = false; public Map extra = null; @@ -97,20 +101,6 @@ public class WindowInfo { extra = new LinkedHashMap(); extra.put("tvCount", tvCount.intValue() + ""); } - /* - if (isChild) { - int ctrlID = Api.User32.instance.GetDlgCtrlID(hWnd); - if (ctrlID > 0){ - //parent = User32.instance.GetParent(hWnd); - int dtresult = Api.User32.instance.GetDlgItemText(hWnd, ctrlID, buffer, 1024); - if (dtresult > 0) { - String dgText = Native.toString(buffer); - if (extra == null) - extra = new LinkedHashMap(); - extra.put("dgText", dgText + ""); - } - } - }*/ char[] buffer2 = new char[1026]; User32.instance.GetClassName(hWnd, buffer2, 1026); @@ -151,6 +141,9 @@ public class WindowInfo { if (isChild) { parent = User32.instance.GetParent(hWnd); parentStr = Api.GetHandleAsString(parent); + // test to see if uiaBridge should be used on this child + if (this.className.startsWith("HwndWrapper") || this.className.startsWith("MicrosoftSilverlight") || this.className.startsWith("GeckoPluginWindow")) + useUiaBridge = true; } else { @@ -160,7 +153,9 @@ public class WindowInfo { Pointer process = Kernel32.instance.OpenProcess(Api.PROCESS_QUERY_INFORMATION | Api.PROCESS_VM_READ, false, pointer.getValue()); Psapi.instance.GetModuleBaseNameW(process, null, buffer2, 512); processName = Native.toString(buffer2); - + //test to see if uiaBridge should be used on this parent + if (this.className.startsWith("HwndWrapper") || this.className.startsWith("WindowsForms")) + useUiaBridge = true; } this.hwnd = hWnd; hwndStr = Api.GetHandleAsString(hWnd); @@ -168,23 +163,12 @@ public class WindowInfo { this.hwndStr = ""; } - public static String replaceEscapedCodes(String input) { - //, is a comma , - String result = input; - result = result.replaceAll(",", ","); - result = result.replaceAll("<", "<"); - result = result.replaceAll(">", ">"); - result = result.replaceAll("'", "'"); - result = result.replaceAll(""", "\""); - result = result.replaceAll("&", "&"); - return result; - } - //support for WPF, Silverlight, WinForms public WindowInfo(String enumProperties, boolean isChild) { //WPF_PROPERTY_LIST = "RuntimeIdProperty,ParentRuntimeIdProperty,ProcessIdProperty,FrameworkIdProperty,LocalizedControlTypeProperty,ClassNameProperty,NameProperty,ValueProperty"; String[] spltProperties = enumProperties.split(","); this.isChild = isChild; + this.useUiaBridge = true; if (SynthuseDlg.config.isFilterUiaDisabled()) { //use wildcard mode extra = new LinkedHashMap(); for(String prop: spltProperties) { @@ -233,13 +217,13 @@ public class WindowInfo { if (spltProperties.length > 3) this.framework = spltProperties[3]; if (spltProperties.length > 4) - this.controlType = replaceEscapedCodes(spltProperties[4]); + this.controlType = UiaBridge.replaceEscapedCodes(spltProperties[4]); if (spltProperties.length > 5) - this.className = replaceEscapedCodes(spltProperties[5]); + this.className = UiaBridge.replaceEscapedCodes(spltProperties[5]); if (spltProperties.length > 6) - this.text = replaceEscapedCodes(spltProperties[6]); + this.text = UiaBridge.replaceEscapedCodes(spltProperties[6]); if (spltProperties.length > 7) - this.value = replaceEscapedCodes(spltProperties[7]); + this.value = UiaBridge.replaceEscapedCodes(spltProperties[7]); if (this.className == "") this.className = this.controlType; if (text != null) @@ -266,6 +250,7 @@ public class WindowInfo { */ } + public static String getRuntimeIdFromProperties(String enumProperties) { String[] spltProperties = enumProperties.split(","); @@ -274,6 +259,26 @@ public class WindowInfo { return ""; } + public static String getFrameworkFromProperties(String enumProperties) + { + String[] spltProperties = enumProperties.split(","); + if (spltProperties.length > 3) + return spltProperties[3]; + return ""; + } + + public static Point findOffset(Rectangle rect, int xPos, int yPos) + { + Point offset = new Point(); + int x = ((rect.width) /2) + rect.x; + int y = ((rect.height) /2) + rect.y; + + offset.x = xPos - x; + offset.y = yPos - y; + + return offset; + } + public String toString() { return String.format("%s \"%s\" [%s] (%s) {%s}", framework, text, className, controlType, hwndStr); } diff --git a/src/org/synthuse/WindowsEnumeratedXml.java b/src/org/synthuse/WindowsEnumeratedXml.java index 858f6d3..a9d92e3 100644 --- a/src/org/synthuse/WindowsEnumeratedXml.java +++ b/src/org/synthuse/WindowsEnumeratedXml.java @@ -79,62 +79,62 @@ public class WindowsEnumeratedXml implements Runnable{ public static String getXml() { final Map infoList = new LinkedHashMap(); - final List wpfParentList = new ArrayList();//HwndWrapper - final List silverlightParentList = new ArrayList();//MicrosoftSilverlight - final List winFormParentList = new ArrayList();//class="WindowsForms*" - //wpf.setTouchableOnly(false); - //wpf.countChildrenWindows();//fix for missing cached elements - - - class ChildWindowCallback implements WinUser.WNDENUMPROC { - @Override - public boolean callback(HWND hWnd, Pointer lParam) { - WindowInfo wi = new WindowInfo(hWnd, true); - infoList.put(wi.hwndStr, wi); - if (wi.className.startsWith("HwndWrapper")) - wpfParentList.add(wi.hwndStr); - if (wi.className.startsWith("MicrosoftSilverlight") || wi.className.startsWith("GeckoPluginWindow")) - silverlightParentList.add(wi.hwndStr); - return true; - } - } + HWND desktopRootHwnd = Api.User32.instance.GetDesktopWindow(); + WindowInfo wi = new WindowInfo(desktopRootHwnd, false); + wi.controlType = "DesktopRoot"; + infoList.put(wi.hwndStr, wi); class ParentWindowCallback implements WinUser.WNDENUMPROC { @Override public boolean callback(HWND hWnd, Pointer lParam) { WindowInfo wi = new WindowInfo(hWnd, false); infoList.put(wi.hwndStr, wi); - if (wi.className.startsWith("HwndWrapper")) - wpfParentList.add(wi.hwndStr); - if (wi.className.startsWith("WindowsForms")) - winFormParentList.add(wi.hwndStr); - Api.User32.instance.EnumChildWindows(hWnd, new ChildWindowCallback(), new Pointer(0)); + infoList.putAll(EnumerateWin32ChildWindows(hWnd)); return true; } - } + } Api.User32.instance.EnumWindows(new ParentWindowCallback(), 0); + //process all windows that have been flagged for uiaBridge (useUiaBridge == true) + appendUiaBridgeWindows(infoList); + + return generateWindowsXml(infoList, "EnumeratedWindows"); + } + + public static void appendUiaBridgeWindows(Map infoList) + { //Enumerate WPF, WinForm, Silverlight windows and add to list if (!SynthuseDlg.config.isUiaBridgeDisabled()) { UiaBridge uiabridge = new UiaBridge(); - for (String handle : wpfParentList) { - Map wpfInfoList = EnumerateWindowsWithUiaBridge(uiabridge, handle, "*"); - infoList.putAll(wpfInfoList); - } - for (String handle : winFormParentList) { - //System.out.println("winform parent " + handle); - Map winFormInfoList = EnumerateWindowsWithUiaBridge(uiabridge, handle, "*"); - infoList.putAll(winFormInfoList); - } - for (String handle : silverlightParentList) { - Map slInfoList = EnumerateWindowsWithUiaBridge(uiabridge, handle, "Silverlight"); - infoList.putAll(slInfoList); - } - + Map uiaInfoList = new LinkedHashMap(); + for (String handle : infoList.keySet()) { + if (infoList.get(handle).useUiaBridge) { + uiaInfoList.putAll(EnumerateWindowsWithUiaBridge(uiabridge, handle, "*")); + } + } + infoList.putAll(uiaInfoList); } - return generateWindowsXml(infoList, "EnumeratedWindows"); + //return infoList; + } + + public static Map EnumerateWin32ChildWindows(HWND parentHwnd) + { + final Map infoList = new LinkedHashMap(); + + class ChildWindowCallback implements WinUser.WNDENUMPROC { + @Override + public boolean callback(HWND hWnd, Pointer lParam) { + WindowInfo wi = new WindowInfo(hWnd, true); + infoList.put(wi.hwndStr, wi); + return true; + } + } + + Api.User32.instance.EnumChildWindows(parentHwnd, new ChildWindowCallback(), new Pointer(0)); + + return infoList; } public static String generateWindowsXml(Map infoList, String rootElementName) @@ -163,17 +163,17 @@ public class WindowsEnumeratedXml implements Runnable{ Element win = null; if (w.framework.equals("win32")) win = doc.createElement("win"); - else if (w.framework.equals("WPF")) + else if (w.framework.equals(UiaBridge.FRAMEWORK_ID_WPF)) { win = doc.createElement("wpf"); ++wpfCount; } - else if (w.framework.equals("WinForm")) + else if (w.framework.equals(UiaBridge.FRAMEWORK_ID_WINFORM)) { win = doc.createElement("winfrm"); ++winFormCount; } - else if (w.framework.equals("Silverlight")) + else if (w.framework.equals(UiaBridge.FRAMEWORK_ID_SILVER)) { win = doc.createElement("silver"); ++silverlightCount; diff --git a/src/org/synthuse/commands/BaseCommand.java b/src/org/synthuse/commands/BaseCommand.java index d885ff3..1d41ac9 100644 --- a/src/org/synthuse/commands/BaseCommand.java +++ b/src/org/synthuse/commands/BaseCommand.java @@ -6,11 +6,14 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.sql.Timestamp; import java.util.Date; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.synthuse.*; +import com.sun.jna.platform.win32.WinDef.HWND; + public class BaseCommand { static String WIN_XML = ""; @@ -132,7 +135,14 @@ public class BaseCommand { } else { // native target refresh - + infoList = new LinkedHashMap(); + HWND parentHwnd = Api.GetHandleFromString(resultHwndStr); + WindowInfo wi = new WindowInfo(parentHwnd, false); + infoList.put(wi.hwndStr, wi); + infoList.putAll(WindowsEnumeratedXml.EnumerateWin32ChildWindows(parentHwnd)); + //WindowsEnumeratedXml.appendUiaBridgeWindows(infoList); //if we need this we should specify a runtimeID handle instead + newXml = WindowsEnumeratedXml.generateWindowsXml(infoList, "updates"); + System.out.println("newNativeXml: " + newXml); } int pos = WIN_XML.indexOf(resultStr); diff --git a/src/org/synthuse/commands/MouseCommands.java b/src/org/synthuse/commands/MouseCommands.java index a7dcfc6..dd1e50a 100644 --- a/src/org/synthuse/commands/MouseCommands.java +++ b/src/org/synthuse/commands/MouseCommands.java @@ -18,9 +18,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 7180508..bc85be8 100644 --- a/src/org/synthuse/commands/WindowsCommands.java +++ b/src/org/synthuse/commands/WindowsCommands.java @@ -17,6 +17,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.activateWindow(handle.hWnd); //api.showWindow(handle); return true; @@ -28,6 +29,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.minimizeWindow(handle.hWnd); return true; } @@ -38,6 +40,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.maximizeWindow(handle.hWnd); return true; } @@ -48,6 +51,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.restoreWindow(handle.hWnd); return true; } @@ -58,6 +62,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.hideWindow(handle.hWnd); return true; } @@ -68,6 +73,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.showWindow(handle.hWnd); return true; } @@ -78,6 +84,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.switchToThisWindow(handle.hWnd, true); return true; } @@ -89,6 +96,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.closeWindow(handle.hWnd); return true; } @@ -99,6 +107,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return false; + handle.convertToNativeHwnd(); api.sendWmSetText(handle.hWnd, args[1]); return true; } @@ -109,6 +118,7 @@ public class WindowsCommands extends BaseCommand { WinPtr handle = findHandleWithXpath(args[0]); if (handle.isEmpty()) return ""; + handle.convertToNativeHwnd(); return api.sendWmGetText(handle.hWnd); } @@ -119,6 +129,7 @@ public class WindowsCommands extends BaseCommand { if (handle.isEmpty()) return false; int id = findMenuIdWithXpath(args[0]); + handle.convertToNativeHwnd(); //LRESULT result = //System.out.println("PostMessage to " + handle.hWndStr + " for id " + id); api.user32.PostMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0)); @@ -133,6 +144,7 @@ public class WindowsCommands extends BaseCommand { if (handle.isEmpty()) return false; int id = Integer.parseInt(args[1]); //context menu id is supplied as second argument + handle.convertToNativeHwnd(); //LRESULT result = System.out.println("PostMessage to " + handle.toString() + " for id " + id + " - " + Api.MAKELONG(id, 0)); //api.user32.PostMessage(handle.hWnd, Api.WM_COMMAND, new WPARAM(id), new LPARAM(0)); diff --git a/src/org/synthuse/img/preferences-desktop.png b/src/org/synthuse/img/preferences-desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..8fe2675c3dedcc5f6903558300e0bae9edecef99 GIT binary patch literal 825 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Y)RhkE7o^m3{2u3(s-zJKntia4E`g;Tn0_?~Y%mh$bon7a*w z|Nd^>BlcUhmR^Vw{x@MS=8*Kd7Z7?@ibTUZ&G=^B_>85k%>El)<#kei>9 znO2EgLlC?CeV_(2kPSYW$*Fn8sSFt