1 //---------------------------------------------------------------------------
6 //
\8dÅ
\93K
\89»
\82Ì
\89Û
\91è
\81F
7 // standard library
\82ð
\8eg
\82í
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
8 //
\8b¤
\97L
\97Ì
\88æ
\82ð
\91\9d\82â
\82·
11 //
\93Ë
\91RDetach
\82³
\82ê
\82é
\8c»
\8fÛ
12 // --> Hook Function
\82Å
\97á
\8aO
\82ª
\94
\90¶
\82µ
\82Ä
\82¢
\82é
\89Â
\94\
\90«
\82ª
\8d\82\82¢
13 //
\82à
\82µ
\82
\82Í
\81A
\83A
\83v
\83\8a\83P
\81[
\83V
\83\87\83\93\82Å
\97á
\8aO
\94
\90¶
\82µ
\82Ä
\82¢
\82é
14 //
\8b¤
\97L
\83\81\83\82\83\8a\82É
\82Â
\82¢
\82Ä
15 //
\95¨
\97\9d\83\81\83\82\83\8a\82ª
\93¯
\88ê
\82¾
\82¯
\82Å
\82 \82Á
\82Ä
\81A
\98_
\97\9d\83A
\83h
\83\8c\83X
\82Í
\93¯
\88ê
\82Æ
\82Í
\8cÀ
\82ç
\82È
\82¢
\81I
\81I
16 //
\8f]
\82Á
\82Ä
\81A
\8b¤
\97L
\83\81\83\82\83\8a\8fã
\82Épointer
\82ð
\94z
\92u
\82·
\82é
\82±
\82Æ
\82Í
\8aî
\96{
\93I
\82É
\8aë
\8c¯
\81I
\81I
22 #define GWL_WNDPROC (-4) //
\82±
\82Ì
\92è
\8b`
\82ª
\82È
\82¢
\82Æerror
\82É
\82È
\82Á
\82½ 2014.11.19
26 #pragma comment(lib, "ImageHlp")
29 #include "..\VxD\hk95d.h"
31 #include "MonitorScale.h"
34 #pragma warning( disable : 4710 ) //
\82Ç
\82¤
\82µ
\82Ä
\82±
\82¤
\82¢
\82¤warning
\82ª
\8fo
\82Ä
\82
\82é
\82Ì
\82©
\81H
37 #define USE_SCALING 1 // Uses DPI scaling
39 #define USE_DBW 0 // DBW
\82ð
\8eg
\97p
\82·
\82é
40 #define USE_SHARE0 1 // share
\82µ
\82Ä
\82à
\96â
\91è
\82È
\82¢
\95Ï
\90\94
42 #define METAEXTTEXTOUT 1 // MetaMethod
\82ÅExtTextOutx
\82ðhook
\82·
\82é
43 #define HOOK_GETDC 0 // GetDC(),ReleaseDC()
\82ðhook
\82·
\82é
44 #define HOOK_TEXT 0 // DrawText(Ex),TextOut,TabbedTextOut
\82Ìhooking
46 #define HOOK_BITBLT 0 // 2016.1.15
\8aO
\82µ
\82Ä
\82Ý
\82½
48 #define GUARD 0 //
\8b¤
\97L
\83\81\83\82\83\8a\82ðVirtualProtect
\82Åguard
\82·
\82é
49 //
\97L
\8cø
\82É
\82·
\82é
\82ÆApplication
\8fI
\97¹
\8e\9e\82É
\88Ù
\8fí
\8fI
\97¹
\82ª
\94
\90¶
\82·
\82é
50 // Application close ->
51 //
\8c´
\88ö
\81FDettach
\82·
\82é
\91O
\82É
\81AOS or Application
\82ª
52 // Protected code
\97Ì
\88æ
\82É
\8f\91\82«
\8d\9e\82Ý
\82ð
\8ds
\82Á
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
54 #define USE_INVALIDATE 0 //
\95`
\89æ
\91O
\82ÉInvalidate
\82ð
\91\97\82é(IE5@Win98
\82Í
\95K
\97v)
55 #define INVALIDATE_TRUE 0 // InvalidateRect
\82Årepaint
\82ð
\8ds
\82¤
56 #define ORG_OFFSET 1 // ViewPort
\82Ìorg offset
\8f\88\97\9d\82ð
\8ds
\82¤
58 #define USE_OPTIMALINVALID 1 //
\8dÄ
\95`
\89æ
\97Ì
\88æ
\82ð
\82È
\82é
\82×
\82
\8f¬
\82³
\82
\82·
\82é
59 #define USE_VXD 0 // no longer support (Win9x)
60 #define EXC_WOW64 0 // do not attach on WOW64
62 #define MAX_KEYS 8 //
\83L
\81[
\83t
\83\89\83O
\82Ì
\8dÅ
\91å
\92è
\8b`
\90\94
64 #define DEBUG_HITTEXT 0 // for debug hit text
66 // ExtTextOut hooking
\82ÅMetafile
\82à
\8eg
\97p
\82·
\82é
67 //
\92P
\93Æ
\82Å
\8ds
\82¤
\8fê
\8d\87\82Í
\81ARETRYMETA
68 #if HOOK_PAINT || HOOK_GETDC || !USE_REDRAW
80 #define DEBUG_HITTEXT 0
83 #define MOVESEND_POST 1
85 // Type Definitions //
89 #define PROTECT_SHARE() ShareProtect( true )
90 #define UNPROTECT_SHARE() ShareProtect( false )
92 #define PROTECT_SHARE()
93 #define UNPROTECT_SHARE()
101 void dbw(const char *format, ...);
103 #define WM_AMODI (WM_APP+0x400) // app communication message with AMODI
104 #define WM_MOVESEND (WM_APP+0x208) // DCH_MOVESEND
\82Ì
\91ã
\82í
\82è
\82ÉPostMessage
\82Å
\91\97\82é
105 #define AMODI_CMD_QUERY 0
106 #define AMODI_CMD_PAGE_CAPTURE 1
108 #define tsizeof(type) sizeof(type)
109 #define int_bool(v) ((v)!=0)
111 #pragma warning (disable : 4996)
113 //==============================================//
114 // TString template class //
115 //==============================================//
120 int Size; // Buffer size in character
121 int Length; // String length in character
126 { Buffer[0] = '\0'; Length = 0; }
127 void Set( const T *str, int len );
128 void Set( TString *obj )
129 { Set( obj->c_str(), obj->Length ); }
130 void Cat( const T *str, int len );
131 operator const T *() const
133 T operator [] ( int index )
134 { return Buffer[index]; }
137 int GetLength() const { return Length; }
138 int GetByte() const { return Length * sizeof(T); }
139 // int GetSize() const { return Size; }
142 TString<T>::TString()
144 Size = 256; // initial size
145 Buffer = new T[ Size + 1 ];
151 TString<T>::~TString()
157 void TString<T>::Set( const T *str, int len )
161 // not enough space to store
165 Buffer = new T[ len + 1 ];
169 CopyMemory( Buffer, str, len*sizeof(T) );
178 void TString<T>::Cat( const T *str, int len )
184 int newlen = Length + len;
186 T *p = new T[ newlen + 1 ];
188 CopyMemory( p, Buffer, newlen*sizeof(T) );
194 CopyMemory( Buffer+Length, str, len * sizeof(T) );
195 Buffer[newlen] = '\0';
204 int GetTextFromPoint( HDC hdc, const char *text, int len, int pos, int pos_y, const int *dx=NULL );
205 int GetTextFromPoint( HDC hdc, const wchar_t *text, int len, int pos, int pos_y, const int *dx=NULL );
207 bool CaptureImage(HWND hwnd, bool movesend, bool non_block);
208 bool WaitAndGetResult(const TCHAR *text_path, unsigned waittime);
209 HANDLE WaitForResult(const TCHAR *text_path, unsigned waittime);
211 int SendAMODI(int cmd, const char *data, int len);
212 void CheckAMODIAlive();
213 void SendMoveMessage();
214 void SendCancelMove();
215 DWORD WINAPI SendMoveThread(LPVOID vdParam);
219 //==============================================//
221 //==============================================//
222 typedef HDC (WINAPI *FNBeginPaint)( HWND, LPPAINTSTRUCT );
223 typedef BOOL (WINAPI *FNEndPaint)( HWND, CONST PAINTSTRUCT * );
224 typedef HDC (WINAPI *FNGetDC)( HWND );
225 typedef int (WINAPI *FNReleaseDC)( HWND, HDC );
226 typedef BOOL (WINAPI *FNExtTextOutW)(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCWSTR str, UINT count, CONST INT *dx );
227 typedef BOOL (WINAPI *FNExtTextOutA)(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCSTR str, UINT count, CONST INT *dx );
228 typedef BOOL (WINAPI *FNBitBlt)(HDC hdcdest, int xdest, int ydest, int width, int height, HDC hdcsrc, int xsrc, int ysrc, DWORD rop );
230 typedef LONG (WINAPI *FNTabbedTextOutA)( HDC hdc, int x, int y, LPCSTR str, int count, int ntabs, LPINT tabs, int origin );
231 typedef LONG (WINAPI *FNTabbedTextOutW)( HDC hdc, int x, int y, LPCWSTR str, int count, int ntabs, LPINT tabs, int origin );
232 typedef BOOL (WINAPI *FNTextOutA)( HDC hdc, int x, int y, LPCSTR str, int count );
233 typedef BOOL (WINAPI *FNTextOutW)( HDC hdc, int x, int y, LPCWSTR str, int count );
234 typedef int (WINAPI *FNDrawTextA)( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format );
235 typedef int (WINAPI *FNDrawTextW)( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format );
236 typedef int (WINAPI *FNDrawTextExA)( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params );
237 typedef int (WINAPI *FNDrawTextExW)( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params );
239 typedef BOOL (WINAPI *FNMoveToEx)(HDC hdc, int x, int y, LPPOINT pt );
242 HDC WINAPI _BeginPaint( HWND hwnd, LPPAINTSTRUCT ps );
243 BOOL WINAPI _EndPaint( HWND hwnd, CONST PAINTSTRUCT *ps );
244 HDC WINAPI _GetDC( HWND hwnd );
245 int WINAPI _ReleaseDC( HWND hwnd, HDC hdc );
246 BOOL WINAPI _ExtTextOutA(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCSTR str, UINT count, CONST INT *dx );
247 BOOL WINAPI _ExtTextOutW(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCWSTR str, UINT count, CONST INT *dx );
248 BOOL WINAPI _BitBlt(HDC hdcdest, int xdest, int ydest, int width, int height, HDC hdcsrc, int xsrc, int ysrc, DWORD rop );
250 LONG WINAPI _TabbedTextOutA( HDC hdc, int x, int y, LPCSTR str, int count, int ntabs, LPINT tabs, int origin );
251 LONG WINAPI _TabbedTextOutW( HDC hdc, int x, int y, LPCWSTR str, int count, int ntabs, LPINT tabs, int origin );
252 BOOL WINAPI _TextOutA( HDC hdc, int x, int y, LPCSTR str, int count );
253 BOOL WINAPI _TextOutW( HDC hdc, int x, int y, LPCWSTR str, int count );
254 int WINAPI _DrawTextA( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format );
255 int WINAPI _DrawTextW( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format );
256 int WINAPI _DrawTextExA( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params );
257 int WINAPI _DrawTextExW( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params );
259 BOOL WINAPI _MoveToEx( HDC hdc, int x, int y, LPPOINT pt );
261 void ShareProtect( bool f );
262 DWORD SetWriteProtect( LPVOID addr, bool f );
263 bool ChangeMemory( void *dst, const void *src, unsigned size );
267 static HMODULE ModuleFromAddress(PVOID pv);
269 // Prototypes for PSAPI.DLL //
270 typedef BOOL (WINAPI *FNEnumProcessModules)( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded );
271 typedef DWORD (WINAPI *FNGetModuleFileNameExA)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize );
272 typedef HANDLE (WINAPI *FNCreateToolhelp32Snapshot)( DWORD dwFlags, DWORD th32ProcessID );
273 typedef BOOL (WINAPI *FNModule32First)( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
274 typedef BOOL (WINAPI *FNModule32Next)( HANDLE hSnapshot, LPMODULEENTRY32 lpme );
277 LRESULT CALLBACK MouseProc( int code, WPARAM wParam, LPARAM lParam );
278 LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam );
279 bool CaptureText( HWND hwnd, bool movesend );
280 bool DoCapture(HWND hwnd, POINT pt, bool movesend, bool image_only=false, bool runOnLaunchedProc=false, bool nonBlock=false);
281 void DokoPopMenu( HWND hwnd );
282 void ToggleClick( HWND hwnd );
283 int CALLBACK EnumMetaFileProc( HDC hdc, HANDLETABLE *, CONST ENHMETARECORD *mfr, int nobj, LPARAM user );
285 //__declspec(dllexport)
286 BOOL WINAPI _ExtTextOutA(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCSTR str, UINT count, CONST INT *dx );
289 void ExtTextOutHit();
292 void DoScale(HDC hdc, POINT *pts, int num);
294 // Prototypes for High DPI //
295 typedef enum _PROCESS_DPI_AWARENESS {
296 Process_DPI_Unaware = 0,
297 Process_System_DPI_Aware = 1,
298 Process_Per_Monitor_DPI_Aware = 2
299 } PROCESS_DPI_AWARENESS;
301 typedef HRESULT (WINAPI *FNGetProcessDPIAwareness)(HANDLE hprocess, PROCESS_DPI_AWARENESS *value);
302 typedef HRESULT (WINAPI *FNSetProcessDPIAwareness)(PROCESS_DPI_AWARENESS value);
304 //==============================================//
306 //==============================================//
307 #pragma data_seg(".sdata")
308 #pragma bss_seg( ".sbss" )
309 HWND hwndCallback = NULL;
311 char VxDpathName[256]; // HK95.vxd path
313 DWORD siPageSize = 0;
315 HWND hwndAMODI = NULL;
316 bool RequireHwndAMODI = false;
317 bool OnlyAMODI = false;
318 bool tryAMODI = false;
319 bool MoveSend = false;
326 const bool WindowsNT = true;
328 bool Initialized = false; // Whether this module initialized or not
329 DWORD idDokopopProcess; // DKPP.EXE process ID
330 HHOOK hMouseHook; // Windows Hook Handle for mouse
331 bool ClickOnlyEnabled = false;
334 unsigned char Action;
338 TKeyConfig KeyConfig[MAX_KEYS] = {
339 { KA_POPUP, KF_CONTROL }, // Ctrl+click
340 { KA_POPUP_NC, KF_CLICKONLY }, // click
\82¾
\82¯
\82Åpopup(DO NOT CHANGE)
341 // { KA_MENU, KF_CONTROL | KF_MENU }, // dokopop menu
342 // { KA_MENU, KF_CONTROL | KF_MENU | KF_CLICKONLY }, // dokopop menu
343 { KA_TOGGLE, KF_CONTROL | KF_MENU }, // dokopop menu
349 POINT CursorPoint; // Client area coordinate //
350 POINT ScreenPoint; // Screen coordinate //
351 POINT PrevCursorPoint;
352 HWND hwndLast = NULL;
353 DWORD PrevMoveTime = 0;
354 bool MoveSent = true;
355 bool OnlyImage = false;
361 RECT rcOrgInvalid; //
\8dÄ
\95`
\89æ
\91O
\82Éinvalid
\82¾
\82Á
\82½
\97Ì
\88æ
363 bool RButtonUpCancel = false; //
\8e\9f\82ÌRButtonUp
\82Í
\94j
\8aü
\82·
\82é
364 bool LButtonUpCancel = false; //
\8e\9f\82ÌLButtonUp
\82Í
\94j
\8aü
\82·
\82é
365 bool MButtonUpCancel = false; //
\8e\9f\82ÌMButtonUp
\82Í
\94j
\8aü
\82·
\82é
366 bool LButtonDown = false;
367 bool MButtonDown = false;
369 HINSTANCE hPSAPI; // handle of PSAPI.DLL(NT only)
370 FNEnumProcessModules fnEnumProcessModules;
371 FNGetModuleFileNameExA fnGetModuleFileNameExA;
372 FNCreateToolhelp32Snapshot fnCreateToolhelp32Snapshot;
373 FNModule32First fnModule32First;
374 FNModule32Next fnModule32Next;
376 #if USE_META || RETRYMETA
385 int BitBltCount; //
\8c»
\8dÝ
\82ÌBitBlt
\89ñ
\90\94
386 int ExtTextOutCount; //
\8c»
\8dÝ
\82ÌBand
\93à
\82ÌExtTextOut
\89ñ
\90\94(A/W
\82Æ
\82à)
387 int TargetBitBltCount; //
\8c\9f\8d¸
\91Î
\8fÛ
\82ÌBitBlt(
\8f\89\89ñ
\95`
\89æ
\8cã
\82É
\94»
\92è)
388 POINT TargetOffset; //
\8c\9f\8d¸
\91Î
\8fÛ
\82ÌBitBlt
\82Ì
\95`
\89æ
\83I
\83t
\83Z
\83b
\83g(
\8f\89\89ñ
\95`
\89æ
\8cã
\82É
\94»
\92è)
392 // hit text information
393 TString<char> *FoundTextA;
394 TString<wchar_t> *FoundTextW;
398 //
\8dÅ
\8cã
\82É
\95`
\89æ
\82µ
\82½
\83e
\83L
\83X
\83g
\82Ì
\8fî
\95ñ
400 int LastX; //
\8dÅ
\8cã
\82É
\95`
\89æ
\82µ
\82½
\83e
\83L
\83X
\83g
\82Ì
\89E
\8fã
\8dÀ
\95W
402 TString<char> *LastTextA;
403 TString<wchar_t> *LastTextW;
404 #endif // METAEXTTEXTOUT
408 TCHAR AMODIPath[256];
409 bool ExtAMODI = false;
410 int ScaleX = 0; // 96
\82ð1
\82Æ
\82µ
\82½
\89æ
\96Ê
\82Ì
\8ag
\91å
\97¦
413 int NumPrevWords = 1; //
\89½
\8cÂ
\82Ü
\82Å
\91O
\82Ì
\92P
\8cê
\82ð
\8fE
\82¤
\82©
\81H
415 TCHAR ImageTextPath[256+40]; // OCR
\97pimage filename or text filename
417 bool CaptureImageBlocking = false;
419 const char STR_USER32[] = "user32.dll";
420 const char STR_GDI32[] = "gdi32.dll";
421 const char STR_KERNEL32[] = "kernel32.dll";
422 const TCHAR STR_PSAPI[] = _T("psapi.dll");
425 const char STR_CreateToolhelp32Snapshot[] = "CreateToolhelp32Snapshot";
426 const char STR_Module32First[] = "Module32First";
427 const char STR_Module32Next[] = "Module32Next";
430 const char STR_EnumProcessModules[] = "EnumProcessModules";
431 const char STR_GetModuleFileNameExA[] = "GetModuleFileNameExA";
433 const char STR_BeginPaint[] = "BeginPaint";
434 const char STR_EndPaint[] = "EndPaint";
435 const char STR_BitBlt[] = "BitBlt";
436 const char STR_GetDC[] = "GetDC";
437 const char STR_ReleaseDC[] = "ReleaseDC";
439 const char STR_ExtTextOutA[] = "ExtTextOutA";
440 const char STR_ExtTextOutW[] = "ExtTextOutW";
441 const char STR_TabbedTextOutA[] = "TabbedTextOutA";
442 const char STR_TabbedTextOutW[] = "TabbedTextOutW";
443 const char STR_TextOutA[] = "TextOutA";
444 const char STR_TextOutW[] = "TextOutW";
445 const char STR_DrawTextA[] = "DrawTextA";
446 const char STR_DrawTextW[] = "DrawTextW";
447 const char STR_DrawTextExA[] = "DrawTextExA";
448 const char STR_DrawTextExW[] = "DrawTextExW";
455 //==============================================//
456 // Module depend values //
457 //==============================================//
458 HINSTANCE hInstance; // attached instance
459 DWORD idProcess; // attached process
460 HANDLE hProcess; // Hook
\8e\9eGetCurrentProcess()
\82Í
\8eg
\82¦
\82È
\82¢
461 // Hook
\8e\9e\82Ìcurrent process
\82ª
\8f\91\82«
\8a·
\82¦
\82½
\82¢thunk
\82Ìprocess
\82Æ
\88ê
\92v
\82·
\82é
\82Æ
\82Í
\8cÀ
\82ç
\82È
\82¢
\82½
\82ß
462 //
\82»
\82Ì
\82½
\82ß
\81ADLL
\82Ìattach
\8e\9e\82ÉWriteProcessMemory()
\97p
\82Éprocess handle
\82ð
\8eæ
\93¾
\82·
\82é
463 DWORD curProcess; // hooking process
465 HANDLE vxd_Handle = INVALID_HANDLE_VALUE; // Not shared
469 HANDLE SendMoveEvent = NULL;
470 DWORD SendMoveThreadId;
473 HINSTANCE hInstSHCore = NULL;
474 FNGetProcessDPIAwareness GetProcessDPIAwareness = NULL;
476 //==============================================//
478 //==============================================//
482 const char *FuncName;
487 PROC OrgFunc; // not shared@NT
489 PROC HookFunc; // not shared
490 // Process dedicated values //
492 static void *MaxAppAddr; // Maximum private memory address
494 static APIHOOK *LinkTop; // top of APIHOOK link
495 APIHOOK *LinkNext; // next pointer of API HOOK link
497 APIHOOK( const char *modname, const char *name, void *hookfunc, bool excme = true );
499 bool GetProcOrgFunc( HINSTANCE hInst );
500 bool GetProcOrgFunc();
507 static void ReplaceIATEntryInAllMods( APIHOOK *obj, PROC pfnCurrent, PROC pfnNew );
508 static bool ReplaceIATEntryInOneMod( APIHOOK *obj, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller);
511 const BYTE cPushOpCode = 0x68; // The PUSH opcode on x86 platforms
512 APIHOOK* APIHOOK::LinkTop = NULL;
513 PVOID APIHOOK::MaxAppAddr = NULL;
515 APIHOOK::APIHOOK( const char *modname, const char *funcname, void *hookfunc, bool excme )
517 // DBW("APIHOOK constructor:%08X %s %s",this, modname, funcname);
521 HookFunc = (PROC)hookfunc;
526 // Functions with address above lpMaximumApplicationAddress require
527 // special processing (Windows 98 only)
530 MaxAppAddr = si.lpMaximumApplicationAddress;
537 // Remove this object from the linked list
538 APIHOOK* p = LinkTop;
539 if (p == this) { // Removing the head node
540 LinkTop = p->LinkNext;
542 // Walk list from head and fix pointers
543 for (; p->LinkNext; p = p->LinkNext){
544 if (p->LinkNext == this) {
545 // Make the node that points to us point to the our next node
546 p->LinkNext = p->LinkNext->LinkNext;
552 bool APIHOOK::GetProcOrgFunc()
554 return GetProcOrgFunc( GetModuleHandleA( ModName ) );
556 bool APIHOOK::GetProcOrgFunc( HINSTANCE hInst )
558 if (Hooked) return true;
560 // Save information about this hooked function
561 OrgFunc = ::GetProcAddress( hInst, FuncName);
563 DBW("Function doesn't exist =%s:%s", ModName, FuncName);
567 if (OrgFunc > MaxAppAddr) {
568 // DBW("The address is in a shared DLL; the address needs fixing up");
569 PBYTE pb = (PBYTE)OrgFunc;
570 if (pb[0] == cPushOpCode){
571 // Skip over the PUSH op code and grab the real address
572 PVOID pv = * (PVOID*) &pb[1];
577 // Set assembler code for hooking at the org entry
579 DBW("Cannot write process memory");
586 bool APIHOOK::StoreCode( )
588 DBW("StoreCode:%s %s", ModName, FuncName);
589 // Hook this function in all currently loaded modules
590 ReplaceIATEntryInAllMods( this, OrgFunc, HookFunc );
593 void APIHOOK::RestoreCode()
595 DBW("RestoreCode:%s %s", ModName, FuncName);
596 ReplaceIATEntryInAllMods( this, HookFunc, OrgFunc );
598 void APIHOOK::ReplaceIATEntryInAllMods( APIHOOK *obj, PROC pfnCurrent, PROC pfnNew )
600 HMODULE hmodThisMod = obj->ExcludeMe
601 ? ModuleFromAddress(ReplaceIATEntryInAllMods) : NULL;
606 if (fnCreateToolhelp32Snapshot){
607 // Toolhelp
\82ª
\8eg
\97p
\82Å
\82«
\82é
\8fê
\8d\87\82Í
\8eg
\97p
\82·
\82é
608 // Get the list of modules in this process
609 HANDLE hSnapshot = fnCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, idProcess);
611 MODULEENTRY32 me = { sizeof(me) };
612 for (BOOL fOk = fnModule32First(hSnapshot,&me); fOk; fOk = fnModule32Next(hSnapshot,&me)){
613 // NOTE: We don't hook functions in our own module
614 if (me.hModule != hmodThisMod){
615 // DBW("Module : %s %s", me.szModule,FuncName);
616 // Hook this function in this module
617 ReplaceIATEntryInOneMod( obj, pfnCurrent, pfnNew, me.hModule);
620 CloseHandle( hSnapshot );
622 if( fnEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
624 for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ )
626 if (hMods[i] != hmodThisMod){
627 char szModName[MAX_PATH];
628 // Get the full path to the module's file.
629 if ( fnGetModuleFileNameExA( hProcess, hMods[i], szModName,
631 // DBW("Module : %s %s", szModName, FuncName );
632 ReplaceIATEntryInOneMod( obj, pfnCurrent, pfnNew, hMods[i]);
638 else DBW("EnumProcessModules failed");
643 // This functions is almost taken from Jeffrey Richter's sample, thank you.
644 bool APIHOOK::ReplaceIATEntryInOneMod( APIHOOK *obj, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
646 if (!hProcess) return false;
648 // Get the address of the module's import section
650 PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)
651 ImageDirectoryEntryToData(hmodCaller, TRUE,
652 IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
655 // DBW("No import section : %s", obj->ModName);
659 // Find the import descriptor containing references to callee's functions
660 for (; pImportDesc->Name; pImportDesc++){
661 PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
662 if (lstrcmpiA(pszModName, obj->ModName) == 0)
666 if (pImportDesc->Name == 0){
667 // DBW("This module doesn't import any functions from this callee");
668 return false; // This module doesn't import any functions from this callee
671 // Get caller's import address table (IAT) for the callee's functions
672 PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)
673 ((PBYTE) hmodCaller + pImportDesc->FirstThunk);
675 // Replace current function address with new function address
676 for (; pThunk->u1.Function; pThunk++){
677 // Get the address of the function address
678 PROC* ppfn = (PROC*) &pThunk->u1.Function;
679 // Is this the function we're looking for?
680 BOOL fFound = (*ppfn == pfnCurrent);
681 if (!fFound && (*ppfn > MaxAppAddr)){
682 // If this is not the function and the address is in a shared DLL,
683 // then maybe we're running under a debugger on Windows 98. In this
684 // case, this address points to an instruction that may have the
686 PBYTE pbInFunc = (PBYTE) *ppfn;
687 if (pbInFunc[0] == cPushOpCode){
688 // We see the PUSH instruction, the real function address follows
689 ppfn = (PROC*) &pbInFunc[1];
691 // Is this the function we're looking for?
692 fFound = (*ppfn == pfnCurrent);
697 // The addresses match, change the import section address
698 if (!WriteProcessMemory(hProcess, ppfn, &pfnNew, sizeof(pfnNew), NULL)){
699 if (SetWriteProtect( (LPVOID)ppfn, false )==~0){ // write protection release
700 DBW("SetWriteProtect failed: %08X %s %s", ppfn, obj->ModName, obj->FuncName);
704 if (!WindowsNT && IsBadWritePtr(ppfn,sizeof(pfnNew))){
705 // Windows9x shared DLL section
706 // change memory attribte using VxD
707 if (!ChangeMemory( ppfn, &pfnNew, sizeof(pfnNew) )){
708 DBW("ChangeMemory failed");
713 if (!WriteProcessMemory(hProcess, ppfn, &pfnNew, sizeof(pfnNew), NULL)){
714 //SetWriteProtect( ppfn, true ); // restore protection
715 DBW("%08X %08X %08X %08X %s %s", hProcess, ppfn, &pfnNew, sizeof(pfnNew), obj->ModName, obj->FuncName );
716 DBW("WriteProcessMemory failed : %d",GetLastError());
721 return true; // We did it, get out
727 // If we get to here, the function is not in the caller's import section
730 bool APIHOOK::HookAgain()
732 if ( Hooked ) return true;
734 // Set assembler code for hooking at the org entry
736 DBW("Cannot write process memory@rehook");
743 void APIHOOK::Finish()
745 if ( !Hooked ) return;
749 // Returns the HMODULE that contains the specified memory address
750 static HMODULE ModuleFromAddress(PVOID pv)
752 MEMORY_BASIC_INFORMATION mbi;
753 return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
754 ? (HMODULE) mbi.AllocationBase : NULL);
757 #if HOOK_PAINT || RETRYMETA
758 APIHOOK BeginPaintHook( STR_USER32, STR_BeginPaint, _BeginPaint );
759 APIHOOK EndPaintHook( STR_USER32, STR_EndPaint, _EndPaint );
763 APIHOOK BitBltHook( STR_GDI32, STR_BitBlt, _BitBlt );
767 APIHOOK GetDCHook( STR_USER32, STR_GetDC, _GetDC );
768 APIHOOK ReleaseDCHook( STR_USER32, STR_ReleaseDC, _ReleaseDC );
772 APIHOOK ExtTextOutAHook( STR_GDI32, STR_ExtTextOutA, _ExtTextOutA );
773 APIHOOK ExtTextOutWHook( STR_GDI32, STR_ExtTextOutW, _ExtTextOutW );
775 APIHOOK TabbedTextOutAHook( STR_USER32, STR_TabbedTextOutA, _TabbedTextOutA );
776 APIHOOK TabbedTextOutWHook( STR_USER32, STR_TabbedTextOutW, _TabbedTextOutW );
777 APIHOOK TextOutAHook( STR_GDI32, STR_TextOutA, _TextOutA );
778 APIHOOK TextOutWHook( STR_GDI32, STR_TextOutW, _TextOutW );
779 APIHOOK DrawTextAHook( STR_USER32, STR_DrawTextA, _DrawTextA );
780 APIHOOK DrawTextWHook( STR_USER32, STR_DrawTextW, _DrawTextW );
781 APIHOOK DrawTextExAHook( STR_USER32, STR_DrawTextExA, _DrawTextExA );
782 APIHOOK DrawTextExWHook( STR_USER32, STR_DrawTextExW, _DrawTextExW );
784 #endif // METAEXTTEXTOUT
786 __declspec(dllexport)
787 bool WINAPI Init( HWND _hwnd, const char * /*module_name*/, bool windowsnt, const char *vxd_path )
789 DBW("Init:%08X %d", _hwnd, windowsnt);
790 hwndCallback = _hwnd;
795 WindowsNT = windowsnt;
797 // DBW("vxd_path=%s",vxd_path);
798 lstrcpy( VxDpathName, "\\\\.\\" );
799 lstrcat( VxDpathName, vxd_path );
801 DBW("Cannot open VxD:%s:%d", VxDpathName,GetLastError() );
807 // HINSTANCE hDll = GetModuleHandle( module_name );
808 hMouseHook = SetWindowsHookEx( WH_MOUSE, (HOOKPROC)MouseProc, hInstance, NULL );
810 DBW("SetWindowsHookEx error: %d", GetLastError());
814 // hKeyHook = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)KeyboardProc, hDll, NULL );
820 DBW("%08X(%08X) Protected", (((INT_PTR)&ExtTextOutAHook) / siPageSize) * siPageSize,&ExtTextOutAHook);
823 idDokopopProcess = GetCurrentProcessId();
825 // get AMODI infomation.
828 hwndAMODI = FindAMODI();
832 if (GetWindowThreadProcessId(hwnd, &procId)){
833 HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, procId);
835 memset(AMODIPath, 0, sizeof(AMODIPath));
836 if (GetModuleFileNameEx(hProc, NULL, AMODIPath, sizeof(AMODIPath))>0){
849 __declspec(dllexport)
853 if ( !Initialized ) return;
856 UnhookWindowsHookEx( hMouseHook );
858 // UnhookWindowsHookEx( hKeyHook );
866 __declspec(dllexport)
867 int WINAPI Config( int clickonly, int keyaction, int keyflag )
869 DBW("Config:%d %d %d", clickonly, keyaction, keyflag);
871 ClickOnlyEnabled = int_bool(clickonly);
873 for ( int i=0;KeyConfig[i].Action;i++ ){
874 if (KeyConfig[i].Action == keyaction){
875 KeyConfig[i].Flag = keyflag;
882 __declspec(dllexport)
883 int WINAPI Config2( const struct TDCHConfig *cfg )
885 DBW("Config2: %d %d %d %d %d", (int)cfg->ScaleX, (int)cfg->ScaleY, (int)cfg->UseAMODI, (int)ExtAMODI, cfg->UseNumPrev ? cfg->NumPrevWords : 1);
887 MoveSend = cfg->MoveSend ? true : false;
889 OnlyImage = cfg->OnlyImage;
890 ScaleX = cfg->ScaleX;
891 ScaleY = cfg->ScaleY;
892 NumPrevWords = cfg->UseNumPrev ? cfg->NumPrevWords : 1;
894 RequireHwndAMODI = false;
898 RequireHwndAMODI = true;
900 hwndAMODI = FindAMODI();
908 OnlyAMODI = int_bool(cfg->OnlyAMODI);
911 if (cfg->AMODIPath[0]){
912 size_t len = strlen(cfg->AMODIPath);
913 if (len<sizeof(AMODIPath)-2){
914 memcpy(AMODIPath, cfg->AMODIPath, len);
915 if (AMODIPath[len-1]!='\\'){
916 AMODIPath[len] = '\\';
919 AMODIPath[len] = '\0';
923 dbw("Config2[%d]: %d %d %s", ++generation, cfg->ScaleX, cfg->ScaleY, AMODIPath);
927 // non_block = true
\82Ì
\8fê
\8d\87
928 //
\81Ewait
\8fó
\91Ô
\82É
\82 \82é
\82©
\82Ç
\82¤
\82©
\82Í
\81AWaitForCaptureResult( false, 0 ) < 0
\82Å
\82í
\82©
\82é
\81B
929 //
\81E
\95K
\82¸
\8dÅ
\8cã
\82É
\82ÍWaitForCaptureResult(1,...)
\82ð
\8cÄ
\82Ñ
\8fo
\82·
\82±
\82Æ
\81B
930 __declspec(dllexport)
931 int WINAPI Capture( HWND hwnd, POINT *ppt, bool movesend, bool non_block )
933 DBW("Capture:%08X %d,%d %d %d", hwnd, ppt ? ppt->x : 0, ppt ? ppt->y : 0, movesend, non_block);
940 pt = PrevCursorPoint;
941 const bool image_only = true;
942 const bool runOnLaunchedProc = false;
943 return int_bool(DoCapture(hwnd, pt, movesend, image_only, runOnLaunchedProc, non_block));
946 // waittime
\82ÍCapture()
\8aJ
\8en
\82µ
\82Ä
\82©
\82ç
\82Ì
\8co
\89ß
\8e\9e\8aÔ
947 // polling
\82·
\82é
\8fê
\8d\87\82Íwaittime
\82ð
\8f
\82µ
\82¸
\82Â
\91\9d\82â
\82·
\95K
\97v
\82 \82è(
\82»
\82Ì
\8fê
\8d\87\82Ísend_text=0)
948 // CaptureImage
\82ð
\8ds
\82Á
\82½
\8fê
\8d\87\82Í
\81A
\81u
\95K
\82¸
\81vWaitForCaptureResult( 1, ... )
\82ð
\8cÄ
\82Ñ
\8fo
\82·
\95K
\97v
\82ª
\82 \82é
\81B
949 //
\82»
\82¤
\82µ
\82È
\82¢
\82Æ
\81ACaptureImageBlocking
\82ª true
\82É
\82È
\82Á
\82½
\82Ü
\82Ü
\81B
952 // 0 : wait
\92\86\82Ì
\82à
\82Ì
\82Í
\82È
\82µ
953 // 1 : OK(text ready)
955 __declspec(dllexport)
956 int WINAPI WaitForCaptureResult( bool send_text, unsigned waittime )
958 DBW("WaitForCaptureResult: %d %d %d", send_text, waittime, CaptureImageBlocking);
959 if (!CaptureImageBlocking) return 0;
962 if (WaitAndGetResult(ImageTextPath, waittime)){
966 HANDLE hf = WaitForResult(ImageTextPath, waittime);
975 void ShareProtect( bool f )
977 LPVOID BaseAddress = (LPVOID)((((INT_PTR)&ExtTextOutAHook) / siPageSize) * siPageSize);
980 if ( !VirtualProtect( BaseAddress, siPageSize, f ? PAGE_READONLY : PAGE_READWRITE, &OldProtect ) ){
981 DBW("Cannot change protect:%08X@rehook",BaseAddress);
985 DWORD SetWriteProtect( LPVOID addr, bool f )
987 LPVOID BaseAddress = (LPVOID)((((INT_PTR)addr) / siPageSize) * siPageSize);
990 if ( !VirtualProtect( BaseAddress, siPageSize, f ? PAGE_READONLY : PAGE_READWRITE, &OldProtect ) ){
991 DBW("Cannot change protect:%08X-%08X@rehook %d", (INT_PTR)BaseAddress>>32, BaseAddress, GetLastError());
997 // change write protected memory for Windows9x
998 bool ChangeMemory( void *dst, const void *src, unsigned size )
1001 if ( vxd_Handle == INVALID_HANDLE_VALUE ){
1006 bool r = int_bool(DeviceIoControl( vxd_Handle, DIOC_CHANGE_MEMORY, (void*)src, size, dst, 0, &DIOC_count, NULL));
1009 DBW("DeviceIoControl failed");
1016 if (vxd_Handle!=INVALID_HANDLE_VALUE){
1017 DBW("Already loaded VxD");
1020 vxd_Handle=CreateFile(&VxDpathName[0],0,0,NULL,0,FILE_FLAG_DELETE_ON_CLOSE,NULL);
1021 return vxd_Handle != INVALID_HANDLE_VALUE;
1025 if (vxd_Handle == INVALID_HANDLE_VALUE)
1027 CloseHandle(vxd_Handle);
1028 vxd_Handle = INVALID_HANDLE_VALUE;
1034 if ( GetKeyState( VK_SHIFT ) & 0x8000 ) r |= KF_SHIFT;
1035 if ( GetKeyState( VK_CONTROL ) & 0x8000 ) r |= KF_CONTROL;
1036 if ( GetKeyState( VK_MENU ) & 0x8000 ) r |= KF_MENU;
1037 if ( GetKeyState( VK_LWIN ) & 0x8000 ) r |= KF_LWIN;
1038 if ( GetKeyState( VK_RWIN ) & 0x8000 ) r |= KF_RWIN;
1039 if ( ClickOnlyEnabled && r == 0 ) r = KF_CLICKONLY;
1040 // if ( GetKeyState( VK_APPS ) & 0x8000 ) r |= KF_APPS;
1043 LRESULT CALLBACK MouseProc( int code, WPARAM wParam, LPARAM lParam )
1045 if ( code < 0 || code != HC_ACTION )
1046 return CallNextHookEx( hMouseHook, code, wParam, lParam );
1048 MOUSEHOOKSTRUCT *mhs;
1054 if (wParam!=0x200 && wParam!=0xA0)
1055 dbw("WParam:%08X", wParam);
1058 curProcess = GetCurrentProcessId();
1059 bool runOnLaunchedProc = false;
1062 case WM_LBUTTONDOWN:
1063 // case WM_NCLBUTTONDOWN:
1065 LButtonUpCancel = false;
1066 // if (LButtonUpCancel)
1070 case WM_MBUTTONDOWN:
1071 // case WM_NCMBUTTONDOWN:
1073 MButtonUpCancel = false;
1074 // if (MButtonUpCancel)
1078 case WM_RBUTTONDOWN:
1079 // case WM_NCRBUTTONDOWN:
1081 RButtonUpCancel = false;
1082 // if (RButtonUpCancel)
1089 mhs = (MOUSEHOOKSTRUCT*)lParam;
1090 hwnd = WindowFromPoint( mhs->pt );
1093 HWND h = GetParent( hwnd );
1103 if (curProcess == idDokopopProcess){
1104 // runs on launched process -> ignored.
1105 DBW("Runs on launched proc(%d)", curProcess);
1106 runOnLaunchedProc = true;
1109 for ( i=0;KeyConfig[i].Action;i++ ){
1110 //DBW("%d:%d %x", i, KeyConfig[i].Action, KeyConfig[i].Flag);
1111 if ( kf == KeyConfig[i].Flag ){
1112 switch ( KeyConfig[i].Action ){
1116 const bool move_send = false;
1117 if (DoCapture(hwnd, mhs->pt, move_send, OnlyImage, runOnLaunchedProc)){
1119 if (wParam == WM_LBUTTONDOWN)
1120 LButtonUpCancel = true;
1121 if (wParam == WM_MBUTTONDOWN)
1122 MButtonUpCancel = true;
1124 RButtonUpCancel = true;
1125 return 1; // discard this message
1130 DokoPopMenu( hwnd );
1134 ToggleClick( hwnd );
1141 DBW("WM_RBUTTONUP:%d",RButtonUpCancel);
1142 if ( RButtonUpCancel ){
1143 RButtonUpCancel = false;
1144 return 1; // no longer process the message
1148 LButtonDown = false;
1149 if ( LButtonUpCancel ){
1150 LButtonUpCancel = false;
1151 return 1; // no longer process the message
1155 MButtonDown = false;
1156 if ( MButtonUpCancel ){
1157 MButtonUpCancel = false;
1158 return 1; // no longer process the message
1163 mhs = (MOUSEHOOKSTRUCT*)lParam;
1164 hwnd = WindowFromPoint( mhs->pt );
1165 if (PrevCursorPoint.x!=mhs->pt.x || PrevCursorPoint.y!=mhs->pt.y){
1166 PrevMoveTime = GetTickCount();
1168 PrevCursorPoint = mhs->pt;
1170 //DBW("Moving:%d %d", mhs->pt.x, mhs->pt.y);
1173 //TODO: 5pixel
\96¢
\96\9e\82Å
\82 \82ê
\82ÎDoCapture
\82·
\82é
1177 #if 0 // 2014.11.18 inc.srch
\82Å
\97\8e\82¿
\82é
\82Ì
\82Å
\82Æ
\82è
\82 \82¦
\82¸comment out
1178 const int MOVE_SEND_INTERVAL = 50; // msec
1179 if (GetTickCount()-PrevMoveTime > MOVE_SEND_INTERVAL){
1181 if (DoCapture(hwndLast, PrevCursorPoint, true)){
1182 // stop the capture from the main.
1194 return CallNextHookEx( hMouseHook, code, wParam, lParam );
1197 bool DoCapture(HWND hwnd, POINT pt, bool movesend, bool image_only, bool runOnLaunchedProc, bool non_block)
1199 DBW("DoCapture: %d %d %d %d %d", image_only, runOnLaunchedProc, hwndAMODI, ExtAMODI, OnlyAMODI);
1200 CursorPoint = ScreenPoint = pt;
1201 ScreenToClient( hwnd, &CursorPoint );
1203 #if 1 // acrobat reader
\8fã
\82Åclick
\82·
\82é
\82ÆhwndAMODI
\82ªnull
\82É
\82È
\82Á
\82Ä
\82µ
\82Ü
\82¤
\8fê
\8d\87\82ª
\82 \82é
\82½
\82ß
\81i
\8c´
\88ö
\95s
\96¾
\81j
1204 //
\81Ereader
\8fã
\82Å
\82Ímouse event
\82ª
\83s
\83^
\83b
\82Æ
\8e~
\82Ü
\82é
1205 //
\81Ereader
\8fã
\82Åclick
\82µ
\82½
\82¾
\82¯
\82Å
\82Ínull
\82É
\82È
\82ç
\82È
\82¢
1206 //
\81Ereader
\8fã
\82Åctrl+click
\82·
\82é
\82Æ
\81Areader
\8fã
\82©
\82çmouse
\82ð
\8aO
\82·
\82Ænull
\82É
\82È
\82Á
\82Ä
\82¢
\82é
1207 //
\81Ereader
\8fã
\82Åshift+click, alt+click, ctrl+click
\82Å
\82Ínull
\82É
\82È
\82ç
\82È
\82¢
1208 //
\81E
\90Ý
\92è
\82ðAlt+click
\82É
\95Ï
\8dX
\82·
\82é
\82Æ
\81AAlt+click
\82Ånull
\82É
\82È
\82è
\81ACtrl+click
\82Å
\82Ínull
\82É
\82È
\82ç
\82È
\82¢
1209 //
\82Ü
\82é
\82ÅDokoPop!
\91Î
\8dô
\82ð
\82µ
\82Ä
\82¢
\82é
\82©
\82Ì
\82æ
\82¤
\82¾
\81B
\82¢
\82¸
\82ê
\82É
\82¹
\82æ
\81Amouse event
\82ª
\82Ü
\82Á
\82½
\82
\97\88\82È
\82¢
\81A
1210 //
\82¨
\82»
\82ç
\82reader
\82Ì
\82Ù
\82¤
\82Åmouse hook
\82ð
\8cÄ
\82Î
\82È
\82¢
\82æ
\82¤
\82É
\82µ
\82Ä
\82¢
\82é
\82Ì
\82¾
\82ë
\82¤
\81A
1211 //
\82È
\82Ì
\82Å
\81Anull
\8c´
\88ö
\82ª
\89¼
\82É
\82í
\82©
\82Á
\82½
\82Æ
\82µ
\82Ä
\82à
\81Areader
\8fã
\82Å
\82Í
\8c\9f\8dõ
\82ª
\82Å
\82«
\82È
\82¢
\82Í
\82¸
1212 if (RequireHwndAMODI){
1214 hwndAMODI = FindAMODI();
1218 if (!image_only && !runOnLaunchedProc){
1219 //DBW("hwnd:%08X %d %d", (int)hwnd, CursorPoint.x, CursorPoint.y);
1220 if ((!hwndAMODI && !ExtAMODI) || !OnlyAMODI){
1221 // Redraw Metafile //
1223 DBW("Target : %08X %d", hwnd, curProcess);
1224 bool r = CaptureText( hwnd, movesend );
1227 return true; // discard this message
1231 if (image_only || hwndAMODI || ExtAMODI){
1232 if (CaptureImage(hwnd, movesend, non_block))
1238 void CallbackMain(int msg, const void *data, int len, HWND wparam=0)
1243 cds.lpData = (LPSTR)data;
1244 SendMessage( hwndCallback, WM_COPYDATA, (WPARAM)wparam, (LPARAM)&cds );
1247 void DokoPopMenu( HWND hwnd )
1249 CallbackMain(DCH_MENU, NULL, 0, hwnd);
1251 void ToggleClick( HWND hwnd )
1253 CallbackMain(DCH_TOGGLE, NULL, 0, hwnd);
1256 LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam )
1258 if ( code < 0 || code != HC_ACTION )
1259 return CallNextHookEx( hKeyHook, code, wParam, lParam );
1261 if ( wParam == VK_CONTROL ){
1262 if ( lParam & (KF_UP<<16) ){
1267 if ( !(lParam & (KF_REPEAT<<16)) ){
1268 // control key down and not repeat
1269 // DBW("wparam=%08X lparam=%08X",wParam,lParam);
1270 long nowt = GetTickCount();
1271 if ( nowt - LastTypeTime < GetDoubleClickTime() ){
1273 ClickOnlyEnabled = !ClickOnlyEnabled;
1274 MessageBeep( MB_OK );
1278 LastTypeTime = nowt;
1282 // control key down and repeat
1286 LastTypeTime -= 10000;
1288 return CallNextHookEx( hMouseHook, code, wParam, lParam );
1292 //__declspec(dllexport)
1293 #if HOOK_PAINT || RETRYMETA
1294 HDC WINAPI _BeginPaint( HWND hwnd, LPPAINTSTRUCT ps )
1296 // DBW("BeginPaint");
1297 HDC hdc = ((FNBeginPaint)BeginPaintHook.OrgFunc)( hwnd, ps );
1301 ps->rcPaint.left = 0;
1302 ps->rcPaint.top = 0;
1303 ps->rcPaint.right = rcInvalid.right;
1304 ps->rcPaint.bottom = rcInvalid.bottom;
1308 //__declspec(dllexport)
1309 BOOL WINAPI _EndPaint( HWND hwnd, CONST PAINTSTRUCT *ps )
1311 ((PAINTSTRUCT*)ps)->hdc = OrgHDC;
1312 return ((FNEndPaint)EndPaintHook.OrgFunc)( hwnd, ps );
1316 HDC WINAPI _GetDC( HWND hwnd )
1319 HDC hdc = ((FNGetDC)GetDCHook.OrgFunc)( hwnd );
1321 if ( hwnd == hwndOrg ){
1327 int WINAPI _ReleaseDC( HWND hwnd, HDC hdc )
1330 if ( hdc == hdcMeta ){
1333 int r = ((FNReleaseDC)ReleaseDCHook.OrgFunc)( hwnd, hdc );
1339 //__declspec(dllexport)
1340 BOOL WINAPI _ExtTextOutA(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCSTR str, UINT count, CONST INT *dx )
1342 DBW("_ExtTextOutA");
1344 GetCurrentPositionEx(hdc,&pt);
1346 BOOL r = ((FNExtTextOutA)ExtTextOutAHook.OrgFunc)( hdc, x, y, option, rc, str, count, dx );
1348 hdcExtTextOut = hdc;
1357 _rc.right = rc->right;
1358 _rc.bottom = rc->bottom;
1360 _rc.right = rcClient.right;
1361 _rc.bottom = rcClient.bottom;
1363 if ( GetTextAlign( hdc ) & TA_UPDATECP ){
1371 if ( TargetBitBltCount == BitBltCount ){
1372 _rc.right += CursorPoint.x; //*+++ bug
\82±
\82¤
\82µ
\82È
\82¢
\82Æ
\95\9d\82ª
\82¹
\82Ü
\82
\82Ähit
\82µ
\82È
\82¢
1373 OffsetRect( &_rc, TargetOffset.x, TargetOffset.y );
1380 #if ORG_OFFSET /* fixed 2001.1.14 for IE@win2k */
1383 GetViewportOrgEx( hdc, &vpt );
1384 GetWindowOrgEx( hdc, &wpt );
1385 OffsetRect( &_rc, vpt.x-wpt.x, vpt.y-wpt.y);
1390 GetViewportOrgEx( hdc, &vpt );
1391 GetWindowOrgEx( hdc, &wpt );
1392 if (vpt.x != wpt.x || vpt.y != wpt.y)
1393 DBW("!!!Org DIFF=%d %d",vpt.x-wpt.x, vpt.y-wpt.y);
1397 //
\98A
\91±
\82µ
\82½
\83e
\83L
\83X
\83g
\82Ì
\8fê
\8d\87\82Í
1398 //
\98A
\8c\8b\82·
\82é
1399 if (LastY == _rc.top && LastX == _rc.left ){
1400 //
\98A
\91±
\82µ
\82½
\83e
\83L
\83X
\83g
\95`
\89æ
\81¨
\98A
\8c\8b
1401 LastTextA->Cat( str, count );
1403 LastTextA->Set( str, count );
1408 if ( PtInRect( &_rc, CursorPoint ) )
1411 char *buf = new char[ count + 1 ];
1412 CopyMemory( buf, str, count );
1414 DBW("CheckA -- %d %d %d %d (%d,%d)", _rc.left, _rc.top, _rc.right, _rc.bottom, CursorPoint.x, CursorPoint.y, count);
1418 int loc = GetTextFromPoint( hdc, str, count, CursorPoint.x - _rc.left, CursorPoint.y - _rc.top, dx );
1420 FoundLocA = loc + LastTextA->GetLength() - count;
1421 FoundTextA->Set( LastTextA );
1423 DBW("HitA loc=%d Len=%d Text=%ws", FoundLocA, FoundTextA->GetLength(), FoundTextA->c_str());
1431 //__declspec(dllexport)
1432 BOOL WINAPI _ExtTextOutW(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCWSTR str, UINT count, CONST INT *dx )
1434 // DBW("_ExtTextOutW");
1436 GetCurrentPositionEx(hdc,&pt);
1438 BOOL r = ((FNExtTextOutW)ExtTextOutWHook.OrgFunc)( hdc, x, y, option, rc, str, count, dx );
1440 hdcExtTextOut = hdc;
1449 _rc.right = rc->right;
1450 _rc.bottom = rc->bottom;
1452 _rc.right = rcClient.right;
1453 _rc.bottom = rcClient.bottom;
1455 if ( GetTextAlign( hdc ) & TA_UPDATECP ){
1463 if ( TargetBitBltCount == BitBltCount ){
1464 _rc.right += CursorPoint.x; //*+++ bug
\82±
\82¤
\82µ
\82È
\82¢
\82Æ
\95\9d\82ª
\82¹
\82Ü
\82
\82Ähit
\82µ
\82È
\82¢
1465 OffsetRect( &_rc, TargetOffset.x, TargetOffset.y );
1472 #if ORG_OFFSET /* fixed 2001.1.14 for IE@win2k */
1475 GetViewportOrgEx( hdc, &vpt );
1476 GetWindowOrgEx( hdc, &wpt );
1477 OffsetRect( &_rc, vpt.x-wpt.x, vpt.y-wpt.y);
1478 #else // !ORG_OFFSET
1482 GetViewportOrgEx( hdc, &vpt );
1483 GetWindowOrgEx( hdc, &wpt );
1484 if (vpt.x != wpt.x || vpt.y != wpt.y)
1485 DBW("!!!Org DIFF=%d %d",vpt.x-wpt.x, vpt.y-wpt.y);
1487 #endif // !ORG_OFFSET
1489 //
\98A
\91±
\82µ
\82½
\83e
\83L
\83X
\83g
\82Ì
\8fê
\8d\87\82Í
\98A
\8c\8b\82·
\82é
1490 if (LastY == _rc.top && LastX == _rc.left ){
1491 //
\98A
\91±
\82µ
\82½
\83e
\83L
\83X
\83g
\95`
\89æ
\81¨
\98A
\8c\8b
1492 LastTextW->Cat( str, count );
1494 LastTextW->Set( str, count );
1499 if ( PtInRect( &_rc, CursorPoint ) )
1501 DBW("%04X %04X %04X %04X",
1507 wchar_t *buf = new wchar_t[ count + 1 ];
1508 CopyMemory( buf, str, count*sizeof(wchar_t) );
1510 DBW("CheckW -- %d %d %d %d (%d,%d)", _rc.left, _rc.top, _rc.right, _rc.bottom, CursorPoint.x, CursorPoint.y, count);
1514 int loc = GetTextFromPoint( hdc, str, count, CursorPoint.x - _rc.left, CursorPoint.y - _rc.top, dx );
1516 FoundLocW = loc + LastTextW->GetLength() - count;
1517 FoundTextW->Set( LastTextW );
1519 DBW("HitW loc=%d Len=%d Text=%ws", FoundLocW, FoundTextW->GetLength(), FoundTextW->c_str());
1527 #endif // !METAEXTTEXTOUT
1530 BOOL WINAPI _BitBlt(HDC hdcdest, int xdest, int ydest, int width, int height, HDC hdcsrc, int xsrc, int ysrc, DWORD rop )
1532 DBW("BitBlt:%08X %d %d %d %d <- %08X %d %d", hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc );
1533 BOOL r = ((FNBitBlt)BitBltHook.OrgFunc)(hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, rop );
1534 // DBW("BitBlt:%08X %d %d %d %d <- %08X %d %d", hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc );
1535 if ( r && hdcExtTextOut == hdcsrc ){
1537 //
\8d¡
\89ñ
\82ÌBitBlt
\8e\9e\82ÉExtTextOut
\82ª
\82 \82Á
\82½
\82©
\81H
1538 if ( ExtTextOutCount > 0 ){
1539 // CursorPoint
\82ª
\8aÜ
\82Ü
\82ê
\82é
\82©
\81H
1540 DBW("ExtTextOutCount=%d",ExtTextOutCount);
1541 if ( (xdest <= CursorPoint.x)
1542 && (xdest+width > CursorPoint.x)
1543 && (ydest <= CursorPoint.y)
1544 && (ydest+height > CursorPoint.y)
1546 TargetBitBltCount = BitBltCount;
1547 TargetOffset.x = xdest - xsrc;
1548 TargetOffset.y = ydest - ysrc;
1549 DBW("TargetOffset %d %d (%d,%d %dx%d)<-(%d,%d)",
1550 TargetOffset.x, TargetOffset.y,xdest,ydest,width,height,xsrc,ysrc);
1555 GetViewportOrgEx( hdcdest, &vpt );
1556 GetWindowOrgEx( hdcdest, &wpt );
1557 DBW("BitBlt OrgDIFF=%d %d",vpt.x-wpt.x, vpt.y-wpt.y);
1560 GetViewportExtEx( hdcdest, &sz1 );
1561 GetWindowExtEx( hdcdest, &sz2 );
1562 DBW("BitBlt Ext %d (%d,%d) (%d,%d)", GetMapMode(hdcdest), sz1.cx, sz1.cy, sz2.cx, sz2.cy );
1565 GetWorldTransform( hdcdest, &xform );
1568 sprintf(buf,"== [%d] %g %g %g %g %g %g", GetGraphicsMode(hdcdest), xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy);
1576 if ( TargetBitBltCount != -1 ){
1577 //
\82·
\82Å
\82É
\82Ù
\82©
\82Ìband
\82Åhit
\82µ
\82Ä
\82¢
\82é
\8fê
\8d\87\81A
1578 // Cancel ExtTextOut
1586 DBW("BitBltCount=%d",BitBltCount);
1587 ExtTextOutCount = 0;
1590 // DBW("Unknown destination BitBlt %08X(%d,%d %dx%d)<-%08X(%d,%d)",hdcdest,xdest,ydest,width,height,hdcsrc,xsrc,ysrc);
1597 #define HK1( name, ret_type, args ) \
1598 ret_type r = ((FN##name)name##Hook.OrgFunc) args; \
1600 LONG WINAPI _TabbedTextOutA( HDC hdc, int x, int y, LPCSTR str, int count, int ntabs, LPINT tabs, int origin )
1602 DBW("_TabbedTextOutA");
1603 HK1( TabbedTextOutA, LONG, ( hdc, x, y, str, count, ntabs, tabs, origin ) );
1605 LONG WINAPI _TabbedTextOutW( HDC hdc, int x, int y, LPCWSTR str, int count, int ntabs, LPINT tabs, int origin )
1607 DBW("TabbedTextOutW");
1608 HK1( TabbedTextOutW, LONG, ( hdc, x, y, str, count, ntabs, tabs, origin ) );
1610 BOOL WINAPI _TextOutA( HDC hdc, int x, int y, LPCSTR str, int count )
1613 HK1( TextOutA, BOOL, ( hdc, x, y, str, count ) );
1615 BOOL WINAPI _TextOutW( HDC hdc, int x, int y, LPCWSTR str, int count )
1618 HK1( TextOutW, BOOL, ( hdc, x, y, str, count ) );
1620 int WINAPI _DrawTextA( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format )
1623 HK1( DrawTextA, int, ( hdc, str, count, rc, format ) );
1625 int WINAPI _DrawTextW( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format )
1628 HK1( DrawTextW, int, ( hdc, str, count, rc, format ) );
1630 int WINAPI _DrawTextExA( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params )
1633 HK1( DrawTextExA, int, ( hdc, str, count, rc, format, params ) );
1635 int WINAPI _DrawTextExW( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params )
1638 HK1( DrawTextExW, int, ( hdc, str, count, rc, format, params ) );
1642 bool CaptureText( HWND hwnd, bool movesend )
1648 MoveSendMode = movesend;
1650 //DoScale(NULL, &CursorPoint, 1);
1655 FoundTextA = new TString<char>;
1656 FoundTextW = new TString<wchar_t>;
1657 LastTextA = new TString<char>;
1658 LastTextW = new TString<wchar_t>;
1665 GetClientRect( hwnd, &rcClient );
1666 GetUpdateRect( hwnd, &rcOrgInvalid, FALSE );
1668 #if USE_OPTIMALINVALID
1669 SetRect( &rcInvalid, 0, max(CursorPoint.y - 64,0), rcClient.right, max(CursorPoint.y + 64,0) );
1671 rcInvalid = rcClient;
1675 hRgn = CreateRectRgn( rcInvalid.left, rcInvalid.top, rcInvalid.right, rcInvalid.bottom );
1678 InvalidateRect( hwnd, &rcInvalid, INVALIDATE_TRUE );
1681 SendMessage( hwnd, WM_PAINT, 0, 0 );
1682 SendMessage( hwnd, WM_NCPAINT, (WPARAM)hRgn, 0 );
1691 HINSTANCE hPSAPI = NULL;
1695 hInst = GetModuleHandleA( STR_KERNEL32 );
1696 fnCreateToolhelp32Snapshot = (FNCreateToolhelp32Snapshot)GetProcAddress( hInst, STR_CreateToolhelp32Snapshot );
1697 if (fnCreateToolhelp32Snapshot){
1698 // Toolhelp
\82É
\82æ
\82émodule enumration
\82ª
\8eg
\97p
\89Â
\94\
1699 fnModule32First = (FNModule32First)GetProcAddress( hInst, STR_Module32First );
1700 fnModule32Next = (FNModule32Next)GetProcAddress( hInst, STR_Module32Next );
1702 // Toolhelp
\82ª
\91¶
\8dÝ
\82µ
\82È
\82¢
\8fê
\8d\87
1703 hPSAPI = LoadLibrary( STR_PSAPI );
1704 DBW("LoadLibrary : %08X",hPSAPI);
1706 DBW("Cannot load PSAPI.DLL!!");
1709 fnEnumProcessModules = (FNEnumProcessModules)GetProcAddress( hPSAPI, STR_EnumProcessModules );
1710 fnGetModuleFileNameExA = (FNGetModuleFileNameExA)GetProcAddress( hPSAPI, STR_GetModuleFileNameExA );
1713 hInst = GetModuleHandleA( STR_USER32 );
1716 DBW("Cannot load USER32.DLL");
1720 hInstGdi = GetModuleHandleA( STR_GDI32 );
1723 DBW("Cannot load GDI32.DLL");
1729 if ( !ExtTextOutAHook.GetProcOrgFunc( hInstGdi ) ){
1730 DBW("Cannot find ExtTextOutA");
1733 if ( !ExtTextOutWHook.GetProcOrgFunc( hInstGdi ) ){
1734 DBW("Cannot find ExtTextOutW");
1740 if ( !BitBltHook.GetProcOrgFunc( hInstGdi ) ){
1741 DBW("Cannot find BitBlt");
1746 TargetBitBltCount = -1;
1748 ExtTextOutCount = 0;
1751 if ( !BeginPaintHook.GetProcOrgFunc( hInst ) ){
1752 DBW("Cannot hook BeginPaint");
1755 if ( !EndPaintHook.GetProcOrgFunc( hInst ) ){
1756 DBW("Cannot hook EndPaint");
1762 TabbedTextOutAHook.GetProcOrgFunc( hInst );
1763 TabbedTextOutWHook.GetProcOrgFunc( hInst );
1764 TextOutAHook.GetProcOrgFunc( hInstGdi );
1765 TextOutWHook.GetProcOrgFunc( hInstGdi );
1766 DrawTextAHook.GetProcOrgFunc( hInst );
1767 DrawTextWHook.GetProcOrgFunc( hInst );
1768 DrawTextExAHook.GetProcOrgFunc( hInst );
1769 DrawTextExWHook.GetProcOrgFunc( hInst );
1773 hdc = GetDC( hwnd );
1775 DBW("Cannot get DC");
1781 if ( !GetDCHook.GetProcOrgFunc( hInst ) ){
1782 DBW("Cannot hook GetDC");
1785 if ( !ReleaseDCHook.GetProcOrgFunc( hInst ) ){
1786 DBW("Cannot hook ReleaseDC");
1792 DBW("Hooked successfully");
1793 // rect.right = 9999;
1794 // rect.bottom = 9999;
1796 int iWidthMM = GetDeviceCaps(hdc, HORZSIZE);
1797 int iHeightMM = GetDeviceCaps(hdc, VERTSIZE);
1798 int iWidthPels = GetDeviceCaps(hdc, HORZRES);
1799 int iHeightPels = GetDeviceCaps(hdc, VERTRES);
1801 // Use iWidthMM, iWidthPels, iHeightMM, and iHeightPels to determine the
1802 // number of .01-millimeter units per pixel in the x and y directions.
1804 int iMMPerPelX = (iWidthMM * 100)/iWidthPels;
1805 int iMMPerPelY = (iHeightMM * 100)/iHeightPels;
1806 DBW("-%d %d-",iMMPerPelX, iMMPerPelY);
1808 // Convert client coordinates to .01-mm units.
1810 rcClient.left = rcClient.left * iMMPerPelX;
1811 rcClient.top = rcClient.top * iMMPerPelY;
1812 rcClient.right = rcClient.right * iMMPerPelX;
1813 rcClient.bottom = rcClient.bottom * iMMPerPelY;
1817 hdcMeta = CreateEnhMetaFile(hdc,
1819 &rcClient, "DCHook\0EnhMetaFile\0");
1821 DBW("Cannot create Meta file");
1825 DBW("hdcMeta=%08X", hdcMeta);
1829 RedrawWindow( hwnd, &rcInvalid, NULL, RDW_UPDATENOW | RDW_NOERASE | RDW_NOFRAME | RDW_INVALIDATE );
1831 WNDPROC PaintWndProc = (WNDPROC)GetWindowLong( hwnd, GWL_WNDPROC );
1832 SendMessage( hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 );
1835 ReleaseDCHook.Finish();
1840 TabbedTextOutAHook.Finish( );
1841 TabbedTextOutWHook.Finish( );
1842 TextOutAHook.Finish( );
1843 TextOutWHook.Finish( );
1844 DrawTextAHook.Finish( );
1845 DrawTextWHook.Finish( );
1846 DrawTextExAHook.Finish( );
1847 DrawTextExWHook.Finish( );
1851 EndPaintHook.Finish();
1852 BeginPaintHook.Finish();
1856 BitBltHook.Finish();
1860 ExtTextOutAHook.Finish();
1861 ExtTextOutWHook.Finish();
1864 // Notify start enumrate meta-file
1865 CallbackMain(DCH_START, &CursorPoint, sizeof(CursorPoint), hwnd);
1870 HENHMETAFILE emf = CloseEnhMetaFile( hdcMeta );
1876 if ( FoundLocA != -1 || FoundLocW != -1 ){
1877 // DBW("Hit ExtText:%d %d",FoundLocA,FoundLocW);
1878 // ExtTextOutx hook
\82Ì
\82Ù
\82¤
\82ð
\97D
\90æ
\82·
\82é
1885 // Create compatible device-context for enumration
1886 HDC _hdc = CreateCompatibleDC( hdc );
1887 HBITMAP hbitmap = CreateCompatibleBitmap( hdc, rcClient.right, rcClient.bottom );
1888 HGDIOBJ gdiobj = SelectObject( _hdc, hbitmap );
1891 // Enumerate meta-file
1892 EnumEnhMetaFile( _hdc, emf, EnumMetaFileProc, NULL, &rcClient );
1895 // Delete compatible device-context
1896 SelectObject( _hdc, gdiobj );
1897 DeleteObject( hbitmap );
1902 DeleteEnhMetaFile( emf );
1912 if ( !HitFound && TargetBitBltCount != -1 ){
1913 DBW("Search from band:%d",TargetBitBltCount);
1915 // Band
\82©
\82ç
\8c\9f\8dõ
1916 hdcMeta = CreateCompatibleDC( hdc );
1918 DBW("Cannot create HDC in retry");
1923 HBITMAP hbitmap = CreateCompatibleBitmap( hdc, rcClient.right, rcClient.bottom );
1924 HGDIOBJ gdiobj = SelectObject( hdcMeta, hbitmap );
1925 DBW("hdcMeata=%08X", hdcMeta);
1936 ExtTextOutAHook.HookAgain();
1937 ExtTextOutWHook.HookAgain();
1940 BitBltHook.HookAgain();
1943 BeginPaintHook.HookAgain();
1944 EndPaintHook.HookAgain();
1947 // DBW("t1:%d %d %d %d",rcClient.left, rcClient.top,rcClient.right,rcClient.bottom);
1950 InvalidateRect( hwnd, &rcInvalid, INVALIDATE_TRUE );
1954 RedrawWindow( hwnd, &rcInvalid, NULL, RDW_UPDATENOW | RDW_NOERASE | RDW_NOFRAME | RDW_INVALIDATE );
1956 CallWindowProc( (WNDPROC)PaintWndProc, hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 );
1960 EndPaintHook.Finish();
1961 BeginPaintHook.Finish();
1964 BitBltHook.Finish();
1968 ExtTextOutAHook.Finish();
1969 ExtTextOutWHook.Finish();
1972 SelectObject( hdcMeta, gdiobj );
1973 DeleteObject( hbitmap );
1974 DeleteDC( hdcMeta );
1976 if ( FoundLocA != -1 || FoundLocW != -1 ){
1977 DBW("Found in BitBlt ExtText:%d %d",FoundLocA,FoundLocW);
1983 #endif // METAEXTTEXTOUT
1989 HDC hdc = GetDC( hwnd );
1991 DBW("Cannot get DC");
1996 if ( !BeginPaintHook.HookAgain( ) ){
1997 DBW("Cannot hook BeginPaint");
2000 if ( !EndPaintHook.HookAgain( ) ){
2001 DBW("Cannot hook EndPaint");
2005 if ( !BeginPaintHook.GetProcOrgFunc( hInst ) ){
2006 DBW("Cannot hook BeginPaint");
2009 if ( !EndPaintHook.GetProcOrgFunc( hInst ) ){
2010 DBW("Cannot hook EndPaint");
2015 hdcMeta = CreateEnhMetaFile(hdc,
2017 &rcClient, _T("DCHook\0EnhMetaFile\0"));
2019 DBW("Cannot create Meta file");
2022 DBW("hdcMeta=%08X", hdcMeta);
2023 // InvalidateRect( hwnd, &rcInvalid, INVALIDATE_TRUE );
2024 #if 1 // 2000.7.15 NT
\82Å
\82à
\82È
\82º
\82±
\82Á
\82¿
\82É
\82µ
\82Ä
\82¢
\82È
\82©
\82Á
\82½
\82Ì
\82©
\82í
\82©
\82ç
\82È
\82¢
\82ª
\81E
\81E
\81E
2025 SendMessage( hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 );
2027 // Notepad
\82Å
\82Í
\88Ù
\8fí
\8fI
\97¹
\82·
\82é
\82½
\82ß
\8bp
\89º
2028 //
\89½
\82à
\82È
\82¢
\82Æ
\82±
\82ë
\82ÅCtrl+
\89E
\83N
\83\8a\83b
\83N
2029 WNDPROC PaintWndProc = (WNDPROC)GetWindowLong( hwnd, GWL_WNDPROC );
2030 if ( PaintWndProc ){
2031 PaintWndProc( hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 );
2034 EndPaintHook.Finish();
2035 BeginPaintHook.Finish();
2037 emf = CloseEnhMetaFile( hdcMeta );
2040 HDC _hdc = CreateCompatibleDC( hdc );
2041 HBITMAP hbitmap = CreateCompatibleBitmap( hdc, rcClient.right, rcClient.bottom );
2042 HGDIOBJ gdiobj = SelectObject( _hdc, hbitmap );
2044 DBW("Start meta-retry");
2045 // Enumerate meta-file
2046 EnumEnhMetaFile( _hdc, emf, EnumMetaFileProc, NULL, &rcClient );
2047 DBW("End meta-retry");
2049 // Delete compatible device-context
2050 SelectObject( _hdc, gdiobj );
2051 DeleteObject( hbitmap );
2053 DeleteEnhMetaFile( emf );
2056 EndPaintHook.Finish();
2058 BeginPaintHook.Finish();
2061 ReleaseDC( hwnd, hdc );
2067 // Notify end enumrate meta-file
2068 CallbackMain(DCH_END | (MoveSendMode ? DCH_MOVESEND : 0), NULL, 0, hwnd);
2072 ReleaseDC( hwnd, hdc );
2075 if ( rcOrgInvalid.right != 0 ){
2076 DBW("Update OrgInvalid--------");
2077 InvalidateRect( hwnd, NULL, INVALIDATE_TRUE );
2082 #if HOOK_GETDC || USE_META
2089 ReleaseDC( hwnd, hdc );
2096 EndPaintHook.Finish();
2098 BeginPaintHook.Finish();
2102 BitBltHook.Finish();
2108 ExtTextOutWHook.Finish();
2110 ExtTextOutAHook.Finish();
2114 FreeLibrary( hPSAPI );
2121 if (vxd_Handle!=INVALID_HANDLE_VALUE)
2134 void ExtTextOutHit()
2136 if ( FoundLocA != -1 ){
2138 DBW("Hit on ANSI@ExtTextOut");
2139 CallbackMain(DCH_HITTEXT1, FoundTextA->c_str(), FoundTextA->GetByte(), (HWND)FoundLocA);
2142 DBW("Hit on UNICODE@ExtTextOut");
2143 CallbackMain(DCH_HITTEXT2, FoundTextW->c_str(), FoundTextW->GetByte(), (HWND)FoundLocW);
2146 #endif // METAEXTTEXTOUT
2148 void DoScale(HDC hdc, POINT *pts, int num)
2150 //TODO: hInst, proc
\82Íglobal
\82É
\82µ
\82½
\82Ù
\82¤
\82ª
\82¢
\82¢
\82Ì
\82Å
\82Í
\81H
2153 if (ScaleX && ScaleY){
2154 scale = ScaleX; //
\8ew
\92è
\82µ
\82½scaling parameter
2156 scale = GetMonitorScale();
2157 if (scale == 96) return;
2162 PROCESS_DPI_AWARENESS value = Process_DPI_Unaware;
2164 if (!GetProcessDPIAwareness){
2165 GetProcessDPIAwareness = (FNGetProcessDPIAwareness)GetProcAddress(hInstSHCore, "GetProcessDpiAwareness");
2167 if (GetProcessDPIAwareness){
2168 GetProcessDPIAwareness(hProcess, &value);
2169 DBW("DPIAware: value=%d", value);
2172 if (value != Process_System_DPI_Aware){
2175 DBW("dpi: %d,%d", dpi_x, dpi_y);
2176 for (int i=0;i<num;i++){
2177 pts[i].x = MulDiv(pts[i].x, dpi_x, 96);
2178 pts[i].y = MulDiv(pts[i].y, dpi_y, 96);
2182 HINSTANCE hInst = NULL;
2183 FNGetProcessDPIAwareness GetProcessDPIAwareness = NULL;
2184 //FNSetProcessDPIAwareness SetProcessDPIAwareness = NULL;
2185 //if (!GetProcessDPIAwareness)
2187 hInst = LoadLibrary("shcore.dll");
2189 GetProcessDPIAwareness = (FNGetProcessDPIAwareness)GetProcAddress(hInst, "GetProcessDpiAwareness");
2190 //SetProcessDPIAwareness = (FNSetProcessDPIAwareness)GetProcAddress(hInst, "SetProcessDpiAwareness");
2191 //DBW("DPI API:%08X %08X", GetProcessDPIAwareness, SetProcessDPIAwareness);
2192 DBW("DPI API:%08X", GetProcessDPIAwareness);
2195 if (GetProcessDPIAwareness || (ScaleX && ScaleY)){
2197 PROCESS_DPI_AWARENESS value;
2198 if (GetProcessDPIAwareness && hdc){
2199 HRESULT hRes = GetProcessDPIAwareness(hProcess, &value);
2200 DBW("DPIAware: value=%d", value);
2201 //SetProcessDPIAwareness(Process_System_DPI_Aware);
2202 dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
2203 dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
2204 DBW("dpi: %d, %d", dpi_x, dpi_y);
2209 for (int i=0;i<num;i++){
2210 pts[i].x = MulDiv(pts[i].x, dpi_x, 96);
2211 pts[i].y = MulDiv(pts[i].y, dpi_y, 96);
2214 if (SetProcessDPIAwareness){
2215 SetProcessDPIAwareness(value);
2223 #else //
\8b\8c\83R
\81[
\83h
2224 HINSTANCE hInst = NULL;
2225 if (!GetProcessDPIAwareness){
2226 hInst = LoadLibrary("shcore.dll");
2227 DBW("shcore=%08X", hInst);
2229 GetProcessDPIAwareness = (FNGetProcessDPIAwareness)GetProcAddress(hInst, "GetProcessDPIAwareness");
2230 SetProcessDPIAwareness = (FNSetProcessDPIAwareness)GetProcAddress(hInst, "SetProcessDPIAwareness");
2231 DBW("DPI API:%08X %08X", GetProcessDPIAwareness, SetProcessDPIAwareness);
2234 if (GetProcessDPIAwareness || (ScaleX && ScaleY)){
2236 PROCESS_DPI_AWARENESS value;
2237 if (GetProcessDPIAwareness && hdc){
2238 HRESULT hRes = GetProcessDPIAwareness(hProcess, &value);
2239 SetProcessDPIAwareness(Process_System_DPI_Aware);
2240 dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
2241 dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
2246 for (int i=0;i<num;i++){
2247 pts[i].x = MulDiv(pts[i].x, dpi_x, 96);
2248 pts[i].y = MulDiv(pts[i].y, dpi_y, 96);
2250 if (SetProcessDPIAwareness){
2251 SetProcessDPIAwareness(value);
2260 int CALLBACK EnumMetaFileProc( HDC hdc, HANDLETABLE *ht, CONST ENHMETARECORD *mfr, int nobj, LPARAM /* user */ )
2262 PlayEnhMetaFileRecord( hdc, ht, mfr, nobj );
2264 //DBW("iType=%d",mfr->iType);
2266 switch ( mfr->iType ){
2267 case EMR_EXTTEXTOUTA:
2268 case EMR_EXTTEXTOUTW:
2270 EMREXTTEXTOUTW *emr = (EMREXTTEXTOUTW*)mfr;
2272 //DBW("(%d,%d) <%d=%d=%d=%d>", CursorPoint.x, CursorPoint.y, emr->rclBounds.left, emr->rclBounds.top,emr->rclBounds.right, emr->rclBounds.bottom);
2274 if ( PtInRect( (RECT*)&emr->rclBounds, CursorPoint ) ){
2275 DBW("(%d,%d) <%d=%d>", CursorPoint.x, CursorPoint.y, emr->rclBounds.left, emr->emrtext.ptlReference.x);
2279 GetWindowExtEx( hdc, &sz1 );
2280 GetViewportExtEx( hdc, &sz2 );
2281 DBW("%d-%d %d-%d", sz1.cx, sz1.cy, sz2.cx, sz2.cy);
2285 if ( mfr->iType == EMR_EXTTEXTOUTW ){
2286 //DBW("offString=%d nChars=%d left=%d top=%d offDx=%d", emr->emrtext.offString, emr->emrtext.nChars, emr->rclBounds.left, emr->rclBounds.top, emr->emrtext.offDx);
2287 //DBW("text=%ws", (wchar_t*) ( ((char*)emr) + emr->emrtext.offString ));
2288 loc = GetTextFromPoint( hdc, (wchar_t*) ( ((char*)emr) + emr->emrtext.offString ),
2289 emr->emrtext.nChars,
2290 CursorPoint.x - emr->rclBounds.left /* + emr->emrtext.ptlReference.x */,
2291 CursorPoint.y - emr->rclBounds.top /* + emr->emrtext.ptlReference.y */,
2292 ((int*)(((char*)emr) + emr->emrtext.offDx)) );
2294 loc = GetTextFromPoint( hdc, ((char*)emr) + emr->emrtext.offString,
2295 emr->emrtext.nChars,
2296 CursorPoint.x - emr->rclBounds.left /* + emr->emrtext.ptlReference.x */,
2297 CursorPoint.y - emr->rclBounds.top /* + emr->emrtext.ptlReference.y */,
2298 ((int*)(((char*)emr) + emr->emrtext.offDx)) );
2301 // char *buf = NULL;
2302 const char *text = ((char*)emr) + emr->emrtext.offString;
2303 int len = emr->emrtext.nChars;
2304 if ( mfr->iType == EMR_EXTTEXTOUTW ){
2306 //DBW("len=%d loc=%d text=%ws", len, loc, text);
2307 CallbackMain(DCH_HITTEXT2, text, len * sizeof(wchar_t), (HWND)loc);
2310 // ANSI
\8fã
\82Å
\82Ìloc
\82ð
\8b\81\82ß
\82é
\82½
\82ß
\81A
\91O
\94¼
\82Æ
\8cã
\94¼
\82ð
\95ª
\82¯
\82Ä
\95Ï
\8a·
2311 wchar_t *wp = (wchar_t*) ( ((char*)emr) + emr->emrtext.offString );
2312 buf = new char[ emr->emrtext.nChars * 2 ];
2313 memset( buf, 0, emr->emrtext.nChars*2 );
2314 //
\91O
\94¼
\95\94\95ª
2317 len = WideCharToMultiByte( CP_ACP, 0, wp, loc,
2318 buf, emr->emrtext.nChars * 2, NULL, NULL );
2321 //
\8cã
\94¼
\95\94\95ª
2322 if ( emr->emrtext.nChars > (unsigned int)loc ){
2323 len += WideCharToMultiByte( CP_ACP, 0, wp+loc, emr->emrtext.nChars - loc,
2324 buf+len, emr->emrtext.nChars * 2 - len, NULL, NULL );
2332 CallbackMain(DCH_HITTEXT1, text, len, (HWND)loc);
2337 CallbackMain(DCH_HITTEXT1, text, len, (HWND)loc);
2344 sprintf(b,"exScale=%f eyScale=%f ptlReference=(%d,%d)",emr->exScale, emr->eyScale, emr->emrtext.ptlReference.x, emr->emrtext.ptlReference.y );
2346 DBW("iGraphicsMode=%d", emr->iGraphicsMode);
2351 for ( int i=0;i<(int)emr->emrtext.nChars;i++ ){
2352 DBW(">%d", ((int*)(((char*)emr) + emr->emrtext.offDx))[i] );
2356 // DBW("[%d %d][%d %d]text=(%s)", emr->rclBounds.left, emr->rclBounds.top, CursorPoint.x, CursorPoint.y, text);
2357 // result = false; // stop enumration //
\8d\82\91¬
\89»
\82Ì
\82½
\82ß
\93r
\92\86\82Å
\8fI
\82í
\82è
\82É
\82µ
\82½
\82¢
\82ª
\81E
\81E
\81E
\82Ç
\82¤
\82µ
\82æ
\82¤
\81H
2359 // prevent to get from ExtTextOut hook
2367 if ( mfr->iType == EMR_EXTTEXTOUTW ){
2368 CallbackMain(DCH_EXTTEXTOUTW, emr, sizeof(EMREXTTEXTOUTW) + emr->emrtext.nChars * sizeof(wchar_t), (HWND)hdc);
2370 CallbackMain(DCH_EXTTEXTOUTA, emr, sizeof(EMREXTTEXTOUTA) + emr->emrtext.nChars, (HWND)hdc);
2381 // text
\82Ì
\90æ
\93ª
\82ð(0,0)
\82Æ
\82µ
\82½
\8dÀ
\95W
\82Å
\81Apos
\82Ì
\88Ê
\92u
\82É
\82 \82étext
\82Ì
\95¶
\8e\9a\88Ê
\92u
\82ð
\95Ô
\82·
2382 int GetTextFromPoint( HDC hdc, const char *text, int len, int pos_x, int pos_y, const int *dx )
2384 if ( pos_x < 0 || pos_y < 0 ) return -1;
2391 memset( rdx, 0, len*sizeof(int) );
2393 if ( !GetTextExtentExPointA( hdc, text, len, pos_x, &count, rdx, &sz ) ){
2394 DBW("GetTextExtentExPointA Failure!!");
2400 LastX += sz.cx; // update
2406 if ( rdx ) delete rdx;
2409 DBW("A:len=%d pos_x=%d sz.cx=%d", len, pos_x, sz.cx);
2410 if ( dx && count > 0 ){
2412 // Win98,Notepad
\82Ì
\93ú
\96{
\8cê
\8fã
\82Å
2413 // dx = 0, 8, 0, 8, 0, 8, ...
2414 // rdx = 9,10, 9,10, 9,10, ...
2418 for ( i=0;i<len;i++ ){
2419 DBW(" dx[%2d]=%d",i,dx[i]);
2421 for ( i=0;i<count;i++ ){
2422 DBW("rdx[%2d]=%d",i,rdx[i+1]-rdx[i]);
2426 // spacing
\82Ì
\8cë
\8d·
\82ð
\8cv
\8eZ
2427 // Times New Roman
\82È
\82Ç
\82Å
\92²
\82×
\82é
\82Æ
\82©
\82È
\82è
\82Ì
\8cë
\8d·
\82ª
\82 \82é
\81B
\82È
\82º
\81H
2432 // DBW("rd(x)[0]=%d,%d",dx[0],rdx[0]);
2435 sumdx = dx[0] - rdx[0];
2437 sumdx = dx[1] - rdx[0];
2442 for ( ;i<count;i++,j++ ){
2444 if ( rdx[i] == rdx[i-1] ){ j--; continue;} // for multi-bytes font
2445 //*++
\82 \82Æ
\82Å ExtTextOut API manual
\82ð
\8eQ
\8fÆ
2446 sumdx += dx[j] - (rdx[i]-rdx[i-1]);
2447 // DBW("%3d <> %3d", dx[j], rdx[i]-rdx[i-1]);
2448 #else // Win98
\82Å
\82Í
\81Amulti-byte
\82Å
\82à
\95ª
\8eU
\82³
\82¹
\82Ä
\82¢
\82é
\8fê
\8d\87\82ª
\82 \82é
\82½
\82ß
\81Adx
\82Å
\94»
\92f
2449 sumdx += (dx[j]?dx[j]:dx[j+1]) - (rdx[i]-rdx[i-1]);
2452 // DBW("sumdx=%d",sumdx);
2453 if ( !GetTextExtentExPointA( hdc, text, len, pos_x - sumdx, &count, rdx, &sz ) ){
2463 int GetTextFromPoint( HDC hdc, const wchar_t *text, int len, int pos_x, int pos_y, const int *dx )
2469 if ( pos_x < 0 || pos_y < 0 ) return -1;
2475 rdx = new int[ len ];
2476 memset( rdx, 0, len );
2478 if ( !GetTextExtentExPointW( hdc, text, len, pos_x, &count, rdx, &sz ) )
2480 DBW("GetTextExtentExPointW Failure!!");
2492 if ( rdx ) delete[] rdx;
2495 DBW("W:len=%d pos_x=%d sz.cx=%d", len, pos_x, sz.cx);
2496 if ( dx && count > 0 ){
2497 // spacing
\82Ì
\8cë
\8d·
\82ð
\8cv
\8eZ
2498 // Times New Roman
\82È
\82Ç
\82Å
\92²
\82×
\82é
\82Æ
\82©
\82È
\82è
\82Ì
\8cë
\8d·
\82ª
\82 \82é
\81B
\82È
\82º
\81H
2502 // DBW("rd(x)[0]=%d,%d",dx[0],rdx[0]);
2504 sumdx = dx[0] - rdx[0];
2508 for ( ;i<count-1;i++,j++ ){
2510 if ( rdx[i] == rdx[i-1] ){ j--; continue;} // for multi-bytes font
2511 //*++
\82 \82Æ
\82Å ExtTextOut API manual
\82ð
\8eQ
\8fÆ
2512 sumdx += dx[j] - (rdx[i]-rdx[i-1]);
2513 // DBW("%3d <> %3d", dx[j], rdx[i]-rdx[i-1]);
2515 sumdx += (dx[j]?dx[j]:dx[j+1]) - (rdx[i]-rdx[i-1]);
2518 // DBW("sumdx=%d",sumdx);
2519 if ( !GetTextExtentExPointW( hdc, text, len, pos_x - sumdx, &count, rdx, &sz ) ){
2527 return (count == len && sz.cx < pos_x) ? -1 : count;
2531 char *buf = new char[ len * sizeof(wchar_t) ];
2532 memset( buf, 0, len * sizeof(wchar_t) );
2533 int ansilen = WideCharToMultiByte( CP_ACP, 0, text, len, buf, len*sizeof(wchar_t), NULL, NULL );
2534 int r = GetTextFromPoint( hdc, buf, ansilen, pos_x, pos_y, dx );
2541 #define WMCD_EXISTCHECK 0x4000
2542 #define WMCD_SETPOINT 0x4001
2556 hdc = GetWindowDC(hwnd);
2565 ReleaseDC(hwnd, hdc);
2569 operator HDC() { return hdc; }
2570 bool operator !() { return hdc==NULL; }
2573 bool CaptureImage(HWND hwnd, bool movesend, bool non_block)
2575 MoveSendMode = movesend;
2576 CaptureImageBlocking = false;
2578 bool capture_page = false;
2580 capture_page = SendMessage(hwndAMODI, WM_AMODI, AMODI_CMD_PAGE_CAPTURE, 0) ? true : false;
2583 // Get the rect of the target window.
2585 if (!GetWindowRect(hwnd, &rcTarget)){
2590 if (!IsWindowEnabled(hwndAMODI)){
2592 hwndAMODI = FindAMODI();
2597 int w = rcTarget.right - rcTarget.left;
2598 int h = rcTarget.bottom - rcTarget.top;
2600 return false; // no area in the target.
2603 POINT ptCursor; //
\89æ
\91\9c\8fã
\82Ì
\83J
\81[
\83\
\83\8b\88Ê
\92u
2608 ptCursor.x = ScreenPoint.x - rcTarget.left;
2609 ptCursor.y = ScreenPoint.y - rcTarget.top;
2611 // x
\95û
\8cü : target rect
\82Ì
\8d¶
\92[
\82©
\82ç
2612 // y
\95û
\8cü : cursor point
\82Ì
\8fã
\89º100 pixel
2615 if (ScreenPoint.y - rcTarget.top < offs){
2616 if (ScreenPoint.y < rcTarget.top) return false; // click on out of rect?
2618 h = ScreenPoint.y - rcTarget.top + offs;
2620 y = ScreenPoint.y - offs;
2623 if (y+h>rcTarget.bottom){
2624 h = rcTarget.bottom - y;
2626 ptCursor.x = ScreenPoint.x - rcTarget.left;
2627 ptCursor.y = ScreenPoint.y - y;
2631 HWND hwnd = GetDesktopWindow();
2633 GetWindowRect(hwnd, &rc);
2636 w = rc.right - rc.left;
2637 h = rc.bottom - rc.top;
2641 // Notify start enumrate
2642 CallbackMain(DCH_START, &CursorPoint, sizeof(CursorPoint), hwnd);
2659 pts[2].x = ptCursor.x;
2660 pts[2].y = ptCursor.y;
2661 DoScale(hdc, pts, 3);
2662 //DBW("%d,%d %d,%d,%d,%d -> %d,%d %d,%d,%d,%d", ptCursor.x, ptCursor.y, x, y, w, h, pts[2].x, pts[2].y, pts[0].x, pts[0].y, pts[1].x, pts[1].y);
2667 ptCursor.x = pts[2].x;
2668 ptCursor.y = pts[2].y;
2673 int wlen = (w*3+3)&~3;
2675 /*
\8f\91\82«
\8d\9e\82Ý
\97p
\83o
\83b
\83t
\83@
\82Ì
\83T
\83C
\83Y
\8cv
\8eZ */
2676 DWORD dwFSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + wlen * h;
2678 /*
\83o
\83b
\83t
\83@
\8am
\95Û
\82Æ
\83|
\83C
\83\93\83^
\90Ý
\92è */
2679 LPBYTE lpBuf = (LPBYTE)new char[dwFSize];
2684 LPBITMAPFILEHEADER lpHead = (LPBITMAPFILEHEADER)lpBuf;
2685 LPBITMAPINFOHEADER lpInfo = (LPBITMAPINFOHEADER)(lpBuf+sizeof(BITMAPFILEHEADER));
2686 LPBYTE lpPixel = lpBuf+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
2688 /* 24
\83r
\83b
\83gBMP
\83t
\83@
\83C
\83\8b\82Ì
\83w
\83b
\83_
\8dì
\90¬ */
2689 lpHead->bfType = ('M'<<8) +'B';
2690 lpHead->bfSize = dwFSize;
2691 lpHead->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
2692 lpInfo->biSize = sizeof(BITMAPINFOHEADER);
2693 lpInfo->biWidth = w;
2694 lpInfo->biHeight = h;
2695 lpInfo->biPlanes = 1;
2696 lpInfo->biBitCount = 24;
2698 HBITMAP hBmp = CreateCompatibleBitmap(hdc, w, h);
2700 HDC hdcMem = CreateCompatibleDC(hdc);
2702 HDC hOld = (HDC)SelectObject(hdcMem, hBmp);
2703 if (hOld!=(HDC)GDI_ERROR){
2704 BOOL r = BitBlt(hdcMem, 0, 0, w, h, hdc, x, y, SRCCOPY);
2705 SelectObject(hdcMem, hOld);
2707 // int lines = GetDIBits(hdc, hBmp, 0, h, NULL, (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
2708 int lines = GetDIBits(hdc, hBmp, 0, h, lpPixel, (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS);
2712 dbw("GetDIBits error??? %d h=%d w=%d bfSize=%d", GetLastError(), h, w, dwFSize);
2715 // dbw("BitBlt error??? %d", GetLastError());
2718 DeleteObject(hdcMem);
2728 //TCHAR path[sizeof(AMODIPath)+40];
2729 TCHAR *path = ImageTextPath;
2730 size_t path_size = sizeof(ImageTextPath);
2733 len = _tcslen(AMODIPath);
2734 _tcscpy(path, AMODIPath);
2736 memset(path, 0, path_size);
2737 len = GetTempPath((DWORD)path_size, path);
2740 // send image to AMODI
2744 wsprintf(path+len, /*path_size-len,*/ _T("\\%04d-%02d-%02d-%02d%02d%02d-(%d,%d)-n%d.bmp"),
2745 t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, ptCursor.x, ptCursor.y, NumPrevWords );
2747 wsprintf(path+len, /*path_size-len,*/ _T("\\amodi\\%04d-%02d-%02d-%02d%02d%02d-n%d.bmp"),
2748 t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, NumPrevWords );
2749 SendAMODI(WMCD_SETPOINT, (char*)&ptCursor, sizeof(ptCursor));
2751 HANDLE fh = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2752 if (fh!=INVALID_HANDLE_VALUE){
2754 WriteFile(fh, lpBuf, dwFSize, &dwSize, NULL);
2756 SaveImageTime = GetTickCount();
2761 len = (int)_tcslen(path);
2762 _tcsncat(path+len, _T(".txt"), path_size-len);
2764 CaptureImageBlocking = true;
2766 if (WaitAndGetResult(path, 3000))
2776 if (!CaptureImageBlocking){
2778 CallbackMain(DCH_END | (MoveSendMode ? DCH_MOVESEND : 0), NULL, 0, hwnd );
2785 bool WaitAndGetResult(const TCHAR *path, unsigned waittime)
2789 // wait and get text from AMODI
2791 HANDLE fh = WaitForResult(path, waittime);
2793 CaptureImageBlocking = false;
2795 if (fh==INVALID_HANDLE_VALUE){
2796 DBW("file open timeout");
2799 DWORD size = GetFileSize(fh, NULL);
2801 unsigned bufsize = size+sizeof(wchar_t);
2802 char *text = new char[bufsize];
2805 if (ReadFile(fh, text, size, &rbyte, NULL)){
2807 *(wchar_t*)&text[size] = '\0';
2808 // text
\82Ì
\82P
\8ds
\96Ú
\82Í
\89ð
\90Í
\8fî
\95ñ
2810 // (
\83}
\83E
\83X
\83J
\81[
\83\
\83\8b\82Ì
\82 \82é
\83e
\83L
\83X
\83g
\88Ê
\92u[
\95¶
\8e\9a\96Ú zero-index])
2813 wchar_t *p = (wchar_t*)text;
2822 while (iswdigit(*p)) p++;
2826 DBW("%d:%ws", loc, p);
2827 CallbackMain(DCH_HITTEXT2, p, bufsize - (int)((char*)p-text), (HWND)loc);
2838 CallbackMain(DCH_END | (MoveSendMode ? DCH_MOVESEND : 0), NULL, 0, NULL );
2842 HANDLE WaitForResult(const TCHAR *path, unsigned waittime)
2844 HANDLE fh = INVALID_HANDLE_VALUE;
2847 fh = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
2848 if (fh!=INVALID_HANDLE_VALUE)
2851 DWORD now = GetTickCount();
2852 if (now-SaveImageTime > waittime)
2861 #define APPNAME _T("Auto MODI")
2863 static HWND hwndFind;
2864 static BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam )
2867 if (GetWindowText(hwnd, wndname, tsizeof(wndname))<0){
2870 if (_tcscmp(wndname, APPNAME)){ return TRUE; }
2873 cd.dwData = WMCD_EXISTCHECK;
2874 cd.lpData = (void*)APPNAME;
2875 cd.cbData = (DWORD)(_tcslen(APPNAME)+1)*sizeof(TCHAR);
2876 if ( SendMessage( hwnd, WM_COPYDATA, 0, (LPARAM)&cd ) )
2888 EnumWindows(EnumWindowsProc, 0);
2892 int SendAMODI(int cmd, const char *data, int len)
2896 cd.lpData = (void*)data;
2898 return (int)SendMessage(hwndAMODI, WM_COPYDATA, 0, (LPARAM)&cd);
2901 void CheckAMODIAlive()
2903 CallbackMain(DCH_LAUNCH_AMODI, NULL, 0, 0);
2906 void SendMoveMessage()
2909 PostMessage(hwndCallback, WM_MOVESEND, MouseMoving ? 0 : -1, 0);
2911 // CallbackMain(DCH_MOVESEND, pt, sizeof(*pt), 0);
2913 if (SendMoveEvent) SetEvent(SendMoveEvent);
2916 void SendCancelMove()
2919 PostMessage(hwndCallback, WM_MOVESEND, MouseMoving ? 0 : -1, 0);
2921 // CallbackMain(DCH_MOVESEND, NULL, 0, (HWND)-1);
2922 MouseMoving = false;
2923 if (SendMoveEvent) SetEvent(SendMoveEvent);
2928 // main program
\82ÌWindows message
\8f\88\97\9d\82ª
\8fd
\82¢
\82Æ
\81ACalblackMain
\82à
\8fd
\82
\82È
\82é
\82½
\82ß
\81A
2929 // mouse move
\82Í
\95Êthread
\82Å
\8f\88\97\9d
2930 DWORD WINAPI SendMoveThread(LPVOID vdParam)
2933 if (WaitForSingleObject(SendMoveEvent, INFINITE) != WAIT_OBJECT_0){
2936 CallbackMain(DCH_MOVESEND, NULL, 0, (HWND)(MouseMoving ? 0 : -1));
2942 #if EXC_WOW64 && defined(_M_X64)
2945 typedef BOOL (WINAPI *FNIsWow64Process)(HANDLE hProcess, PBOOL Wow64Process);
2947 FNIsWow64Process _IsWow64Process = (FNIsWow64Process)GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process");
2948 if (_IsWow64Process){
2950 if (_IsWow64Process(hProcess, &flag)){
2951 fWow64 = int_bool(flag);
2957 bool EnablePrivilege(LPTSTR lpszPrivilege, bool bEnable)
2962 TOKEN_PRIVILEGES tokenPrivileges;
2964 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
2967 if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid)) {
2968 CloseHandle(hToken);
2972 tokenPrivileges.PrivilegeCount = 1;
2973 tokenPrivileges.Privileges[0].Luid = luid;
2974 tokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
2976 bResult = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
2978 CloseHandle(hToken);
2980 return bResult && GetLastError() == ERROR_SUCCESS;
2983 /*======================================================================//
2985 //----------------------------------------------------------------------//
2992 //======================================================================*/
2994 BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID )
2996 int WINAPI DllEntryPoint(HINSTANCE hInst, DWORD reason, LPVOID)
3000 case DLL_PROCESS_ATTACH:
3002 idProcess = GetCurrentProcessId();
3003 for (int i=0;i<2;i++){
3004 hProcess = OpenProcess( PROCESS_ALL_ACCESS|PROCESS_VM_WRITE|PROCESS_VM_OPERATION, TRUE, idProcess );
3007 DBW("Attach %d(%08X)-%d : %08X", idProcess, hProcess, attach++,_ExtTextOutA);
3011 DBW("OpenProcess Error: %08X %d", idProcess, GetLastError());
3013 if (!EnablePrivilege(SE_DEBUG_NAME, true)) {
3019 #if EXC_WOW64 && defined(_M_X64)
3032 DBW("fWow64=%d", fWow64);
3036 GetSystemInfo( &si );
3037 siPageSize = si.dwPageSize;
3039 hInstSHCore = LoadLibrary(_T("shcore.dll"));
3041 SendMoveEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
3042 CreateThread(NULL , 0 , SendMoveThread , NULL , 0 , &SendMoveThreadId);
3045 case DLL_PROCESS_DETACH:
3046 // UNPROTECT_SHARE();
3049 CloseHandle(SendMoveEvent);
3050 SendMoveEvent = NULL;
3054 FreeLibrary(hInstSHCore);
3058 DBW("Detach %d-%d", GetCurrentProcessId(),--attach);
3061 CloseHandle( hProcess );
3067 //---------------------------------------------------------------------------
3068 static HWND hWin = NULL;
3069 static const char *clsname = "TDbgMsgForm";
3070 static const char *winname = "Debug Messenger";
3071 void dbw( const char *format, ... )
3074 hWin = FindWindowA( clsname, winname );
3075 if ( !hWin ) return;
3078 va_start( ap, format );
3081 strcpy(buf, "x64:");
3082 wvsprintfA( buf+4, format, ap );
3084 wvsprintfA( buf, format, ap );
3087 cds.dwData = 1; // Indicate String
3088 cds.cbData = (DWORD)strlen(buf);
3090 SendMessage( hWin, WM_COPYDATA, NULL, (LPARAM)&cds );