From 604bbdbb47d898210fdb1b5b496b9bf55d27751d Mon Sep 17 00:00:00 2001 From: tnishi Date: Thu, 27 Oct 2016 23:00:32 +0900 Subject: [PATCH] first commit --- DCHook/DCHook.6.0.sln | 25 + DCHook/DCHook.7.1.vcproj | 142 ++ DCHook/DCHook.cpp | 3069 ++++++++++++++++++++++++++ DCHook/DCHook.def | 16 + DCHook/DCHook.h | 67 + DCHook/DCHook.mak | 100 + DCHook/DCHook.sln | 25 + DCHook/DCHook.vcproj | 376 ++++ DCHook/DCHook.vcxproj | 167 ++ DCHook/DCHook.vcxproj.filters | 35 + DCHook/MonitorScale.cpp | 270 +++ DCHook/MonitorScale.h | 6 + DCHook/VS2003/DCHook.sln | 21 + DCHook/VS2003/DCHook.vcproj | 145 ++ DCHook/VS2008/DCHook.sln | 26 + DCHook/VS2008/DCHook.vcproj | 359 +++ DCHook/VS2015/DCHook.sln | 28 + DCHook/VS2015/DCHook.vcxproj | 158 ++ DCHook/VS2015/DCHook.vcxproj.filters | 30 + DCHook/dchook.rc | 0 DCHook64/DCHook64.h | 38 + DCHook64/dchk64/ReadMe.txt | 69 + DCHook64/dchk64/Resource.h | 31 + DCHook64/dchk64/dchk64.cpp | 336 +++ DCHook64/dchk64/dchk64.h | 3 + DCHook64/dchk64/dchk64.ico | Bin 0 -> 23558 bytes DCHook64/dchk64/dchk64.rc | Bin 0 -> 5392 bytes DCHook64/dchk64/dchk64.sln | 26 + DCHook64/dchk64/dchk64.suo | Bin 0 -> 11264 bytes DCHook64/dchk64/dchk64.vcxproj | 162 ++ DCHook64/dchk64/dchk64.vcxproj.filters | 56 + DCHook64/dchk64/small.ico | Bin 0 -> 23558 bytes DCHook64/dchk64/stdafx.cpp | 8 + DCHook64/dchk64/stdafx.h | 21 + DCHook64/dchk64/targetver.h | 8 + DCHookTest/DCHookLoader.cpp | 292 +++ DCHookTest/DCHookLoader.h | 96 + DCHookTest/DCHookMain.cpp | 1680 ++++++++++++++ DCHookTest/DCHookMain.dfm | 2741 +++++++++++++++++++++++ DCHookTest/DCHookMain.h | 197 ++ DCHookTest/DCHookTest.bpr | 634 ++++++ DCHookTest/DCHookTest.cpp | 67 + DCHookTest/DCHookTest.dfm | Bin 0 -> 468 bytes DCHookTest/DCHookTest.h | 27 + DCHookTest/DCHookTest.mak | 184 ++ DCHookTest/DCHookTest.rc | 1 + DCHookTest/DCHookTest.res | Bin 0 -> 2040 bytes DCHookTest/DKPU.txt | 208 ++ DCHookTest/HookDLl.cpp | 4 + DCHookTest/HookDLl.h | 22 + DCHookTest/HookLoader.cpp | 294 +++ DCHookTest/HookLoader.h | 91 + DCHookTest/MODINotifyDlg.cpp | 102 + DCHookTest/MODINotifyDlg.dfm | 44 + DCHookTest/MODINotifyDlg.h | 37 + DCHookTest/Notify.cpp | 66 + DCHookTest/Notify.dfm | 1211 ++++++++++ DCHookTest/Notify.h | 33 + DCHookTest/OCRTextFrm.cpp | 46 + DCHookTest/OCRTextFrm.dfm | 27 + DCHookTest/OCRTextFrm.h | 26 + DCHookTest/PopupConfig.cpp | 228 ++ DCHookTest/PopupConfig.dfm | 331 +++ DCHookTest/PopupConfig.h | 82 + DCHookTest/StringLib.cpp | 243 ++ DCHookTest/StringLib.h | 74 + DCHookTest/Util.cpp | 690 ++++++ DCHookTest/Util.h | 118 + DCHookTest/cpd.bat | 3 + DCHookTest/dkpp.bmp | Bin 0 -> 78394 bytes DCHookTest/dkpp.ico | Bin 0 -> 1078 bytes DCHookTest/dkpp0.ico | Bin 0 -> 1078 bytes DCHookTest/dkpp2.bmp | Bin 0 -> 80066 bytes DCHookTest/dkpp3.bmp | Bin 0 -> 83574 bytes DCHookTest/dkpp4.bmp | Bin 0 -> 63938 bytes DCHookTest/dkpps.ico | Bin 0 -> 318 bytes DCHookTest/dkpps0.ico | Bin 0 -> 318 bytes DCHookTest/icon.rc | 2 + DCHookTest/icon.res | Bin 0 -> 412 bytes DCHookTest/mustr.cpp | 54 + DCHookTest/mustr.h | 32 + DCHookTest/obj/icon.res | Bin 0 -> 412 bytes DCHookTest/popdisable.bmp | Bin 0 -> 18774 bytes DCHookTest/popdisable.h | 40 + DCHookTest/popenable.bmp | Bin 0 -> 18776 bytes DCHookTest/popenable.h | 28 + DCHookTest/prgconfig.cpp | 9 + DCHookTest/prgconfig.h | 9 + DCHookTest/prgprof.cpp | 10 + DCHookTest/prgprof.h | 37 + DCHookTest/stdafx.h | 0 DKPP.TXT | 213 ++ DKPPu.TXT | 41 + DKPU.TXT | 190 ++ DKPUu.TXT | 34 + Diary.txt | 280 +++ ExMODIst/ExMODIst.bpf | 5 + ExMODIst/ExMODIst.bpr | 114 + ExMODIst/ExMODIst.cpp | 46 + ExMODIst/ExMODIst.h | 3 + ExMODIst/ExMODIst.rc | 69 + ExMODIst/ExMODIst.sln | 20 + ExMODIst/ExMODIst.vcproj | 239 ++ ExMODIst/ExMODIst.vcxproj | 107 + ExMODIst/ExMODIst.vcxproj.filters | 47 + ExMODIst/ReadMe.txt | 2 + ExMODIst/Resource.h | 17 + ExMODIst/main.cpp | 123 ++ ExMODIst/stdafx.cpp | 8 + ExMODIst/stdafx.h | 14 + ExMODIst/targetver.h | 24 + ExMODIstBCC/ExMODIst.bpf | 5 + ExMODIstBCC/ExMODIst.bpr | 114 + ExMODIstBCC/main.cpp | 39 + MK.BAT | 80 + MKU.BAT | 74 + Makefile | 39 + README.TXT | 334 +++ VxD/hk95c.c | 164 ++ VxD/hk95d.asm | 120 + VxD/hk95d.def | 24 + VxD/hk95d.h | 12 + VxD/makefile | 70 + amodi/amodi.sln | 18 + amodi/amodi/MainForm.Designer.cs | 204 ++ amodi/amodi/MainForm.cs | 403 ++++ amodi/amodi/MainForm.resx | 123 ++ amodi/amodi/Program.cs | 35 + amodi/amodi/Properties/AssemblyInfo.cs | 36 + amodi/amodi/Properties/Resources.Designer.cs | 63 + amodi/amodi/Properties/Resources.resx | 117 + amodi/amodi/Properties/Settings.Designer.cs | 26 + amodi/amodi/Properties/Settings.settings | 7 + amodi/amodi/amodi.csproj | 106 + amodi/amodi/app.config | 3 + amodi/readme.txt | 16 + change_iss.pl | 46 + cpr.bat | 3 + dchook.ind | 232 ++ dchook.tpl | 678 ++++++ dchooku.ind | 232 ++ dchooku.tpl | 377 ++++ mktpl.bat | 2 + mktplu.bat | 2 + 144 files changed, 21343 insertions(+) create mode 100644 DCHook/DCHook.6.0.sln create mode 100644 DCHook/DCHook.7.1.vcproj create mode 100644 DCHook/DCHook.cpp create mode 100644 DCHook/DCHook.def create mode 100644 DCHook/DCHook.h create mode 100644 DCHook/DCHook.mak create mode 100644 DCHook/DCHook.sln create mode 100644 DCHook/DCHook.vcproj create mode 100644 DCHook/DCHook.vcxproj create mode 100644 DCHook/DCHook.vcxproj.filters create mode 100644 DCHook/MonitorScale.cpp create mode 100644 DCHook/MonitorScale.h create mode 100644 DCHook/VS2003/DCHook.sln create mode 100644 DCHook/VS2003/DCHook.vcproj create mode 100644 DCHook/VS2008/DCHook.sln create mode 100644 DCHook/VS2008/DCHook.vcproj create mode 100644 DCHook/VS2015/DCHook.sln create mode 100644 DCHook/VS2015/DCHook.vcxproj create mode 100644 DCHook/VS2015/DCHook.vcxproj.filters create mode 100644 DCHook/dchook.rc create mode 100644 DCHook64/DCHook64.h create mode 100644 DCHook64/dchk64/ReadMe.txt create mode 100644 DCHook64/dchk64/Resource.h create mode 100644 DCHook64/dchk64/dchk64.cpp create mode 100644 DCHook64/dchk64/dchk64.h create mode 100644 DCHook64/dchk64/dchk64.ico create mode 100644 DCHook64/dchk64/dchk64.rc create mode 100644 DCHook64/dchk64/dchk64.sln create mode 100644 DCHook64/dchk64/dchk64.suo create mode 100644 DCHook64/dchk64/dchk64.vcxproj create mode 100644 DCHook64/dchk64/dchk64.vcxproj.filters create mode 100644 DCHook64/dchk64/small.ico create mode 100644 DCHook64/dchk64/stdafx.cpp create mode 100644 DCHook64/dchk64/stdafx.h create mode 100644 DCHook64/dchk64/targetver.h create mode 100644 DCHookTest/DCHookLoader.cpp create mode 100644 DCHookTest/DCHookLoader.h create mode 100644 DCHookTest/DCHookMain.cpp create mode 100644 DCHookTest/DCHookMain.dfm create mode 100644 DCHookTest/DCHookMain.h create mode 100644 DCHookTest/DCHookTest.bpr create mode 100644 DCHookTest/DCHookTest.cpp create mode 100644 DCHookTest/DCHookTest.dfm create mode 100644 DCHookTest/DCHookTest.h create mode 100644 DCHookTest/DCHookTest.mak create mode 100644 DCHookTest/DCHookTest.rc create mode 100644 DCHookTest/DCHookTest.res create mode 100644 DCHookTest/DKPU.txt create mode 100644 DCHookTest/HookDLl.cpp create mode 100644 DCHookTest/HookDLl.h create mode 100644 DCHookTest/HookLoader.cpp create mode 100644 DCHookTest/HookLoader.h create mode 100644 DCHookTest/MODINotifyDlg.cpp create mode 100644 DCHookTest/MODINotifyDlg.dfm create mode 100644 DCHookTest/MODINotifyDlg.h create mode 100644 DCHookTest/Notify.cpp create mode 100644 DCHookTest/Notify.dfm create mode 100644 DCHookTest/Notify.h create mode 100644 DCHookTest/OCRTextFrm.cpp create mode 100644 DCHookTest/OCRTextFrm.dfm create mode 100644 DCHookTest/OCRTextFrm.h create mode 100644 DCHookTest/PopupConfig.cpp create mode 100644 DCHookTest/PopupConfig.dfm create mode 100644 DCHookTest/PopupConfig.h create mode 100644 DCHookTest/StringLib.cpp create mode 100644 DCHookTest/StringLib.h create mode 100644 DCHookTest/Util.cpp create mode 100644 DCHookTest/Util.h create mode 100644 DCHookTest/cpd.bat create mode 100644 DCHookTest/dkpp.bmp create mode 100644 DCHookTest/dkpp.ico create mode 100644 DCHookTest/dkpp0.ico create mode 100644 DCHookTest/dkpp2.bmp create mode 100644 DCHookTest/dkpp3.bmp create mode 100644 DCHookTest/dkpp4.bmp create mode 100644 DCHookTest/dkpps.ico create mode 100644 DCHookTest/dkpps0.ico create mode 100644 DCHookTest/icon.rc create mode 100644 DCHookTest/icon.res create mode 100644 DCHookTest/mustr.cpp create mode 100644 DCHookTest/mustr.h create mode 100644 DCHookTest/obj/icon.res create mode 100644 DCHookTest/popdisable.bmp create mode 100644 DCHookTest/popdisable.h create mode 100644 DCHookTest/popenable.bmp create mode 100644 DCHookTest/popenable.h create mode 100644 DCHookTest/prgconfig.cpp create mode 100644 DCHookTest/prgconfig.h create mode 100644 DCHookTest/prgprof.cpp create mode 100644 DCHookTest/prgprof.h create mode 100644 DCHookTest/stdafx.h create mode 100644 DKPP.TXT create mode 100644 DKPPu.TXT create mode 100644 DKPU.TXT create mode 100644 DKPUu.TXT create mode 100644 Diary.txt create mode 100644 ExMODIst/ExMODIst.bpf create mode 100644 ExMODIst/ExMODIst.bpr create mode 100644 ExMODIst/ExMODIst.cpp create mode 100644 ExMODIst/ExMODIst.h create mode 100644 ExMODIst/ExMODIst.rc create mode 100644 ExMODIst/ExMODIst.sln create mode 100644 ExMODIst/ExMODIst.vcproj create mode 100644 ExMODIst/ExMODIst.vcxproj create mode 100644 ExMODIst/ExMODIst.vcxproj.filters create mode 100644 ExMODIst/ReadMe.txt create mode 100644 ExMODIst/Resource.h create mode 100644 ExMODIst/main.cpp create mode 100644 ExMODIst/stdafx.cpp create mode 100644 ExMODIst/stdafx.h create mode 100644 ExMODIst/targetver.h create mode 100644 ExMODIstBCC/ExMODIst.bpf create mode 100644 ExMODIstBCC/ExMODIst.bpr create mode 100644 ExMODIstBCC/main.cpp create mode 100644 MK.BAT create mode 100644 MKU.BAT create mode 100644 Makefile create mode 100644 README.TXT create mode 100644 VxD/hk95c.c create mode 100644 VxD/hk95d.asm create mode 100644 VxD/hk95d.def create mode 100644 VxD/hk95d.h create mode 100644 VxD/makefile create mode 100644 amodi/amodi.sln create mode 100644 amodi/amodi/MainForm.Designer.cs create mode 100644 amodi/amodi/MainForm.cs create mode 100644 amodi/amodi/MainForm.resx create mode 100644 amodi/amodi/Program.cs create mode 100644 amodi/amodi/Properties/AssemblyInfo.cs create mode 100644 amodi/amodi/Properties/Resources.Designer.cs create mode 100644 amodi/amodi/Properties/Resources.resx create mode 100644 amodi/amodi/Properties/Settings.Designer.cs create mode 100644 amodi/amodi/Properties/Settings.settings create mode 100644 amodi/amodi/amodi.csproj create mode 100644 amodi/amodi/app.config create mode 100644 amodi/readme.txt create mode 100644 change_iss.pl create mode 100644 cpr.bat create mode 100644 dchook.ind create mode 100644 dchook.tpl create mode 100644 dchooku.ind create mode 100644 dchooku.tpl create mode 100644 mktpl.bat create mode 100644 mktplu.bat diff --git a/DCHook/DCHook.6.0.sln b/DCHook/DCHook.6.0.sln new file mode 100644 index 0000000..22d6daf --- /dev/null +++ b/DCHook/DCHook.6.0.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DCHook", "DCHook.vcproj", "{8C65CE15-64F8-43E6-968D-DBBB96858BB2}" +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 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug|Win32.ActiveCfg = Debug|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug|Win32.Build.0 = Debug|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug|x64.ActiveCfg = Debug|x64 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug|x64.Build.0 = Debug|x64 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release|Win32.ActiveCfg = Release|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release|Win32.Build.0 = Release|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release|x64.ActiveCfg = Release|x64 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DCHook/DCHook.7.1.vcproj b/DCHook/DCHook.7.1.vcproj new file mode 100644 index 0000000..c6c4c8c --- /dev/null +++ b/DCHook/DCHook.7.1.vcproj @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DCHook/DCHook.cpp b/DCHook/DCHook.cpp new file mode 100644 index 0000000..03bd3c8 --- /dev/null +++ b/DCHook/DCHook.cpp @@ -0,0 +1,3069 @@ +//--------------------------------------------------------------------------- +// +// –â‘è“_F +// Ver0.50 +// +// Å“K‰»‚̉ۑèF +// standard library‚ðŽg‚í‚È‚¢‚悤‚É‚·‚é +// ‹¤—L—̈æ‚𑝂₷ +// +// Tips: +// “Ë‘RDetach‚³‚ê‚錻Û +// --> Hook Function‚Å—áŠO‚ª”­¶‚µ‚Ä‚¢‚é‰Â”\«‚ª‚‚¢ +// ‚à‚µ‚­‚́AƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚Å—áŠO”­¶‚µ‚Ä‚¢‚é +// ‹¤—Lƒƒ‚ƒŠ‚ɂ‚¢‚Ä +// •¨—ƒƒ‚ƒŠ‚ª“¯ˆê‚¾‚¯‚Å‚ ‚Á‚āA˜_—ƒAƒhƒŒƒX‚Í“¯ˆê‚Æ‚ÍŒÀ‚ç‚È‚¢II +// ]‚Á‚āA‹¤—Lƒƒ‚ƒŠã‚Épointer‚ð”z’u‚·‚邱‚Æ‚ÍŠî–{“I‚Ɋ댯II +#define STRICT +#include +#include +#pragma hdrstop +#ifndef GWL_WNDPROC +#define GWL_WNDPROC (-4) // ‚±‚Ì’è‹`‚ª‚È‚¢‚Æerror‚É‚È‚Á‚½ 2014.11.19 +#endif +#include +#include +#pragma comment(lib, "ImageHlp") +#include "DCHook.h" +#ifndef UNICODE +#include "..\VxD\hk95d.h" +#endif +#include "MonitorScale.h" + +// Compiler // +#pragma warning( disable : 4710 ) // ‚Ç‚¤‚µ‚Ä‚±‚¤‚¢‚¤warning‚ªo‚Ä‚­‚é‚Ì‚©H + +// Configuration // +#define USE_SCALING 1 // Uses DPI scaling + +#define USE_DBW 1 // DBW‚ðŽg—p‚·‚é +#define USE_SHARE0 1 // share‚µ‚Ä‚à–â‘è‚È‚¢•Ï” + +#define METAEXTTEXTOUT 1 // MetaMethod‚ÅExtTextOutx‚ðhook‚·‚é +#define HOOK_GETDC 0 // GetDC(),ReleaseDC()‚ðhook‚·‚é +#define HOOK_TEXT 0 // DrawText(Ex),TextOut,TabbedTextOut‚Ìhooking +#define USE_REDRAW 1 +#define HOOK_BITBLT 0 // 2016.1.15 ŠO‚µ‚Ä‚Ý‚½ +#define HOOK_PAINT 0 +#define GUARD 0 // ‹¤—Lƒƒ‚ƒŠ‚ðVirtualProtect‚Åguard‚·‚é + // —LŒø‚É‚·‚é‚ÆApplicationI—¹Žž‚ɈُíI—¹‚ª”­¶‚·‚é + // Application close -> + // Œ´ˆöFDettach‚·‚é‘O‚ɁAOS or Application‚ª + // Protected code—̈æ‚ɏ‘‚«ž‚Ý‚ðs‚Á‚Ä‚¢‚é‚悤‚¾ + +#define USE_INVALIDATE 0 // •`‰æ‘O‚ÉInvalidate‚ð‘—‚é(IE5@Win98‚Í•K—v) +#define INVALIDATE_TRUE 0 // InvalidateRect‚Årepaint‚ðs‚¤ +#define ORG_OFFSET 1 // ViewPort‚Ìorg offsetˆ—‚ðs‚¤ + +#define USE_OPTIMALINVALID 1 // Ä•`‰æ—̈æ‚ð‚È‚é‚ׂ­¬‚³‚­‚·‚é +#define USE_VXD 0 // no longer support (Win9x) +#define EXC_WOW64 0 // do not attach on WOW64 + +#define MAX_KEYS 8 // ƒL[ƒtƒ‰ƒO‚̍őå’è‹`” + +#define DEBUG_HITTEXT 0 // for debug hit text + +// ExtTextOut hooking‚ÅMetafile‚àŽg—p‚·‚é +// ’P“Ƃōs‚¤ê‡‚́ARETRYMETA +#if HOOK_PAINT || HOOK_GETDC || !USE_REDRAW +#define USE_META 1 +#else +#define USE_META 0 +#endif + +#define RETRYMETA 1 + +#if USE_DBW +#include +#else // !USE_DBW +#undef DEBUG_HITTEXT +#define DEBUG_HITTEXT 0 +#endif // !USE_DBW + +#define MOVESEND_POST 1 + +// Type Definitions // + +// Macros // +#if GUARD +#define PROTECT_SHARE() ShareProtect( true ) +#define UNPROTECT_SHARE() ShareProtect( false ) +#else +#define PROTECT_SHARE() +#define UNPROTECT_SHARE() +#endif + +#if USE_DBW +#define DBW dbw +#else +#define DBW (void) +#endif +void dbw(const char *format, ...); + +#define WM_AMODI (WM_APP+0x400) // app communication message with AMODI +#define WM_MOVESEND (WM_APP+0x208) // DCH_MOVESEND‚Ì‘ã‚í‚è‚ÉPostMessage‚Å‘—‚é +#define AMODI_CMD_QUERY 0 +#define AMODI_CMD_PAGE_CAPTURE 1 + +#define tsizeof(type) sizeof(type) +#define int_bool(v) ((v)!=0) + +#pragma warning (disable : 4996) + +//==============================================// +// TString template class // +//==============================================// +template +class TString { +protected: + T *Buffer; + int Size; // Buffer size in character + int Length; // String length in character +public: + TString(); + ~TString(); + void Clear() + { Buffer[0] = '\0'; Length = 0; } + void Set( const T *str, int len ); + void Set( TString *obj ) + { Set( obj->c_str(), obj->Length ); } + void Cat( const T *str, int len ); + operator const T *() const + { return Buffer; } + T operator [] ( int index ) + { return Buffer[index]; } + const T *c_str() + { return Buffer; } + int GetLength() const { return Length; } + int GetByte() const { return Length * sizeof(T); } +// int GetSize() const { return Size; } +}; +template +TString::TString() +{ + Size = 256; // initial size + Buffer = new T[ Size + 1 ]; + if (!Buffer) + Size = 0; + Length = 0; +} +template +TString::~TString() +{ + if (Buffer) + delete[] Buffer; +} +template +void TString::Set( const T *str, int len ) +{ + if (Buffer){ + if ( Size < len ){ + // not enough space to store + delete[] Buffer; + } else goto j1; + } + Buffer = new T[ len + 1 ]; + Size = len; + if (Buffer){ +j1:; + CopyMemory( Buffer, str, len*sizeof(T) ); + Buffer[len] = '\0'; + Length = len; + } else { + Size = 0; + Length = 0; + } +} +template +void TString::Cat( const T *str, int len ) +{ + if (!Buffer){ + Set( str, len ); + return; + } + int newlen = Length + len; + if (Size < newlen){ + T *p = new T[ newlen + 1 ]; + if (p) + CopyMemory( p, Buffer, newlen*sizeof(T) ); + delete[] Buffer; + Buffer = p; + Size = newlen; + } + if (Buffer){ + CopyMemory( Buffer+Length, str, len * sizeof(T) ); + Buffer[newlen] = '\0'; + Length = newlen; + } else { + Size = 0; + Length = 0; + Set( str, len ); + } +} + +int GetTextFromPoint( HDC hdc, const char *text, int len, int pos, int pos_y, const int *dx=NULL ); +int GetTextFromPoint( HDC hdc, const wchar_t *text, int len, int pos, int pos_y, const int *dx=NULL ); + +bool CaptureImage(HWND hwnd, bool movesend, bool non_block); +bool WaitAndGetResult(const TCHAR *text_path, unsigned waittime); +HANDLE WaitForResult(const TCHAR *text_path, unsigned waittime); +HWND FindAMODI(); +int SendAMODI(int cmd, const char *data, int len); +void CheckAMODIAlive(); +void SendMoveMessage(); +void SendCancelMove(); +DWORD WINAPI SendMoveThread(LPVOID vdParam); +void CheckWOW64(); + +extern "C" { +//==============================================// +// Prototypes // +//==============================================// +typedef HDC (WINAPI *FNBeginPaint)( HWND, LPPAINTSTRUCT ); +typedef BOOL (WINAPI *FNEndPaint)( HWND, CONST PAINTSTRUCT * ); +typedef HDC (WINAPI *FNGetDC)( HWND ); +typedef int (WINAPI *FNReleaseDC)( HWND, HDC ); +typedef BOOL (WINAPI *FNExtTextOutW)(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCWSTR str, UINT count, CONST INT *dx ); +typedef BOOL (WINAPI *FNExtTextOutA)(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCSTR str, UINT count, CONST INT *dx ); +typedef BOOL (WINAPI *FNBitBlt)(HDC hdcdest, int xdest, int ydest, int width, int height, HDC hdcsrc, int xsrc, int ysrc, DWORD rop ); + +typedef LONG (WINAPI *FNTabbedTextOutA)( HDC hdc, int x, int y, LPCSTR str, int count, int ntabs, LPINT tabs, int origin ); +typedef LONG (WINAPI *FNTabbedTextOutW)( HDC hdc, int x, int y, LPCWSTR str, int count, int ntabs, LPINT tabs, int origin ); +typedef BOOL (WINAPI *FNTextOutA)( HDC hdc, int x, int y, LPCSTR str, int count ); +typedef BOOL (WINAPI *FNTextOutW)( HDC hdc, int x, int y, LPCWSTR str, int count ); +typedef int (WINAPI *FNDrawTextA)( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format ); +typedef int (WINAPI *FNDrawTextW)( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format ); +typedef int (WINAPI *FNDrawTextExA)( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params ); +typedef int (WINAPI *FNDrawTextExW)( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params ); + +typedef BOOL (WINAPI *FNMoveToEx)(HDC hdc, int x, int y, LPPOINT pt ); + + +HDC WINAPI _BeginPaint( HWND hwnd, LPPAINTSTRUCT ps ); +BOOL WINAPI _EndPaint( HWND hwnd, CONST PAINTSTRUCT *ps ); +HDC WINAPI _GetDC( HWND hwnd ); +int WINAPI _ReleaseDC( HWND hwnd, HDC hdc ); +BOOL WINAPI _ExtTextOutA(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCSTR str, UINT count, CONST INT *dx ); +BOOL WINAPI _ExtTextOutW(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCWSTR str, UINT count, CONST INT *dx ); +BOOL WINAPI _BitBlt(HDC hdcdest, int xdest, int ydest, int width, int height, HDC hdcsrc, int xsrc, int ysrc, DWORD rop ); + +LONG WINAPI _TabbedTextOutA( HDC hdc, int x, int y, LPCSTR str, int count, int ntabs, LPINT tabs, int origin ); +LONG WINAPI _TabbedTextOutW( HDC hdc, int x, int y, LPCWSTR str, int count, int ntabs, LPINT tabs, int origin ); +BOOL WINAPI _TextOutA( HDC hdc, int x, int y, LPCSTR str, int count ); +BOOL WINAPI _TextOutW( HDC hdc, int x, int y, LPCWSTR str, int count ); +int WINAPI _DrawTextA( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format ); +int WINAPI _DrawTextW( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format ); +int WINAPI _DrawTextExA( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params ); +int WINAPI _DrawTextExW( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params ); + +BOOL WINAPI _MoveToEx( HDC hdc, int x, int y, LPPOINT pt ); + +void ShareProtect( bool f ); +DWORD SetWriteProtect( LPVOID addr, bool f ); +bool ChangeMemory( void *dst, const void *src, unsigned size ); +bool LoadVxD(); +void UnloadVxD(); + +static HMODULE ModuleFromAddress(PVOID pv); + +// Prototypes for PSAPI.DLL // +typedef BOOL (WINAPI *FNEnumProcessModules)( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); +typedef DWORD (WINAPI *FNGetModuleFileNameExA)( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); +typedef HANDLE (WINAPI *FNCreateToolhelp32Snapshot)( DWORD dwFlags, DWORD th32ProcessID ); +typedef BOOL (WINAPI *FNModule32First)( HANDLE hSnapshot, LPMODULEENTRY32 lpme ); +typedef BOOL (WINAPI *FNModule32Next)( HANDLE hSnapshot, LPMODULEENTRY32 lpme ); + + +LRESULT CALLBACK MouseProc( int code, WPARAM wParam, LPARAM lParam ); +LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam ); +bool CaptureText( HWND hwnd, bool movesend ); +bool DoCapture(HWND hwnd, POINT pt, bool movesend, bool image_only=false, bool runOnLaunchedProc=false, bool nonBlock=false); +void DokoPopMenu( HWND hwnd ); +void ToggleClick( HWND hwnd ); +int CALLBACK EnumMetaFileProc( HDC hdc, HANDLETABLE *, CONST ENHMETARECORD *mfr, int nobj, LPARAM user ); + +//__declspec(dllexport) +BOOL WINAPI _ExtTextOutA(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCSTR str, UINT count, CONST INT *dx ); + +#if METAEXTTEXTOUT +void ExtTextOutHit(); +#endif + +void DoScale(HDC hdc, POINT *pts, int num); + +// Prototypes for High DPI // +typedef enum _PROCESS_DPI_AWARENESS { + Process_DPI_Unaware = 0, + Process_System_DPI_Aware = 1, + Process_Per_Monitor_DPI_Aware = 2 +} PROCESS_DPI_AWARENESS; + +typedef HRESULT (WINAPI *FNGetProcessDPIAwareness)(HANDLE hprocess, PROCESS_DPI_AWARENESS *value); +typedef HRESULT (WINAPI *FNSetProcessDPIAwareness)(PROCESS_DPI_AWARENESS value); + +//==============================================// +// Shared Section // +//==============================================// +#pragma data_seg(".sdata") +#pragma bss_seg( ".sbss" ) +HWND hwndCallback = NULL; +#if USE_VXD +char VxDpathName[256]; // HK95.vxd path +#endif +DWORD siPageSize = 0; +HWND hwndOrg = NULL; +HWND hwndAMODI = NULL; +bool OnlyAMODI = false; +bool tryAMODI = false; +bool MoveSend = false; +#if USE_DBW +int attach = 0; +#endif +#if USE_VXD +bool WindowsNT; +#else +const bool WindowsNT = true; +#endif +bool Initialized = false; // Whether this module initialized or not +DWORD idDokopopProcess; // DKPP.EXE process ID +HHOOK hMouseHook; // Windows Hook Handle for mouse +bool ClickOnlyEnabled = false; + +struct TKeyConfig { + unsigned char Action; + int Flag; +}; + +TKeyConfig KeyConfig[MAX_KEYS] = { + { KA_POPUP, KF_CONTROL }, // Ctrl+click + { KA_POPUP_NC, KF_CLICKONLY }, // click‚¾‚¯‚Åpopup(DO NOT CHANGE) +// { KA_MENU, KF_CONTROL | KF_MENU }, // dokopop menu +// { KA_MENU, KF_CONTROL | KF_MENU | KF_CLICKONLY }, // dokopop menu + { KA_TOGGLE, KF_CONTROL | KF_MENU }, // dokopop menu + { 0, 0 } +}; + +bool fWow64 = false; + +POINT CursorPoint; // Client area coordinate // +POINT ScreenPoint; // Screen coordinate // +POINT PrevCursorPoint; +HWND hwndLast = NULL; +DWORD PrevMoveTime = 0; +bool MoveSent = true; +bool OnlyImage = false; + +bool MouseMoving; + +RECT rcClient; +RECT rcInvalid; +RECT rcOrgInvalid; // Ä•`‰æ‘O‚Éinvalid‚¾‚Á‚½—̈æ +bool HitFound; +bool RButtonUpCancel = false; // ŽŸ‚ÌRButtonUp‚Í”jŠü‚·‚é +bool LButtonUpCancel = false; // ŽŸ‚ÌLButtonUp‚Í”jŠü‚·‚é +bool MButtonUpCancel = false; // ŽŸ‚ÌMButtonUp‚Í”jŠü‚·‚é +bool LButtonDown = false; +bool MButtonDown = false; + +HINSTANCE hPSAPI; // handle of PSAPI.DLL(NT only) +FNEnumProcessModules fnEnumProcessModules; +FNGetModuleFileNameExA fnGetModuleFileNameExA; +FNCreateToolhelp32Snapshot fnCreateToolhelp32Snapshot; +FNModule32First fnModule32First; +FNModule32Next fnModule32Next; + +#if USE_META || RETRYMETA +HDC OrgHDC; +HDC hdcMeta; +#endif +HDC hdcExtTextOut; +#if HOOK_GETDC +HDC OrgGetDC; +#endif + +int BitBltCount; // Œ»Ý‚ÌBitBlt‰ñ” +int ExtTextOutCount; // Œ»Ý‚ÌBand“à‚ÌExtTextOut‰ñ”(A/W‚Æ‚à) +int TargetBitBltCount; // ŒŸ¸‘ΏۂÌBitBlt(‰‰ñ•`‰æŒã‚É”»’è) +POINT TargetOffset; // ŒŸ¸‘ΏۂÌBitBlt‚Ì•`‰æƒIƒtƒZƒbƒg(‰‰ñ•`‰æŒã‚É”»’è) +bool RetryPhase; + +#if METAEXTTEXTOUT +// hit text information +TString *FoundTextA; +TString *FoundTextW; +int FoundLocA; +int FoundLocW; + +// ÅŒã‚É•`‰æ‚µ‚½ƒeƒLƒXƒg‚̏î•ñ +// for text merge +int LastX; // ÅŒã‚É•`‰æ‚µ‚½ƒeƒLƒXƒg‚̉EãÀ•W +int LastY; +TString *LastTextA; +TString *LastTextW; +#endif // METAEXTTEXTOUT + +bool MoveSendMode; + +TCHAR AMODIPath[256]; +bool ExtAMODI = false; +int ScaleX = 0; // 96‚ð1‚Æ‚µ‚½‰æ–Ê‚ÌŠg‘å—¦ +int ScaleY = 0; +int generation = 0; + +TCHAR ImageTextPath[256+40]; // OCR—pimage filename or text filename +DWORD SaveImageTime; +bool CaptureImageBlocking = false; + +const char STR_USER32[] = "user32.dll"; +const char STR_GDI32[] = "gdi32.dll"; +const char STR_KERNEL32[] = "kernel32.dll"; +const TCHAR STR_PSAPI[] = _T("psapi.dll"); + +// KERNEL32.DLL // +const char STR_CreateToolhelp32Snapshot[] = "CreateToolhelp32Snapshot"; +const char STR_Module32First[] = "Module32First"; +const char STR_Module32Next[] = "Module32Next"; + +// PSAPI.DLL // +const char STR_EnumProcessModules[] = "EnumProcessModules"; +const char STR_GetModuleFileNameExA[] = "GetModuleFileNameExA"; + +const char STR_BeginPaint[] = "BeginPaint"; +const char STR_EndPaint[] = "EndPaint"; +const char STR_BitBlt[] = "BitBlt"; +const char STR_GetDC[] = "GetDC"; +const char STR_ReleaseDC[] = "ReleaseDC"; + +const char STR_ExtTextOutA[] = "ExtTextOutA"; +const char STR_ExtTextOutW[] = "ExtTextOutW"; +const char STR_TabbedTextOutA[] = "TabbedTextOutA"; +const char STR_TabbedTextOutW[] = "TabbedTextOutW"; +const char STR_TextOutA[] = "TextOutA"; +const char STR_TextOutW[] = "TextOutW"; +const char STR_DrawTextA[] = "DrawTextA"; +const char STR_DrawTextW[] = "DrawTextW"; +const char STR_DrawTextExA[] = "DrawTextExA"; +const char STR_DrawTextExW[] = "DrawTextExW"; + +#if USE_SHARE0 +#pragma data_seg() +#pragma bss_seg() +#endif + +//==============================================// +// Module depend values // +//==============================================// +HINSTANCE hInstance; // attached instance +DWORD idProcess; // attached process +HANDLE hProcess; // HookŽžGetCurrentProcess()‚ÍŽg‚¦‚È‚¢ + // HookŽž‚Ìcurrent process‚ª‘‚«Š·‚¦‚½‚¢thunk‚Ìprocess‚ƈê’v‚·‚é‚Æ‚ÍŒÀ‚ç‚È‚¢‚½‚ß + // ‚»‚Ì‚½‚߁ADLL‚ÌattachŽž‚ÉWriteProcessMemory()—p‚Éprocess handle‚ðŽæ“¾‚·‚é +DWORD curProcess; // hooking process +#if USE_VXD +HANDLE vxd_Handle = INVALID_HANDLE_VALUE; // Not shared +#endif + +#if !MOVESEND_POST +HANDLE SendMoveEvent = NULL; +DWORD SendMoveThreadId; +#endif + +HINSTANCE hInstSHCore = NULL; +FNGetProcessDPIAwareness GetProcessDPIAwareness = NULL; + +//==============================================// +// APIHOOK // +//==============================================// +class APIHOOK { +public: + const char *ModName; + const char *FuncName; +protected: + bool ExcludeMe; + bool Hooked; +public: + PROC OrgFunc; // not shared@NT +protected: + PROC HookFunc; // not shared + // Process dedicated values // +public: + static void *MaxAppAddr; // Maximum private memory address +protected: + static APIHOOK *LinkTop; // top of APIHOOK link + APIHOOK *LinkNext; // next pointer of API HOOK link +public: + APIHOOK( const char *modname, const char *name, void *hookfunc, bool excme = true ); + ~APIHOOK(); + bool GetProcOrgFunc( HINSTANCE hInst ); + bool GetProcOrgFunc(); + bool HookAgain(); + void Finish(); +protected: + bool StoreCode( ); + void RestoreCode( ); +protected: + static void ReplaceIATEntryInAllMods( APIHOOK *obj, PROC pfnCurrent, PROC pfnNew ); + static bool ReplaceIATEntryInOneMod( APIHOOK *obj, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller); +}; + +const BYTE cPushOpCode = 0x68; // The PUSH opcode on x86 platforms +APIHOOK* APIHOOK::LinkTop = NULL; +PVOID APIHOOK::MaxAppAddr = NULL; + +APIHOOK::APIHOOK( const char *modname, const char *funcname, void *hookfunc, bool excme ) +{ +// DBW("APIHOOK constructor:%08X %s %s",this, modname, funcname); + Hooked = false; + ModName = modname; + FuncName = funcname; + HookFunc = (PROC)hookfunc; + ExcludeMe = excme; + LinkNext = LinkTop; + LinkTop = this; + if (!MaxAppAddr){ + // Functions with address above lpMaximumApplicationAddress require + // special processing (Windows 98 only) + SYSTEM_INFO si; + GetSystemInfo(&si); + MaxAppAddr = si.lpMaximumApplicationAddress; + } +} + +APIHOOK::~APIHOOK() +{ + Finish(); + // Remove this object from the linked list + APIHOOK* p = LinkTop; + if (p == this) { // Removing the head node + LinkTop = p->LinkNext; + } else { + // Walk list from head and fix pointers + for (; p->LinkNext; p = p->LinkNext){ + if (p->LinkNext == this) { + // Make the node that points to us point to the our next node + p->LinkNext = p->LinkNext->LinkNext; + break; + } + } + } +} +bool APIHOOK::GetProcOrgFunc() +{ + return GetProcOrgFunc( GetModuleHandleA( ModName ) ); +} +bool APIHOOK::GetProcOrgFunc( HINSTANCE hInst ) +{ + if (Hooked) return true; + + // Save information about this hooked function + OrgFunc = ::GetProcAddress( hInst, FuncName); + if (!OrgFunc){ + DBW("Function doesn't exist =%s:%s", ModName, FuncName); + return false; + } + + if (OrgFunc > MaxAppAddr) { +// DBW("The address is in a shared DLL; the address needs fixing up"); + PBYTE pb = (PBYTE)OrgFunc; + if (pb[0] == cPushOpCode){ + // Skip over the PUSH op code and grab the real address + PVOID pv = * (PVOID*) &pb[1]; + OrgFunc = (PROC) pv; + } + } + + // Set assembler code for hooking at the org entry + if ( !StoreCode() ){ + DBW("Cannot write process memory"); + return false; + } + + Hooked = true; + return true; +} +bool APIHOOK::StoreCode( ) +{ + DBW("StoreCode:%s %s", ModName, FuncName); + // Hook this function in all currently loaded modules + ReplaceIATEntryInAllMods( this, OrgFunc, HookFunc ); + return true; +} +void APIHOOK::RestoreCode() +{ + DBW("RestoreCode:%s %s", ModName, FuncName); + ReplaceIATEntryInAllMods( this, HookFunc, OrgFunc ); +} +void APIHOOK::ReplaceIATEntryInAllMods( APIHOOK *obj, PROC pfnCurrent, PROC pfnNew ) +{ + HMODULE hmodThisMod = obj->ExcludeMe + ? ModuleFromAddress(ReplaceIATEntryInAllMods) : NULL; + + DWORD cbNeeded; + HMODULE hMods[1024]; + unsigned i; + if (fnCreateToolhelp32Snapshot){ + // Toolhelp‚ªŽg—p‚Å‚«‚éê‡‚ÍŽg—p‚·‚é + // Get the list of modules in this process + HANDLE hSnapshot = fnCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, idProcess); + + MODULEENTRY32 me = { sizeof(me) }; + for (BOOL fOk = fnModule32First(hSnapshot,&me); fOk; fOk = fnModule32Next(hSnapshot,&me)){ + // NOTE: We don't hook functions in our own module + if (me.hModule != hmodThisMod){ + // DBW("Module : %s %s", me.szModule,FuncName); + // Hook this function in this module + ReplaceIATEntryInOneMod( obj, pfnCurrent, pfnNew, me.hModule); + } + } + CloseHandle( hSnapshot ); + } else { + if( fnEnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) + { + for ( i = 0; i < (cbNeeded / sizeof(HMODULE)); i++ ) + { + if (hMods[i] != hmodThisMod){ + char szModName[MAX_PATH]; + // Get the full path to the module's file. + if ( fnGetModuleFileNameExA( hProcess, hMods[i], szModName, + sizeof(szModName))){ + // DBW("Module : %s %s", szModName, FuncName ); + ReplaceIATEntryInOneMod( obj, pfnCurrent, pfnNew, hMods[i]); + } + } + } + } +#if USE_DBW + else DBW("EnumProcessModules failed"); +#endif + } +} + +// This functions is almost taken from Jeffrey Richter's sample, thank you. +bool APIHOOK::ReplaceIATEntryInOneMod( APIHOOK *obj, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller) +{ + if (!hProcess) return false; + + // Get the address of the module's import section + ULONG ulSize; + PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) + ImageDirectoryEntryToData(hmodCaller, TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize); + + if (!pImportDesc){ +// DBW("No import section : %s", obj->ModName); + return false; + } + + // Find the import descriptor containing references to callee's functions + for (; pImportDesc->Name; pImportDesc++){ + PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name); + if (lstrcmpiA(pszModName, obj->ModName) == 0) + break; // Found + } + + if (pImportDesc->Name == 0){ +// DBW("This module doesn't import any functions from this callee"); + return false; // This module doesn't import any functions from this callee + } + + // Get caller's import address table (IAT) for the callee's functions + PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) + ((PBYTE) hmodCaller + pImportDesc->FirstThunk); + + // Replace current function address with new function address + for (; pThunk->u1.Function; pThunk++){ + // Get the address of the function address + PROC* ppfn = (PROC*) &pThunk->u1.Function; + // Is this the function we're looking for? + BOOL fFound = (*ppfn == pfnCurrent); + if (!fFound && (*ppfn > MaxAppAddr)){ + // If this is not the function and the address is in a shared DLL, + // then maybe we're running under a debugger on Windows 98. In this + // case, this address points to an instruction that may have the + // correct address. + PBYTE pbInFunc = (PBYTE) *ppfn; + if (pbInFunc[0] == cPushOpCode){ + // We see the PUSH instruction, the real function address follows + ppfn = (PROC*) &pbInFunc[1]; + + // Is this the function we're looking for? + fFound = (*ppfn == pfnCurrent); + } + } + + if (fFound){ + // The addresses match, change the import section address + if (!WriteProcessMemory(hProcess, ppfn, &pfnNew, sizeof(pfnNew), NULL)){ + if (SetWriteProtect( (LPVOID)ppfn, false )==~0){ // write protection release + DBW("SetWriteProtect failed: %08X %s %s", ppfn, obj->ModName, obj->FuncName); + return false; + } +#if USE_VXD + if (!WindowsNT && IsBadWritePtr(ppfn,sizeof(pfnNew))){ + // Windows9x shared DLL section + // change memory attribte using VxD + if (!ChangeMemory( ppfn, &pfnNew, sizeof(pfnNew) )){ + DBW("ChangeMemory failed"); + } + } else +#endif + { + if (!WriteProcessMemory(hProcess, ppfn, &pfnNew, sizeof(pfnNew), NULL)){ + //SetWriteProtect( ppfn, true ); // restore protection + DBW("%08X %08X %08X %08X %s %s", hProcess, ppfn, &pfnNew, sizeof(pfnNew), obj->ModName, obj->FuncName ); + DBW("WriteProcessMemory failed : %d",GetLastError()); + return false; + } + } + } + return true; // We did it, get out + } + } + + //DBW("Not found"); + + // If we get to here, the function is not in the caller's import section + return false; +} +bool APIHOOK::HookAgain() +{ + if ( Hooked ) return true; + + // Set assembler code for hooking at the org entry + if ( !StoreCode() ){ + DBW("Cannot write process memory@rehook"); + return false; + } + + Hooked = true; + return true; +} +void APIHOOK::Finish() +{ + if ( !Hooked ) return; + RestoreCode(); + Hooked = false; +} +// Returns the HMODULE that contains the specified memory address +static HMODULE ModuleFromAddress(PVOID pv) +{ + MEMORY_BASIC_INFORMATION mbi; + return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) + ? (HMODULE) mbi.AllocationBase : NULL); +} + +#if HOOK_PAINT || RETRYMETA +APIHOOK BeginPaintHook( STR_USER32, STR_BeginPaint, _BeginPaint ); +APIHOOK EndPaintHook( STR_USER32, STR_EndPaint, _EndPaint ); +#endif + +#if HOOK_BITBLT +APIHOOK BitBltHook( STR_GDI32, STR_BitBlt, _BitBlt ); +#endif + +#if HOOK_GETDC +APIHOOK GetDCHook( STR_USER32, STR_GetDC, _GetDC ); +APIHOOK ReleaseDCHook( STR_USER32, STR_ReleaseDC, _ReleaseDC ); +#endif + +#if METAEXTTEXTOUT +APIHOOK ExtTextOutAHook( STR_GDI32, STR_ExtTextOutA, _ExtTextOutA ); +APIHOOK ExtTextOutWHook( STR_GDI32, STR_ExtTextOutW, _ExtTextOutW ); +#if HOOK_TEXT +APIHOOK TabbedTextOutAHook( STR_USER32, STR_TabbedTextOutA, _TabbedTextOutA ); +APIHOOK TabbedTextOutWHook( STR_USER32, STR_TabbedTextOutW, _TabbedTextOutW ); +APIHOOK TextOutAHook( STR_GDI32, STR_TextOutA, _TextOutA ); +APIHOOK TextOutWHook( STR_GDI32, STR_TextOutW, _TextOutW ); +APIHOOK DrawTextAHook( STR_USER32, STR_DrawTextA, _DrawTextA ); +APIHOOK DrawTextWHook( STR_USER32, STR_DrawTextW, _DrawTextW ); +APIHOOK DrawTextExAHook( STR_USER32, STR_DrawTextExA, _DrawTextExA ); +APIHOOK DrawTextExWHook( STR_USER32, STR_DrawTextExW, _DrawTextExW ); +#endif +#endif // METAEXTTEXTOUT + +__declspec(dllexport) +bool WINAPI Init( HWND _hwnd, const char * /*module_name*/, bool windowsnt, const char *vxd_path ) +{ + DBW("Init:%08X %d", _hwnd, windowsnt); + hwndCallback = _hwnd; + if ( Initialized ){ + return true; + } +#if USE_VXD + WindowsNT = windowsnt; + if (vxd_path){ +// DBW("vxd_path=%s",vxd_path); + lstrcpy( VxDpathName, "\\\\.\\" ); + lstrcat( VxDpathName, vxd_path ); + if (!LoadVxD()){ + DBW("Cannot open VxD:%s:%d", VxDpathName,GetLastError() ); + return false; + } + } +#endif + +// HINSTANCE hDll = GetModuleHandle( module_name ); + hMouseHook = SetWindowsHookEx( WH_MOUSE, (HOOKPROC)MouseProc, hInstance, NULL ); + if (!hMouseHook){ + DBW("SetWindowsHookEx error: %d", GetLastError()); + return false; + } + +// hKeyHook = SetWindowsHookEx( WH_KEYBOARD, (HOOKPROC)KeyboardProc, hDll, NULL ); + + Initialized = true; + +#if GUARD + PROTECT_SHARE(); + DBW("%08X(%08X) Protected", (((INT_PTR)&ExtTextOutAHook) / siPageSize) * siPageSize,&ExtTextOutAHook); +#endif + + idDokopopProcess = GetCurrentProcessId(); + + // get AMODI infomation. + if (!tryAMODI){ + tryAMODI = true; + hwndAMODI = FindAMODI(); +#if 0 + if (hwndAMODI){ + DWORD procId; + if (GetWindowThreadProcessId(hwnd, &procId)){ + HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, procId); + if (hProc){ + memset(AMODIPath, 0, sizeof(AMODIPath)); + if (GetModuleFileNameEx(hProc, NULL, AMODIPath, sizeof(AMODIPath))>0){ + // OK + } + CloseHandle(hProc); + } + } + } +#endif + } + + return true; +} + +__declspec(dllexport) +void WINAPI Uninit() +{ + UNPROTECT_SHARE(); + if ( !Initialized ) return; + + DBW("Uninit"); + UnhookWindowsHookEx( hMouseHook ); + +// UnhookWindowsHookEx( hKeyHook ); + +#if USE_VXD + UnloadVxD(); +#endif + + Initialized = false; +} +__declspec(dllexport) +int WINAPI Config( int clickonly, int keyaction, int keyflag ) +{ + DBW("Config:%d %d %d", clickonly, keyaction, keyflag); + if (clickonly!=-1) + ClickOnlyEnabled = int_bool(clickonly); + if ( keyflag != 0 ){ + for ( int i=0;KeyConfig[i].Action;i++ ){ + if (KeyConfig[i].Action == keyaction){ + KeyConfig[i].Flag = keyflag; + break; + } + } + } + return 0; +} +__declspec(dllexport) +int WINAPI Config2( const struct TDCHConfig *cfg ) +{ + DBW("Config2: %d %d", cfg->ScaleX, cfg->ScaleY); + + MoveSend = cfg->MoveSend ? true : false; + MoveSent = false; + OnlyImage = cfg->OnlyImage; + ScaleX = cfg->ScaleX; + ScaleY = cfg->ScaleY; + + if (cfg->UseAMODI){ + if (!ExtAMODI){ + if (!hwndAMODI) + hwndAMODI = FindAMODI(); + } + } else { + hwndAMODI = NULL; + ExtAMODI = false; + return 0; + } + + OnlyAMODI = int_bool(cfg->OnlyAMODI); + AMODIPath[0] = '\0'; + ExtAMODI = false; + if (cfg->AMODIPath[0]){ + size_t len = strlen(cfg->AMODIPath); + if (lenAMODIPath, len); + if (AMODIPath[len-1]!='\\'){ + AMODIPath[len] = '\\'; + len++; + } + AMODIPath[len] = '\0'; + ExtAMODI = true; + } + } + dbw("Config2[%d]: %d %d %s", ++generation, cfg->ScaleX, cfg->ScaleY, AMODIPath); + return 0; +} +//Note: +// non_block = true‚̏ꍇ +// Ewaitó‘Ô‚É‚ ‚é‚©‚Ç‚¤‚©‚́AWaitForCaptureResult( false, 0 ) < 0 ‚Å‚í‚©‚éB +// E•K‚¸ÅŒã‚É‚ÍWaitForCaptureResult(1,...)‚ðŒÄ‚яo‚·‚±‚ƁB +__declspec(dllexport) +int WINAPI Capture( HWND hwnd, POINT *ppt, bool movesend, bool non_block ) +{ + DBW("Capture:%08X %d,%d %d %d", hwnd, ppt ? ppt->x : 0, ppt ? ppt->y : 0, movesend, non_block); + if (!hwnd) + hwnd = hwndLast; + POINT pt; + if (ppt) + pt = *ppt; + else + pt = PrevCursorPoint; + const bool image_only = true; + const bool runOnLaunchedProc = false; + return int_bool(DoCapture(hwnd, pt, movesend, image_only, runOnLaunchedProc, non_block)); +} +//Note: +// waittime‚ÍCapture()ŠJŽn‚µ‚Ä‚©‚ç‚ÌŒo‰ßŽžŠÔ +// polling‚·‚éê‡‚Íwaittime‚ð­‚µ‚¸‚‘‚â‚·•K—v‚ ‚è(‚»‚̏ꍇ‚Ísend_text=0) +// CaptureImage‚ðs‚Á‚½ê‡‚́Au•K‚¸vWaitForCaptureResult( 1, ... )‚ðŒÄ‚яo‚·•K—v‚ª‚ ‚éB +// ‚»‚¤‚µ‚È‚¢‚ƁACaptureImageBlocking‚ª true ‚É‚È‚Á‚½‚܂܁B +// +// return: +// 0 : wait’†‚Ì‚à‚Ì‚Í‚È‚µ +// 1 : OK(text ready) +// -1: timeout +__declspec(dllexport) +int WINAPI WaitForCaptureResult( bool send_text, unsigned waittime ) +{ + DBW("WaitForCaptureResult: %d %d %d", send_text, waittime, CaptureImageBlocking); + if (!CaptureImageBlocking) return 0; + + if (send_text){ + if (WaitAndGetResult(ImageTextPath, waittime)){ + return 1; + } + } else { + HANDLE hf = WaitForResult(ImageTextPath, waittime); + if (hf){ + CloseHandle(hf); + return 1; + } + } + return -1; +} +#if GUARD +void ShareProtect( bool f ) +{ + LPVOID BaseAddress = (LPVOID)((((INT_PTR)&ExtTextOutAHook) / siPageSize) * siPageSize); + + DWORD OldProtect; + if ( !VirtualProtect( BaseAddress, siPageSize, f ? PAGE_READONLY : PAGE_READWRITE, &OldProtect ) ){ + DBW("Cannot change protect:%08X@rehook",BaseAddress); + } +} +#endif +DWORD SetWriteProtect( LPVOID addr, bool f ) +{ + LPVOID BaseAddress = (LPVOID)((((INT_PTR)addr) / siPageSize) * siPageSize); + + DWORD OldProtect; + if ( !VirtualProtect( BaseAddress, siPageSize, f ? PAGE_READONLY : PAGE_READWRITE, &OldProtect ) ){ + DBW("Cannot change protect:%08X-%08X@rehook %d", (INT_PTR)BaseAddress>>32, BaseAddress, GetLastError()); + return ~0; + } + return OldProtect; +} +#if USE_VXD +// change write protected memory for Windows9x +bool ChangeMemory( void *dst, const void *src, unsigned size ) +{ + DWORD DIOC_count; + if ( vxd_Handle == INVALID_HANDLE_VALUE ){ + if (!LoadVxD()) + return false; + } + + bool r = int_bool(DeviceIoControl( vxd_Handle, DIOC_CHANGE_MEMORY, (void*)src, size, dst, 0, &DIOC_count, NULL)); +#if USE_DBW + if ( !r ){ + DBW("DeviceIoControl failed"); + } +#endif + return r; +} +bool LoadVxD() +{ + if (vxd_Handle!=INVALID_HANDLE_VALUE){ + DBW("Already loaded VxD"); + return true; + } + vxd_Handle=CreateFile(&VxDpathName[0],0,0,NULL,0,FILE_FLAG_DELETE_ON_CLOSE,NULL); + return vxd_Handle != INVALID_HANDLE_VALUE; +} +void UnloadVxD() +{ + if (vxd_Handle == INVALID_HANDLE_VALUE) + return; + CloseHandle(vxd_Handle); + vxd_Handle = INVALID_HANDLE_VALUE; +} +#endif +int GetKeyFlag( ) +{ + int r = 0; + if ( GetKeyState( VK_SHIFT ) & 0x8000 ) r |= KF_SHIFT; + if ( GetKeyState( VK_CONTROL ) & 0x8000 ) r |= KF_CONTROL; + if ( GetKeyState( VK_MENU ) & 0x8000 ) r |= KF_MENU; + if ( GetKeyState( VK_LWIN ) & 0x8000 ) r |= KF_LWIN; + if ( GetKeyState( VK_RWIN ) & 0x8000 ) r |= KF_RWIN; + if ( ClickOnlyEnabled && r == 0 ) r = KF_CLICKONLY; +// if ( GetKeyState( VK_APPS ) & 0x8000 ) r |= KF_APPS; + return r; +} +LRESULT CALLBACK MouseProc( int code, WPARAM wParam, LPARAM lParam ) +{ + if ( code < 0 || code != HC_ACTION ) + return CallNextHookEx( hMouseHook, code, wParam, lParam ); + + MOUSEHOOKSTRUCT *mhs; + HWND hwnd; + int kf; + int i; + +#if 0 + if (wParam!=0x200 && wParam!=0xA0) + dbw("WParam:%08X", wParam); +#endif + + curProcess = GetCurrentProcessId(); + bool runOnLaunchedProc = false; + + switch ( wParam ){ + case WM_LBUTTONDOWN: + // case WM_NCLBUTTONDOWN: + LButtonDown = true; + LButtonUpCancel = false; +// if (LButtonUpCancel) +// goto j_end; + kf = KF_LEFTCLICK; + goto j_rbuttondown; + case WM_MBUTTONDOWN: + // case WM_NCMBUTTONDOWN: + MButtonDown = true; + MButtonUpCancel = false; +// if (MButtonUpCancel) +// goto j_end; + kf = KF_MIDCLICK; + goto j_rbuttondown; + case WM_RBUTTONDOWN: + // case WM_NCRBUTTONDOWN: + DBW("RButtonDown"); + RButtonUpCancel = false; +// if (RButtonUpCancel) +// goto j_end; + kf = 0; + if (LButtonDown){ + kf = KF_LRCLICK; + } + j_rbuttondown:; + mhs = (MOUSEHOOKSTRUCT*)lParam; + hwnd = WindowFromPoint( mhs->pt ); + //hwnd = mhs->hwnd; +#if 0 + HWND h = GetParent( hwnd ); + if ( h ) + hwnd = h; +#endif + kf |= GetKeyFlag(); + +#if 0 + dbw("kf=%02X", kf); +#endif + + if (curProcess == idDokopopProcess){ + // runs on launched process -> ignored. + DBW("Runs on launched proc(%d)", curProcess); + runOnLaunchedProc = true; + } + + for ( i=0;KeyConfig[i].Action;i++ ){ + //DBW("%d:%d %x", i, KeyConfig[i].Action, KeyConfig[i].Flag); + if ( kf == KeyConfig[i].Flag ){ + switch ( KeyConfig[i].Action ){ + case KA_POPUP: + case KA_POPUP_NC: + { + const bool move_send = false; + if (DoCapture(hwnd, mhs->pt, move_send, OnlyImage, runOnLaunchedProc)){ +j_discard: + if (wParam == WM_LBUTTONDOWN) + LButtonUpCancel = true; + if (wParam == WM_MBUTTONDOWN) + MButtonUpCancel = true; + else + RButtonUpCancel = true; + return 1; // discard this message + } + } + break; + case KA_MENU: + DokoPopMenu( hwnd ); + goto j_discard; + case KA_TOGGLE: + DBW("KA_TOGGLE"); + ToggleClick( hwnd ); + goto j_discard; + } + } + } + break; + case WM_RBUTTONUP: + DBW("WM_RBUTTONUP:%d",RButtonUpCancel); + if ( RButtonUpCancel ){ + RButtonUpCancel = false; + return 1; // no longer process the message + } + break; + case WM_LBUTTONUP: + LButtonDown = false; + if ( LButtonUpCancel ){ + LButtonUpCancel = false; + return 1; // no longer process the message + } + break; + case WM_MBUTTONUP: + MButtonDown = false; + if ( MButtonUpCancel ){ + MButtonUpCancel = false; + return 1; // no longer process the message + } + break; + case WM_MOUSEMOVE: + if (MoveSend){ + mhs = (MOUSEHOOKSTRUCT*)lParam; + hwnd = WindowFromPoint( mhs->pt ); + if (PrevCursorPoint.x!=mhs->pt.x || PrevCursorPoint.y!=mhs->pt.y){ + PrevMoveTime = GetTickCount(); + MoveSent = false; + PrevCursorPoint = mhs->pt; + hwndLast = hwnd; + //DBW("Moving:%d %d", mhs->pt.x, mhs->pt.y); + SendMoveMessage(); +#if 0 + //TODO: 5pixel–¢–ž‚Å‚ ‚ê‚ÎDoCapture‚·‚é +#endif + } else { + if (!MoveSent){ +#if 0 // 2014.11.18 inc.srch‚Å—Ž‚¿‚é‚Ì‚Å‚Æ‚è‚ ‚¦‚¸comment out + const int MOVE_SEND_INTERVAL = 50; // msec + if (GetTickCount()-PrevMoveTime > MOVE_SEND_INTERVAL){ + MoveSent = true; + if (DoCapture(hwndLast, PrevCursorPoint, true)){ + // stop the capture from the main. + SendCancelMove(); + } + } +#endif + } + } + } + break; + } + +//j_end:; + return CallNextHookEx( hMouseHook, code, wParam, lParam ); +} + +bool DoCapture(HWND hwnd, POINT pt, bool movesend, bool image_only, bool runOnLaunchedProc, bool non_block) +{ + CursorPoint = ScreenPoint = pt; + ScreenToClient( hwnd, &CursorPoint ); + + if (!image_only && !runOnLaunchedProc){ + //DBW("hwnd:%08X %d %d", (int)hwnd, CursorPoint.x, CursorPoint.y); + if ((!hwndAMODI && !ExtAMODI) || !OnlyAMODI){ + // Redraw Metafile // + UNPROTECT_SHARE(); + DBW("Target : %08X %d", hwnd, curProcess); + bool r = CaptureText( hwnd, movesend ); + PROTECT_SHARE(); + if (r){ + return true; // discard this message + } + } + } + if (image_only || hwndAMODI || ExtAMODI){ + if (CaptureImage(hwnd, movesend, non_block)) + return true; + } + return false; +} + +void CallbackMain(int msg, const void *data, int len, HWND wparam=0) +{ + COPYDATASTRUCT cds; + cds.dwData = msg; + cds.cbData = len; + cds.lpData = (LPSTR)data; + SendMessage( hwndCallback, WM_COPYDATA, (WPARAM)wparam, (LPARAM)&cds ); +} + +void DokoPopMenu( HWND hwnd ) +{ + CallbackMain(DCH_MENU, NULL, 0, hwnd); +} +void ToggleClick( HWND hwnd ) +{ + CallbackMain(DCH_TOGGLE, NULL, 0, hwnd); +} +#if 0 +LRESULT CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam ) +{ + if ( code < 0 || code != HC_ACTION ) + return CallNextHookEx( hKeyHook, code, wParam, lParam ); + + if ( wParam == VK_CONTROL ){ + if ( lParam & (KF_UP<<16) ){ + // control key up + // -> hold on time + goto j1; + } else + if ( !(lParam & (KF_REPEAT<<16)) ){ + // control key down and not repeat +// DBW("wparam=%08X lparam=%08X",wParam,lParam); + long nowt = GetTickCount(); + if ( nowt - LastTypeTime < GetDoubleClickTime() ){ +// DBW("On/off!"); + ClickOnlyEnabled = !ClickOnlyEnabled; + MessageBeep( MB_OK ); + // -> cancel time + } else { + // -> hold on time + LastTypeTime = nowt; + goto j1; + } + } else { + // control key down and repeat + // -> cancel time + } + } + LastTypeTime -= 10000; +j1:; + return CallNextHookEx( hMouseHook, code, wParam, lParam ); +} +#endif + +//__declspec(dllexport) +#if HOOK_PAINT || RETRYMETA +HDC WINAPI _BeginPaint( HWND hwnd, LPPAINTSTRUCT ps ) +{ +// DBW("BeginPaint"); + HDC hdc = ((FNBeginPaint)BeginPaintHook.OrgFunc)( hwnd, ps ); + OrgHDC = hdc; + ps->hdc = hdcMeta; +#if 1 + ps->rcPaint.left = 0; + ps->rcPaint.top = 0; + ps->rcPaint.right = rcInvalid.right; + ps->rcPaint.bottom = rcInvalid.bottom; +#endif + return hdcMeta; +} +//__declspec(dllexport) +BOOL WINAPI _EndPaint( HWND hwnd, CONST PAINTSTRUCT *ps ) +{ + ((PAINTSTRUCT*)ps)->hdc = OrgHDC; + return ((FNEndPaint)EndPaintHook.OrgFunc)( hwnd, ps ); +} +#endif +#if HOOK_GETDC +HDC WINAPI _GetDC( HWND hwnd ) +{ + DBW("GetDC"); + HDC hdc = ((FNGetDC)GetDCHook.OrgFunc)( hwnd ); + OrgHDC = hdc; + if ( hwnd == hwndOrg ){ + return hdcMeta; + } else { + return OrgHDC; + } +} +int WINAPI _ReleaseDC( HWND hwnd, HDC hdc ) +{ + DBW("ReleaseDC"); + if ( hdc == hdcMeta ){ + hdc = OrgHDC; + } + int r = ((FNReleaseDC)ReleaseDCHook.OrgFunc)( hwnd, hdc ); + return r; +} +#endif + +#if METAEXTTEXTOUT +//__declspec(dllexport) +BOOL WINAPI _ExtTextOutA(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCSTR str, UINT count, CONST INT *dx ) +{ + DBW("_ExtTextOutA"); + POINT pt; + GetCurrentPositionEx(hdc,&pt); + + BOOL r = ((FNExtTextOutA)ExtTextOutAHook.OrgFunc)( hdc, x, y, option, rc, str, count, dx ); + + hdcExtTextOut = hdc; + + if ( r +#if USE_META + && hdcMeta != hdc +#endif + && count > 0 ){ + RECT _rc; + if ( rc ){ + _rc.right = rc->right; + _rc.bottom = rc->bottom; + } else { + _rc.right = rcClient.right; + _rc.bottom = rcClient.bottom; + } + if ( GetTextAlign( hdc ) & TA_UPDATECP ){ + _rc.left = pt.x; + _rc.top = pt.y; + } else { + _rc.left = x; + _rc.top = y; + } + if ( RetryPhase ){ + if ( TargetBitBltCount == BitBltCount ){ + _rc.right += CursorPoint.x; //*+++ bug ‚±‚¤‚µ‚È‚¢‚Æ•‚ª‚¹‚Ü‚­‚Ähit‚µ‚È‚¢ + OffsetRect( &_rc, TargetOffset.x, TargetOffset.y ); + } else { + return r; + } + } else { + ExtTextOutCount++; + } +#if ORG_OFFSET /* fixed 2001.1.14 for IE@win2k */ + POINT vpt; + POINT wpt; + GetViewportOrgEx( hdc, &vpt ); + GetWindowOrgEx( hdc, &wpt ); + OffsetRect( &_rc, vpt.x-wpt.x, vpt.y-wpt.y); +#else +#if USE_DBW + POINT vpt; + POINT wpt; + GetViewportOrgEx( hdc, &vpt ); + GetWindowOrgEx( hdc, &wpt ); + if (vpt.x != wpt.x || vpt.y != wpt.y) + DBW("!!!Org DIFF=%d %d",vpt.x-wpt.x, vpt.y-wpt.y); +#endif +#endif + + // ˜A‘±‚µ‚½ƒeƒLƒXƒg‚̏ꍇ‚Í + // ˜AŒ‹‚·‚é + if (LastY == _rc.top && LastX == _rc.left ){ + // ˜A‘±‚µ‚½ƒeƒLƒXƒg•`‰æ¨˜AŒ‹ + LastTextA->Cat( str, count ); + } else { + LastTextA->Set( str, count ); + } + LastX = _rc.left; + LastY = _rc.top; + + if ( PtInRect( &_rc, CursorPoint ) ) + { +#if DEBUG_HITTEXT + char *buf = new char[ count + 1 ]; + CopyMemory( buf, str, count ); + buf[count] = '\0'; + DBW("CheckA -- %d %d %d %d (%d,%d)", _rc.left, _rc.top, _rc.right, _rc.bottom, CursorPoint.x, CursorPoint.y, count); + DBW("%s", buf); + delete[] buf; +#endif + int loc = GetTextFromPoint( hdc, str, count, CursorPoint.x - _rc.left, CursorPoint.y - _rc.top, dx ); + if ( loc != -1 ){ + FoundLocA = loc + LastTextA->GetLength() - count; + FoundTextA->Set( LastTextA ); +#if DEBUG_HITTEXT + DBW("HitA loc=%d Len=%d Text=%ws", FoundLocA, FoundTextA->GetLength(), FoundTextA->c_str()); +#endif + } + } + } + + return r; +} +//__declspec(dllexport) +BOOL WINAPI _ExtTextOutW(HDC hdc, int x, int y, UINT option, CONST RECT *rc, LPCWSTR str, UINT count, CONST INT *dx ) +{ +// DBW("_ExtTextOutW"); + POINT pt; + GetCurrentPositionEx(hdc,&pt); + + BOOL r = ((FNExtTextOutW)ExtTextOutWHook.OrgFunc)( hdc, x, y, option, rc, str, count, dx ); + + hdcExtTextOut = hdc; + + if ( r +#if USE_META + && hdcMeta != hdc +#endif + && count > 0 ){ + RECT _rc; + if ( rc ){ + _rc.right = rc->right; + _rc.bottom = rc->bottom; + } else { + _rc.right = rcClient.right; + _rc.bottom = rcClient.bottom; + } + if ( GetTextAlign( hdc ) & TA_UPDATECP ){ + _rc.left = pt.x; + _rc.top = pt.y; + } else { + _rc.left = x; + _rc.top = y; + } + if ( RetryPhase ){ + if ( TargetBitBltCount == BitBltCount ){ + _rc.right += CursorPoint.x; //*+++ bug ‚±‚¤‚µ‚È‚¢‚Æ•‚ª‚¹‚Ü‚­‚Ähit‚µ‚È‚¢ + OffsetRect( &_rc, TargetOffset.x, TargetOffset.y ); + } else { + return r; + } + } else { + ExtTextOutCount++; + } +#if ORG_OFFSET /* fixed 2001.1.14 for IE@win2k */ + POINT vpt; + POINT wpt; + GetViewportOrgEx( hdc, &vpt ); + GetWindowOrgEx( hdc, &wpt ); + OffsetRect( &_rc, vpt.x-wpt.x, vpt.y-wpt.y); +#else // !ORG_OFFSET +#if USE_DBW + POINT vpt; + POINT wpt; + GetViewportOrgEx( hdc, &vpt ); + GetWindowOrgEx( hdc, &wpt ); + if (vpt.x != wpt.x || vpt.y != wpt.y) + DBW("!!!Org DIFF=%d %d",vpt.x-wpt.x, vpt.y-wpt.y); +#endif // USE_DBW +#endif // !ORG_OFFSET + + // ˜A‘±‚µ‚½ƒeƒLƒXƒg‚̏ꍇ‚͘AŒ‹‚·‚é + if (LastY == _rc.top && LastX == _rc.left ){ + // ˜A‘±‚µ‚½ƒeƒLƒXƒg•`‰æ¨˜AŒ‹ + LastTextW->Cat( str, count ); + } else { + LastTextW->Set( str, count ); + } + LastX = _rc.left; + LastY = _rc.top; + + if ( PtInRect( &_rc, CursorPoint ) ) + { + DBW("%04X %04X %04X %04X", + str[0], + str[1], + str[2], + str[3]); +#if DEBUG_HITTEXT + wchar_t *buf = new wchar_t[ count + 1 ]; + CopyMemory( buf, str, count*sizeof(wchar_t) ); + buf[count] = '\0'; + DBW("CheckW -- %d %d %d %d (%d,%d)", _rc.left, _rc.top, _rc.right, _rc.bottom, CursorPoint.x, CursorPoint.y, count); + DBW("%ws", buf); + delete[] buf; +#endif + int loc = GetTextFromPoint( hdc, str, count, CursorPoint.x - _rc.left, CursorPoint.y - _rc.top, dx ); + if ( loc != -1 ){ + FoundLocW = loc + LastTextW->GetLength() - count; + FoundTextW->Set( LastTextW ); +#if DEBUG_HITTEXT + DBW("HitW loc=%d Len=%d Text=%ws", FoundLocW, FoundTextW->GetLength(), FoundTextW->c_str()); +#endif + } + } + } + + return r; +} +#endif // !METAEXTTEXTOUT + +#if HOOK_BITBLT +BOOL WINAPI _BitBlt(HDC hdcdest, int xdest, int ydest, int width, int height, HDC hdcsrc, int xsrc, int ysrc, DWORD rop ) +{ + DBW("BitBlt:%08X %d %d %d %d <- %08X %d %d", hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc ); + BOOL r = ((FNBitBlt)BitBltHook.OrgFunc)(hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc, rop ); +// DBW("BitBlt:%08X %d %d %d %d <- %08X %d %d", hdcdest, xdest, ydest, width, height, hdcsrc, xsrc, ysrc ); + if ( r && hdcExtTextOut == hdcsrc ){ + if ( !RetryPhase ){ + // ¡‰ñ‚ÌBitBltŽž‚ÉExtTextOut‚ª‚ ‚Á‚½‚©H + if ( ExtTextOutCount > 0 ){ + // CursorPoint‚ªŠÜ‚Ü‚ê‚é‚©H + DBW("ExtTextOutCount=%d",ExtTextOutCount); + if ( (xdest <= CursorPoint.x) + && (xdest+width > CursorPoint.x) + && (ydest <= CursorPoint.y) + && (ydest+height > CursorPoint.y) + ){ + TargetBitBltCount = BitBltCount; + TargetOffset.x = xdest - xsrc; + TargetOffset.y = ydest - ysrc; + DBW("TargetOffset %d %d (%d,%d %dx%d)<-(%d,%d)", + TargetOffset.x, TargetOffset.y,xdest,ydest,width,height,xsrc,ysrc); +#if USE_DBW + { + POINT vpt; + POINT wpt; + GetViewportOrgEx( hdcdest, &vpt ); + GetWindowOrgEx( hdcdest, &wpt ); + DBW("BitBlt OrgDIFF=%d %d",vpt.x-wpt.x, vpt.y-wpt.y); + SIZE sz1; + SIZE sz2; + GetViewportExtEx( hdcdest, &sz1 ); + GetWindowExtEx( hdcdest, &sz2 ); + DBW("BitBlt Ext %d (%d,%d) (%d,%d)", GetMapMode(hdcdest), sz1.cx, sz1.cy, sz2.cx, sz2.cy ); +#if 1 + XFORM xform; + GetWorldTransform( hdcdest, &xform ); + { + char buf[100]; + sprintf(buf,"== [%d] %g %g %g %g %g %g", GetGraphicsMode(hdcdest), xform.eM11, xform.eM12, xform.eM21, xform.eM22, xform.eDx, xform.eDy); + DBW(buf); + } +#endif + } +#endif + } +#if METAEXTTEXTOUT + if ( TargetBitBltCount != -1 ){ + // ‚·‚Å‚É‚Ù‚©‚Ìband‚Åhit‚µ‚Ä‚¢‚éê‡A + // Cancel ExtTextOut + FoundLocA = -1; + FoundLocW = -1; + } +#endif + } + } + BitBltCount++; + DBW("BitBltCount=%d",BitBltCount); + ExtTextOutCount = 0; + return r; + } else { +// DBW("Unknown destination BitBlt %08X(%d,%d %dx%d)<-%08X(%d,%d)",hdcdest,xdest,ydest,width,height,hdcsrc,xsrc,ysrc); + } + return r; +} +#endif + +#if HOOK_TEXT +#define HK1( name, ret_type, args ) \ + ret_type r = ((FN##name)name##Hook.OrgFunc) args; \ + return r +LONG WINAPI _TabbedTextOutA( HDC hdc, int x, int y, LPCSTR str, int count, int ntabs, LPINT tabs, int origin ) +{ + DBW("_TabbedTextOutA"); + HK1( TabbedTextOutA, LONG, ( hdc, x, y, str, count, ntabs, tabs, origin ) ); +} +LONG WINAPI _TabbedTextOutW( HDC hdc, int x, int y, LPCWSTR str, int count, int ntabs, LPINT tabs, int origin ) +{ + DBW("TabbedTextOutW"); + HK1( TabbedTextOutW, LONG, ( hdc, x, y, str, count, ntabs, tabs, origin ) ); +} +BOOL WINAPI _TextOutA( HDC hdc, int x, int y, LPCSTR str, int count ) +{ + DBW("_TextOutA"); + HK1( TextOutA, BOOL, ( hdc, x, y, str, count ) ); +} +BOOL WINAPI _TextOutW( HDC hdc, int x, int y, LPCWSTR str, int count ) +{ + DBW("_TextOutW"); + HK1( TextOutW, BOOL, ( hdc, x, y, str, count ) ); +} +int WINAPI _DrawTextA( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format ) +{ + DBW("s5"); + HK1( DrawTextA, int, ( hdc, str, count, rc, format ) ); +} +int WINAPI _DrawTextW( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format ) +{ + DBW("s6"); + HK1( DrawTextW, int, ( hdc, str, count, rc, format ) ); +} +int WINAPI _DrawTextExA( HDC hdc, LPCSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params ) +{ + DBW("s7"); + HK1( DrawTextExA, int, ( hdc, str, count, rc, format, params ) ); +} +int WINAPI _DrawTextExW( HDC hdc, LPCWSTR str, int count, LPRECT rc, UINT format, LPDRAWTEXTPARAMS params ) +{ + DBW("s8"); + HK1( DrawTextExW, int, ( hdc, str, count, rc, format, params ) ); +} +#endif // HOOK_TEXT + +bool CaptureText( HWND hwnd, bool movesend ) +{ + if ( !hwnd ){ + return false; + } + + MoveSendMode = movesend; + + //DoScale(NULL, &CursorPoint, 1); + +#if METAEXTTEXTOUT + FoundLocA = -1; + FoundLocW = -1; + FoundTextA = new TString; + FoundTextW = new TString; + LastTextA = new TString; + LastTextW = new TString; +#endif + +#if !USE_REDRAW + HRGN hRgn; +#endif + + GetClientRect( hwnd, &rcClient ); + GetUpdateRect( hwnd, &rcOrgInvalid, FALSE ); + +#if USE_OPTIMALINVALID + SetRect( &rcInvalid, 0, max(CursorPoint.y - 64,0), rcClient.right, max(CursorPoint.y + 64,0) ); +#else + rcInvalid = rcClient; +#endif + +#if !USE_REDRAW + hRgn = CreateRectRgn( rcInvalid.left, rcInvalid.top, rcInvalid.right, rcInvalid.bottom ); + +#if USE_INVALIDATE + InvalidateRect( hwnd, &rcInvalid, INVALIDATE_TRUE ); +#endif + + SendMessage( hwnd, WM_PAINT, 0, 0 ); + SendMessage( hwnd, WM_NCPAINT, (WPARAM)hRgn, 0 ); +#endif + + hwndOrg = hwnd; + +#if USE_META + HDC hdc; +#endif + + HINSTANCE hPSAPI = NULL; + HMODULE hInst; + HMODULE hInstGdi; + + hInst = GetModuleHandleA( STR_KERNEL32 ); + fnCreateToolhelp32Snapshot = (FNCreateToolhelp32Snapshot)GetProcAddress( hInst, STR_CreateToolhelp32Snapshot ); + if (fnCreateToolhelp32Snapshot){ + // Toolhelp‚É‚æ‚émodule enumration‚ªŽg—p‰Â”\ + fnModule32First = (FNModule32First)GetProcAddress( hInst, STR_Module32First ); + fnModule32Next = (FNModule32Next)GetProcAddress( hInst, STR_Module32Next ); + } else { + // Toolhelp‚ª‘¶Ý‚µ‚È‚¢ê‡ + hPSAPI = LoadLibrary( STR_PSAPI ); + DBW("LoadLibrary : %08X",hPSAPI); + if (!hPSAPI){ + DBW("Cannot load PSAPI.DLL!!"); + return false; + } + fnEnumProcessModules = (FNEnumProcessModules)GetProcAddress( hPSAPI, STR_EnumProcessModules ); + fnGetModuleFileNameExA = (FNGetModuleFileNameExA)GetProcAddress( hPSAPI, STR_GetModuleFileNameExA ); + } + + hInst = GetModuleHandleA( STR_USER32 ); +#if USE_DBW + if ( !hInst ){ + DBW("Cannot load USER32.DLL"); + return false; + } +#endif + hInstGdi = GetModuleHandleA( STR_GDI32 ); +#if USE_DBW + if ( !hInstGdi ){ + DBW("Cannot load GDI32.DLL"); + goto err9; + } +#endif + +#if METAEXTTEXTOUT + if ( !ExtTextOutAHook.GetProcOrgFunc( hInstGdi ) ){ + DBW("Cannot find ExtTextOutA"); + goto err8; + } + if ( !ExtTextOutWHook.GetProcOrgFunc( hInstGdi ) ){ + DBW("Cannot find ExtTextOutW"); + goto err7; + } +#endif + +#if HOOK_BITBLT + if ( !BitBltHook.GetProcOrgFunc( hInstGdi ) ){ + DBW("Cannot find BitBlt"); + goto err71; + } +#endif + RetryPhase = false; + TargetBitBltCount = -1; + BitBltCount = 0; + ExtTextOutCount = 0; + +#if HOOK_PAINT + if ( !BeginPaintHook.GetProcOrgFunc( hInst ) ){ + DBW("Cannot hook BeginPaint"); + goto err73; + } + if ( !EndPaintHook.GetProcOrgFunc( hInst ) ){ + DBW("Cannot hook EndPaint"); + goto err6; + } +#endif + +#if HOOK_TEXT + TabbedTextOutAHook.GetProcOrgFunc( hInst ); + TabbedTextOutWHook.GetProcOrgFunc( hInst ); + TextOutAHook.GetProcOrgFunc( hInstGdi ); + TextOutWHook.GetProcOrgFunc( hInstGdi ); + DrawTextAHook.GetProcOrgFunc( hInst ); + DrawTextWHook.GetProcOrgFunc( hInst ); + DrawTextExAHook.GetProcOrgFunc( hInst ); + DrawTextExWHook.GetProcOrgFunc( hInst ); +#endif + +#if USE_META + hdc = GetDC( hwnd ); + if ( !hdc ){ + DBW("Cannot get DC"); + goto err5; + } +#endif + +#if HOOK_GETDC + if ( !GetDCHook.GetProcOrgFunc( hInst ) ){ + DBW("Cannot hook GetDC"); + goto err4; + } + if ( !ReleaseDCHook.GetProcOrgFunc( hInst ) ){ + DBW("Cannot hook ReleaseDC"); + goto err3; + } +#endif + + { + DBW("Hooked successfully"); +// rect.right = 9999; +// rect.bottom = 9999; +#if 0 + int iWidthMM = GetDeviceCaps(hdc, HORZSIZE); + int iHeightMM = GetDeviceCaps(hdc, VERTSIZE); + int iWidthPels = GetDeviceCaps(hdc, HORZRES); + int iHeightPels = GetDeviceCaps(hdc, VERTRES); + + // Use iWidthMM, iWidthPels, iHeightMM, and iHeightPels to determine the + // number of .01-millimeter units per pixel in the x and y directions. + + int iMMPerPelX = (iWidthMM * 100)/iWidthPels; + int iMMPerPelY = (iHeightMM * 100)/iHeightPels; + DBW("-%d %d-",iMMPerPelX, iMMPerPelY); + + // Convert client coordinates to .01-mm units. + + rcClient.left = rcClient.left * iMMPerPelX; + rcClient.top = rcClient.top * iMMPerPelY; + rcClient.right = rcClient.right * iMMPerPelX; + rcClient.bottom = rcClient.bottom * iMMPerPelY; +#endif + +#if USE_META + hdcMeta = CreateEnhMetaFile(hdc, + NULL, + &rcClient, "DCHook\0EnhMetaFile\0"); + if ( !hdcMeta ){ + DBW("Cannot create Meta file"); + goto err3; + } + + DBW("hdcMeta=%08X", hdcMeta); +#endif + +#if USE_REDRAW + RedrawWindow( hwnd, &rcInvalid, NULL, RDW_UPDATENOW | RDW_NOERASE | RDW_NOFRAME | RDW_INVALIDATE ); +#else + WNDPROC PaintWndProc = (WNDPROC)GetWindowLong( hwnd, GWL_WNDPROC ); + SendMessage( hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 ); +#endif +#if HOOK_GETDC + ReleaseDCHook.Finish(); + GetDCHook.Finish(); +#endif + +#if HOOK_TEXT + TabbedTextOutAHook.Finish( ); + TabbedTextOutWHook.Finish( ); + TextOutAHook.Finish( ); + TextOutWHook.Finish( ); + DrawTextAHook.Finish( ); + DrawTextWHook.Finish( ); + DrawTextExAHook.Finish( ); + DrawTextExWHook.Finish( ); +#endif + +#if HOOK_PAINT + EndPaintHook.Finish(); + BeginPaintHook.Finish(); +#endif + +#if HOOK_BITBLT + BitBltHook.Finish(); +#endif + +#if METAEXTTEXTOUT + ExtTextOutAHook.Finish(); + ExtTextOutWHook.Finish(); +#endif + + // Notify start enumrate meta-file + CallbackMain(DCH_START, &CursorPoint, sizeof(CursorPoint), hwnd); + + HitFound = false; + +#if USE_META + HENHMETAFILE emf = CloseEnhMetaFile( hdcMeta ); + + if ( emf ) +#endif + { +#if METAEXTTEXTOUT + if ( FoundLocA != -1 || FoundLocW != -1 ){ +// DBW("Hit ExtText:%d %d",FoundLocA,FoundLocW); + // ExtTextOutx hook‚Ì‚Ù‚¤‚ð—Dæ‚·‚é + ExtTextOutHit( ); + HitFound = true; + } else +#endif + { +#if USE_META + // Create compatible device-context for enumration + HDC _hdc = CreateCompatibleDC( hdc ); + HBITMAP hbitmap = CreateCompatibleBitmap( hdc, rcClient.right, rcClient.bottom ); + HGDIOBJ gdiobj = SelectObject( _hdc, hbitmap ); + + DBW("Start meta"); + // Enumerate meta-file + EnumEnhMetaFile( _hdc, emf, EnumMetaFileProc, NULL, &rcClient ); + DBW("End meta"); + + // Delete compatible device-context + SelectObject( _hdc, gdiobj ); + DeleteObject( hbitmap ); + DeleteDC( _hdc ); +#endif + } +#if USE_META + DeleteEnhMetaFile( emf ); +#endif + } +#if USE_META + else { + DBW("emf is NULL"); + } +#endif + +#if METAEXTTEXTOUT + if ( !HitFound && TargetBitBltCount != -1 ){ + DBW("Search from band:%d",TargetBitBltCount); +#if USE_META + // Band‚©‚猟õ + hdcMeta = CreateCompatibleDC( hdc ); + if ( !hdcMeta ){ + DBW("Cannot create HDC in retry"); + } else +#endif + { +#if USE_META + HBITMAP hbitmap = CreateCompatibleBitmap( hdc, rcClient.right, rcClient.bottom ); + HGDIOBJ gdiobj = SelectObject( hdcMeta, hbitmap ); + DBW("hdcMeata=%08X", hdcMeta); +#endif + + BitBltCount = 0; + RetryPhase = true; +#if METAEXTTEXOUT + FoundLocA = -1; + FoundLocW = -1; +#endif + +#if METAEXTTEXTOUT + ExtTextOutAHook.HookAgain(); + ExtTextOutWHook.HookAgain(); +#endif +#if HOOK_BITBLT + BitBltHook.HookAgain(); +#endif +#if HOOK_PAINT + BeginPaintHook.HookAgain(); + EndPaintHook.HookAgain(); +#endif + +// DBW("t1:%d %d %d %d",rcClient.left, rcClient.top,rcClient.right,rcClient.bottom); + +#if USE_INVALIDATE + InvalidateRect( hwnd, &rcInvalid, INVALIDATE_TRUE ); +#endif + +#if USE_REDRAW + RedrawWindow( hwnd, &rcInvalid, NULL, RDW_UPDATENOW | RDW_NOERASE | RDW_NOFRAME | RDW_INVALIDATE ); +#else + CallWindowProc( (WNDPROC)PaintWndProc, hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 ); +#endif + +#if HOOK_PAINT + EndPaintHook.Finish(); + BeginPaintHook.Finish(); +#endif +#if HOOK_BITBLT + BitBltHook.Finish(); +#endif + +#if METAEXTTEXTOUT + ExtTextOutAHook.Finish(); + ExtTextOutWHook.Finish(); +#endif +#if USE_META + SelectObject( hdcMeta, gdiobj ); + DeleteObject( hbitmap ); + DeleteDC( hdcMeta ); +#endif + if ( FoundLocA != -1 || FoundLocW != -1 ){ + DBW("Found in BitBlt ExtText:%d %d",FoundLocA,FoundLocW); + ExtTextOutHit( ); + HitFound = true; + } + } + } +#endif // METAEXTTEXTOUT + +#if RETRYMETA + if ( !HitFound ){ + HENHMETAFILE emf; +#if !USE_META + HDC hdc = GetDC( hwnd ); + if ( !hdc ){ + DBW("Cannot get DC"); + goto err01; + } +#endif +#if HOOK_PAINT + if ( !BeginPaintHook.HookAgain( ) ){ + DBW("Cannot hook BeginPaint"); + goto err02; + } + if ( !EndPaintHook.HookAgain( ) ){ + DBW("Cannot hook EndPaint"); + goto err03; + } +#else + if ( !BeginPaintHook.GetProcOrgFunc( hInst ) ){ + DBW("Cannot hook BeginPaint"); + goto err02; + } + if ( !EndPaintHook.GetProcOrgFunc( hInst ) ){ + DBW("Cannot hook EndPaint"); + goto err03; + } +#endif + + hdcMeta = CreateEnhMetaFile(hdc, + NULL, + &rcClient, _T("DCHook\0EnhMetaFile\0")); + if ( !hdcMeta ){ + DBW("Cannot create Meta file"); + goto err04; + } + DBW("hdcMeta=%08X", hdcMeta); +// InvalidateRect( hwnd, &rcInvalid, INVALIDATE_TRUE ); +#if 1 // 2000.7.15 NT‚Å‚à‚È‚º‚±‚Á‚¿‚É‚µ‚Ä‚¢‚È‚©‚Á‚½‚Ì‚©‚í‚©‚ç‚È‚¢‚ªEEE + SendMessage( hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 ); +#else + // Notepad‚łُ͈íI—¹‚·‚邽‚ß‹p‰º + // ‰½‚à‚È‚¢‚Æ‚±‚ë‚ÅCtrl+‰EƒNƒŠƒbƒN + WNDPROC PaintWndProc = (WNDPROC)GetWindowLong( hwnd, GWL_WNDPROC ); + if ( PaintWndProc ){ + PaintWndProc( hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 ); + } +#endif + EndPaintHook.Finish(); + BeginPaintHook.Finish(); + + emf = CloseEnhMetaFile( hdcMeta ); + + if ( emf ){ + HDC _hdc = CreateCompatibleDC( hdc ); + HBITMAP hbitmap = CreateCompatibleBitmap( hdc, rcClient.right, rcClient.bottom ); + HGDIOBJ gdiobj = SelectObject( _hdc, hbitmap ); + + DBW("Start meta-retry"); + // Enumerate meta-file + EnumEnhMetaFile( _hdc, emf, EnumMetaFileProc, NULL, &rcClient ); + DBW("End meta-retry"); + + // Delete compatible device-context + SelectObject( _hdc, gdiobj ); + DeleteObject( hbitmap ); + DeleteDC( _hdc ); + DeleteEnhMetaFile( emf ); + } + err04: + EndPaintHook.Finish(); + err03: + BeginPaintHook.Finish(); + err02: +#if !USE_META + ReleaseDC( hwnd, hdc ); +#endif + err01:; + } +#endif + + // Notify end enumrate meta-file + CallbackMain(DCH_END | (MoveSendMode ? DCH_MOVESEND : 0), NULL, 0, hwnd); + } + +#if USE_META + ReleaseDC( hwnd, hdc ); +#endif + + if ( rcOrgInvalid.right != 0 ){ + DBW("Update OrgInvalid--------"); + InvalidateRect( hwnd, NULL, INVALIDATE_TRUE ); + } + + goto jreturn; + +#if HOOK_GETDC || USE_META +err3:; +#endif +#if HOOK_GETDC + GetDCHook.Finish(); +err4:; +#if USE_META + ReleaseDC( hwnd, hdc ); +#endif +#endif +#if USE_META +err5:; +#endif +#if HOOK_PAINT + EndPaintHook.Finish(); +err6:; + BeginPaintHook.Finish(); +err73:; +#endif +#if HOOK_BITBLT + BitBltHook.Finish(); +#endif +#if HOOK_BITBLT +err71:; +#endif +#if METAEXTTEXTOUT + ExtTextOutWHook.Finish(); +err7:; + ExtTextOutAHook.Finish(); +err8: +#endif + if (hPSAPI) + FreeLibrary( hPSAPI ); +#if USE_DBW +err9: +#endif + HitFound = false; +jreturn:; +#if USE_VXD + if (vxd_Handle!=INVALID_HANDLE_VALUE) + UnloadVxD(); +#endif +#if METAEXTTEXTOUT + delete FoundTextA; + delete FoundTextW; + delete LastTextA; + delete LastTextW; +#endif + + return HitFound; +} +#if METAEXTTEXTOUT +void ExtTextOutHit() +{ + if ( FoundLocA != -1 ){ + // Hit on ANSI + DBW("Hit on ANSI@ExtTextOut"); + CallbackMain(DCH_HITTEXT1, FoundTextA->c_str(), FoundTextA->GetByte(), (HWND)FoundLocA); + } else { + // Hit on UNICODE + DBW("Hit on UNICODE@ExtTextOut"); + CallbackMain(DCH_HITTEXT2, FoundTextW->c_str(), FoundTextW->GetByte(), (HWND)FoundLocW); + } +} +#endif // METAEXTTEXTOUT + +void DoScale(HDC hdc, POINT *pts, int num) +{ + //TODO: hInst, proc‚Íglobal‚É‚µ‚½‚Ù‚¤‚ª‚¢‚¢‚̂ł́H + + int scale = 0; + if (ScaleX && ScaleY){ + scale = ScaleX; // Žw’肵‚½scaling parameter + } else { + scale = GetMonitorScale(); + if (scale == 96) return; + } + +#if 1 +#if 1 + PROCESS_DPI_AWARENESS value = Process_DPI_Unaware; + if (hInstSHCore){ + if (!GetProcessDPIAwareness){ + GetProcessDPIAwareness = (FNGetProcessDPIAwareness)GetProcAddress(hInstSHCore, "GetProcessDpiAwareness"); + } + if (GetProcessDPIAwareness){ + GetProcessDPIAwareness(hProcess, &value); + DBW("DPIAware: value=%d", value); + } + } + if (value != Process_System_DPI_Aware){ + int dpi_x = scale; + int dpi_y = scale; + DBW("dpi: %d,%d", dpi_x, dpi_y); + for (int i=0;iiType); + + switch ( mfr->iType ){ + case EMR_EXTTEXTOUTA: + case EMR_EXTTEXTOUTW: + { + EMREXTTEXTOUTW *emr = (EMREXTTEXTOUTW*)mfr; + + //DBW("(%d,%d) <%d=%d=%d=%d>", CursorPoint.x, CursorPoint.y, emr->rclBounds.left, emr->rclBounds.top,emr->rclBounds.right, emr->rclBounds.bottom); +#if 1 + if ( PtInRect( (RECT*)&emr->rclBounds, CursorPoint ) ){ + DBW("(%d,%d) <%d=%d>", CursorPoint.x, CursorPoint.y, emr->rclBounds.left, emr->emrtext.ptlReference.x); +#if 0 + { + SIZE sz1, sz2; + GetWindowExtEx( hdc, &sz1 ); + GetViewportExtEx( hdc, &sz2 ); + DBW("%d-%d %d-%d", sz1.cx, sz1.cy, sz2.cx, sz2.cy); + } +#endif + int loc; + if ( mfr->iType == EMR_EXTTEXTOUTW ){ + //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); + //DBW("text=%ws", (wchar_t*) ( ((char*)emr) + emr->emrtext.offString )); + loc = GetTextFromPoint( hdc, (wchar_t*) ( ((char*)emr) + emr->emrtext.offString ), + emr->emrtext.nChars, + CursorPoint.x - emr->rclBounds.left /* + emr->emrtext.ptlReference.x */, + CursorPoint.y - emr->rclBounds.top /* + emr->emrtext.ptlReference.y */, + ((int*)(((char*)emr) + emr->emrtext.offDx)) ); + } else { + loc = GetTextFromPoint( hdc, ((char*)emr) + emr->emrtext.offString, + emr->emrtext.nChars, + CursorPoint.x - emr->rclBounds.left /* + emr->emrtext.ptlReference.x */, + CursorPoint.y - emr->rclBounds.top /* + emr->emrtext.ptlReference.y */, + ((int*)(((char*)emr) + emr->emrtext.offDx)) ); + } + if ( loc != -1 ){ +// char *buf = NULL; + const char *text = ((char*)emr) + emr->emrtext.offString; + int len = emr->emrtext.nChars; + if ( mfr->iType == EMR_EXTTEXTOUTW ){ + // WIDE + //DBW("len=%d loc=%d text=%ws", len, loc, text); + CallbackMain(DCH_HITTEXT2, text, len * sizeof(wchar_t), (HWND)loc); +#if 0 + // UNICODE->ANSI + // ANSIã‚Å‚Ìloc‚ð‹‚ß‚é‚½‚߁A‘O”¼‚ƌ㔼‚𕪂¯‚Ä•ÏŠ· + wchar_t *wp = (wchar_t*) ( ((char*)emr) + emr->emrtext.offString ); + buf = new char[ emr->emrtext.nChars * 2 ]; + memset( buf, 0, emr->emrtext.nChars*2 ); + // ‘O”¼•”•ª + len = 0; + if ( loc > 0 ){ + len = WideCharToMultiByte( CP_ACP, 0, wp, loc, + buf, emr->emrtext.nChars * 2, NULL, NULL ); + } + int newloc = len; + // Œã”¼•”•ª + if ( emr->emrtext.nChars > (unsigned int)loc ){ + len += WideCharToMultiByte( CP_ACP, 0, wp+loc, emr->emrtext.nChars - loc, + buf+len, emr->emrtext.nChars * 2 - len, NULL, NULL ); + } + loc = newloc; + text = buf; +#endif + + } else { + // ANSI + CallbackMain(DCH_HITTEXT1, text, len, (HWND)loc); + } + + DBW("Found@Enum"); +#if 0 + CallbackMain(DCH_HITTEXT1, text, len, (HWND)loc); + if ( buf ) + delete buf; +#endif +#if 0 + { + char b[100]; + sprintf(b,"exScale=%f eyScale=%f ptlReference=(%d,%d)",emr->exScale, emr->eyScale, emr->emrtext.ptlReference.x, emr->emrtext.ptlReference.y ); + DBW(b); + DBW("iGraphicsMode=%d", emr->iGraphicsMode); + } +#endif +#if 0 + { + for ( int i=0;i<(int)emr->emrtext.nChars;i++ ){ + DBW(">%d", ((int*)(((char*)emr) + emr->emrtext.offDx))[i] ); + } + } +#endif +// DBW("[%d %d][%d %d]text=(%s)", emr->rclBounds.left, emr->rclBounds.top, CursorPoint.x, CursorPoint.y, text); +// result = false; // stop enumration // ‚‘¬‰»‚Ì‚½‚ß“r’†‚ŏI‚í‚è‚É‚µ‚½‚¢‚ªEEE‚Ç‚¤‚µ‚悤H +#if METAEXTTEXTOUT + // prevent to get from ExtTextOut hook + FoundLocA = -1; + FoundLocW = -1; +#endif + HitFound = true; + } + } +#else // for debug + if ( mfr->iType == EMR_EXTTEXTOUTW ){ + CallbackMain(DCH_EXTTEXTOUTW, emr, sizeof(EMREXTTEXTOUTW) + emr->emrtext.nChars * sizeof(wchar_t), (HWND)hdc); + } else { + CallbackMain(DCH_EXTTEXTOUTA, emr, sizeof(EMREXTTEXTOUTA) + emr->emrtext.nChars, (HWND)hdc); + } +#endif + } + break; + } + return true; +} + +} // extern "C" + +// text‚̐擪‚ð(0,0)‚Æ‚µ‚½À•W‚ŁApos‚̈ʒu‚É‚ ‚étext‚Ì•¶ŽšˆÊ’u‚ð•Ô‚· +int GetTextFromPoint( HDC hdc, const char *text, int len, int pos_x, int pos_y, const int *dx ) +{ + if ( pos_x < 0 || pos_y < 0 ) return -1; + + int count = 0; + SIZE sz; + int *rdx = NULL; + if ( dx ){ + rdx = new int[len]; + memset( rdx, 0, len*sizeof(int) ); + } + if ( !GetTextExtentExPointA( hdc, text, len, pos_x, &count, rdx, &sz ) ){ + DBW("GetTextExtentExPointA Failure!!"); + if ( rdx ) + delete rdx; + return -1; + } +#if METAEXTTEXTOUT + LastX += sz.cx; // update +#endif + // size over check + if ( pos_y > sz.cy + || pos_x > sz.cx + ){ + if ( rdx ) delete rdx; + return -1; + } + DBW("A:len=%d pos_x=%d sz.cx=%d", len, pos_x, sz.cx); + if ( dx && count > 0 ){ + // ex. + // Win98,Notepad‚Ì“ú–{Œêã‚Å + // dx = 0, 8, 0, 8, 0, 8, ... + // rdx = 9,10, 9,10, 9,10, ... +#if 0 + { + int i; + for ( i=0;i %3d", dx[j], rdx[i]-rdx[i-1]); +#else // Win98‚ł́Amulti-byte‚Å‚à•ªŽU‚³‚¹‚Ä‚¢‚éê‡‚ª‚ ‚邽‚߁Adx‚Å”»’f + sumdx += (dx[j]?dx[j]:dx[j+1]) - (rdx[i]-rdx[i-1]); +#endif + } +// DBW("sumdx=%d",sumdx); + if ( !GetTextExtentExPointA( hdc, text, len, pos_x - sumdx, &count, rdx, &sz ) ){ + if ( rdx ) + delete rdx; + return -1; + } + } + if ( rdx ) + delete rdx; + return count; +} +int GetTextFromPoint( HDC hdc, const wchar_t *text, int len, int pos_x, int pos_y, const int *dx ) +{ +#if USE_VXD + if (WindowsNT) +#endif + { + if ( pos_x < 0 || pos_y < 0 ) return -1; + + int count = 0; + SIZE sz; + int *rdx = NULL; + if ( dx ){ + rdx = new int[ len ]; + memset( rdx, 0, len ); + } + if ( !GetTextExtentExPointW( hdc, text, len, pos_x, &count, rdx, &sz ) ) + { + DBW("GetTextExtentExPointW Failure!!"); + if ( rdx ) + delete[] rdx; + return -1; + } +#if METAEXTTEXTOUT + LastX += sz.cx; +#endif + // size over check + if ( pos_y > sz.cy + || pos_x > sz.cx + ){ + if ( rdx ) delete[] rdx; + return -1; + } + DBW("W:len=%d pos_x=%d sz.cx=%d", len, pos_x, sz.cx); + if ( dx && count > 0 ){ + // spacing‚̌덷‚ðŒvŽZ + // Times New Roman‚È‚Ç‚Å’²‚ׂé‚Æ‚©‚È‚è‚̌덷‚ª‚ ‚éB‚È‚ºH + int i = 0; + int j = 0; + int sumdx = 0; + // DBW("rd(x)[0]=%d,%d",dx[0],rdx[0]); + if ( rdx[0] ){ + sumdx = dx[0] - rdx[0]; + i++; + j++; + } + for ( ;i %3d", dx[j], rdx[i]-rdx[i-1]); +#else + sumdx += (dx[j]?dx[j]:dx[j+1]) - (rdx[i]-rdx[i-1]); +#endif + } + // DBW("sumdx=%d",sumdx); + if ( !GetTextExtentExPointW( hdc, text, len, pos_x - sumdx, &count, rdx, &sz ) ){ + if ( rdx ) + delete rdx; + return -1; + } + } + if ( rdx ) + delete rdx; + return (count == len && sz.cx < pos_x) ? -1 : count; + } +#if USE_VXD + else { + char *buf = new char[ len * sizeof(wchar_t) ]; + memset( buf, 0, len * sizeof(wchar_t) ); + int ansilen = WideCharToMultiByte( CP_ACP, 0, text, len, buf, len*sizeof(wchar_t), NULL, NULL ); + int r = GetTextFromPoint( hdc, buf, ansilen, pos_x, pos_y, dx ); + delete buf; + return r; + } +#endif +} + +#define WMCD_EXISTCHECK 0x4000 +#define WMCD_SETPOINT 0x4001 + +class TDC { + HDC hdc; + HWND hwnd; +public: + TDC() + :hwnd(NULL) + { + hdc = GetDC(NULL); + } + TDC(HWND _hwnd) + :hwnd(_hwnd) + { + hdc = GetWindowDC(hwnd); + } + ~TDC() + { + reset(); + } + void reset() + { + if (hdc){ + ReleaseDC(hwnd, hdc); + hdc = NULL; + } + } + operator HDC() { return hdc; } + bool operator !() { return hdc==NULL; } +}; + +bool CaptureImage(HWND hwnd, bool movesend, bool non_block) +{ + MoveSendMode = movesend; + CaptureImageBlocking = false; + + bool capture_page = false; + if (hwndAMODI){ + capture_page = SendMessage(hwndAMODI, WM_AMODI, AMODI_CMD_PAGE_CAPTURE, 0) ? true : false; + } + + // Get the rect of the target window. + RECT rcTarget; + if (!GetWindowRect(hwnd, &rcTarget)){ + // window died? + return false; + } + if (!ExtAMODI){ + if (!IsWindowEnabled(hwndAMODI)){ + // AMODI died? + hwndAMODI = FindAMODI(); + if (!hwndAMODI) + return false; + } + } + int w = rcTarget.right - rcTarget.left; + int h = rcTarget.bottom - rcTarget.top; + if (w==0 || h==0){ + return false; // no area in the target. + } + + POINT ptCursor; // ‰æ‘œã‚̃J[ƒ\ƒ‹ˆÊ’u + int x, y; + if (capture_page){ + x = rcTarget.left; + y = rcTarget.top; + ptCursor.x = ScreenPoint.x - rcTarget.left; + ptCursor.y = ScreenPoint.y - rcTarget.top; + } else { + // x•ûŒü : target rect‚̍¶’[‚©‚ç + // y•ûŒü : cursor point‚̏㉺100 pixel + x = rcTarget.left; + int offs = 100; + if (ScreenPoint.y - rcTarget.top < offs){ + if (ScreenPoint.y < rcTarget.top) return false; // click on out of rect? + y = rcTarget.top; + h = ScreenPoint.y - rcTarget.top + offs; + } else { + y = ScreenPoint.y - offs; + h = offs * 2; + } + if (y+h>rcTarget.bottom){ + h = rcTarget.bottom - y; + } + ptCursor.x = ScreenPoint.x - rcTarget.left; + ptCursor.y = ScreenPoint.y - y; + } + + if (0){ + HWND hwnd = GetDesktopWindow(); + RECT rc; + GetWindowRect(hwnd, &rc); + x = 0; + y = 0; + w = rc.right - rc.left; + h = rc.bottom - rc.top; + } + + if (!capture_page){ + // Notify start enumrate + CallbackMain(DCH_START, &CursorPoint, sizeof(CursorPoint), hwnd); + } + + bool ok = false; + + TDC hdc; + + if (!hdc){ + goto jend; + } + +#if USE_SCALING + POINT pts[3]; + pts[0].x = x; + pts[0].y = y; + pts[1].x = w; + pts[1].y = h; + pts[2].x = ptCursor.x; + pts[2].y = ptCursor.y; + DoScale(hdc, pts, 3); + //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); + x = pts[0].x; + y = pts[0].y; + w = pts[1].x; + h = pts[1].y; + ptCursor.x = pts[2].x; + ptCursor.y = pts[2].y; +#endif + + // capture image + + int wlen = (w*3+3)&~3; + + /* ‘‚«ž‚Ý—pƒoƒbƒtƒ@‚̃TƒCƒYŒvŽZ */ + DWORD dwFSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) + wlen * h; + + /* ƒoƒbƒtƒ@Šm•Û‚ƃ|ƒCƒ“ƒ^Ý’è */ + LPBYTE lpBuf = (LPBYTE)new char[dwFSize]; + if (!lpBuf){ + goto jend; + } + + LPBITMAPFILEHEADER lpHead = (LPBITMAPFILEHEADER)lpBuf; + LPBITMAPINFOHEADER lpInfo = (LPBITMAPINFOHEADER)(lpBuf+sizeof(BITMAPFILEHEADER)); + LPBYTE lpPixel = lpBuf+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); + + /* 24ƒrƒbƒgBMPƒtƒ@ƒCƒ‹‚̃wƒbƒ_ì¬ */ + lpHead->bfType = ('M'<<8) +'B'; + lpHead->bfSize = dwFSize; + lpHead->bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); + lpInfo->biSize = sizeof(BITMAPINFOHEADER); + lpInfo->biWidth = w; + lpInfo->biHeight = h; + lpInfo->biPlanes = 1; + lpInfo->biBitCount = 24; + + HBITMAP hBmp = CreateCompatibleBitmap(hdc, w, h); + if (hBmp){ + HDC hdcMem = CreateCompatibleDC(hdc); + if (hdcMem){ + HDC hOld = (HDC)SelectObject(hdcMem, hBmp); + if (hOld!=(HDC)GDI_ERROR){ + BOOL r = BitBlt(hdcMem, 0, 0, w, h, hdc, x, y, SRCCOPY); + SelectObject(hdcMem, hOld); + if (r){ +// int lines = GetDIBits(hdc, hBmp, 0, h, NULL, (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS); + int lines = GetDIBits(hdc, hBmp, 0, h, lpPixel, (LPBITMAPINFO)lpInfo, DIB_RGB_COLORS); + if (lines!=0){ + ok = true; + } else { + dbw("GetDIBits error??? %d h=%d w=%d bfSize=%d", GetLastError(), h, w, dwFSize); + } + } else { +// dbw("BitBlt error??? %d", GetLastError()); + } + } + DeleteObject(hdcMem); + } + DeleteObject(hBmp); + } + + hdc.reset(); + + if (ok){ + ok = false; + + //TCHAR path[sizeof(AMODIPath)+40]; + TCHAR *path = ImageTextPath; + size_t path_size = sizeof(ImageTextPath); + size_t len; + if (ExtAMODI){ + len = _tcslen(AMODIPath); + _tcscpy(path, AMODIPath); + } else { + memset(path, 0, path_size); + len = GetTempPath((DWORD)path_size, path); + } + if (len>0){ + // send image to AMODI + SYSTEMTIME t; + GetLocalTime(&t); + if (ExtAMODI){ + wsprintf(path+len, /*path_size-len,*/ _T("\\%04d-%02d-%02d-%02d%02d%02d-(%d,%d).bmp"), + t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond, ptCursor.x, ptCursor.y); + } else { + wsprintf(path+len, /*path_size-len,*/ _T("\\amodi\\%04d-%02d-%02d-%02d%02d%02d.bmp"), + t.wYear, t.wMonth, t.wDay, t.wHour, t.wMinute, t.wSecond); + SendAMODI(WMCD_SETPOINT, (char*)&ptCursor, sizeof(ptCursor)); + } + HANDLE fh = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (fh!=INVALID_HANDLE_VALUE){ + DWORD dwSize; + WriteFile(fh, lpBuf, dwFSize, &dwSize, NULL); + CloseHandle(fh); + SaveImageTime = GetTickCount(); + + if (capture_page){ + ok = true; + } else { + len = (int)_tcslen(path); + _tcsncat(path+len, _T(".txt"), path_size-len); + if (non_block){ + CaptureImageBlocking = true; + } else { + if (WaitAndGetResult(path, 3000)) + ok = true; + } + } + } + } + } + delete[] lpBuf; + +jend: + if (!CaptureImageBlocking){ + if (!capture_page){ + CallbackMain(DCH_END | (MoveSendMode ? DCH_MOVESEND : 0), NULL, 0, hwnd ); + } + } + + return ok; +} + +bool WaitAndGetResult(const TCHAR *path, unsigned waittime) +{ + bool ok = false; + + // wait and get text from AMODI + + HANDLE fh = WaitForResult(path, waittime); + + CaptureImageBlocking = false; + + if (fh==INVALID_HANDLE_VALUE){ + DBW("file open timeout"); + CheckAMODIAlive(); + } else { + DWORD size = GetFileSize(fh, NULL); + if (size>0){ + unsigned bufsize = size+sizeof(wchar_t); + char *text = new char[bufsize]; + if (text){ + DWORD rbyte; + if (ReadFile(fh, text, size, &rbyte, NULL)){ + if (rbyte==size){ + *(wchar_t*)&text[size] = '\0'; + // text‚Ì‚Ps–ڂ͉ðÍî•ñ + // format + // (ƒ}ƒEƒXƒJ[ƒ\ƒ‹‚Ì‚ ‚éƒeƒLƒXƒgˆÊ’u[•¶Žš–Ú zero-index]) + int loc = 0; + int col = 0; + wchar_t *p = (wchar_t*)text; + while (*p){ + wchar_t c = *p++; + if (c=='\n'){ + break; + } + if (col==0){ + loc = _wtoi(p); + col++; + } + } + + DBW("%d:%ws", loc, p); + CallbackMain(DCH_HITTEXT2, p, bufsize - (int)((char*)p-text), (HWND)loc); + + ok = true; + } + } + delete[] text; + } + } + CloseHandle(fh); + DeleteFile(path); + } + CallbackMain(DCH_END | (MoveSendMode ? DCH_MOVESEND : 0), NULL, 0, NULL ); + return ok; +} + +HANDLE WaitForResult(const TCHAR *path, unsigned waittime) +{ + HANDLE fh = INVALID_HANDLE_VALUE; + + while (1){ + fh = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (fh!=INVALID_HANDLE_VALUE) + break; + + DWORD now = GetTickCount(); + if (now-SaveImageTime > waittime) + break; + + Sleep(10); + } + + return fh; +} + +#define APPNAME _T("Auto MODI") + +static HWND hwndFind; +static BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) +{ + TCHAR wndname[80]; + if (GetWindowText(hwnd, wndname, tsizeof(wndname))<0){ + return TRUE; + } + if (_tcscmp(wndname, APPNAME)){ return TRUE; } + + COPYDATASTRUCT cd; + cd.dwData = WMCD_EXISTCHECK; + cd.lpData = (void*)APPNAME; + cd.cbData = (DWORD)(_tcslen(APPNAME)+1)*sizeof(TCHAR); + if ( SendMessage( hwnd, WM_COPYDATA, 0, (LPARAM)&cd ) ) + { + // found + hwndFind = hwnd; + return FALSE; + } + return TRUE; +} + +HWND FindAMODI() +{ + hwndFind = NULL; + EnumWindows(EnumWindowsProc, 0); + return hwndFind; +} + +int SendAMODI(int cmd, const char *data, int len) +{ + COPYDATASTRUCT cd; + cd.dwData = cmd; + cd.lpData = (void*)data; + cd.cbData = len; + return (int)SendMessage(hwndAMODI, WM_COPYDATA, 0, (LPARAM)&cd); +} + +void CheckAMODIAlive() +{ + CallbackMain(DCH_LAUNCH_AMODI, NULL, 0, 0); +} + +void SendMoveMessage() +{ +#if MOVESEND_POST + PostMessage(hwndCallback, WM_MOVESEND, MouseMoving ? 0 : -1, 0); +#else +// CallbackMain(DCH_MOVESEND, pt, sizeof(*pt), 0); + MouseMoving = true; + if (SendMoveEvent) SetEvent(SendMoveEvent); +#endif +} +void SendCancelMove() +{ +#if MOVESEND_POST + PostMessage(hwndCallback, WM_MOVESEND, MouseMoving ? 0 : -1, 0); +#else +// CallbackMain(DCH_MOVESEND, NULL, 0, (HWND)-1); + MouseMoving = false; + if (SendMoveEvent) SetEvent(SendMoveEvent); +#endif +} + +#if !MOVESEND_POST +// main program‚ÌWindows messageˆ—‚ªd‚¢‚ƁACalblackMain‚àd‚­‚Ȃ邽‚߁A +// mouse move‚Í•Êthread‚ŏˆ— +DWORD WINAPI SendMoveThread(LPVOID vdParam) +{ + while(1){ + if (WaitForSingleObject(SendMoveEvent, INFINITE) != WAIT_OBJECT_0){ + break; + } + CallbackMain(DCH_MOVESEND, NULL, 0, (HWND)(MouseMoving ? 0 : -1)); + } + return 0; +} +#endif + +#if EXC_WOW64 && defined(_M_X64) +void CheckWOW64() +{ + typedef BOOL (WINAPI *FNIsWow64Process)(HANDLE hProcess, PBOOL Wow64Process); + + FNIsWow64Process _IsWow64Process = (FNIsWow64Process)GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process"); + if (_IsWow64Process){ + BOOL flag = FALSE; + if (_IsWow64Process(hProcess, &flag)){ + fWow64 = int_bool(flag); + } + } +} +#endif + +bool EnablePrivilege(LPTSTR lpszPrivilege, bool bEnable) +{ + BOOL bResult; + LUID luid; + HANDLE hToken; + TOKEN_PRIVILEGES tokenPrivileges; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) + return false; + + if (!LookupPrivilegeValue(NULL, lpszPrivilege, &luid)) { + CloseHandle(hToken); + return false; + } + + tokenPrivileges.PrivilegeCount = 1; + tokenPrivileges.Privileges[0].Luid = luid; + tokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; + + bResult = AdjustTokenPrivileges(hToken, FALSE, &tokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL); + + CloseHandle(hToken); + + return bResult && GetLastError() == ERROR_SUCCESS; +} + +/*======================================================================// +// DllMain +//----------------------------------------------------------------------// +// Description: +// +// Arguments: +// +// Return Value: +// +//======================================================================*/ +#ifdef _MSC_VER +BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID ) +#else +int WINAPI DllEntryPoint(HINSTANCE hInst, DWORD reason, LPVOID) +#endif +{ + switch ( reason ){ + case DLL_PROCESS_ATTACH: + hInstance = hInst; + idProcess = GetCurrentProcessId(); + for (int i=0;i<2;i++){ + hProcess = OpenProcess( PROCESS_ALL_ACCESS|PROCESS_VM_WRITE|PROCESS_VM_OPERATION, TRUE, idProcess ); + if ( hProcess ){ +#if USE_DBW + DBW("Attach %d(%08X)-%d : %08X", idProcess, hProcess, attach++,_ExtTextOutA); +#endif + break; + } else { + DBW("OpenProcess Error: %08X %d", idProcess, GetLastError()); + if (i==0){ + if (!EnablePrivilege(SE_DEBUG_NAME, true)) { + break; // failed + } + } + } + } +#if EXC_WOW64 && defined(_M_X64) + CheckWOW64(); +#ifdef _WIN64 + if (fWow64){ + DBW("WOW64 true"); + return FALSE; + } +#else + if (!fWow64){ + DBW("WOW64 false"); + return FALSE; + } +#endif + DBW("fWow64=%d", fWow64); +#endif + if (siPageSize==0){ + SYSTEM_INFO si; + GetSystemInfo( &si ); + siPageSize = si.dwPageSize; + } + hInstSHCore = LoadLibrary(_T("shcore.dll")); +#if !MOVESEND_POST + SendMoveEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + CreateThread(NULL , 0 , SendMoveThread , NULL , 0 , &SendMoveThreadId); +#endif + break; + case DLL_PROCESS_DETACH: +// UNPROTECT_SHARE(); +#if !MOVESEND_POST + if (SendMoveEvent){ + CloseHandle(SendMoveEvent); + SendMoveEvent = NULL; + } +#endif + if (hInstSHCore){ + FreeLibrary(hInstSHCore); + hInstSHCore = NULL; + } +#if USE_DBW + DBW("Detach %d-%d", GetCurrentProcessId(),--attach); +#endif + if ( hProcess ){ + CloseHandle( hProcess ); + } + break; + } + return TRUE; +} +//--------------------------------------------------------------------------- +static HWND hWin = NULL; +static const char *clsname = "TDbgMsgForm"; +static const char *winname = "Debug Messenger"; +void dbw( const char *format, ... ) +{ + if ( !hWin ){ + hWin = FindWindowA( clsname, winname ); + if ( !hWin ) return; + } + va_list ap; + va_start( ap, format ); + char buf[ 2048 ]; +#ifdef _WIN64 + strcpy(buf, "x64:"); + wvsprintfA( buf+4, format, ap ); +#else + wvsprintfA( buf, format, ap ); +#endif + COPYDATASTRUCT cds; + cds.dwData = 1; // Indicate String + cds.cbData = (DWORD)strlen(buf); + cds.lpData = buf; + SendMessage( hWin, WM_COPYDATA, NULL, (LPARAM)&cds ); + va_end( ap ); +} diff --git a/DCHook/DCHook.def b/DCHook/DCHook.def new file mode 100644 index 0000000..85ca43d --- /dev/null +++ b/DCHook/DCHook.def @@ -0,0 +1,16 @@ +LIBRARY DCHOOK +DESCRIPTION 'DC hook for event hot keys' + +SECTIONS + .sdata READ WRITE SHARED + .sbss READ WRITE SHARED + .stext READ SHARED + +EXPORTS + Config @1 + Init @2 + Uninit @3 + Config2 @4 + Capture @5 + WaitForCaptureResult @6 + diff --git a/DCHook/DCHook.h b/DCHook/DCHook.h new file mode 100644 index 0000000..d19877b --- /dev/null +++ b/DCHook/DCHook.h @@ -0,0 +1,67 @@ +#ifndef __DCHOOK_H +#define __DCHOOK_H + +struct TDCHConfig { + int UseAMODI : 1; + int OnlyAMODI : 1; + int MoveSend : 1; + int OnlyImage : 1; + int ScaleX; + int ScaleY; + char AMODIPath[_MAX_PATH]; +}; + +extern "C" { + +__declspec(dllexport) bool WINAPI Init( HWND, const char *module_name, bool windowsnt, const char *vxd_path ); +__declspec(dllexport) void WINAPI Uninit(); +__declspec(dllexport) unsigned int WINAPI Debug(); + +typedef bool (WINAPI *FNDCHInit)( HWND, const char *module_name, bool windowsnt, const char *vxd_path ); +typedef void (WINAPI *FNDCHUninit)(); +typedef int (WINAPI *FNDCHConfig)( int clickonly, int keyaction, int keyflag ); +typedef int (WINAPI *FNDCHConfig2)( struct TDCHConfig *cfg ); +typedef int (WINAPI *FNDCHCapture)( HWND hwnd, POINT *pt, bool movesend, bool non_block ); +typedef int (WINAPI *FNDCHWaitForCaptureResult)( bool send_text, unsigned waittime ); +typedef unsigned int (WINAPI *FNDebug)(); + +} + +/* WM_COPYSTRUCT message */ +#define DCH_START 0x1000 +#define DCH_END 0x1001 +#define DCH_EXTTEXTOUTA 0x1002 +#define DCH_EXTTEXTOUTW 0x1003 +#define DCH_HITTEXT1 0x1010 +#define DCH_HITTEXT2 0x1011 // UNICODE‚Ì‚Ý(DCH_HITTEXT2‚Ì‚ ‚ƁADCH_HITTEXT3‚ª‚­‚é) +#define DCH_HITTEXT3 0x1012 // ANSI‚Ì‚Ý +// UNICODE‚ňµ‚¢‚½‚¢ê‡‚́ADCH_HITTEXT2‚ÆDCH_HITTEXT3‚ðŽg—p‚·‚é +// UNICODE‚ňµ‚¢‚½‚­‚È‚¢ê‡(UNICODE->ANSI•ÏŠ·‚ð•K—v‚Æ‚·‚éê‡)‚́ADCH_HITTEXT1‚Ì‚Ý‚ðŽg—p‚·‚é +#define DCH_MOVESEND 0x0200 // DCH_END‚Æ‚Ì‘g‚ݍ‡‚킹 or ’P‘Ì + +#define DCH_MENU 0x1100 // DokoPop Menu +#define DCH_TOGGLE 0x1101 // Toggle Click Only +#define DCH_LAUNCH_AMODI 0x1102 // Launch AMODI if not alive + +/* Do not use 0x12xx!! */ + +/* Key Definitions */ +#define KA_POPUP 1 +#define KA_MENU 2 +#define KA_TOGGLE 3 +#define KA_POPUP_NC 0x10 + +#define KF_SHIFT 0x01 +#define KF_CONTROL 0x02 +#define KF_MENU 0x04 +#define KF_LWIN 0x08 +#define KF_RWIN 0x10 +#define KF_APPS 0x20 +#define KF_LEFTCLICK 0x40 +#define KF_CLICKONLY 0x80 +#define KF_LRCLICK 0x100 +#define KF_MIDCLICK 0x200 + + +#endif // __DCHOOK_H + diff --git a/DCHook/DCHook.mak b/DCHook/DCHook.mak new file mode 100644 index 0000000..72f5799 --- /dev/null +++ b/DCHook/DCHook.mak @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on DCHook.dsp + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +OUTDIR=. +INTDIR=. +# Begin Custom Macros +OutDir=.\. +# End Custom Macros + + +ALL : "$(OUTDIR)\DCHook.dll" + + + +CLEAN : + -@erase "$(INTDIR)\dchook.res" + -@erase "$(INTDIR)\dchook.obj" + -@erase "$(INTDIR)\dchook.sbr" + -@erase "$(OUTDIR)\DCHook.dll" + -@erase "$(OUTDIR)\DCHook.exp" + -@erase "$(OUTDIR)\DCHook.lib" + -@erase "$(OUTDIR)\DCHook.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP_PROJ=/nologo /ML /W4 /GX /G4 /GA /O1 /I "$(MSAADEV)\inc32" /D "WIN32" /D "NDEBUG"\ + /D "_WINDOWS" /FR"$(INTDIR)\\" /Fp"$(INTDIR)\DCHook.pch" /YX /Fo"$(INTDIR)\\"\ + /Fd"$(INTDIR)\\" /FD /c +CPP_OBJS=./ +CPP_SBRS=./ +MTL_PROJ=/nologo /I "$(MSAADEV)\inc32" /D "NDEBUG" /mktyplib203 /win32 +RSC_PROJ=/l 0x409 /fo"$(INTDIR)\dchook.res" /i "$(MSAADEV)\inc32" /d "NDEBUG" + +LINK32=link.exe +LINK32_FLAGS=user32.lib kernel32.lib gdi32.lib advapi32.lib \ + /nologo /subsystem:windows /dll /incremental:no\ + /pdb:"$(OUTDIR)\DCHook.pdb" /map:"$(INTDIR)\DCHook.map" /machine:I386\ + /def:".\dchook.def" /out:"$(OUTDIR)\DCHook.dll"\ + /implib:"$(OUTDIR)\DCHook.lib" /libpath:"$(MSAADEV)\lib" +DEF_FILE= \ + ".\dchook.def" +LINK32_OBJS= \ + "$(INTDIR)\dchook.res" \ + "$(INTDIR)\dchook.obj" + +"$(OUTDIR)\DCHook.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +.c{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_OBJS)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(CPP_SBRS)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +SOURCE=.\dchook.rc + +"$(INTDIR)\dchook.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + +SOURCE=.\dchook.cpp +DEP_CPP_KEYS_= "DCHook.h" + +"$(INTDIR)\dchook.obj" : $(SOURCE) $(DEP_CPP_KEYS_) "$(INTDIR)" + diff --git a/DCHook/DCHook.sln b/DCHook/DCHook.sln new file mode 100644 index 0000000..e8518fa --- /dev/null +++ b/DCHook/DCHook.sln @@ -0,0 +1,25 @@ +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DCHook", "DCHook.vcxproj", "{8C65CE15-64F8-43E6-968D-DBBB96858BB2}" +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 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug|Win32.ActiveCfg = Debug|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug|Win32.Build.0 = Debug|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug|x64.ActiveCfg = Debug|x64 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug|x64.Build.0 = Debug|x64 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release|Win32.ActiveCfg = Release|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release|Win32.Build.0 = Release|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release|x64.ActiveCfg = Release|x64 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DCHook/DCHook.vcproj b/DCHook/DCHook.vcproj new file mode 100644 index 0000000..2023513 --- /dev/null +++ b/DCHook/DCHook.vcproj @@ -0,0 +1,376 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DCHook/DCHook.vcxproj b/DCHook/DCHook.vcxproj new file mode 100644 index 0000000..0cba8e7 --- /dev/null +++ b/DCHook/DCHook.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {8C65CE15-64F8-43E6-968D-DBBB96858BB2} + Win32Proj + + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + DynamicLibrary + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(Platform)\$(Configuration) + $(Platform)\$(Configuration) + Debug\ + Debug\ + true + true + $(Platform)\$(Configuration) + $(Platform)\$(Configuration) + Release\ + Release\ + false + false + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DCHOOK_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + + + Level3 + EditAndContinue + + + $(OutDir)DCHook.dll + DCHook.def + true + $(OutDir)DCHook.pdb + Windows + $(OutDir)DCHook.lib + MachineX86 + + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DCHOOK_EXPORTS;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + + + Level3 + ProgramDatabase + + + $(OutDir)DCHook.dll + DCHook.def + true + $(OutDir)DCHook.pdb + Windows + $(OutDir)DCHook.lib + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DCHOOK_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + $(OutDir)DCHook.dll + DCHook.def + true + Windows + true + true + $(OutDir)DCHook.lib + MachineX86 + + + + + WIN32;NDEBUG;_WINDOWS;_USRDLL;DCHOOK_EXPORTS;%(PreprocessorDefinitions) + MultiThreaded + + + Level3 + ProgramDatabase + + + $(OutDir)DCHook.dll + DCHook.def + true + Windows + true + true + $(OutDir)DCHook.lib + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/DCHook/DCHook.vcxproj.filters b/DCHook/DCHook.vcxproj.filters new file mode 100644 index 0000000..245a5fc --- /dev/null +++ b/DCHook/DCHook.vcxproj.filters @@ -0,0 +1,35 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;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 + + + + + ソース ファイル + + + ソース ファイル + + + + + ソース ファイル + + + + + リソース ファイル + + + \ No newline at end of file diff --git a/DCHook/MonitorScale.cpp b/DCHook/MonitorScale.cpp new file mode 100644 index 0000000..5de8714 --- /dev/null +++ b/DCHook/MonitorScale.cpp @@ -0,0 +1,270 @@ +#include +#include + +#if WINVER<0x0601 +#define QDC_ALL_PATHS 0x00000001 +#define QDC_ONLY_ACTIVE_PATHS 0x00000002 +#define QDC_DATABASE_CURRENT 0x00000004 +typedef enum +{ + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = -1, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = 3, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = 4, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = 5, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = 6, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = 8, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = 9, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = 10, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = 11, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = 12, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = 13, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = 14, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x80000000, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY; +typedef enum +{ + DISPLAYCONFIG_ROTATION_IDENTITY = 1, + DISPLAYCONFIG_ROTATION_ROTATE90 = 2, + DISPLAYCONFIG_ROTATION_ROTATE180 = 3, + DISPLAYCONFIG_ROTATION_ROTATE270 = 4, + DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_ROTATION; +typedef enum +{ + DISPLAYCONFIG_SCALING_IDENTITY = 1, + DISPLAYCONFIG_SCALING_CENTERED = 2, + DISPLAYCONFIG_SCALING_STRETCHED = 3, + DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4, + DISPLAYCONFIG_SCALING_CUSTOM = 5, + DISPLAYCONFIG_SCALING_PREFERRED = 128, + DISPLAYCONFIG_SCALING_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_SCALING; +typedef struct DISPLAYCONFIG_RATIONAL +{ + UINT32 Numerator; + UINT32 Denominator; +} DISPLAYCONFIG_RATIONAL; +typedef enum +{ + DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0, + DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3, + DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_SCANLINE_ORDERING; +typedef enum +{ + DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1, + DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2, + DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_MODE_INFO_TYPE; +typedef struct DISPLAYCONFIG_2DREGION +{ + UINT32 cx; + UINT32 cy; +} DISPLAYCONFIG_2DREGION; +typedef struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO +{ + UINT64 pixelRate; + DISPLAYCONFIG_RATIONAL hSyncFreq; + DISPLAYCONFIG_RATIONAL vSyncFreq; + DISPLAYCONFIG_2DREGION activeSize; + DISPLAYCONFIG_2DREGION totalSize; + UINT32 videoStandard; + DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering; +} DISPLAYCONFIG_VIDEO_SIGNAL_INFO; +typedef enum +{ + DISPLAYCONFIG_PIXELFORMAT_8BPP = 1, + DISPLAYCONFIG_PIXELFORMAT_16BPP = 2, + DISPLAYCONFIG_PIXELFORMAT_24BPP = 3, + DISPLAYCONFIG_PIXELFORMAT_32BPP = 4, + DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5, + DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32 = 0xffffffff +} DISPLAYCONFIG_PIXELFORMAT; +typedef enum +{ + DISPLAYCONFIG_TOPOLOGY_INTERNAL = 0x00000001, + DISPLAYCONFIG_TOPOLOGY_CLONE = 0x00000002, + DISPLAYCONFIG_TOPOLOGY_EXTEND = 0x00000004, + DISPLAYCONFIG_TOPOLOGY_EXTERNAL = 0x00000008, + DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_TOPOLOGY_ID; +typedef enum +{ + DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1, + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2, + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3, + DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4, + DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5, + DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_DEVICE_INFO_TYPE; + +typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO +{ + LUID adapterId; + UINT32 id; + UINT32 modeInfoIdx; + UINT32 statusFlags; +} DISPLAYCONFIG_PATH_SOURCE_INFO; +typedef struct DISPLAYCONFIG_PATH_TARGET_INFO +{ + LUID adapterId; + UINT32 id; + UINT32 modeInfoIdx; + DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology; + DISPLAYCONFIG_ROTATION rotation; + DISPLAYCONFIG_SCALING scaling; + DISPLAYCONFIG_RATIONAL refreshRate; + DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering; + BOOL targetAvailable; + UINT32 statusFlags; +} DISPLAYCONFIG_PATH_TARGET_INFO; +typedef struct DISPLAYCONFIG_PATH_INFO +{ + DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo; + DISPLAYCONFIG_PATH_TARGET_INFO targetInfo; + UINT32 flags; +} DISPLAYCONFIG_PATH_INFO; +typedef struct DISPLAYCONFIG_TARGET_MODE +{ + DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo; +} DISPLAYCONFIG_TARGET_MODE; +typedef struct DISPLAYCONFIG_SOURCE_MODE +{ + UINT32 width; + UINT32 height; + DISPLAYCONFIG_PIXELFORMAT pixelFormat; + POINTL position; +} DISPLAYCONFIG_SOURCE_MODE; +typedef struct DISPLAYCONFIG_MODE_INFO +{ + DISPLAYCONFIG_MODE_INFO_TYPE infoType; + UINT32 id; + LUID adapterId; + union + { + DISPLAYCONFIG_TARGET_MODE targetMode; + DISPLAYCONFIG_SOURCE_MODE sourceMode; + }; +} DISPLAYCONFIG_MODE_INFO; +typedef struct DISPLAYCONFIG_DEVICE_INFO_HEADER +{ + DISPLAYCONFIG_DEVICE_INFO_TYPE type; + UINT32 size; + LUID adapterId; + UINT32 id; +} DISPLAYCONFIG_DEVICE_INFO_HEADER; + +#endif + +typedef WINUSERAPI LONG (WINAPI *FNGetDisplayConfigBufferSizes)(UINT32 flags, UINT32* numPathArrayElements, UINT32* numModeInfoArrayElements); +typedef WINUSERAPI LONG (WINAPI *FNSetDisplayConfig)(UINT32 numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32 numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, UINT32 flags); +typedef WINUSERAPI LONG (WINAPI *FNQueryDisplayConfig)(UINT32 flags, UINT32* numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32* numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID* currentTopologyId); +typedef WINUSERAPI LONG (WINAPI *FNDisplayConfigGetDeviceInfo)(DISPLAYCONFIG_DEVICE_INFO_HEADER* requestPacket); + +class TDllHandle { +protected: + HINSTANCE hInst; +public: + TDllHandle(HINSTANCE _hInst) + :hInst(_hInst) + { + } + ~TDllHandle(){ + if (hInst) FreeLibrary(hInst); + } + HINSTANCE inst(){ return hInst; } + operator HINSTANCE (){ return hInst; } + FARPROC GetProcAddress(LPCSTR name) + { return ::GetProcAddress(hInst, name); } +}; + +static TDllHandle *dllHandle = NULL; +static FNGetDisplayConfigBufferSizes _GetDisplayConfigBufferSizes; +static FNQueryDisplayConfig _QueryDisplayConfig; +static bool called = false; +static HMONITOR hPrevMonitor = NULL; +static int prevDpi = 0; +class TDestructor { +public: + ~TDestructor(){ if (dllHandle){ delete dllHandle; dllHandle = NULL; } } +} destructor; + +int GetMonitorScale() +{ + int dpi = 96; + + if (!called){ + called = true; + HINSTANCE hDll = LoadLibrary( _T("user32") ); + if (!hDll) + return dpi; + + TDllHandle hInst(hDll); + dllHandle = new TDllHandle(hDll); + + _GetDisplayConfigBufferSizes = (FNGetDisplayConfigBufferSizes)dllHandle->GetProcAddress("GetDisplayConfigBufferSizes"); + if (!_GetDisplayConfigBufferSizes) return dpi; + _QueryDisplayConfig = (FNQueryDisplayConfig)dllHandle->GetProcAddress("QueryDisplayConfig"); + if (!_QueryDisplayConfig) return dpi; + } + + if (!dllHandle) return dpi; + + POINT pt; + GetCursorPos( &pt ); + HMONITOR hMonitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONULL ); + if (!hMonitor) return dpi; + + if (hMonitor == hPrevMonitor){ + return prevDpi; + } + hPrevMonitor = hMonitor; + + MONITORINFOEX LogicalMonitorInfo; + LogicalMonitorInfo.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &LogicalMonitorInfo); + int LogicalMonitorWidth = LogicalMonitorInfo.rcMonitor.right - LogicalMonitorInfo.rcMonitor.left; + + int LogicalDesktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + + UINT32 numofpath; + UINT32 numofmode; + _GetDisplayConfigBufferSizes(QDC_DATABASE_CURRENT, &numofpath, &numofmode); + + DISPLAYCONFIG_PATH_INFO *dpis = new DISPLAYCONFIG_PATH_INFO[numofpath]; + DISPLAYCONFIG_MODE_INFO *pModeInfoArray = new DISPLAYCONFIG_MODE_INFO[numofmode]; + DISPLAYCONFIG_TOPOLOGY_ID tid; + _QueryDisplayConfig(QDC_DATABASE_CURRENT, &numofpath, dpis, &numofmode, pModeInfoArray, &tid); //TODO: Windows7 or later + + int PhysicalDesktopWidth = LogicalDesktopWidth; + int PhysicalMonitorWidth = LogicalMonitorWidth; + + for (int i=0;i<(int)numofmode;i++){ + if (pModeInfoArray[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE){ + //DBW("%d: %d", i, pModeInfoArray[i].sourceMode.width); + PhysicalDesktopWidth = pModeInfoArray[i].sourceMode.width; + //int PhysicalDesktopWidth = + //int ScaleFactor = (LogicalMonitorWidth/LogicalDesktopWidth) / (PhysicalMonitorWidth/PhysicalDesktopWidth) + //return 96 * 1; + } else + if (pModeInfoArray[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_TARGET){ + PhysicalMonitorWidth = pModeInfoArray[i].targetMode.targetVideoSignalInfo.activeSize.cx; + //DBW("%d: %d", i, PhysicalMonitorWidth); + } + } + + //int PhysicalMonitorWidth = pModeInfoArray[i].sourceMode.width; + //int ScaleFactor = (LogicalMonitorWidth/LogicalDesktopWidth) / (PhysicalMonitorWidth/PhysicalDesktopWidth) + + delete[] dpis; + delete[] pModeInfoArray; + + return prevDpi = dpi * PhysicalDesktopWidth / LogicalDesktopWidth; +} diff --git a/DCHook/MonitorScale.h b/DCHook/MonitorScale.h new file mode 100644 index 0000000..c900b8e --- /dev/null +++ b/DCHook/MonitorScale.h @@ -0,0 +1,6 @@ +#ifndef __MonitorScale_h +#define __MonitorScale_h + +int GetMonitorScale(); + +#endif diff --git a/DCHook/VS2003/DCHook.sln b/DCHook/VS2003/DCHook.sln new file mode 100644 index 0000000..9b639fc --- /dev/null +++ b/DCHook/VS2003/DCHook.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DCHook", "DCHook.vcproj", "{8C65CE15-64F8-43E6-968D-DBBB96858BB2}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug.ActiveCfg = Debug|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Debug.Build.0 = Debug|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release.ActiveCfg = Release|Win32 + {8C65CE15-64F8-43E6-968D-DBBB96858BB2}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/DCHook/VS2003/DCHook.vcproj b/DCHook/VS2003/DCHook.vcproj new file mode 100644 index 0000000..c7274d2 --- /dev/null +++ b/DCHook/VS2003/DCHook.vcproj @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DCHook/VS2008/DCHook.sln b/DCHook/VS2008/DCHook.sln new file mode 100644 index 0000000..a89cf9d --- /dev/null +++ b/DCHook/VS2008/DCHook.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DCHook", "DCHook.vcproj", "{B8C9A2E3-2767-45C7-91B5-1B717C3653F3}" +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 + {B8C9A2E3-2767-45C7-91B5-1B717C3653F3}.Debug|Win32.ActiveCfg = Debug|Win32 + {B8C9A2E3-2767-45C7-91B5-1B717C3653F3}.Debug|Win32.Build.0 = Debug|Win32 + {B8C9A2E3-2767-45C7-91B5-1B717C3653F3}.Debug|x64.ActiveCfg = Debug|x64 + {B8C9A2E3-2767-45C7-91B5-1B717C3653F3}.Debug|x64.Build.0 = Debug|x64 + {B8C9A2E3-2767-45C7-91B5-1B717C3653F3}.Release|Win32.ActiveCfg = Release|Win32 + {B8C9A2E3-2767-45C7-91B5-1B717C3653F3}.Release|Win32.Build.0 = Release|Win32 + {B8C9A2E3-2767-45C7-91B5-1B717C3653F3}.Release|x64.ActiveCfg = Release|x64 + {B8C9A2E3-2767-45C7-91B5-1B717C3653F3}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DCHook/VS2008/DCHook.vcproj b/DCHook/VS2008/DCHook.vcproj new file mode 100644 index 0000000..c356754 --- /dev/null +++ b/DCHook/VS2008/DCHook.vcproj @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/DCHook/VS2015/DCHook.sln b/DCHook/VS2015/DCHook.sln new file mode 100644 index 0000000..05c95f6 --- /dev/null +++ b/DCHook/VS2015/DCHook.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DCHook", "DCHook.vcxproj", "{16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}.Debug|x64.ActiveCfg = Debug|x64 + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}.Debug|x64.Build.0 = Debug|x64 + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}.Debug|x86.ActiveCfg = Debug|Win32 + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}.Debug|x86.Build.0 = Debug|Win32 + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}.Release|x64.ActiveCfg = Release|x64 + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}.Release|x64.Build.0 = Release|x64 + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}.Release|x86.ActiveCfg = Release|Win32 + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DCHook/VS2015/DCHook.vcxproj b/DCHook/VS2015/DCHook.vcxproj new file mode 100644 index 0000000..e66c96d --- /dev/null +++ b/DCHook/VS2015/DCHook.vcxproj @@ -0,0 +1,158 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + {16E6F306-BD26-4E7E-9A8E-96A5231AD6A3} + Win32Proj + DCHook + 8.1 + + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + DynamicLibrary + true + v140 + Unicode + + + DynamicLibrary + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + + + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;_USRDLL;DCHOOK_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + + + Level3 + Disabled + _DEBUG;_WINDOWS;_USRDLL;DCHOOK_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + + + + + Level3 + + + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;_USRDLL;DCHOOK_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + NDEBUG;_WINDOWS;_USRDLL;DCHOOK_EXPORTS;%(PreprocessorDefinitions) + true + + + Windows + true + true + true + + + + + + + + + + + + + \ No newline at end of file diff --git a/DCHook/VS2015/DCHook.vcxproj.filters b/DCHook/VS2015/DCHook.vcxproj.filters new file mode 100644 index 0000000..883d488 --- /dev/null +++ b/DCHook/VS2015/DCHook.vcxproj.filters @@ -0,0 +1,30 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;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 + + + + + ソース ファイル + + + ソース ファイル + + + + + ソース ファイル + + + \ No newline at end of file diff --git a/DCHook/dchook.rc b/DCHook/dchook.rc new file mode 100644 index 0000000..e69de29 diff --git a/DCHook64/DCHook64.h b/DCHook64/DCHook64.h new file mode 100644 index 0000000..6029090 --- /dev/null +++ b/DCHook64/DCHook64.h @@ -0,0 +1,38 @@ +#ifndef __DCHook64_h +#define __DCHook64_h + +// App -> dchk64.exe + +enum eHookDllCmd { + HDC_Load = WM_APP+0x100, + HDC_Unload, + HDC_Init, + HDC_Uninit, + HDC_Config, + HDC_Config2, + HDC_Capture, + HDC_CaptureAsync, + HDC_CaptureAsyncWait, + HDC_Debug, +}; + +struct HDCInitParam { + HWND hwnd; + //char module_name[]; + //bool windowsnt; + //const char *vxd_path; +}; + +struct HDCConfigParam { + int clickonly; + int keyaction; + int keyflag; +}; + +// dchk64.exe -> App +#define UM_SHORTCUT (WM_APP+33) + +// WPARAM value +#define SCINX_NOTIFY64 (0x1000) // notify from 64bit HookDll + +#endif diff --git a/DCHook64/dchk64/ReadMe.txt b/DCHook64/dchk64/ReadMe.txt new file mode 100644 index 0000000..9a4113d --- /dev/null +++ b/DCHook64/dchk64/ReadMe.txt @@ -0,0 +1,69 @@ +======================================================================== + Win32 アプリケーション: dchk64 プロジェクトの概要 +======================================================================== + +この dchk64 アプリケーションは、AppWizard により作成されました。 + +このファイルには、dchk64 +アプリケーションを構成する各ファイルの内容の概要が含まれています。 + + +dchk64.vcxproj + これは、アプリケーション ウィザードを使用して生成された VC++ + プロジェクトのメイン プロジェクト ファイルです。 + ファイルを生成した Visual C++ のバージョンに関する情報と、アプリケーション + ウィザードで選択されたプラットフォーム、 + 構成、およびプロジェクト機能に関する情報が含まれています。 + +dchk64.vcxproj.filters + これは、アプリケーション ウィザードで生成された VC++ プロジェクトのフィルター + ファイルです。 + このファイルには、プロジェクト内のファイルとフィルターとの間の関連付けに関する + 情報が含まれています。 この関連付けは、特定のノー + ドで同様の拡張子を持つファイルのグループ化を + 示すために IDE で使用されます (たとえば、".cpp" ファイルは "ソース ファイル" + フィルターに関連付けられています)。 + +dchk64.cpp + これは、メインのアプリケーション ソース ファイルです。 + +///////////////////////////////////////////////////////////////////////////// +AppWizard によって、次のリソースが作成されました。 + +dchk64.rc + これは、プログラムが使用するすべての Microsoft Windows リソースの一覧です。RES + サブディレクトリに格納されるアイコン、ビットマップ、 + およびカーソルをインクルードしています。 このファイルは、Microsoft Visual C++ + で直接編集できます。 + +Resource.h + これは、新しいリソース ID を定義する標準のヘッダー ファイルです。 + このファイルの読み込みおよび更新は、Microsoft Visual C++ で行います。 + +dchk64.ico + これは、アプリケーションのアイコン (32x32) として使用されるアイコン + ファイルです。 + このアイコンは、メイン リソース ファイル dchk64.rc + にインクルードされます。 + +small.ico + これは、アプリケーションのアイコンの小さいバージョン (16x16) を含むアイコン + ファイルです。 このアイコンは、メイン リソース ファイル dchk64.rc + にインクルードされます。 + +///////////////////////////////////////////////////////////////////////////// +その他の標準ファイル : + +StdAfx.h、StdAfx.cpp + これらのファイルは、dchk64.pch + という名前のプリコンパイル済みヘッダー (PCH) ファイルと、StdAfx.obj + という名前のプリコンパイル済みの型ファイルを構築するために使用されます。 + +///////////////////////////////////////////////////////////////////////////// +その他のメモ : + +AppWizard では "TODO:" +コメントを使用して、ユーザーが追加またはカスタマイズする必要のあるソース +コードを示します。 + +///////////////////////////////////////////////////////////////////////////// diff --git a/DCHook64/dchk64/Resource.h b/DCHook64/dchk64/Resource.h new file mode 100644 index 0000000..87a7c48 --- /dev/null +++ b/DCHook64/dchk64/Resource.h @@ -0,0 +1,31 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by dchk64.rc +// + +#define IDS_APP_TITLE 103 + +#define IDR_MAINFRAME 128 +#define IDD_DCHK64_DIALOG 102 +#define IDD_ABOUTBOX 103 +#define IDM_ABOUT 104 +#define IDM_EXIT 105 +#define IDI_DCHK64 107 +#define IDI_SMALL 108 +#define IDC_DCHK64 109 +#define IDC_MYICON 2 +#ifndef IDC_STATIC +#define IDC_STATIC -1 +#endif +// V‚µ‚¢ƒIƒuƒWƒFƒNƒg‚ÌŽŸ‚ÌŠù’è’l +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS + +#define _APS_NO_MFC 130 +#define _APS_NEXT_RESOURCE_VALUE 129 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif diff --git a/DCHook64/dchk64/dchk64.cpp b/DCHook64/dchk64/dchk64.cpp new file mode 100644 index 0000000..8812dd7 --- /dev/null +++ b/DCHook64/dchk64/dchk64.cpp @@ -0,0 +1,336 @@ +// dchk64.cpp : ƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚̃Gƒ“ƒgƒŠ ƒ|ƒCƒ“ƒg‚ð’è‹`‚µ‚Ü‚·B +// + +#include "stdafx.h" +#include "dchk64.h" +#include "../../DCHookTest/HookLoader.h" +#include "../DCHook64.h" + +#define MAX_LOADSTRING 100 + +// ƒOƒ[ƒoƒ‹•Ï”: +HINSTANCE hInst; // Œ»Ý‚̃Cƒ“ƒ^[ƒtƒFƒCƒX +TCHAR szTitle[MAX_LOADSTRING]; // ƒ^ƒCƒgƒ‹ ƒo[‚̃eƒLƒXƒg +TCHAR szWindowClass[MAX_LOADSTRING]; // ƒƒCƒ“ ƒEƒBƒ“ƒhƒE ƒNƒ‰ƒX–¼ + +const char *StrDCHOOKDLL = "DKPUHK64.dll"; +THookLoader HookDll(StrDCHOOKDLL); + +HWND hWnd = NULL; +HWND hwndParent = NULL; +HANDLE hMutex = NULL; +bool WindowsNT = true; + +#ifdef _DEBUG +#define DBW dbw +#else +#define DBW +#endif +void dbw( const char *format, ... ); + +// ‚±‚̃R[ƒh ƒ‚ƒWƒ…[ƒ‹‚ÉŠÜ‚Ü‚ê‚éŠÖ”‚̐錾‚ð“]‘—‚µ‚Ü‚·: +ATOM MyRegisterClass(HINSTANCE hInstance); +BOOL InitInstance(HINSTANCE, LPTSTR lpCmdLine, int); +void Cleanup(); +LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); + +int atox( const TCHAR *str, TCHAR **next ); + +int APIENTRY _tWinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPTSTR lpCmdLine, + int nCmdShow) +{ + UNREFERENCED_PARAMETER(hPrevInstance); + //UNREFERENCED_PARAMETER(lpCmdLine); + + MSG msg; + HACCEL hAccelTable; + + // ƒOƒ[ƒoƒ‹•¶Žš—ñ‚ð‰Šú‰»‚µ‚Ä‚¢‚Ü‚·B + LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); + LoadString(hInstance, IDC_DCHK64, szWindowClass, MAX_LOADSTRING); + MyRegisterClass(hInstance); + + // ƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚̏‰Šú‰»‚ðŽÀs‚µ‚Ü‚·: + if (!InitInstance (hInstance, lpCmdLine, nCmdShow)) + { + return FALSE; + } + + hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DCHK64)); + + // ƒƒCƒ“ ƒƒbƒZ[ƒW ƒ‹[ƒv: + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + + Cleanup(); + + return (int) msg.wParam; +} + + + +// +// ŠÖ”: MyRegisterClass() +// +// –Ú“I: ƒEƒBƒ“ƒhƒE ƒNƒ‰ƒX‚ð“o˜^‚µ‚Ü‚·B +// +// ƒRƒƒ“ƒg: +// +// ‚±‚̊֐”‚¨‚æ‚ÑŽg‚¢•û‚́A'RegisterClassEx' ŠÖ”‚ª’ljÁ‚³‚ꂽ +// Windows 95 ‚æ‚è‘O‚Ì Win32 ƒVƒXƒeƒ€‚ƌ݊·‚³‚¹‚éê‡‚É‚Ì‚Ý•K—v‚Å‚·B +// ƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚ªAŠÖ˜A•t‚¯‚ç‚ꂽ +// ³‚µ‚¢Œ`Ž®‚̏¬‚³‚¢ƒAƒCƒRƒ“‚ðŽæ“¾‚Å‚«‚é‚悤‚É‚·‚é‚ɂ́A +// ‚±‚̊֐”‚ðŒÄ‚яo‚µ‚Ä‚­‚¾‚³‚¢B +// +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 = NULL; //LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PDHK64)); +#ifdef _DEBUG + wcex.hCursor = LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); +#else + wcex.hCursor = NULL; //LoadCursor(NULL, IDC_ARROW); + wcex.hbrBackground = NULL; //(HBRUSH)(COLOR_WINDOW+1); +#endif + wcex.lpszMenuName = NULL; //MAKEINTRESOURCE(IDC_PDHK64); + wcex.lpszClassName = szWindowClass; + wcex.hIconSm = NULL; //LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL)); + + return RegisterClassEx(&wcex); +} + +// +// ŠÖ”: InitInstance(HINSTANCE, LPTSTR, int) +// +// –Ú“I: ƒCƒ“ƒXƒ^ƒ“ƒX ƒnƒ“ƒhƒ‹‚ð•Û‘¶‚µ‚āAƒƒCƒ“ ƒEƒBƒ“ƒhƒE‚ðì¬‚µ‚Ü‚·B +// +// ƒRƒƒ“ƒg: +// +// ‚±‚̊֐”‚ŁAƒOƒ[ƒoƒ‹•Ï”‚ŃCƒ“ƒXƒ^ƒ“ƒX ƒnƒ“ƒhƒ‹‚ð•Û‘¶‚µA +// ƒƒCƒ“ ƒvƒƒOƒ‰ƒ€ ƒEƒBƒ“ƒhƒE‚ðì¬‚¨‚æ‚Ñ•\Ž¦‚µ‚Ü‚·B +// +BOOL InitInstance(HINSTANCE hInstance, LPTSTR lpCmdLine, int nCmdShow) +{ + hInst = hInstance; // ƒOƒ[ƒoƒ‹•Ï”‚ɃCƒ“ƒXƒ^ƒ“ƒXˆ—‚ðŠi”[‚µ‚Ü‚·B + + TCHAR ModuleName[_MAX_PATH]; + GetModuleFileName(NULL, ModuleName, sizeof(ModuleName)/sizeof(TCHAR)); + hMutex = CreateMutex(NULL, FALSE, ModuleName); + if (GetLastError()==ERROR_ALREADY_EXISTS){ + return FALSE; // dup launched + } + +#ifdef _DEBUG + const int width = 800; + const int height = 400; +#else + const int width = 0; + const int height = 0; +#endif + + hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL); + + if (!hWnd) + { + return FALSE; + } + + hwndParent = (HWND)(LONG_PTR)atox(lpCmdLine, NULL); + //DBW("hwndParent=%d", (int)(LONG_PTR)hwndParent); + if (hwndParent){ + PostMessage(hwndParent, UM_SHORTCUT, SCINX_NOTIFY64, (LPARAM)hWnd); + //DBW("Posted"); + } + +#ifdef _DEBUG + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); +#endif + + return TRUE; +} + +void Cleanup() +{ + if (hMutex){ + CloseHandle(hMutex); + hMutex = NULL; + } +} + +// +// ŠÖ”: WndProc(HWND, UINT, WPARAM, LPARAM) +// +// –Ú“I: ƒƒCƒ“ ƒEƒBƒ“ƒhƒE‚̃ƒbƒZ[ƒW‚ðˆ—‚µ‚Ü‚·B +// +// WM_COMMAND - ƒAƒvƒŠƒP[ƒVƒ‡ƒ“ ƒƒjƒ…[‚̏ˆ— +// WM_PAINT - ƒƒCƒ“ ƒEƒBƒ“ƒhƒE‚Ì•`‰æ +// WM_DESTROY - ’†Ž~ƒƒbƒZ[ƒW‚ð•\Ž¦‚µ‚Ä–ß‚é +// +// +LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + //int wmId, wmEvent; + PAINTSTRUCT ps; + HDC hdc; + + switch (message) + { + case WM_CREATE: + HookDll.Load(hWnd); +#ifdef _DEBUG + { + if (!HookDll.Init(hWnd)){ + DBW("Hook.Init error"); + } +#if 0 + HookDll.Config(-1, KA_POPUP, KF_CONTROL); + TDCHConfig cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.UseAMODI = 0; + cfg.MoveSend = 0; + cfg.ScaleX = 0; + cfg.ScaleY = 0; + HookDll.Config2(&cfg); +#endif + } +#endif + break; +#if 0 + case WM_COMMAND: + wmId = LOWORD(wParam); + wmEvent = HIWORD(wParam); + // ‘I‘ð‚³‚ê‚½ƒƒjƒ…[‚̉ðÍ: + switch (wmId) + { + 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; +#endif + case WM_PAINT: + hdc = BeginPaint(hWnd, &ps); + EndPaint(hWnd, &ps); + break; + case WM_DESTROY: + PostQuitMessage(0); + break; + + case WM_COPYDATA: + { + COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lParam; + if ( !cds ) break; + switch (cds->dwData){ + case HDC_Init: + { + HDCInitParam &p = *(HDCInitParam*)cds->lpData; + return HookDll.Init(p.hwnd); + } + case HDC_Uninit: + HookDll.Uninit(); + break; + case HDC_Config: + { + HDCConfigParam &p = *(HDCConfigParam*)cds->lpData; + return HookDll.Config(p.clickonly, p.keyaction, p.keyflag); + } + case HDC_Config2: + return HookDll.Config2((TDCHConfig*)cds->lpData); + case HDC_Capture: + return HookDll.Capture(); + case HDC_CaptureAsync: + return HookDll.CaptureAsync(); + case HDC_CaptureAsyncWait: + return HookDll.CaptureAsyncWait(); + case HDC_Debug: + return HookDll.Debug(); + } + } + break; + default: + return DefWindowProc(hWnd, message, wParam, lParam); + } + return 0; +} + +int atox( const TCHAR *str, TCHAR **next ) +{ + unsigned val = 0; + while ( 1 ) + { + TCHAR c = *str; + if ( c >= '0' && c <= '9' ){ + val = (val<<4) + (c - '0'); + } else if ( c >= 'A' && c <= 'F' ){ + val = (val<<4) + ( c - 'A' + 10 ); + } else if ( c >= 'a' && c <= 'f' ){ + val = (val<<4) + ( c - 'a' + 10 ); + } else { + break; + } + str++; + } + if ( next ) *next = (TCHAR*)str; + return val; +} + +static HWND hWin = NULL; +static const TCHAR *clsnameW = _T("TDbgMsgForm"); +static const TCHAR *winnameW = _T("Debug Messenger"); + +void dbw( const char *format, ... ) +{ + if ( !hWin ){ + hWin = FindWindow( clsnameW, winnameW ); + if ( !hWin ) return; + } + va_list ap; + va_start( ap, format ); + char buf[ 2048 ]; + wvsprintfA( buf, format, ap ); + COPYDATASTRUCT cds; + cds.dwData = 1; // Indicate String + cds.cbData = (DWORD)strlen(buf)+1; + cds.lpData = buf; + SendMessageA( hWin, WM_COPYDATA, NULL, (LPARAM)&cds ); + va_end( ap ); +} + +static const char *MyWinTitle = ""; +HANDLE WinExecEx( const char *cmd, int show, const char *dir, const char *title ) +{ + STARTUPINFO sui; + memset( &sui, 0, sizeof(STARTUPINFO) ); + sui.cb = sizeof(STARTUPINFO); + sui.dwFlags = STARTF_USESHOWWINDOW; + sui.wShowWindow = (WORD)show; + sui.lpTitle = (LPTSTR)(title ? title : MyWinTitle); + PROCESS_INFORMATION pi; + if ( !CreateProcess( NULL, (LPTSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, dir, &sui, &pi ) ) + return NULL; + return pi.hProcess; +} diff --git a/DCHook64/dchk64/dchk64.h b/DCHook64/dchk64/dchk64.h new file mode 100644 index 0000000..d00d47e --- /dev/null +++ b/DCHook64/dchk64/dchk64.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/DCHook64/dchk64/dchk64.ico b/DCHook64/dchk64/dchk64.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 zZ4R8=3lZmX8>yW^9Yk!Kt?uy8b*xp(f|d+vFB=bU@y z#q$Z7kg_aFTUO;0S;O6tb@Aj3#@1v*&dD;~a`G-NPrCZ%#_Q*s`kl_}BfX~2bW1(i z(qHhlt$%A*XZ005BnLrtLfDRh&I+h6gVqIE01Y2IEx4UF&}*YVE*CM%*})3V>$r8C zpOvcAr6EnpOHoeCywqe0qj~fzQj%GW)bT9KBt}Z;+y3NX^e*GhS`V^KNej;+Cd+2>ti#xdTlHx=Yd;sh@#{PJwnl)i&#}_^Nbafpz&5&((-^ z#_-M^7Ga&?EHwj}@=lscqLq@+amiW!0+4tKC<(DK1_TX~Z@0Zh4++Lmpv%G14TJfB z4z1(KTRkMu`xekY43C)x$^!4H0|!m`Q4Uy`hkZ)8j$qa2xV+Sr4bZ4b0V_U$Pgbyk zJC-n7!Dth0!QnO|C*?iR$++*FW0H+*KG2@kZ{e?B>XIH%>3*fJ%{4W@L*H{g;>p|9kX8xv z-l#2U`TLbG7;UfY#8q-apDH@L$VYZm)xpx_*xsD z7DQj8TSqL-I!yGhkB$u5WlcVIxnmg~9Noh-IeJJSN5-ACp4`)a^ggU@BW!t7SGhhL zl!5;WJb^PN(Jx?L#l4x{s<2BHGpewSFSqnZpzX09mUrNtM|yU!xycmltL;^E`J?RU zZ6XWD(K&hf>k6s29Cdo-;EQsVAr~_eDN_<#LD_=LVIy&A?m&`lC(F$LAj?f?{SW73 zf1S;=C_@%h$KB<-_+nf{TjM|LP6N$U2|`)SqN9n(WK?eA#Pz2>)F;r<^&zpD1zs8N zOSo&$Wdlg8^-fE1r0s9r@a$9vb_+l&y>A+F(#EDq_Id8;^zz(rXC>x0VvG7CRqo-r z_oThz`ZRoUeIC9QVv{G@E!HJWJ*Snww#6~8Lyd{$r*k8WQ>N*uHkzD z8KZxG2HD_f;u@l)IwXBc({Q*d_pLZC$7A$EjD@}E`O3h+;bf zU8T=T#!_-UHYeK4MxlMU6Kj%}-y!g~L8o^jH>^(PPLNv>IZ z&`6^bRx;^xcB?}NRUGM5`|DvJl@3SaHP0aK2iFRF;VaGFNB3m!H0jfJ`R|^;pZs_W ze@Y&qcK8+lPHrHB-^RHq>c#Byj|by5D=XGrlP+)bOOh8ev-F=v={LUnVpT%apSY&( zvQZTgejdBPahVpWJ>>e~|124` c(Y0t4e}-LhyZgC;e>6WrEq<)^YJ+nA3vxc7KL7v# literal 0 HcmV?d00001 diff --git a/DCHook64/dchk64/dchk64.sln b/DCHook64/dchk64/dchk64.sln new file mode 100644 index 0000000..4f667e0 --- /dev/null +++ b/DCHook64/dchk64/dchk64.sln @@ -0,0 +1,26 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dchk64", "dchk64.vcxproj", "{5CBB6025-CCD7-40F7-8279-2B633DFA63CA}" +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 + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA}.Debug|Win32.ActiveCfg = Debug|Win32 + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA}.Debug|Win32.Build.0 = Debug|Win32 + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA}.Debug|x64.ActiveCfg = Debug|x64 + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA}.Debug|x64.Build.0 = Debug|x64 + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA}.Release|Win32.ActiveCfg = Release|x64 + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA}.Release|Win32.Build.0 = Release|x64 + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA}.Release|x64.ActiveCfg = Release|x64 + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/DCHook64/dchk64/dchk64.suo b/DCHook64/dchk64/dchk64.suo new file mode 100644 index 0000000000000000000000000000000000000000..e43c8d0682fddd756fa4236a55349f326dc21f99 GIT binary patch literal 11264 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 + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {5CBB6025-CCD7-40F7-8279-2B633DFA63CA} + Win32Proj + dchk64 + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + true + + + true + + + false + + + false + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);USE_UNICODE + + + Windows + true + + + + + Use + Level3 + Disabled + WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);USE_UNICODE + MultiThreadedDebug + + + Windows + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);USE_UNICODE + + + Windows + true + true + true + + + + + Level3 + Use + MaxSpeed + true + true + WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);USE_UNICODE + MultiThreaded + + + Windows + true + true + true + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + \ No newline at end of file diff --git a/DCHook64/dchk64/dchk64.vcxproj.filters b/DCHook64/dchk64/dchk64.vcxproj.filters new file mode 100644 index 0000000..25f1275 --- /dev/null +++ b/DCHook64/dchk64/dchk64.vcxproj.filters @@ -0,0 +1,56 @@ + + + + + {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 + + + + + + リソース ファイル + + + リソース ファイル + + + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + + + ソース ファイル + + + ソース ファイル + + + ソース ファイル + + + + + リソース ファイル + + + \ No newline at end of file diff --git a/DCHook64/dchk64/small.ico b/DCHook64/dchk64/small.ico new file mode 100644 index 0000000000000000000000000000000000000000..d551aa3aaf80adf9b7760e2eb8de95a5c3e53df6 GIT binary patch literal 23558 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 + +// C ƒ‰ƒ“ƒ^ƒCƒ€ ƒwƒbƒ_[ ƒtƒ@ƒCƒ‹ +#include +#include +#include +#include + + +// TODO: ƒvƒƒOƒ‰ƒ€‚É•K—v‚ȒljÁƒwƒbƒ_[‚ð‚±‚±‚ÅŽQÆ‚µ‚Ä‚­‚¾‚³‚¢B diff --git a/DCHook64/dchk64/targetver.h b/DCHook64/dchk64/targetver.h new file mode 100644 index 0000000..10b7ccd --- /dev/null +++ b/DCHook64/dchk64/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// SDKDDKVer.h ‚ðƒCƒ“ƒNƒ‹[ƒh‚·‚é‚ƁA—˜—p‚Å‚«‚éÅ‚àãˆÊ‚Ì Windows ƒvƒ‰ƒbƒgƒtƒH[ƒ€‚ª’è‹`‚³‚ê‚Ü‚·B + +// ˆÈ‘O‚Ì Windows ƒvƒ‰ƒbƒgƒtƒH[ƒ€—p‚ɃAƒvƒŠƒP[ƒVƒ‡ƒ“‚ðƒrƒ‹ƒh‚·‚éê‡‚́AWinSDKVer.h ‚ðƒCƒ“ƒNƒ‹[ƒh‚µA +// SDKDDKVer.h ‚ðƒCƒ“ƒNƒ‹[ƒh‚·‚é‘O‚ɁAƒTƒ|[ƒg‘ΏۂƂ·‚éƒvƒ‰ƒbƒgƒtƒH[ƒ€‚ðŽ¦‚·‚悤‚É _WIN32_WINNT ƒ}ƒNƒ‚ðÝ’肵‚Ü‚·B + +#include diff --git a/DCHookTest/DCHookLoader.cpp b/DCHookTest/DCHookLoader.cpp new file mode 100644 index 0000000..dbf85b0 --- /dev/null +++ b/DCHookTest/DCHookLoader.cpp @@ -0,0 +1,292 @@ +#include +#pragma hdrstop +#include +#include +#include "StringLib.h" +#include "DCHookLoader.h" +#include "HookLoader.h" +#include "Util.h" + +// LoadHook()‚Íapplication—§‚¿ã‚ª‚莞A‚Ü‚½‚ÍConfigurationŽž‚É‚P‰ñ‚¾‚¯ŒÄ‚΂ê‚é +// UnloadHook()‚ÍLoadHook()‚Æ•K‚¸‘΂Ŏg—p‚·‚é + +#define USE_HOOK64 1 + +#if USE_HOOK64 +#define IsWow64() (fWow64) +#else +#define IsWow64() (false) +#endif + +/// THookArray /// +THookArray::~THookArray() +{ + clear(); +} + +bool THookArray::Load(HWND hwnd) +{ + bool ret = true; + foreach(Hooks, it, hook_vec){ + if (!(*it)->Load(hwnd)){ + ret = false; + break; + } + } + return ret; +} +void THookArray::Unload() +{ + foreach(Hooks, it, hook_vec){ + (*it)->Unload(); + } +} +void THookArray::Uninit() +{ + foreach(Hooks, it, hook_vec){ + (*it)->Uninit(); + } +} +bool THookArray::Init(HWND hwnd) +{ + DBW("HookArray::Init"); + bool ret = true; +#if 0 // debug code + DBW("Init1"); Hooks[1]->Init(hwnd); // 64bit + DBW("Init0"); Hooks[0]->Init(hwnd); // 32bit +#else + foreach(Hooks, it, hook_vec){ + if (!(*it)->Init(hwnd)){ + ret = false; + } + } +#endif + return ret; +} +void THookArray::Init32(HWND hwnd) +{ + Hooks[0]->Init(hwnd); +} +int THookArray::Config( int clickonly, int keyaction, int keyflag ) +{ + foreach(Hooks, it, hook_vec){ + (*it)->Config(clickonly, keyaction, keyflag); + } + return 0; +} +int THookArray::Config2( struct TDCHConfig *cfg ) +{ + foreach(Hooks, it, hook_vec){ + (*it)->Config2(cfg); + } + return 0; +} +int THookArray::Capture() +{ + int ret = 0; + foreach(Hooks, it, hook_vec){ + if ((*it)->Capture()) + ret = 1; + } + return ret; +} +int THookArray::CaptureAsync() +{ + int ret = 0; + foreach(Hooks, it, hook_vec){ + if ((*it)->CaptureAsync()) + ret = 1; + } + return ret; +} +int THookArray::CaptureAsyncWait() +{ + int ret = 0; + foreach(Hooks, it, hook_vec){ + int r = (*it)->CaptureAsyncWait(); + if (r!=0){ + ret = r; + break; + } + } + return ret; +} +int THookArray::Debug() +{ + int ret = 0; + foreach(Hooks, it, hook_vec){ + int r = (*it)->Debug(); + if (r) + ret = r; + } + return ret; +} + +void THookArray::clear() +{ + Uninit(); + foreach(Hooks, it, hook_vec){ + delete *it; + } + Hooks.clear(); +} + +bool THookArray::IsLoaded() +{ + if (Hooks.size()==0) + return false; + return Hooks[0]->IsLoaded(); +} + +/// TDCHookLoader /// +TDCHookLoader::TDCHookLoader(bool use64) + :Use64(use64) +{ + EnableSendAllKeys = false; + Hook64 = NULL; + Hook32 = NULL; + LoadPending = false; +} +#if !defined(DSKSVR) && !defined(DCHOOK) +void TDCHookLoader::SaveProfile(const tchar *param_string) +{ + prof.WriteString(PFS_SHORTCUT, StrParams, param_string); +} + +tnstr TDCHookLoader::LoadProfile() +{ + return prof.ReadString(PFS_SHORTCUT, StrParams, _T("")); +} +#endif + +bool TDCHookLoader::LoadHook( HWND hwndParent ) +{ + if (Hooks.IsLoaded() || LoadPending) return true; + + if (Hooks.size()==0){ + Hooks.add(Hook32 = new THookLoader(NAME_DKPPHKDLL) ); +#ifdef _DEBUG + if (!DebugHook) +#endif + { + if (Use64 && IsWow64()){ + Hooks.add(Hook64 = new THookLoader64(hwndParent)); + } + } + } + + if (!Hooks.Load(hwndParent)){ + DBW("Hooks.Load failed"); + return false; + } + + if (Hook64 && Hook64->IsPending()){ + LoadPending = true; + hwndSavedParent = hwndParent; + return true; + } + + LoadHookPost(hwndParent); + + return true; +} + +void TDCHookLoader::LoadHookPost(HWND hwndParent) +{ + Hooks.Init(hwndParent); +#if 0 + int num = LoadKeyProfiles(); + if ( num > 0 || EnableSendAllKeys ){ + if ( !Hooks.InitHook( hwndParent, UM_SHORTCUT ) ){ + num = 0; + } + } + +#if !defined(DSKSVR) && !defined(DCHOOK) + //Note: SendAllKeys‚ð—LŒø‚É‚·‚é‚Æ32bitAppã‚Å“ñd‚ɃCƒxƒ“ƒg‚ª‘—‚ç‚ê‚Ä‚­‚éBiŒ´ˆö•s–¾j + // ‚»‚Ì‚½‚ß‚±‚̐ݒ肾‚¯‚Í32bit‘¤‚¾‚¯—LŒø‚É‚·‚éB + // i64bitAppã‚Å‚Í“ñd‚É‚È‚ç‚È‚¢j + // ‚È‚¨A64bitHook‚¾‚¯‚ðload‚µ‚½ê‡‚̓Cƒxƒ“ƒg‚ª‚Ü‚Á‚½‚­‚±‚È‚­‚È‚éi‚±‚ê‚àŒ´ˆö•s–¾j + if (Hook32) + Hook32->Add( NULL, EnableSendAllKeys, FUNC_SENDALLKEYS ); +#endif + + if ( num == 0 && !EnableSendAllKeys ){ + Hooks.Unload(); + } +#endif +} + +void TDCHookLoader::UnloadHook() +{ + LoadPending = false; + if (!Hooks.IsLoaded()){ + return; + } + //Hooks.FinishHook(); + Hooks.Uninit(); + Hooks.Unload(); + //if ( fWindowsNT ) + { +#if 1 // ‚µ‚΂炭‚Í‚±‚Á‚¿‚Ì•û–@(C++Builder‚ª‘Ήž‚µ‚Ä‚¢‚È‚¢ - ‚Æ‚¢‚¤‚©AMS‚Ìbug‚Å‚¤‚Ü‚­link‚Å‚«‚È‚¢) + typedef long (WINAPI *FNBroadcastSystemMessage) + (DWORD dwFlags,LPDWORD lpdwRecipients,UINT uiMessage,WPARAM wParam,LPARAM lParam); + HINSTANCE hDll = LoadLibrary( _T("user32") ); + if ( hDll ){ + FNBroadcastSystemMessage _BroadcastSystemMessage = (FNBroadcastSystemMessage)GetProcAddress( hDll, "BroadcastSystemMessage"); + if ( _BroadcastSystemMessage ){ + UINT msg = RegisterWindowMessage( _T("wmBroadcastForUnhook") ); + if ( msg ){ + DWORD receipt = BSM_APPLICATIONS; + _BroadcastSystemMessage( BSF_POSTMESSAGE, &receipt, msg, 0, 0 ); // Win95‚Å‚Ísupport‚³‚ê‚Ä‚¢‚È‚¢ŠÖ” + } + } + FreeLibrary( hDll ); + } +#else + UINT msg = RegisterWindowMessage( "wmBroadcastForUnhook" ); + DWORD receipt = BSM_APPLICATIONS; + BroadcastSystemMessage( BSF_POSTMESSAGE, &receipt, msg, 0, 0 ); // Win95‚Å‚Ísupport‚³‚ê‚Ä‚¢‚È‚¢ŠÖ” +#endif + } +} + +void TDCHookLoader::Config( int clickonly, int keyaction, int keyflag ) +{ + Hooks.Config(clickonly, keyaction, keyflag); +} +void TDCHookLoader::Config2( struct TDCHConfig *cfg ) +{ + Hooks.Config2(cfg); +} + +void TDCHookLoader::Capture() +{ + Hooks.Capture(); +} +void TDCHookLoader::CaptureAsync() +{ + Hooks.CaptureAsync(); +} +void TDCHookLoader::CaptureAsyncWait() +{ + Hooks.CaptureAsyncWait(); +} +void TDCHookLoader::Init32(HWND hwnd) +{ + Hooks.Init32(hwnd); +} + +void TDCHookLoader::Notify64(LPARAM lParam) +{ + DBW("Notify64 : lParam=%08X Hook64=%08X", lParam, Hook64); + if (!Hook64 || !lParam) + return; + Hook64->Notify64(); + Hook64->SetTarget((HWND)lParam); + if (LoadPending){ + LoadHookPost(hwndSavedParent); + LoadPending = false; + } +} + diff --git a/DCHookTest/DCHookLoader.h b/DCHookTest/DCHookLoader.h new file mode 100644 index 0000000..d89325f --- /dev/null +++ b/DCHookTest/DCHookLoader.h @@ -0,0 +1,96 @@ +#ifndef __DCHookLoader_h +#define __DCHookLoader_h + +#include +using namespace std; + +enum eShortCutIndexes { + SCINX_AUTOSRCH_TOGGLE, + SCINX_AUTOSRCH_ON, + SCINX_AUTOSRCH_OFF, + SCINX_TOPMOST, + SCINX_TO_MAIN, + SCINX_QUICK_POPUP, + SCINX_POPUP_WINDOW, + SCINX_GROUP_CHANGE_1, + SCINX_GROUP_CHANGE_2, + SCINX_GROUP_CHANGE_3, + SCINX_GROUP_CHANGE_4, + SCINX_CBDSRCH, + SCINX_CLIPHISTORY, + SCINX_TAB_CHANGE_1, + SCINX_TAB_CHANGE_2, + SCINX_TAB_CHANGE_3, + SCINX_TAB_CHANGE_4, + SCINX_LAST, +}; + +#define SCINX_NOTIFY64 (0x1000) // notify from 64bit HookDll + +#include "HookDll.h" + +class THookArray : public THookDllI { +protected: + typedef vector hook_vec; + vector Hooks; +public: + virtual ~THookArray(); + void add(THookDllI*dll) + { + Hooks.push_back(dll); + } + int size() const + { return Hooks.size(); } + virtual bool Load(HWND hwnd); + virtual void Unload(); + + virtual bool Init(HWND hwnd); + void Init32(HWND hwnd); + virtual void Uninit(); + virtual int Config( int clickonly, int keyaction, int keyflag ); + virtual int Config2( struct TDCHConfig *cfg ); + virtual int Capture(); + virtual int CaptureAsync(); + virtual int CaptureAsyncWait(); + virtual int Debug(); + virtual bool IsLoaded(); + THookDllI &operator [](int i) + { return *Hooks[i]; } +protected: + void clear(); +}; + +class TDCHookLoader { +protected: + bool Use64; + bool EnableSendAllKeys; + THookArray Hooks; + class THookLoader64 *Hook64; // reference pointer + class THookLoader *Hook32; // reference pointer + bool LoadPending; + HWND hwndSavedParent; +public: + TDCHookLoader(bool use64); + bool LoadHook( HWND hwndParent ); + void UnloadHook(); + void Config( int clickonly, int keyaction, int keyflag ); + void Config2( struct TDCHConfig *cfg ); + void Capture(); + void CaptureAsync(); + void CaptureAsyncWait(); + + // for 64bit OS + void Notify64(LPARAM lParam); + bool IsReady() const + { return !LoadPending; } + + void Init32(HWND hwnd); // for debug +protected: + void LoadHookPost(HWND hwndParent); + int LoadKeyProfiles( ); +}; + +extern ::TDCHookLoader shortcut; + +#endif // __DCHookLoader_h + diff --git a/DCHookTest/DCHookMain.cpp b/DCHookTest/DCHookMain.cpp new file mode 100644 index 0000000..cab3929 --- /dev/null +++ b/DCHookTest/DCHookMain.cpp @@ -0,0 +1,1680 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop +#include +#include "DCHookMain.h" +#include +#include +#include "StringLib.h" +#include "PopupConfig.h" +#include "Notify.h" +#include "DCHookLoader.h" +#include "prgprof.h" +#include "MODINotifyDlg.h" +#include "prgconfig.h" +#include "OCRTextFrm.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) + +/*------------------------------------------*/ +/* Configuration */ +/*------------------------------------------*/ +// Popup‚Ì‚½‚Ñ‚ÉDLL‚ðUnload/Load‚·‚é +// ”½‰ž‚µ‚È‚­‚È‚Á‚½‚Æ‚«‚Ì‚½‚߂̑ΏǗÖ@ +// Note: 2013.3.12 +// inc.srch ON‚Ì‚Æ‚«AMoveSent‚ªí‚Éreset‚³‚ê‚Ä‚µ‚Ü‚¤‚½‚߁A +// mouse‚ªstilló‘Ô‚Å‚ ‚Á‚Ä‚à‰½“x‚àinc.srch‚̃ŠƒNƒGƒXƒg‚ª‚â‚Á‚Ä‚­‚éB +// ‚Ù‚©Apopup/inc.srch‚ð‚â‚邽‚Ñ‚ÉDLL“à‚̕ϐ”‚ªreset‚³‚ê‚邽‚ß‚±‚ê‚Í‚æ‚낵‚­‚È‚¢B +#define DETACHRELEASE 0 + +#define MIGROUP_INDEX 1 // Ž«‘ƒOƒ‹[ƒv•ÏXƒƒjƒ…[‚Ìindex + +// PDIC‹N“®Œã‚ÌOpenLink()Ž¸”sŽž‚Ìretry‚¨‚æ‚Ñwaittime +#define OPEN_RETRY 5 +#define OPEN_WAITTIME 500 // [mSec] + +#define DPI_DETECT 0 // DPI Detect in main (monitor‚²‚Ƃ̐ݒ肪‚Å‚«‚È‚¢‚½‚ßdebug—p) + +#define DEF_USE64 (false) + +/*------------------------------------------*/ +/* Definitions */ +/*------------------------------------------*/ +#define URL_MODI_INSTALL "http://support.microsoft.com/kb/982760" + +#define DEF_POPUPKEY (KF_CONTROL) +#define DEF_TOGGLEKEY (KF_CONTROL+KF_MENU) + +#define WM_AMODI (WM_APP+0x400) // app communication message with AMODI + +#define FLG_MOVESEND 0x40000000 // mouse move send + +#pragma resource "*.dfm" +TDCHookMainForm *DCHookMainForm; + +#define COMPANYNAME "Software\\DokoPopProject\\" + +bool Reboot = false; + +/*------------------------------------------*/ +/* Prototypes */ +/*------------------------------------------*/ +bool DdePoke( TDdeClientConv *dde, AnsiString Item, AnsiString Data ); +#ifdef USE_UNICODE +// Unicode‚Å“n‚·ê‡ +bool DdePoke( TDdeClientConv *dde, AnsiString Item, const wchar_t *Data ); +#endif; +void GetGroupList(TMyIni &ini, TStringList &list); +#if DPI_DETECT +int GetMonitorScale(); +#endif + +//--------------------------------------------------------------------------- +__fastcall TDCHookMainForm::TDCHookMainForm(TComponent* Owner) + : TForm(Owner) +{ + hDll = NULL; + EnablePopup = true; + + WindowsNT = false; + + OSVERSIONINFO VersionInfo; + VersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&VersionInfo); + switch (VersionInfo.dwPlatformId){ + case VER_PLATFORM_WIN32_NT: + WindowsNT = true; + break; + } + CheckWOW64(); + BootUp = true; + Capturing = false; + PopupText = NULL; + DoPopupRetry = 0; + CaptureMode = CM_TEXT | CM_IMAGE; + AMODIAvail = false; + MouseIncSrch = false; +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::FormCreate(TObject *Sender) +{ + Ini = new TMyIni( HKEY_CURRENT_USER, COMPANYNAME APPREGNAME, true ); +// DBW("Handle=%08X",Handle); + +#ifdef _DEBUG + Left = Ini->ReadInteger( PFS_MAIN, "Left", Left ); + Top = Ini->ReadInteger( PFS_MAIN, "Top", Top ); + Width = Ini->ReadInteger( PFS_MAIN, "Width", Width ); + Height = Ini->ReadInteger( PFS_MAIN, "Height", Height ); +#endif + + GroupOpen = Ini->ReadInteger( PFS_CONFIG, PFS_GROUPOPEN, false ); + GroupName = Ini->ReadString( PFS_CONFIG, PFS_GROUPNAME, "" ); + CtrlClose = Ini->ReadInteger( PFS_CONFIG, PFS_CTRLCLOSE, false ); + IgnoreJ = Ini->ReadInteger( PFS_CONFIG, PFS_IGNOREJ, true ); + Banner = Ini->ReadInteger( PFS_CONFIG, PFS_BANNER, true ); + +#ifndef _DEBUG + BorderStyle = bsNone; + + Memo->Visible = false; + Panel1->Visible = false; + Splitter1->Visible = false; + Menu->Items->Delete( 0 ); + Image->Visible = true; +// Title->Caption = Title->Caption + " " + StrVersion; +// Title->Align = alBottom; +#if 0 + Title->Visible = true; +#endif + + AnsiString bmp = ExtractFilePath( Application->ExeName ); + bmp += NAME_BMPFILE; + if ( FileExists( bmp ) ){ + Image->Picture->Bitmap->LoadFromFile( bmp ); + } + + Width = Image->Picture->Width; + Height = Image->Picture->Height; + + // To center + Left += ( ( ( GetSystemMetrics( SM_CXSCREEN ) - ( Width ) ) / 2 + 4 ) & ~7 ) - Left; + Top += ( ( GetSystemMetrics( SM_CYSCREEN ) - ( Height ) ) / 2 ) - Top; +#endif + + SavedWidth = Width; + +#ifdef _DEBUG + BootTimer->Interval = 100; + Width = SavedWidth; + WindowState = wsNormal; +#else + if ( !Banner ){ + BootTimer->Interval = 10; + // ‚È‚ñ‚ÆVisible = false;‚É‚·‚é‚ƁA + // ƒAƒCƒRƒ“‰»‚µ‚½‚Æ‚«EEEƒAƒCƒRƒ“‚ª•\Ž¦‚³‚ê‚é + // ƒAƒCƒRƒ“‰»‚µ‚È‚¢‚Æ‚«EEƒAƒCƒRƒ“‚͏o‚Ä‚±‚È‚¢ + // •Ï‚ÈŽd—lH + // ‚Æ‚¢‚¤‚킯‚Å•‚ðƒ[ƒ‚É‚µ‚ÄWindow‚ð”ñ•\Ž¦‰»‚Æ‚¤‚¢Ž×“¹‚È•û–@ + // Å‰‚©‚炸‚Á‚ÆVisible=false‚Æ‚¢‚¤•û–@‚à‚ ‚邪A + // VCL‚ªMainWindow‚ð•K‚¸visible‚É‚·‚鏈—‚ðs‚Á‚Ä‚¢‚邽‚ß•s‰Â”\ + // ‚Ù‚©‚É‚¢‚¢•û–@‚ª‚ ‚Á‚½‚悤‚È‹C‚ª‚·‚邪AAAA + Width = 0; + } else { + Visible = true; // Å¬‰»‚Å‹N“®‚·‚é‚ƁAƒAƒCƒRƒ“•\Ž¦‚ªÁ‚¦‚È‚¢‚½‚߁B + // ‚±‚Ì•û–@‚ª“K“–‚Å‚ ‚é‚©‚Ç‚¤‚©[‚­l‚¦‚Ä‚¢‚È‚¢EE + // (‚½‚Ü‚½‚Ü‚¤‚Ü‚­“®‚¢‚½:-) + Width = SavedWidth; + WindowState = wsNormal; + } +#endif + + //TODO: default=ON‚É‚·‚é‚Æ•sˆÀ’è‚É‚È‚é‚Ì‚Å‚µ‚΂炭def=false + //MouseIncSrch = Ini->ReadInteger( PFS_CONFIG, PFS_INCSRCH, MouseIncSrch ); + CaptureMode = Ini->ReadInteger( PFS_CONFIG, PFS_CAPTURE_MODE, CaptureMode ); + InitAMODI(); + btnOK->Left = (SavedWidth - btnOK->Width)>>1; + btnOK->Top = Height - btnOK->Height - 8; + lbVersion->Caption = StrVersion; + lbVersion->Left = btnOK->Left + btnOK->Width + 4; + lbVersion->Top = btnOK->Top; + + BootTimer->Enabled = true; + + if (!AMODIAvail && (CaptureMode & CM_IMAGE)){ + tmMODINotify->Enabled = true; + } + +// Application->OnIdle = IdleHandler; +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + if (AMODIAvail){ + TerminateAMODI(); + } + if (OCRTextForm){ + OCRTextForm->Visible = false; + delete OCRTextForm; + OCRTextForm = NULL; + } + RegisterTrayIcon( false ); +#ifdef _DEBUG + WINDOWPLACEMENT wp; + wp.length = sizeof(WINDOWPLACEMENT); + GetWindowPlacement( Handle, &wp ); + RECT &rc = wp.rcNormalPosition; + Ini->WriteInteger( PFS_MAIN, "Left", rc.left ); + Ini->WriteInteger( PFS_MAIN, "Top", rc.top ); + Ini->WriteInteger( PFS_MAIN, "Width", rc.right - rc.left ); + Ini->WriteInteger( PFS_MAIN, "Height", rc.bottom - rc.top ); +#endif + + miUnhookClick( this ); + + delete Ini; + if (PopupText){ + delete[] PopupText; + PopupText = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::FormKeyPress(TObject *Sender, char &Key) +{ +#ifndef _DEBUG + if ( Key == 0x1b ){ + Key = 0; + Start(); + } +#endif +} +#if 0 +void __fastcall TDCHookMainForm::IdleHandler(TObject *sender, bool &done) +{ + if (NotifyAMODIEnabled){ + NotifyAMODIEnabled = false; + NotifyAMODI(); + } +} +#endif +//--------------------------------------------------------------------------- +// Menu event +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miDicGroup(TObject *Sender) +{ + // Ž«‘ƒOƒ‹[ƒv + AnsiString name = ((TMenuItem*)Sender)->Caption; + if ( name.Length() ){ + OpenDicGroup( name.c_str() ); + } +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miClickOnlyClick(TObject *Sender) +{ + miClickOnly->Checked = !miClickOnly->Checked; + EnableClickOnly( miClickOnly->Checked ); + MenuClosed(); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miIncSearchClick(TObject *Sender) +{ + miIncSearch->Checked = !miIncSearch->Checked; + MouseIncSrch = miIncSearch->Checked; + Ini->WriteInteger( PFS_CONFIG, PFS_INCSRCH, MouseIncSrch ); + SetupConfig2(); + if (MouseIncSrch){ + HWND hwnd = FindPdic(); + if (hwnd){ + MoveToTop(hwnd); + } + } +} +//--------------------------------------------------------------------------- +#if 0 // change capture mode + if (!AMODIAvail && (CaptureMode & CM_IMAGE)){ + InitAMODI(); + } + if (AMODIAvail){ + SetupConfig2(); + } else { + NotifyAMODI(); + } + + MenuClosed(); +#endif +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miEnablePopupClick(TObject *Sender) +{ + if ( miEnablePopup->Checked ){ + miUnhookClick( this ); + EnablePopup = false; + } else { + miHookClick( this ); + EnablePopup = true; + } + MenuClosed(); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miOCRTextClick(TObject *Sender) +{ + if (!OCRTextForm) OCRTextForm = new TOCRTextForm(this); + OCRTextForm->Visible = true; +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miOptionClick(TObject *Sender) +{ + if (PopupConfigDlg){ + MoveToTop(PopupConfigDlg->Handle); + return; + } + + // Configuration // + PopupConfigDlg = new TPopupConfigDlg( this ); + PopupConfigDlg->cbGroupOpen->Checked = GroupOpen; + PopupConfigDlg->edGroupName->Text = GroupName; + PopupConfigDlg->SetPopupKey( Ini->ReadInteger( PFS_CONFIG, PFS_POPUPKEY, DEF_POPUPKEY ) ); + PopupConfigDlg->SetToggleKey( Ini->ReadInteger( PFS_CONFIG, PFS_TOGGLEKEY, DEF_TOGGLEKEY ) ); + PopupConfigDlg->cbCtrlClose->Checked = CtrlClose; + PopupConfigDlg->cbIgnoreJ->Checked = IgnoreJ; + PopupConfigDlg->cbBanner->Checked = Banner; + bool useAMODI = CaptureMode & CM_IMAGE ? true : false; + PopupConfigDlg->SetCaptureMode( CaptureMode ); + PopupConfigDlg->SetScaler( Ini->ReadInteger(PFS_CONFIG, PFS_SCALE, 0) ); + PopupConfigDlg->edAMODIPath->Text = AMODIPath; + PopupConfigDlg->SetMODIAvail( AMODIAvail ); + bool use64 = Ini->ReadInteger(PFS_CONFIG, PFS_USE64, DEF_USE64); + PopupConfigDlg->cbUse64->Checked = use64; + SetForegroundWindow( PopupConfigDlg->Handle ); + if ( PopupConfigDlg->ShowModal() == IDOK ){ + GroupOpen = PopupConfigDlg->cbGroupOpen->Checked; + GroupName = PopupConfigDlg->edGroupName->Text; + CtrlClose = PopupConfigDlg->cbCtrlClose->Checked; + IgnoreJ = PopupConfigDlg->cbIgnoreJ->Checked; + Banner = PopupConfigDlg->cbBanner->Checked; + AMODIPath = PopupConfigDlg->edAMODIPath->Text; + Ini->WriteInteger( PFS_CONFIG, PFS_POPUPKEY, + PopupConfigDlg->GetPopupKey() ); + Ini->WriteInteger( PFS_CONFIG, PFS_TOGGLEKEY, + PopupConfigDlg->GetToggleKey() ); + CaptureMode = PopupConfigDlg->GetCaptureMode(); + Ini->WriteInteger( PFS_CONFIG, PFS_CAPTURE_MODE, CaptureMode ); + Ini->WriteInteger( PFS_CONFIG, PFS_SCALE, PopupConfigDlg->GetScaler() ); + Ini->WriteString(PFS_CONFIG, PFS_AMODIPATH, AMODIPath.c_str()); + Ini->WriteInteger(PFS_CONFIG, PFS_USE64, PopupConfigDlg->cbUse64->Checked); + SaveConfig(); + SetupConfig(); + if (!useAMODI && (CaptureMode & CM_IMAGE) && !AMODIAvail){ + // AMODI off->ON ‚©‚ AMODI‚ª‚¢‚È‚¢ê‡ + NotifyAMODI(); + } + if (PopupConfigDlg->cbUse64->Checked != use64){ + // 64bit hook •ÏXŽž + Unhook(); + Hook(); + } + } + delete PopupConfigDlg; + PopupConfigDlg = NULL; +} +void __fastcall TDCHookMainForm::miReadMeClick(TObject *Sender) +{ + ShowManual(Handle); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miAboutClick(TObject *Sender) +{ + // show version dialog +#if 1 + Width = SavedWidth; + btnOK->Visible = true; + btnOK->SetFocus(); + Visible = true; +#else + VersionDlg = new TVersionDlg( this ); + VersionDlg->ShowModal(); + delete VersionDlg; +#endif +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miCheckLatestClick(TObject *Sender) +{ + ShowLatestVersion(); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miCloseClick(TObject *Sender) +{ + MenuClosed(); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miReloadClick(TObject *Sender) +{ + // Ä‹N“® + Unhook(); + Hook(); + MenuClosed(); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miHookClick(TObject *Sender) +{ + if ( !Hook() ){ + Application->MessageBox( "DLL‚ð‰Šú‰»‚·‚邱‚Æ‚ª‚Å‚«‚Ü‚¹‚ñ\rI—¹‚µ‚Ü‚·", APPNAME, MB_OK ); + Close(); + } +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miUnhookClick(TObject *Sender) +{ + Unhook(); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miConfigClick(TObject *Sender) +{ + miOptionClick(Sender); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miDdeTestClick(TObject *Sender) +{ +#ifdef _DEBUG + DoPopup( _t("test"), NULL, false ); +#endif +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miTestClick(TObject *Sender) +{ +#ifdef _DEBUG +#if 1 + hDll->Init32(Handle); +#endif +#if 0 + NotifyAMODI(); +#endif +#if 0 + miIncSearchClick(Sender); +#endif +#if 0 + if (hDll){ + hDll->Capture(); + } +#endif +#endif // _DEBUG +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::miExitClick(TObject *Sender) +{ + Close(); +} +//--------------------------------------------------------------------------- +// Popup on tray icon // +void __fastcall TDCHookMainForm::pmTrayIconPopup(TObject *Sender) +{ + // Add group names to menu + TAppIni ini; + if ( !ini.hroot ){ + return; + } + + int sel = ini.ReadInteger( PFS_COMMON, PFS_GRPSEL, -1 ); + + TStringList *strs = new TStringList; + TMenuItem *sub = pmTrayIcon->Items->Items[MIGROUP_INDEX]; + for ( ;sub->Count;){ + sub->Delete(0); + } + GetGroupList(ini, *strs); + int index = 0; + for ( int i=0;iCount;i++ ){ + AnsiString name = strs->Strings[i]; + if (name.IsEmpty() || name.AnsiPos("::")==1){ + continue; // Ignore the group. + } + TMenuItem *item = new TMenuItem( this ); + item->Caption = name; + item->OnClick = miDicGroup; + sub->Add( item ); + // Check current group name // + if ( sel == index ){ + item->Checked = true; + } + index++; + } + delete strs; + miGroup->Visible = sub->Count != 0; + // Check enable popup item // + miIncSearch->Checked = MouseIncSrch; + miEnablePopup->Checked = EnablePopup; + + miOCRText->Visible = CaptureMode & CM_IMAGE ? true : false; +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::btnOKClick(TObject *Sender) +{ +#ifndef _DEBUG + Width = 0; +#endif + MenuClosed(); +} +//--------------------------------------------------------------------------- +// Timers +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::TestTimerTimer(TObject *Sender) +{ +#ifdef _DEBUG +#if 0 + if ( DCDebug ){ + char *p = (char*)DCDebug( ); + if ( memcmp( share, p, COMPSIZE ) ){ + DBW("Different"); + for ( int i=0;iHandle, SW_HIDE ); + tmMenuClose->Enabled = false; +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::tmNotifyTimer(TObject *Sender) +{ + if ( NotifyForm ){ + tmNotify->Enabled = false; + delete NotifyForm; + NotifyForm = NULL; + } +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::tmPopupTimer(TObject *Sender) +{ + PostMessage( Handle, WM_POPUP, PopupLoc | (PopupMoveSend ? FLG_MOVESEND : 0), (LPARAM)PopupText ); + PopupText = NULL; // release ownership + tmPopup->Enabled = false; // stop timer +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::tmMouseMoveTimer(TObject *Sender) +{ + tmMouseMove->Enabled = false; + + if (!hDll) + return; + //hDll->Capture(); + hDll->CaptureAsync(); +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::tmMODIInstallCheckTimer(TObject *Sender) +{ + if (MODIInstalled()){ +#if 0 + Reboot(); +#else + // Å‰‚Ìpopup‚Å—Ž‚¿‚Ä‚µ‚Ü‚¤H + if (!AMODIAvail && (CaptureMode & CM_IMAGE)){ + InitAMODI(); + } + if (AMODIAvail){ + SetupConfig2(); + } +#endif + } +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::tmMODINotifyTimer(TObject *Sender) +{ + tmMODINotify->Enabled = false; + if (!AMODIRunable()){ + NotifyAMODI(); + } +} +//--------------------------------------------------------------------------- +// Mouse Events +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::ImageMouseDown(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if ( BootUp ) return; + Capturing = true; + SetCapture( Handle ); + CapPoint.x = X; + CapPoint.y = Y; +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::ImageMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + if ( Capturing ){ + POINT pt; + GetCursorPos( &pt ); + Left = pt.x - CapPoint.x; + Top = pt.y - CapPoint.y; + } +} +//--------------------------------------------------------------------------- +void __fastcall TDCHookMainForm::ImageMouseUp(TObject *Sender, + TMouseButton Button, TShiftState Shift, int X, int Y) +{ + if ( BootUp ) + Start(); + Capturing = false; +} +//--------------------------------------------------------------------------- +// User Functions +//--------------------------------------------------------------------------- +void TDCHookMainForm::InitAMODI() +{ + AMODIPath = Ini->ReadString(PFS_CONFIG, PFS_AMODIPATH, AMODIPath.c_str()); + SetupAMODI(); +} +void TDCHookMainForm::Start() +{ + BootTimer->Enabled = false; +#ifndef _DEBUG + ShowWindow( Application->Handle, SW_HIDE ); + Visible = false; + Width = 0; +#endif + if ( BootUp ){ + RegisterTrayIcon( true ); + miHookClick( this ); + BootUp = false; + } +} +//--------------------------------------------------------------------------- +bool TDCHookMainForm::Hook() +{ + if ( hDll ){ + DBW("Already hooked"); + return true; // already loaded + } + + bool use64 = Ini->ReadInteger(PFS_CONFIG, PFS_USE64, false); + hDll = new TDCHookLoader(use64); + if (!hDll->LoadHook(Handle)){ + DBW("Load failed"); + delete hDll; + hDll = NULL; + return false; + } + + miHook->Enabled = false; + miUnhook->Enabled = true; + + if (hDll->IsReady()){ + SetupConfig(); + extern HWND hwnd64; + PostMessage(Handle, UM_SHORTCUT, SCINX_NOTIFY64, (LPARAM)hwnd64); + } + + DBW("Hook OK"); + + return true; +} +void TDCHookMainForm::Unhook() +{ + if ( !hDll ) return; + + hDll->UnloadHook(); + delete hDll; + hDll = NULL; + + miHook->Enabled = true; + miUnhook->Enabled = false; +} +//--------------------------------------------------------------------------- +#ifdef _DEBUG +// text‚̐擪‚ð(0,0)‚Æ‚µ‚½À•W‚ŁApos‚̈ʒu‚É‚ ‚étext‚Ì•¶ŽšˆÊ’u‚ð•Ô‚· +int GetTextFromPoint( HDC hdc, const char *text, int pos ) +{ + int len = lstrlen(text); + int left = 0; + int right = len; + SIZE sz; + int loc; + for(;;){ + loc = (right + left)/2; + if ( right - left <= 1 ){ + break; + } + GetTextExtentPoint32A( hdc, text, loc, &sz ); +// DBW("%08X %d %d %d %d", hdc, left, right, loc, sz.cx); + if ( pos < sz.cx ){ + right = loc; + } else { + left = loc; + } + } + return (right+left)/2; +} +int GetTextFromPoint( HDC hdc, const wchar_t *text, int pos ) +{ + int len = lstrlenW(text); + int left = 0; + int right = len; + SIZE sz; + int loc; + for(;;){ + loc = (right + left)/2; + if ( right - left <= 1 ){ + break; + } + GetTextExtentPoint32W( hdc, text, loc, &sz ); +// DBW("%08X %d %d %d %d", hdc, left, right, loc, sz.cx); + if ( pos < sz.cx ){ + right = loc; + } else { + left = loc; + } + } + return (right+left)/2; +} +#endif +void TDCHookMainForm::EvCopyData(TMessage& msg ) +{ + COPYDATASTRUCT *cds = (COPYDATASTRUCT*)msg.LParam; + if ( !cds ){ return; } + switch ( cds->dwData ){ + case DCH_MOVESEND: + //DBW("DCH_MOVESEND"); + // mouse move message + EvMoveSend(msg.WParam==0); + break; + case DCH_START: + CursorPoint = *(POINT*)cds->lpData; +#ifdef _DEBUG + PaintBox->Canvas->FillRect( PaintBox->Canvas->ClipRect ); +#endif + if (PopupText){ + delete[] PopupText; + PopupText = NULL; + } + break; + case DCH_END: + case DCH_END | DCH_MOVESEND: + if ( PopupText ){ + PopupMoveSend = cds->dwData & DCH_MOVESEND ? true : false; + PostMessage( Handle, WM_POPUP, PopupLoc | (PopupMoveSend ? FLG_MOVESEND : 0), (LPARAM)PopupText ); + if (OCRTextForm) OCRTextForm->SetText(PopupText); + PopupText = NULL; // release ownership + } + break; + case DCH_HITTEXT1: // single char + { + DBW("DCH_HITTEXT1"); + if (PopupText) + delete[] PopupText; +#ifdef USE_UNICODE + // ANSI -> Unicode + //*+++ “®ì–¢Šm”F 2002.12.4 + PopupText = new tchar[ cds->cbData*2 + 1 ]; + // ‘O”¼•”•ª + PopupLoc = MultiByteToWideChar( CP_ACP, 0, + (LPCSTR)cds->lpData, msg.WParam, PopupText, cds->cbData*2 ); + // Œã”¼•”•ª + int r = MultiByteToWideChar( CP_ACP, 0, + &((char*)cds->lpData)[msg.WParam], cds->cbData-msg.WParam, &PopupText[PopupLoc], cds->cbData-PopupLoc ); + PopupText[PopupLoc+r] = '\0'; +#else // !USE_UNICODE + PopupText = new tchar[ cds->cbData + 1 ]; + memcpy( PopupText, cds->lpData, cds->cbData ); + PopupText[cds->cbData] = '\0'; + PopupLoc = msg.WParam; +#ifdef _DEBUG + Memo->Lines->Add( PopupText ); + edFound->Text = PopupText + msg.WParam; + TestTimer->Enabled = true; + if ( DCDebug ){ + char *p = (char*)DCDebug( ); + memcpy( share, p, COMPSIZE ); + } +#endif +#endif + } + break; + case DCH_HITTEXT2: // wide char + { + DBW("DCH_HITTEXT2"); + if (PopupText) + delete[] PopupText; +#ifdef USE_UNICODE + PopupText = new tchar[ cds->cbData + 1 ]; + memcpy( PopupText, cds->lpData, cds->cbData ); + PopupText[cds->cbData/sizeof(tchar)] = '\0'; + PopupLoc = msg.WParam; +#else // !USE_UNICODE + // Unicode -> ANSI + //*+++ “®ì–¢Šm”F 2002.12.4 + PopupText = new tchar[ cds->cbData + 1 ]; + // ‘O”¼•”•ª + BOOL defchar; + PopupLoc = WideCharToMultiByte( CP_ACP, 0, + (wchar_t*)cds->lpData, msg.WParam, + PopupText, cds->cbData, 0, &defchar ); + // Œã”¼•”•ª + int r = WideCharToMultiByte( CP_ACP, 0, + &((wchar_t*)cds->lpData)[msg.WParam], (cds->cbData>>1)-msg.WParam, + &PopupText[PopupLoc], cds->cbData-PopupLoc, 0, &defchar ); + PopupText[PopupLoc+r] = '\0'; +#endif + } + break; +#ifdef _DEBUG + case DCH_EXTTEXTOUTA: + case DCH_EXTTEXTOUTW: + { + EMREXTTEXTOUTW *emr = (EMREXTTEXTOUTW*)cds->lpData; + wchar_t *p = (wchar_t*) ( ((char*)emr) + emr->emrtext.offString ); + char *buf = NULL; +#if 0 + char b[200]; + sprintf(b,"exScale=%f eyScale=%f ptlReference=(%d,%d)",emr->exScale, emr->eyScale, emr->emrtext.ptlReference.x, emr->emrtext.ptlReference.y ); + DBW(b); +#endif + if ( cds->dwData == DCH_EXTTEXTOUTW ){ + buf = new char[ emr->emrtext.nChars * 2 ]; + memset( buf, 0, emr->emrtext.nChars*2 ); + WideCharToMultiByte( CP_ACP, 0, p, emr->emrtext.nChars, buf, emr->emrtext.nChars * 2, NULL, NULL ); + } + const char *text = buf ? buf : (char*)p; + Memo->Lines->Add( text ); + PaintBox->Canvas->TextOut( emr->rclBounds.left, emr->rclBounds.top, text ); + + if ( PtInRect( (RECT*)&emr->rclBounds, CursorPoint ) ){ + int loc = GetTextFromPoint( (HDC)msg.WParam, text, CursorPoint.x - emr->rclBounds.left ); + if ( loc != -1 ){ + edFound->Text = text + loc; + } + } + if ( buf ) + delete[] buf; + } + break; +#endif + case DCH_MENU: + DokoPopMenu( false ); + break; + case DCH_TOGGLE: + PostMessage( Handle, WM_TOGGLE, 0, 0 ); + break; + case WMCD_EXISTCHECK: // exist check + if ( cds->cbData != strlen(APPNAME)+1 ){ + msg.Result = false; + return; + } + msg.Result = (memcmp( cds->lpData, APPNAME, strlen(APPNAME)+1 ) == 0); + return; + case DCH_LAUNCH_AMODI: + SetupAMODI(); + //Reboot(); // AMODI.exeÄ‹N“®‚Å‚Í‰ðŒˆ‚Å‚«‚È‚¢‚½‚ß + break; + } + return; +} +//--------------------------------------------------------------------------- +bool WaitTransaction( TDdeClientConv *dde ) +{ +#if 1 + for ( int i=0;i<100000;i++ ){ + Application->ProcessMessages(); + if ( !dde->WaitStat ){ +// DBW("DCHook:Wait OK"); + return true; + } + } + DBW("DCHook:Wait failure"); + return false; +#else + return true; +#endif +} +// ANSI‚Å“n‚·ê‡ +bool DdePoke( TDdeClientConv *dde, AnsiString Item, AnsiString Data ) +{ +#ifdef USE_UNICODE + int ansilen = Data.Length(); + wchar_t *buf = new wchar_t[ansilen*2+1]; + int len = MultiByteToWideChar( CP_ACP, 0, + (LPCSTR)Data.c_str(), ansilen, buf, ansilen*2 ); + buf[len] = '\0'; + bool r = DdePoke( dde, Item, (wchar_t*)buf ); + delete[] buf; + return r; +#else // !USE_UNICODE + HSZ hszItem = DdeCreateStringHandle(ddeMgr->DdeInstId, Item.c_str(), CP_WINANSI ); + if ( !hszItem ) return false; + HDDEDATA hszDat = DdeCreateDataHandle( ddeMgr->DdeInstId, Data.c_str(), Data.Length() + 1, + 0, hszItem, dde->DdeFmt, 0); + bool r = false; + if ( hszDat ){ + HDDEDATA hdata = DdeClientTransaction( (LPBYTE)hszDat, (DWORD)-1, (HCONV)dde->Conv, hszItem, + dde->DdeFmt, XTYP_POKE, 10000, NULL); + r = hdata ? true : false; + } + DdeFreeStringHandle (ddeMgr->DdeInstId, hszItem); + return r; +#endif +} +#ifdef USE_UNICODE +// Unicode‚Å“n‚·ê‡ +bool DdePoke( TDdeClientConv *dde, AnsiString Item, const wchar_t *Data ) +{ + // Item–¼‚ÍANSIAƒf[ƒ^‚ÍUNICODE // + int ddeFmt = /*dde->DdeFmt*/CF_UNICODETEXT; + HSZ hszItem = DdeCreateStringHandle(ddeMgr->DdeInstId, Item.c_str(), CP_WINANSI ); + if ( !hszItem ) return false; + HDDEDATA hszDat = DdeCreateDataHandle( ddeMgr->DdeInstId, (LPBYTE)Data, (_tcslen(Data)+1)*sizeof(wchar_t), + 0, hszItem, ddeFmt, 0); + bool r = false; + if ( hszDat ){ + HDDEDATA hdata = DdeClientTransaction( (LPBYTE)hszDat, (DWORD)-1, (HCONV)dde->Conv, hszItem, + ddeFmt, XTYP_POKE, 10000, NULL); + r = hdata ? true : false; + } + DdeFreeStringHandle (ddeMgr->DdeInstId, hszItem); + return r; +} +#endif +TDdeClientConv *TDCHookMainForm::OpenPdic( const char *topic ) +{ + TDdeClientConv *PdicDde = new TDdeClientConv( this ); + + PdicDde->ConnectMode = ddeManual; + static int entry = 0; + PdicDde->Name = AnsiString("PdicDde") + (++entry); + PdicDde->ServiceApplication = DDE_SERVICE_NAME; + if ( !PdicDde->SetLink( DDE_SERVICE_NAME, topic ) ){ + DBW("DCHook:Cannot SetLink"); + delete PdicDde; + return NULL; + } + if ( !PdicDde->OpenLink( ) ){ // ‚±‚±‚ª’x‚¢II + // PDIC auto launch + if ( LaunchPdic() ){ + for(int i=0;iOpenLink() ){ + return PdicDde; + } + Sleep(OPEN_WAITTIME); + } + } + DBW("PDIC‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ(OpenPdic)"); + Application->MessageBox( "PDIC‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ(OpenPdic)", APPNAME, MB_OK ); + delete PdicDde; + return NULL; + } + return PdicDde; +} +#ifdef USE_UNICODE +static const TCHAR *clsname = TEXT("TPdicMain.UnicodeClass"); +#else +static const TCHAR *clsname = TEXT(DDE_SERVICE_NAME); +#endif +static const TCHAR *winname = NULL; +HWND TDCHookMainForm::FindPdic( ) +{ + HWND hWin = FindWindow( clsname, winname ); + if ( !hWin ){ + // PDIC auto launch + if ( LaunchPdic() ){ + hWin = FindWindow( clsname, winname ); + if ( !hWin ){ + DBW("PDIC‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ(FindPdic)"); + Application->MessageBox( "PDIC‚ªŒ©‚‚©‚è‚Ü‚¹‚ñ(FindPdic)", APPNAME, MB_OK ); + return NULL; + } + } + } + return hWin; +} +#if !USE_DDE +LRESULT TDCHookMainForm::SendCopyData( HWND hwnd, int message, const char *str ) +{ + COPYDATASTRUCT cds; + cds.dwData = message; + cds.lpData = (LPSTR)str; + cds.cbData = lstrlen(str)+1; + SendMessage( hwnd, WM_COPYDATA, (WPARAM)Handle, (LPARAM)&cds ); +} +#endif +void TDCHookMainForm::ClosePdic( TDdeClientConv *dde ) +{ + dde->CloseLink(); + delete dde; +} +bool TDCHookMainForm::DoPopup( const tchar *text, const tchar *prevtext, bool movesend ) +{ + static int ct = 0; + if ( ct >= 1 ){ + if (PopupText){ + // already pending + DBW("Reentrant!!!!!"); + return true; + } + HWND hwnd = FindPopupWindow( ); + if (hwnd){ + HWND hwndParent = GetParent( hwnd ); + if (hwndParent){ + DBW("Parent exist!!!!"); + hwnd = hwndParent; + } + DBW("Retry again:%d:%08X",ct,hwnd); + // •K‚¸PostMessage()‚Åclose‚·‚邱‚ƁB + // CloseWindow()‚Å‚ÍPopup Winodow‚̏‰Šú‰»’†‚É + // closeˆ—‚ðŽÀs‚µ‚Ä‚µ‚Ü‚¢A + // popup window‚ª‚¨‚©‚µ‚ȏó‘Ô‚É‚Í‚¢‚Á‚Ä‚µ‚Ü‚¤ê‡‚ª‚ ‚é + PostMessage( hwnd, WM_CLOSE, 0, 0 ); + return false; + } else { + if (ct >= 1 ){ + DBW("Not found popup window"); + if (DoPopupRetry++ > 10){ + DoPopupRetry = 0; + return true; // abort + } else { + return false; // retry + } + } + } + } + DoPopupRetry = 0; + ct++; + +#if USE_DDE + // Windows9x‚ł́ADDE transaction‚ª’x‚¢‚Æ‚«‚ª‚ ‚é + // why? - because of 24bit OS:-) + // ->‚ÆŽv‚Á‚āAWM_COPYDATA version‚ðì‚Á‚Ä‚¢‚½‚瑬‚­‚È‚Á‚½HHH + // ->WM_COPYDATA‰» project‚Í’†’f + TDdeClientConv *PdicDde; + bool r; + + if (movesend){ + // incremental search + PdicDde = OpenPdic("Simulate"); + if (!PdicDde){ + ct--; + return true; + } + r = DdePoke(PdicDde, "InputWord3", text); + if (!r){ + DBW("PDIC DDE : InputWord3 failure"); + delete PdicDde; + ct--; + return true; + } + } else { + // popup + if (GroupOpen){ + PdicDde = OpenPdic( "Simulate" ); + if (PdicDde){ + DdePoke( PdicDde, "Open", GroupName ); + PdicDde->CloseLink(); + delete PdicDde; + } + } + PdicDde = OpenPdic( "Dictionary" ); + if ( !PdicDde ){ + ct--; + return true; + } + + r = DdePoke( PdicDde, "Open", "" ); + if ( !r ){ + DBW("PDIC DDE : Open failure"); + PdicDde->CloseLink(); + delete PdicDde; + ct--; + if ( GroupOpen ){ + static int ct = 0; + ct++; + if ( ct == 1 ){ + Application->MessageBox( + "Ž«‘ƒOƒ‹[ƒv‚ªŠJ‚¯‚Ü‚¹‚ñ\r" + "DokoPop!‚ŁuŽ«‘ƒOƒ‹[ƒvŽw’èv‚ð—LŒø‚É‚µ‚Ä‚¢‚éê‡‚́A‚·‚Å‚ÉPDIC–{‘̂ŃI[ƒvƒ“‚³‚ê‚Ä‚¢‚鎫‘‚Æ‹¤—Lˆá”½‚ð‹N‚±‚µ‚Ä‚¢‚é‰Â”\«‚ª‚ ‚è‚Ü‚·\r" + "DokoPop!‚ÆPDIC–{‘Ì‚ÅŽg—p‚µ‚Ä‚¢‚鎫‘‚É“¯ˆê‚Ì‚à‚Ì‚ª‚È‚¢‚©’²‚ׂĂ­‚¾‚³‚¢\r" + "‚à‚µ‚ ‚Á‚½ê‡‚Í“o˜^‹ÖŽ~‚È‚Ç‹¤—L‚Å‚«‚é‚悤‚ȏó‘Ô‚É‚µ‚Ä‚­‚¾‚³‚¢\r" + "‚±‚̃ƒbƒZ[ƒW‚̈Ӗ¡‚ª‚í‚©‚ç‚È‚¢ê‡‚́AuŽ«‘ƒOƒ‹[ƒvŽw’èv‹@”\‚ðŽg‚í‚È‚¢‚Ù‚¤‚ªˆÀ‘S‚Å‚·" + , + APPNAME, MB_OK ); + } else { + SetForegroundWindow( Handle ); + } + ct--; + } + return true; + } + if ( CtrlClose ) + DdePoke( PdicDde, "PopupSearchConfig", "c1" ); // Ctrl close + // Sleep(1000); + DdePoke( PdicDde, "PopupSearchConfig", "o1w1" ); // overlap window and no wait transaction + if ( prevtext && (prevtext != text) ){ + //DBW("prevtext="FMTS,prevtext); + DdePoke( PdicDde, "PopupSearch2", (tchar*)prevtext ); + // ExecuteMacro( "PopupSearch2", true ); + WaitTransaction( PdicDde ); + } else { + //DBW("text="FMTS,text); + DdePoke( PdicDde, "PopupSearch", (tchar*)text ); + // PdicDde->ExecuteMacro( "PopupSearch", true ); + WaitTransaction( PdicDde ); + } + DdePoke( PdicDde, "Close", "" ); + } + ClosePdic( PdicDde ); +#else // !USE_DDE + // WM_COPYDATA‚É‚æ‚é•û–@(‚Ü‚¾document‰»‚³‚ê‚Ä‚¢‚È‚¢•û–@(Ver.4.30) + // PDIC/W32 Ver.4.22`‚ɑΉž + // ‚½‚¾‚µAVer.4.29‚܂ł́AWMCD_POPUPSEARCH‚ÆWMCD_POPUPSEARCH2‚Í“¯‚¶ + + // WM_COPYDATA code // + // ˆÈ‰º‚̐”’l‚͏«—ˆ•Ï‚í‚é‰Â”\«‚ª‚ ‚é(undocumented) // + #define WMCD_GETVERSION 0x0001 + #define WMCD_CHECKOPEN 0x0010 + #define WMCD_AUTOSEARCH 0x0020 + #define WMCD_AUTOSEARCHMODE 0x0021 + + #define WMCD_ISOPENED 0x0080 + #define WMCD_CLOSE 0x0081 + + #define WMCD_POPUPSEARCH 0x0100 + #define WMCD_POPUPSEARCH2 0x0101 + #define WMCD_POPUPSEARCHPOINT 0x0102 + #define WMCD_POPUPSEARCHCONFIG 0x0103 + #define WMCD_POPUPSEARCHDIALOG 0x0104 + #define WMCD_POPUPSEARCHWINDOW 0x0105 + + #define WMCD_SPELLCHECK 0x0110 + + HWND hwnd = FindPdic(); + if ( !hwnd ){ + ct--; + return; + } + + bool r; + if ( CtrlClose ) + SendCopyData( hwnd, WMCD_POPUPSEARCHCONFIG, "c1" ); + POINT pt; + GetCursorPos( &pt ); + char buf[20]; + wsprintf( buf, "%d,%d", pt.x, pt.y ); + SendCopyData( hwnd, WMCD_POPUPSEARCHPOINT, buf ); + if ( prevtext && (prevtext != text) ){ + DBW("prevtext=%s",prevtext); + SendCopyData( hwnd, WMCD_POPUPSEARCH2, prevtext ); + } else { + DBW("text=%s",text); + SendCopyData( hwnd, WMCD_POPUPSEARCH, text ); + } + SendCopyData( hwnd, WMCD_CLOSE, "" ); +#endif // !USE_DDE + ct--; + DBW("DCHook:Exit Popup:%d",ct); + +#if DETACHRELEASE + if ( EnablePopup ){ + miUnhookClick( this ); + miHookClick( this ); + } +#endif + return true; +} +//--------------------------------------------------------------------------- +// EvPopup +// WParam : text location & FLG_MOVESEND +// LParam : text pointer (must be freed when done) +void TDCHookMainForm::EvPopup(TMessage &msg) +{ + //DBW("EvPopup"); + if (!msg.LParam) + return; + + tchar *text = (tchar*)msg.LParam; + int loc = msg.WParam & ~FLG_MOVESEND; + bool movesend = msg.WParam & FLG_MOVESEND ? true : false; + + int start, end; + int prevstart; + if ( !GetWord( text, loc, start, end, prevstart, true, 10, true, IgnoreJ ) ){ + // no words + delete[] text; + return; + } +#ifdef _DEBUG + edWord->Text = text + start; + edPrev->Text = loc + prevstart; +#endif + + if (DoPopup( text + start, text + prevstart, movesend )){ + // done + delete[] text; + } else { + // retry again + if (PopupText) + delete[] PopupText; // ‚ ‚Æ‚É—ˆ‚½‚Ù‚¤‚ð—Dæ‚·‚é + PopupText = text; + PopupLoc = loc; + PopupMoveSend = movesend; + tmPopup->Enabled = true; // start timer for delayed popup + } + //DBW("EvPopup - end"); +} +void TDCHookMainForm::EvMoveSend(TMessage &msg) +{ + EvMoveSend(msg.WParam==0); +} +void TDCHookMainForm::EvMoveSend(bool enable) +{ + tmMouseMove->Enabled = false; + if (enable){ + tmMouseMove->Enabled = true; + } +} +void TDCHookMainForm::RegisterTrayIcon( bool flag ) +{ + NOTIFYICONDATA m_tnid; //‚±‚ê‚Í*.h‚Å’è‹`‚µ‚Ä‚¨‚­ + + m_tnid.cbSize = sizeof(NOTIFYICONDATA); + m_tnid.hWnd = Handle; + m_tnid.uID = 1; + m_tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + m_tnid.uCallbackMessage = WM_NOTIFYICON; + // Get small icon from me + HICON hIconSm; + HICON hIcon; + ExtractIconEx( Application->ExeName.c_str(), -2, &hIcon, &hIconSm, 1 ); + m_tnid.hIcon = hIconSm; + lstrcpy(m_tnid.szTip, APPNAME ); + Shell_NotifyIcon( flag ? NIM_ADD : NIM_DELETE, &m_tnid); +} +void TDCHookMainForm::EvNotifyIcon(TMessage &msg) +{ + //UINT uID = (UINT) msg.WParam; + UINT uMouseMsg = (UINT) msg.LParam; + if (uMouseMsg == WM_LBUTTONDBLCLK) + { + miOptionClick( this ); + } + else if (uMouseMsg == WM_RBUTTONDOWN) + { + DokoPopMenu( true ); + } +} +//--------------------------------------------------------------------------- +void TDCHookMainForm::SaveConfig() +{ + Ini->WriteInteger( PFS_CONFIG, PFS_GROUPOPEN, GroupOpen ); + Ini->WriteString( PFS_CONFIG, PFS_GROUPNAME, GroupName.c_str() ); + Ini->WriteInteger( PFS_CONFIG, PFS_CTRLCLOSE, CtrlClose ); + Ini->WriteInteger( PFS_CONFIG, PFS_IGNOREJ, IgnoreJ ); + Ini->WriteInteger( PFS_CONFIG, PFS_BANNER, Banner ); +} +void TDCHookMainForm::OpenDicGroup( const char *name ) +{ + TDdeClientConv *dde = OpenPdic( PFS_PDIC ); + if ( !dde ) + return; + // Ž«‘ƒOƒ‹[ƒvƒI[ƒvƒ“ˆ— // + if ( name[0] == '&' ) + name++; + DdePoke(dde, "OpenGroup", (tchar*)mustr(name)); + ClosePdic( dde ); +} +//--------------------------------------------------------------------------- +// DokoPop‚̐ݒè +void TDCHookMainForm::SetupConfig() +{ + EnableClickOnly( miClickOnly->Checked ); + if (hDll){ + hDll->Config( -1, KA_POPUP, + Ini->ReadInteger( PFS_CONFIG, PFS_POPUPKEY, DEF_POPUPKEY ) ); + hDll->Config( -1, KA_TOGGLE, + Ini->ReadInteger( PFS_CONFIG, PFS_TOGGLEKEY, DEF_TOGGLEKEY ) ); + + SetupConfig2(); + } + SetupAMODI(); +} +void TDCHookMainForm::SetupConfig2() +{ + if (!hDll) + return; + + TDCHConfig cfg; + memset(&cfg, 0, sizeof(cfg)); + cfg.UseAMODI = AMODIAvail && (CaptureMode & CM_IMAGE); + cfg.OnlyAMODI = AMODIAvail && !(CaptureMode & CM_TEXT); + cfg.MoveSend = MouseIncSrch; + //cfg.OnlyImage = 1; //TODO: + if (AMODIPath.data()){ + strncpy(cfg.AMODIPath, AMODIPath.c_str(), sizeof(cfg.AMODIPath)-1); + } + + int dpiDetect = Ini->ReadInteger(PFS_CONFIG, PFS_DPI_DETECT, 1); + if (dpiDetect){ +#if DPI_DETECT + cfg.ScaleX = GetMonitorScale(); +#endif + } else { + cfg.ScaleX = Ini->ReadInteger(PFS_CONFIG, PFS_SCALE, 0); + } + cfg.ScaleY = cfg.ScaleX; + hDll->Config2(&cfg); +} +void TDCHookMainForm::SetupAMODI() +{ + if (AMODIPath.data()){ + AMODIAvail = true; + } else { + HWND hwnd = FindAMODI(); + if (hwnd){ + AMODIAvail = true; + } else { + AMODIAvail = LaunchAMODI(); + if (!AMODIAvail){ + HWND hwnd = FindAMODI(); + if (hwnd) + AMODIAvail = true; + } + } + } + if (AMODIAvail){ + tmMODIInstallCheck->Enabled = false; + } +} +void TDCHookMainForm::EnableClickOnly( bool enable ) +{ + if (hDll) + hDll->Config( enable, 0, 0 ); +} +void TDCHookMainForm::DokoPopMenu( bool all ) +{ +// Width = 0; + SetForegroundWindow( Handle ); + POINT pt; + GetCursorPos( &pt ); + miEnablePopup->Visible = all; + miReload->Visible = !all; + miClose->Visible = !all; + miExit2->Visible = all; + pmTrayIcon->TrackButton = tbRightButton; + pmTrayIcon->Popup( pt.x, pt.y ); + MoveToTop( Handle ); +// MoveToTop( pmTrayIcon->WindowHandle ); +} +void TDCHookMainForm::MenuClosed() +{ + Visible = false; + ShowWindow( Application->Handle, SW_HIDE ); + tmMenuClose->Enabled = true; +} +void TDCHookMainForm::EvToggle( TMessage &msg ) +{ + miClickOnlyClick( this ); + ShowNotify(); +} +void TDCHookMainForm::EvShortcut( TMessage &msg ) +{ + switch (msg.WParam){ + case SCINX_NOTIFY64: + DBW("SCINX_NOTIFY64:%08X %08X", msg.LParam, hDll); + if (hDll){ + hDll->Notify64(msg.LParam); + SetupConfig(); + } + break; + } +} +void TDCHookMainForm::EvGetVersion( TMessage &msg ) +{ + msg.Result = VersionValue; +} +//--------------------------------------------------------------------------- +// ‰EƒNƒŠƒbƒNŒŸõON/OFF•\Ž¦ +void TDCHookMainForm::ShowNotify() +{ + POINT pt; + GetCursorPos( &pt ); + if ( !NotifyForm ){ + NotifyForm = new TNotifyForm( this ); + } else { + NotifyForm->Visible = false; + } + NotifyForm->enable = miClickOnly->Checked; + NotifyForm->Left = pt.x + 8; + NotifyForm->Top = pt.y + 8; + NotifyForm->Setup(); + NotifyForm->Show(); + SetWindowPos( Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + SetWindowPos( NotifyForm->Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE ); + tmNotify->Enabled = false; + tmNotify->Enabled = true; +} +void TDCHookMainForm::NotifyAMODI() +{ + MODINotifyDialog = new TMODINotifyDialog(this); + MODINotifyDialog->ShowModal(); + if (MODINotifyDialog->LinkClicked || AMODIRunable()){ + tmMODIInstallCheck->Enabled = true; + } + delete MODINotifyDialog; +} +void TDCHookMainForm::Reboot() +{ + ::Reboot = true; + Close(); +} +void GetGroupList(TMyIni &ini, TStringList &list) +{ + AnsiString s = ini.ReadString("Group", "::GroupNames::", ""); + if (s.IsEmpty()){ + // for old version (not work correctly) + ini.ReadValues( "Group", &list); + } else { + const TCHAR *p = _tcstok(s.c_str(), _T("\t")); + while (p){ + list.Add( p ); + p = _tcstok(NULL, _T("\t")); + } + } +} + +#if DPI_DETECT +#if WINVER<0x0601 +#define QDC_ALL_PATHS 0x00000001 +#define QDC_ONLY_ACTIVE_PATHS 0x00000002 +#define QDC_DATABASE_CURRENT 0x00000004 +typedef enum +{ + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER = -1, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15 = 0, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO = 1, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO = 2, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO = 3, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI = 4, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI = 5, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS = 6, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN = 8, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI = 9, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL = 10, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED = 11, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL = 12, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED = 13, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE = 14, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL = 0x80000000, + DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY; +typedef enum +{ + DISPLAYCONFIG_ROTATION_IDENTITY = 1, + DISPLAYCONFIG_ROTATION_ROTATE90 = 2, + DISPLAYCONFIG_ROTATION_ROTATE180 = 3, + DISPLAYCONFIG_ROTATION_ROTATE270 = 4, + DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_ROTATION; +typedef enum +{ + DISPLAYCONFIG_SCALING_IDENTITY = 1, + DISPLAYCONFIG_SCALING_CENTERED = 2, + DISPLAYCONFIG_SCALING_STRETCHED = 3, + DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX = 4, + DISPLAYCONFIG_SCALING_CUSTOM = 5, + DISPLAYCONFIG_SCALING_PREFERRED = 128, + DISPLAYCONFIG_SCALING_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_SCALING; +typedef struct DISPLAYCONFIG_RATIONAL +{ + UINT32 Numerator; + UINT32 Denominator; +} DISPLAYCONFIG_RATIONAL; +typedef enum +{ + DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED = 0, + DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE = 1, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED = 2, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED, + DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST = 3, + DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_SCANLINE_ORDERING; +typedef enum +{ + DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1, + DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2, + DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_MODE_INFO_TYPE; +typedef struct DISPLAYCONFIG_2DREGION +{ + UINT32 cx; + UINT32 cy; +} DISPLAYCONFIG_2DREGION; +typedef struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO +{ + UINT64 pixelRate; + DISPLAYCONFIG_RATIONAL hSyncFreq; + DISPLAYCONFIG_RATIONAL vSyncFreq; + DISPLAYCONFIG_2DREGION activeSize; + DISPLAYCONFIG_2DREGION totalSize; + UINT32 videoStandard; + DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering; +} DISPLAYCONFIG_VIDEO_SIGNAL_INFO; +typedef enum +{ + DISPLAYCONFIG_PIXELFORMAT_8BPP = 1, + DISPLAYCONFIG_PIXELFORMAT_16BPP = 2, + DISPLAYCONFIG_PIXELFORMAT_24BPP = 3, + DISPLAYCONFIG_PIXELFORMAT_32BPP = 4, + DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5, + DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32 = 0xffffffff +} DISPLAYCONFIG_PIXELFORMAT; +typedef enum +{ + DISPLAYCONFIG_TOPOLOGY_INTERNAL = 0x00000001, + DISPLAYCONFIG_TOPOLOGY_CLONE = 0x00000002, + DISPLAYCONFIG_TOPOLOGY_EXTEND = 0x00000004, + DISPLAYCONFIG_TOPOLOGY_EXTERNAL = 0x00000008, + DISPLAYCONFIG_TOPOLOGY_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_TOPOLOGY_ID; +typedef enum +{ + DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME = 1, + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME = 2, + DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE = 3, + DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME = 4, + DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE = 5, + DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32 = 0xFFFFFFFF +} DISPLAYCONFIG_DEVICE_INFO_TYPE; + +typedef struct DISPLAYCONFIG_PATH_SOURCE_INFO +{ + LUID adapterId; + UINT32 id; + UINT32 modeInfoIdx; + UINT32 statusFlags; +} DISPLAYCONFIG_PATH_SOURCE_INFO; +typedef struct DISPLAYCONFIG_PATH_TARGET_INFO +{ + LUID adapterId; + UINT32 id; + UINT32 modeInfoIdx; + DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology; + DISPLAYCONFIG_ROTATION rotation; + DISPLAYCONFIG_SCALING scaling; + DISPLAYCONFIG_RATIONAL refreshRate; + DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering; + BOOL targetAvailable; + UINT32 statusFlags; +} DISPLAYCONFIG_PATH_TARGET_INFO; +typedef struct DISPLAYCONFIG_PATH_INFO +{ + DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo; + DISPLAYCONFIG_PATH_TARGET_INFO targetInfo; + UINT32 flags; +} DISPLAYCONFIG_PATH_INFO; +typedef struct DISPLAYCONFIG_TARGET_MODE +{ + DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo; +} DISPLAYCONFIG_TARGET_MODE; +typedef struct DISPLAYCONFIG_SOURCE_MODE +{ + UINT32 width; + UINT32 height; + DISPLAYCONFIG_PIXELFORMAT pixelFormat; + POINTL position; +} DISPLAYCONFIG_SOURCE_MODE; +typedef struct DISPLAYCONFIG_MODE_INFO +{ + DISPLAYCONFIG_MODE_INFO_TYPE infoType; + UINT32 id; + LUID adapterId; + union + { + DISPLAYCONFIG_TARGET_MODE targetMode; + DISPLAYCONFIG_SOURCE_MODE sourceMode; + }; +} DISPLAYCONFIG_MODE_INFO; +typedef struct DISPLAYCONFIG_DEVICE_INFO_HEADER +{ + DISPLAYCONFIG_DEVICE_INFO_TYPE type; + UINT32 size; + LUID adapterId; + UINT32 id; +} DISPLAYCONFIG_DEVICE_INFO_HEADER; + +#endif + +typedef WINUSERAPI LONG (WINAPI *FNGetDisplayConfigBufferSizes)(UINT32 flags, UINT32* numPathArrayElements, UINT32* numModeInfoArrayElements); +typedef WINUSERAPI LONG (WINAPI *FNSetDisplayConfig)(UINT32 numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32 numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, UINT32 flags); +typedef WINUSERAPI LONG (WINAPI *FNQueryDisplayConfig)(UINT32 flags, UINT32* numPathArrayElements, DISPLAYCONFIG_PATH_INFO* pathArray, UINT32* numModeInfoArrayElements, DISPLAYCONFIG_MODE_INFO* modeInfoArray, DISPLAYCONFIG_TOPOLOGY_ID* currentTopologyId); +typedef WINUSERAPI LONG (WINAPI *FNDisplayConfigGetDeviceInfo)(DISPLAYCONFIG_DEVICE_INFO_HEADER* requestPacket); + +class TDllHandle { +protected: + HINSTANCE hInst; +public: + TDllHandle(HINSTANCE _hInst) + :hInst(_hInst) + { + } + ~TDllHandle(){ + if (hInst) FreeLibrary(hInst); + } + HINSTANCE inst(){ return hInst; } + operator HINSTANCE (){ return hInst; } +}; + +int GetMonitorScale() +{ + int dpi = 96; + + HINSTANCE hDll = LoadLibrary( user32 ); + if (!hDll) + return dpi; + + TDllHandle hInst(hDll); + + FNGetDisplayConfigBufferSizes _GetDisplayConfigBufferSizes = (FNGetDisplayConfigBufferSizes)GetProcAddress(hInst, "GetDisplayConfigBufferSizes"); + if (!_GetDisplayConfigBufferSizes) return dpi; + FNQueryDisplayConfig _QueryDisplayConfig = (FNQueryDisplayConfig)GetProcAddress(hInst, "QueryDisplayConfig"); + if (!_QueryDisplayConfig) return dpi; + + POINT pt; + GetCursorPos( &pt ); + HMONITOR hMonitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONULL ); + if (!hMonitor) return dpi; + + MONITORINFOEX LogicalMonitorInfo; + LogicalMonitorInfo.cbSize = sizeof(MONITORINFOEX); + GetMonitorInfo(hMonitor, &LogicalMonitorInfo); + int LogicalMonitorWidth = LogicalMonitorInfo.rcMonitor.right - LogicalMonitorInfo.rcMonitor.left; + + int LogicalDesktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + + UINT32 numofpath; + UINT32 numofmode; + _GetDisplayConfigBufferSizes(QDC_DATABASE_CURRENT, &numofpath, &numofmode); + + DISPLAYCONFIG_PATH_INFO *dpis=new DISPLAYCONFIG_PATH_INFO[numofpath]; + DISPLAYCONFIG_MODE_INFO *pModeInfoArray =new DISPLAYCONFIG_MODE_INFO[numofmode]; + DISPLAYCONFIG_TOPOLOGY_ID tid; + _QueryDisplayConfig(QDC_DATABASE_CURRENT, &numofpath, dpis, &numofmode, pModeInfoArray, &tid); //TODO: Windows7 or later + + int PhysicalDesktopWidth = LogicalDesktopWidth; + int PhysicalMonitorWidth = LogicalMonitorWidth; + + for (int i=0;i<(int)numofmode;i++){ + if (pModeInfoArray[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE){ + dbw("%d: %d", i, pModeInfoArray[i].sourceMode.width); + PhysicalDesktopWidth = pModeInfoArray[i].sourceMode.width; + //int PhysicalDesktopWidth = + //int ScaleFactor = (LogicalMonitorWidth/LogicalDesktopWidth) / (PhysicalMonitorWidth/PhysicalDesktopWidth) + //return 96 * 1; + } else + if (pModeInfoArray[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE_TARGET){ + PhysicalMonitorWidth = pModeInfoArray[i].targetMode.targetVideoSignalInfo.activeSize.cx; + dbw("%d: %d", i, PhysicalMonitorWidth); + } + } + + //int PhysicalMonitorWidth = pModeInfoArray[i].sourceMode.width; + //int ScaleFactor = (LogicalMonitorWidth/LogicalDesktopWidth) / (PhysicalMonitorWidth/PhysicalDesktopWidth) + + delete[] dpis; + delete[] pModeInfoArray; + + return dpi * PhysicalDesktopWidth / LogicalDesktopWidth; +} +#endif + + diff --git a/DCHookTest/DCHookMain.dfm b/DCHookTest/DCHookMain.dfm new file mode 100644 index 0000000..a560812 --- /dev/null +++ b/DCHookTest/DCHookMain.dfm @@ -0,0 +1,2741 @@ +object DCHookMainForm: TDCHookMainForm + Left = 467 + Top = 181 + Width = 443 + Height = 369 + Caption = 'DCHookMainForm' + Color = clWhite + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = '‚l‚r ‚oƒSƒVƒbƒN' + Font.Style = [] + Menu = MainMenu + OldCreateOrder = False + PopupMenu = pmTrayIcon + Position = poScreenCenter + OnCloseQuery = FormCloseQuery + OnCreate = FormCreate + OnKeyPress = FormKeyPress + PixelsPerInch = 96 + TextHeight = 12 + object Splitter1: TSplitter + Left = 105 + Top = 0 + Width = 6 + Height = 228 + Cursor = crHSplit + end + object PaintBox: TPaintBox + Left = 111 + Top = 0 + Width = 316 + Height = 228 + Align = alClient + end + object Image: TImage + Left = 111 + Top = 0 + Width = 316 + Height = 228 + Align = alClient + AutoSize = True + Center = True + Picture.Data = { + 07544269746D61703A320100424D3A3201000000000000000000280000003401 + 0000E80000000100080001000000042E01000000000000000000000100000001 + 0000000000000101010002020200030303000404040005050500060606000707 + 070008080800090909000A0A0A000B0B0B000C0C0C000D0D0D000E0E0E000F0F + 0F00101010001111110012121200131313001414140015151500161616001717 + 170018181800191919001A1A1A001B1B1B001C1C1C001D1D1D001E1E1E001F1F + 1F00202020002121210022222200232323002424240025252500262626002727 + 270028282800292929002A2A2A002B2B2B002C2C2C002D2D2D002E2E2E002F2F + 2F00303030003131310032323200333333003434340035353500363636003737 + 370038383800393939003A3A3A003B3B3B003C3C3C003D3D3D003E3E3E003F3F + 3F00404040004141410042424200434343004444440045454500464646004747 + 470048484800494949004A4A4A004B4B4B004C4C4C004D4D4D004E4E4E004F4F + 4F00505050005151510052525200535353005454540055555500565656005757 + 570058585800595959005A5A5A005B5B5B005C5C5C005D5D5D005E5E5E005F5F + 5F00606060006161610062626200636363006464640065656500666666006767 + 670068686800696969006A6A6A006B6B6B006C6C6C006D6D6D006E6E6E006F6F + 6F00707070007171710072727200737373007474740075757500767676007777 + 770078787800797979007A7A7A007B7B7B007C7C7C007D7D7D007E7E7E007F7F + 7F00808080008181810082828200838383008484840085858500868686008787 + 870088888800898989008A8A8A008B8B8B008C8C8C008D8D8D008E8E8E008F8F + 8F00909090009191910092929200939393009494940095959500969696009797 + 970098989800999999009A9A9A009B9B9B009C9C9C009D9D9D009E9E9E009F9F + 9F00A0A0A000A1A1A100A2A2A200A3A3A300A4A4A400A5A5A500A6A6A600A7A7 + A700A8A8A800A9A9A900AAAAAA00ABABAB00ACACAC00ADADAD00AEAEAE00AFAF + AF00B0B0B000B1B1B100B2B2B200B3B3B300B4B4B400B5B5B500B6B6B600B7B7 + B700B8B8B800B9B9B900BABABA00BBBBBB00BCBCBC00BDBDBD00BEBEBE00BFBF + BF00C0C0C000C1C1C100C2C2C200C3C3C300C4C4C400C5C5C500C6C6C600C7C7 + C700C8C8C800C9C9C900CACACA00CBCBCB00CCCCCC00CDCDCD00CECECE00CFCF + CF00D0D0D000D1D1D100D2D2D200D3D3D300D4D4D400D5D5D500D6D6D600D7D7 + D700D8D8D800D9D9D900DADADA00DBDBDB00DCDCDC00DDDDDD00DEDEDE00DFDF + DF00E0E0E000E1E1E100E2E2E200E3E3E300E4E4E400E5E5E500E6E6E600E7E7 + E700E8E8E800E9E9E900EAEAEA00EBEBEB00ECECEC00EDEDED00EEEEEE00EFEF + EF00F0F0F000F1F1F100F2F2F200F3F3F300F4F4F400F5F5F500F6F6F600F7F7 + F700F8F8F800F9F9F900FAFAFA00FBFBFB00FCFCFC00FDFDFD00FEFEFE00FFFF + FF0003A601A501A402A301A202A102A0029F029E019D019C029B029A01990298 + 02970296019503940193029202910190028F018E028D028C028B018A02890188 + 02870286028502840283028202810280027F027E027D017C027B027A02790278 + 02770176027502740173027201710270016F026E016D016C026B026A01690268 + 0167026601650264016301620261026000035F5E5D00025C025B015A02590003 + 58575600025500035453520002510005504F4E4D4C00024B00034A4948000247 + 00044544434202410011403F3E3D3C3B3A3938373635343332313000022F0006 + 2E2D2C2B2A2902280004272625240223022201210120021F021E011D021C021B + 021A0219021801170316011501140213021201110110020F00030E0D0C00020B + 020A0003090807000306010503040203030206010C0008010202020301040405 + 03040105020601040803070203010200000001A702A601A502A402A301A202A1 + 01A0029F029E029D029C019B019A029902980297029601950294019302920291 + 0190028F018E028D028C028B028A028901880287018602850384018302820281 + 0280027F027E027D017C027B027A027902780277017602750274017302720171 + 0270016F026E016D016C026B026A016902680167026601650264016301620261 + 026000035F5E5D00025C015B025A015901580257015601550254000553525150 + 4F00024E00054D4C4B4A49000248000647464544434202410006403F3E3D3C3B + 02390004383735340233000A3231302F2E2D2C2B2A2902280004272625240223 + 012202210120021F011E021D021C011B031A0219021801170216021502140113 + 011202110110010F020E010D020C010B020A0109020801070206020502040303 + 030206010D000701020203030504020301040205040405030702040101000000 + 03A701A601A502A401A302A202A102A0019F029E019D029C029B019A02990298 + 01970296019502940293029201910290028F018E028D028C018B028A02890288 + 01870286028502840283018202810280027F027E027D027C027B017A02790278 + 02770176027502740173027201710270016F026E016D016C026B026A01690268 + 01670266016502640163016202610160025F015E015D025C00035B5A59000258 + 015702560005555453525100025000054F4E4D4C4B00024A0009494847464544 + 43424100024000113F3E3C3B3A393837363534333231302F2E00022D00062C2B + 2A292827022601250223022201210120021F011E021D021C021B011A03190118 + 02170216011503140113021201110210010F020E010D020C010B020A01090208 + 01070306010503040203040206010D0007010003020304000205020406030604 + 06030202020304020301000001A802A701A602A501A402A302A201A102A0019F + 029E029D029C019B029A0299019802970296019502940293019202910290018F + 028E028D018C028B028A0189028802870286028501840283018202810380027F + 027E017D027C027B027A0279017802770276017502740173027201710170026F + 016E016D026C016B026A0269026801670266000365646300026202610003605F + 5E00025D00035C5B5A00025901580157025600045554535202510006504F4E4D + 4C4B024A0020494847464544434241403F3E3D3C3B3A39383736353433323130 + 2F2E2D2C2B2A02290006282726252423022201210120021F021E011D021C011B + 021A0219021801170316011502140213021202110110020F010E020D020C010B + 020A0209010802070206020502040303030207010D0004010302000803040709 + 0A08060405030704090304020301000002A802A701A602A502A401A302A201A1 + 02A0029F019E029D019C029B029A029901980297019602950294029301920291 + 0290018F028E028D018C028B028A018902880287028601850184028302820281 + 0280027F037E017D027C017B027A027901780277017601750274027300037271 + 7000026F026E016D026C016B026A026901680267000366656400026301620261 + 0160015F025E015D015C025B00035A595800025701560255000754535251504F + 4E00024D00164C4B4A494847464544434241403F3E3D3C3B3A39383702350003 + 34333100023000032E2D2C00022B00082A29282726252423022201210120021F + 011E021D011C011B021A0319011802170116031502140213021202110210010F + 020E010D020C020B020A0209010801070306020503040303030206010D000201 + 0302020300090405080B0F100E0A0600050307040A0304020201000001A902A8 + 02A701A601A502A402A301A202A101A0029F029E029D019C029B019A02990298 + 01970296019502940293029202910190028F028E018D028C028B018A02890288 + 01870286018502840283018202810280027F037E017D027C017B027A01790278 + 01770176027502740173017202710170026F016E026D016C026B016A02690168 + 0267016602650003646362000261026000035F5E5D00025C00055B5A59585700 + 0256015502540009535251504F4E4D4C4B00024A000449484746024400204341 + 403F3E3D3C3B3A393837363534333231302F2E2D2C2B2A292827262524230222 + 01210120021F011E011D021C011B021A01190218021702160215031401130312 + 01110310020F010E020D020C020B010A03090108020702060205030403030302 + 06010C00030101020203000D04050607090B0F13151410090400040308040203 + 0104070303020201000002A902A801A702A601A501A402A302A202A101A0029F + 029E019D029C029B019A0199039801970296029501940293019202910290028F + 018E028D018C028B018A0289028802870186028502840183018202810280027F + 027E027D027C017B027A0179017802770176027501740273017202710170016F + 026E026D016C016B026A0169026801670266000365646300026201610260015F + 015E025D00045C5B5A5902580157015602550153015202510022504F4E4D4C4B + 4A494847464544434241403F3E3D3C3B3A3938373534333231302F2E022D0008 + 2B2A292827262524022302210120011F021E011D011C021B021A011902180117 + 0316021502140213021202110210020F030E020D020C010B020A030902080207 + 02060205020403030A020D010302000A0304050607090B0D101402180003140C + 060004030C04060304020101000003A902A801A702A601A502A401A302A201A1 + 02A0019F029E029D029C019B019A029902980297019602950294029301920291 + 0290018F028E018D018C028B028A018902880287028601850284018301820281 + 0280027F027E017D027C027B017A017902780177027602750174017302720171 + 0170026F016E026D016C016B026A016902680167016602650164016302620161 + 026000035F5E5D00025C00045B5A595802570006565554535251025000074F4E + 4D4C4B4A490002470019464544434241403E3D3C3B3A39383736353433323130 + 2F2D2C00022B012A0129022700042524232202210004201F1E1D021C011B021A + 0119021802170216021502140213021203110210020F020E030D020C020B020A + 020902080207020601050106030503040B031002001003040506080A0C0E1115 + 181A170F070402030E0405030502000001AA02A902A802A701A601A502A402A3 + 02A201A102A0029F019E029D029C019B019A0299029802970196029502940193 + 029201910290018F028E028D018C028B018A0289018802870286018502840183 + 018202810280027F017E027D027C017B017A0279027801770276000375747300 + 0272000371706F00026E026D016C016B026A0169016802670266000465646362 + 02610160025F00055E5D5C5B5A0002590003585756000255002D54535251504F + 4E4D4C4B4A494847464544434241403F3E3D3C3B393837363534333231302F2E + 2D2C2B2A292827000225022300052221201F1E00021D011C011B021A01190218 + 01170216021502140213021202110310020F030E010D040C020B020A03090408 + 01070A0602050204050502040703060203030204000E0507080A0C0E1115181A + 1810070402030E0407030302000003AA01A902A802A701A602A501A402A301A2 + 02A101A0029F029E029D019C019B029A02990298029701960195029401930292 + 01910290028F028E018D028C018B018A02890188028702860185028401830182 + 02810280017F027E027D017C027B017A02790178017702760003757473000272 + 01710170026F016E016D026C026B00036A696800026701660265000464636261 + 026000045F5E5D5C025B00045A595857025600085554535251504F4E024D0008 + 4C4B4A49484745440243000C4241403F3D3C3B3A393837350234000C3231302F + 2E2D2C2B2A29282702250123012202210005201F1E1D1C00021B011A01190218 + 02170216011501140313021201110310030F020E030D020C040B020A0A090108 + 0107030800050908090809000208050702060205010406030402030301040305 + 000E0607080A0C0E1114181A1810070402030F0406030302000001AB02AA02A9 + 02A801A701A602A502A402A301A202A102A0019F029E029D019C019B029A0299 + 029800039796950002940193039201910290018F028E018D028C018B018A0289 + 018802870286018502840183018202810180027F017E027D017C027B017A0279 + 017801770276017501740273000372717000026F016E026D016C016B026A0003 + 6968670002660003656463000262000561605F5E5D00025C00045B5A59580257 + 0004565554530252000E51504F4E4D4C4B4A4948474645430242001D41403F3E + 3D3C3A3938373635333231302F2E2D2C2B2A292726252423220002210005201F + 1E1D1C00021B00031A19180002170116021502140113021202110310030F020E + 030D030C040B060A020B050C0C0B010A01090308020702060205060405030204 + 010502060307000C080A0C0E1114171A170F070403030F0407030102000001AC + 01AB02AA01A902A802A701A602A502A402A301A201A102A0029F029E019D029C + 019B029A0199029801970196029502940193029202910190018F028E018D028C + 018B018A0289018802870286018501840283018201810280017F027E00037D7C + 7B00027A017902780177027601750274000473727170026F00036E6D6C00026B + 00036A6968000267000366656400026300056261605F5E00025D00055C5B5A59 + 58000257000356555400025300105251504F4E4D4C4B4A494847464544430241 + 001E403F3E3D3B3A3938373635343331302F2E2D2C2B2A292827262524232221 + 021F00041E1D1C1B021A0119011802170116021501140113021203110210020F + 020E030D050C050B010C010B030C020D020E090F030E030D010C010B020A0109 + 04080207060604050504010501060307000D08090A0C0E10131619170F070400 + 030310040703000002AC01AB02AA01A902A802A702A601A502A402A301A201A1 + 02A0029F019E019D029C019B029A019902980297019601950294019302920291 + 0190028F018E018D028C018B018A028901880287018602850184018302820181 + 0180027F017E017D027C017B017A02790178017702760006757473727170026F + 016E016D026C00046B6A696802670003666564000263000362616000025F0004 + 5E5D5C5B025A015902570156015502540013535251504F4E4D4C4B4A49484746 + 454443424000023F00123E3D3B3A3938373635343331302F2E2D2C2B02290128 + 022600072524232221201F00021D00041C1B1A19021801170216011501140213 + 021201110210030F020E030D090C020D020E030F021001110312031301120113 + 021202110110010F030E020D010C060B010A0509020803070206020502040205 + 010601070308000C090A0B0D0F121618160F0804030308040305060406030000 + 02AC02AB01AA02A902A801A702A602A501A402A301A202A101A0029F019E019D + 029C019B029A0299019802970196019502940293019202910190028F018E018D + 028C018B018A028901880287018601850284000483828180027F017E027D0004 + 7C7B7A790278000477767574027300047271706F026E00036D6C6B00026A0005 + 69686766650002640005636261605F00025E00045D5C5B5A0259000458575655 + 025401520151025000074F4E4D4C4B4A49000247014601440243001542413F3E + 3D3C3B3A3938373635333231302F2E2D2C00022A012902270126012402230121 + 0120021F00061E1D1C1B1A19021800031716150002140113021201110310020F + 030E0B0D010E010F021001110212021301140215061601150214021302120111 + 0410060F030E010D010C020B020A020903080207010601050204020501060207 + 0308000B0A0B0D0F121518161008040002030804040507040503000001AD02AC + 01AB02AA02A901A802A702A602A50003A4A3A20002A101A0029F019E019D029C + 029B029A029900049897969502940293019202910190028F018E018D028C018B + 018A0289000388878600028500038483820002810004807F7E7D027C00077B7A + 79787776750002740173017202710006706F6E6D6C6B026A0007696867666564 + 63000262000561605F5E5D00025C00045B5A59580257002C565554535251504F + 4E4D4C4B4A494847464544434241403F3E3D3C3B3A3938363534333231302F2E + 2D2C2B2A022800072625242322212000021F00081E1D1C1B1A19181702160115 + 01140213021202110110020F030E030D010C020D010E030F0210000611121314 + 151603170218051903180117011605150114011505140313011202110004100F + 0E0D020C020B010A02090308010702060405010603070208000B090B0D0F1115 + 17161008040002030804050509040203000003AD01AC01AB02AA02A901A802A7 + 01A602A501A401A302A201A102A0019F029E029D019C019B029A029900049897 + 969502940293019201910290018F028E00038D8C8B00028A0004898887860285 + 000484838281028000047F7E7D7C027B00087A79787776757473027200087170 + 6F6E6D6C6B6A026900086867666564636261026000065F5E5D5C5B5A02590009 + 58575655545352515000024F014D014C024B000B4A4948474645444342403F00 + 023E001E3D3B3A393837363534333231302F2E2D2B2A29282726252423222120 + 1F1E021D00081C1B1A191817161503140213021201110210010F030E040D020E + 00040F1112130214000615161718191A021B011C041B071A0619041A03190118 + 02170004161514130211010F010E030D00030C0B0A0003090308010701060305 + 020603070208000B090A0C0E111416150F080400020307040A05050402030000 + 01AE02AD01AC02AB02AA01A902A801A701A602A501A401A302A202A101A0029F + 019E029D019C019B029A029900049897969502940293000392919000028F0004 + 8E8D8C8B028A01890188028700078685848382818000027F000E7E7D7C7B7A79 + 7877767574737271027000096F6E6D6C6B6A6968670002660009656463626160 + 5F5E5D00025C00035B59580002570004565554530252002151504F4E4D4C4B4A + 494847464544434241403F3E3D3C3B3A39383736353433313000022F00162D2C + 2B2A292827262524232221201F1E1D1C1B1A1918021700031615140002130112 + 0313011201110210010F030E020F02100009111213141718191A1B00021C041D + 011E031D061C021D021E081F021E021C000B1B1A19181715141311100F00020E + 020D010C010B030A02090208010702060205020601070208000D0708090A0C0E + 1013161510080400020306040B0506040103000002AE02AD01AC01AB02AA01A9 + 02A801A701A602A502A401A302A201A101A0029F019E029D019C019B029A0199 + 029800039796950002940193019202910003908F8E00028D00058C8B8A898800 + 0287000E868584838281807F7E7D7C7B7A790278001877767574737271706F6E + 6D6C6B6A69686766656463626160025F000C5E5D5C5B5A595857565554530252 + 000D51504F4E4D4C4B4A49484746450002440027434241403F3E3C3B3A393837 + 363534333231302F2E2D2C2B292827262524232221201F1E1D1C1B00021A0004 + 191817160215011401130212011101120313011201110410000B111314151618 + 191B1C1D1E00021F0320031F061E021F02200004212223240525000324232200 + 0221000D1F1E1D1C1B1A19181715141311000210010F020E010D020C010B030A + 02090208010701060205010602070208000D0708090A0C0E1013161510090500 + 020305040D050604000003AE01AD02AC0003ABAAA90002A801A702A602A501A4 + 01A302A201A101A0029F019E029D00039C9B9A00029901980197029600049594 + 939202910004908F8E8D028C00058B8A89888700028600188584838281807F7E + 7D7C7B7A7978777675747372716F6E6D026C00086B6A69686765646302620010 + 61605F5E5D5C5B5A59585756555453520251000D504F4E4D4C4B4A4948474645 + 4400024300104241403F3E3D3C3B3A3837363534333202310017302F2D2C2B2A + 292827262524232221201F1E1D1C1B1A19000218000317161500021401130212 + 041103120313000B141517191B1C1E1F20212200022303220721032200062324 + 252627280629001628272625242221201F1E1D1C1B1A19181615141312110210 + 00030F0E0D00030C020B020A02090208010703060207050800050A0C0D101200 + 021500031009050007040E050504000002AF01AE01AD02AC01AB01AA02A901A8 + 02A702A60003A5A4A30002A20003A1A09F00029E019D029C019B019A02990006 + 9897969594930292000691908F8E8D8C028B00078A898887868584000283002D + 8281807F7E7C7B7A7978777675747372706F6E6D6C6B6A696867666564636261 + 605F5E5D5C5B5A595857565554000253000351504F00024E000D4D4C4B4A4948 + 4746454443424100024000143F3E3D3C3B3A393837363534333231302F2E2D2C + 022A00062928272625240222000B21201F1E1D1C1B1A19181700021601150114 + 02130712000C13151617191B1C1E202122240625022405230224000426272829 + 022A022B022C032D012C022B00082A292827252423220220000D1F1E1D1B1A19 + 181716151413120002110110010F020E010D030C020B020A0209010801070306 + 0107060800050A0C0D0F1200021500031109050007040F050404000002AF01AE + 02AD01AC02AB01AA01A902A801A702A60003A5A4A30002A20004A1A09F9E029D + 019C019B029A00069998979695940293000B9291908F8E8D8C8B8A8988000287 + 0033868584838281807F7E7D7C7A7978777675747271706F6E6D6C6B6A696867 + 6665646361605F5E5D5C5B5A59585756555453525100025000034E4D4C00024B + 000E4A494847464544434241403F3E3D023C001C3B3A39383736353433323130 + 2F2E2D2C2B2A29282726252423222120021F00031E1D1C00021A011902180004 + 171615140413011402150009161718191B1E2022240002260127052801270326 + 042500082627282A2C2D2E2F0530032F012E022D00172C2B2A29282725242322 + 21201F1E1D1C1B1A1918171615000214000413121110020F020E010D030C010B + 020A020901080107030601070608000A0A0C0D0F121415110A05070409050206 + 050502040105000002AF01AE02AD02AC01AB01AA02A901A801A702A60004A5A4 + A3A202A10003A09F9E00029D00069C9B9A9998970296019501940292004B9190 + 8F8E8D8C8B8A898887868584838281807F7E7D7C7B7A78777675747371706F6E + 6D6B6A696867666564636261605E5D5C5B5A595857565554535251504F4E4D4C + 4B4A49484746454443000242000841403F3E3D3C3B3A02390011383736353433 + 3231302F2E2D2C2B2A292800022702250003242322000220011F011E021D0003 + 1B1A19000218041701160315000C16181A1C1E20212224252729022A032B022A + 012902280527000828292B2C2E2F313304340233013202310130012F022E022C + 00042B2A29270226012402230221000C201F1E1D1C1B1A191817161502140003 + 131211000210020F020E010D020C010B020A020902080407060800050A0B0D0F + 110002140003110A050006040A050206050502040105000001B002AF02AE0003 + ADACAB0002AA0005A9A8A7A6A50002A40003A3A2A10002A0000A9F9E9D9C9B9A + 9998979602950194019302910037908F8E8D8C8B8A8988878684838281807F7E + 7D7C7B7A79777675747371706F6E6C6B6A6968676564636261605F5E5C5B5A59 + 5857565553000252000551504F4D4C00024B000C4A494847464544434241403F + 023E00083D3C3B3A3938373602350134023201310130022E00052D2C2B2A2900 + 02280127012602240007232221201F1E1D00041C011A011904180119021A0009 + 1B1C1D1F2124272A2C00022D052E022D022C022B032A022900092A2B2C2E3032 + 3435360005370235000934333231302F2E2D2C00022B00112A29282726252423 + 2221201F1E1D1C1B1A000219011801170216000315141300021202110110020F + 010E020D010C010B020A03090108040706080005090B0D0E110002140003110B + 0500060406050606060501040105000001B002AF02AE0003ADACAB0002AA0005 + A9A8A7A6A50002A4000FA3A2A1A09F9E9D9C9B9A999897969500029400499392 + 908F8E8D8C8B8A8988878685848381807F7E7D7C7B7A78777675747271706F6D + 6C6B6A68676665636261605F5D5C5B5A5958565554535251504F4E4D4C4B4A49 + 48474645444342000241000A403F3E3D3C3B3A39383702360004353433320231 + 022F00082E2D2C2B2A292827022600092524232221201F1E1D00021C00031B1A + 1B00051C000D1D1F2021232527292C2E2F31320003340133013202310230032E + 022D022E012F0230013101330235000337383900033A0239000C383736353433 + 3231302F2E2D022C00092B2A29282726252423000222000421201F1E021C011B + 011A0219000318171600021501140113021202110110020F010E020D020C010B + 020A0309010803070608000A090B0C0E111314120B06060404050C0604050000 + 02B002AF0005AEADACABAA0002A90059A8A7A6A5A4A3A2A1A09F9E9D9C9B9A99 + 9897969594939291908F8E8D8C8B8A88878685848382817F7E7D7C7B7A787776 + 747372716F6E6D6C6A69686765646361605F5E5D5B5A5958575554535251504F + 4E4D4C4B4A494847460002440009434241403F3E3D3C3B00023A000639383736 + 3534023300093231302F2E2D2C2B2A0002290005282726252400022301220221 + 0006201F1E1D1C1B041A000E1C1F212326282A2C2E3031333435063601350234 + 02330632000633343537393A023B053D023C013B023A00083937363534333231 + 023000072F2E2D2C2B2A29000228000B27262524232221201F1E1D00021C011B + 011A021901170116021502140113021202110110020F020E020D020C020B020A + 010901080307010802090308000A090B0C0E111314120C06060404050C060405 + 000001B101B002AF0005AEADACABAA0002A901A801A702A50059A4A3A2A1A09E + 9D9C9B9A9998979695949391908F8E8D8C8B8A8988868584838281807E7D7C7A + 79787775747372716F6E6C6B6A686766646362615F5E5C5B5A59585655545352 + 514F4E4D4C4B4A494847464544434241403F3E00023D013B013A023900033837 + 360002350233000332313000022F00052E2D2C2B2A0002290004282726250224 + 022201210120031F011E011D021B0319000A1B1D2024292D3134353703380439 + 013805370336033702380006393A3B3C3E3F0241024202410240023E00103D3C + 3B3A393837363534333231302F2E022D000D2C2B2A2928272625242322212000 + 021F00031E1D1C00021B00051A1918171600021502140113031201110210020F + 030E010D020C020B010A020904080309000C08090A0B0D0E101314120C060604 + 03050E060305000001B101B002AF01AE02AC005AABAAA9A8A7A6A5A4A3A2A1A0 + 9F9D9C9B9A9998969594939291908E8D8C8B8A89888785848382817F7E7D7C7A + 79787775747271706E6D6C6B69686665646261605E5D5C5A5958565554535250 + 4F4E4D4C4B4A49484745444342410240013F023D00083C3B3A39383736350234 + 000433323130022F00042E2D2C2B022A00052928272625000224012301220221 + 0004201F1E1D041C011B031900091B1E23282D3235383A00053B083A023B033C + 00043D3E3F400241014201440245034601450244000443424140023E013D013C + 023A0012393837363534333231302F2E2D2C2B2A29280227000C262524232221 + 201F1E1D1C1B021A0119021801170116021503140213011201110210040F010E + 020D020C010B020A010903080409000C08090A0C0D0E101314130C0705040405 + 0F06020500000006B1B0AFAEADAC02AB0064AAA9A8A7A5A4A3A2A1A09F9E9C9B + 9A99989695949392908F8E8C8B8A89888785848382807F7E7D7C7A7978767573 + 72716F6E6D6B6A696766646361605F5D5C5B5A585755545251504F4E4C4B4A49 + 4847464544434241403F3E3D3C3B3A393837363534330232000331302F00022E + 022C00032B2A2900022800032726250002240003232221000220011F021E011D + 011C021B021A041900091B1E242A3035393A3C00023D063C023D023F01400241 + 024202430003444648000249054A0249001048474645444342403F3E3D3C3B3A + 393802370003363534000232000431302E2D022C00102B2A2928272625242322 + 21201F1E1D1C021B011A0219021800031716150004140213011202110310020F + 030E020D00030C0B0A000809000C08090A0C0D0E111315130D07050404050806 + 03070506010500000067B1B0AFAEADACABAAA9A8A7A6A4A3A2A1A09E9D9C9B9A + 98979694939291908E8D8C8A89888785848382807F7E7C7B7A78777674737270 + 6F6D6C6A696867656462615F5E5C5B5A585756545351504E4D4C4B4A48474645 + 44434241403F3E3D3C3B3A39383736353400023300043231302F022E00042D2C + 2B2A0229000328272600022500032423220002210120011F021E011D021C011B + 011A02190318000B191B1D20252B31373B3D3E00033F03400341000542434546 + 470003480005494A4B4D4E000350024F00164E4D4C4B4A494847464443424140 + 3F3E3D3C3B3A39380237000E3635343231302F2E2D2C2B2A2928022600052523 + 22212000021F021E011D021C011B021A01190318011701150414021301120211 + 0210050F010E020D020C010A0A09000A0A0C0D0E111315130D07050404050806 + 0307060600000061B1B0AFAEADACABAAA8A7A6A5A3A2A1A09F9D9B9A99989695 + 949291908E8D8B8A89888685848281807F7D7C7B797876757472716F6E6C6B6A + 686766646361605E5D5B5A585756545352504F4D4C4B4948474645444241403F + 3E3D3C3B3A393837360002350133013202310005302F2E2D2C00022B00032A29 + 280002270003262524000223022201210120021F021E011D011C021B011A0119 + 02180317000D181B20262A2F34393D4042434400024502470148054900054A4B + 4D4F50000251015201530254015501540253000A51504F4E4C4B4A4948470245 + 000D444241403F3E3D3C3B3A393837000236000D343331302F2E2D2C2B292827 + 260002250005242322212000031F011E011D031C011B011A0219021801170116 + 04150213031201110510020F010E020D010C010B080A0209000A0A0C0D0E1013 + 15130D07050403050506070702060207020600000061B1B0AFAEADACAAA9A8A6 + A5A3A2A1A09E9D9C9A989796949391908E8D8B8A888786858382807F7E7C7B7A + 787775747371706F6D6C6A696766646362605F5D5B5A585756545351504E4D4C + 4A49484645444342403F3E3D3C3B3A39383736353433320002310004302F2E2D + 022C00052B2A292827000226000325242300022201210220011F021E011D041C + 00041B1A191805170011181C212830383D41444647494A4B4C4D4E00024F0250 + 034F000550525456580004590258000F575655545351504E4D4C4B4A49484600 + 0245000444424140023F00073D3C3B3A39373600023500073332312F2D2C2B00 + 022A0128012704250005242322212000031F021E021D011C011B021A02190118 + 01170316021501140213031204110210020F010E020D010C010B040A020B040A + 000B0C0D0E101315130E070403000304030504060C07020600000060B0AFAEAD + ACABA9A8A7A5A4A2A1A09E9D9B9A9896959392908F8D8C8A888785848381807F + 7D7C7A797776747372706F6E6C6B6A6867656362605F5E5C5B59575654535250 + 4F4D4C4A49484645444241403F3E3C3B3A393837363534333231302F032E0004 + 2D2C2B29022800032726250002240123012202210120021F011E021D011C031B + 011A021900031A1917000316000C181B1E20232A323B43494C4D044F02500251 + 01520254025600065758595B5C5D035E00145D5C5B5A59575655535251504E4D + 4C4B4A4948460245000444424140023F00063D3C3B3938360234000733323130 + 2E2C2B00022A00032928270002260325022301210220021F031E011D021C011B + 021A021901180317021601140313041203110210020F00040E0D0C0B030A040B + 030A000C0C0D0F111315140F08040304050504060E070000005EB0AFAEADABAA + A9A7A6A4A3A1A09E9D9B9998969493918F8D8C8A8987858482817F7E7D7B7A78 + 77757472716F6D6C6B6A6967666463615F5E5C5B595856555352504F4D4C4A49 + 4846454342413F3E3D3C3B3A3837363534333231302F2E2D022C012B032A0004 + 2928262502240123012202210120021F011E021D021C011B021A011902180717 + 000C181B212B34383A3F444A4E500552000A53545556585A5C5E5F6002610362 + 0261001B605F5D5C5B5A59575654535251504E4D4C4B4A494847464544424100 + 024000073F3E3D3C393633000432000531302E2C2B00032A0128012702260325 + 00032423220002210120011F031E021D021C011B031A01190118021702160115 + 01140613031202110110020F00030E0D0C00050B010C040B000A0C0E0F111416 + 15100905020404050406060702080707000002AF004EADACAAA9A8A6A4A3A1A0 + 9E9C9A9997959391908E8C8A8987868482817F7D7C7A797776747371706E6D6B + 696867656462615F5E5C5B595856555352504F4D4C4A494746454342413F3E3D + 3B3A39380236023400073332302F2E2D2C00022B00042A292827032601250124 + 0523012203210004201F1E1D021C011B011A021902180417000B191B1D20242B + 37485558560002550003565758000259025A00085B5D5E606162646504660265 + 001F64636261605E5D5C5B5958575654535251504F4E4D4C4A49484746454442 + 4100024000073F3E3D3C3936330004320130012F022D012C012B022A00032928 + 2700022602250224000423222120041F011E011D031C011B021A011901180217 + 0216011503140713011201110210020F010E020C010B050C030B000A0C0E0F11 + 14161511090503040305040606070408050700000052AFAEADABAAA8A6A5A3A1 + 9F9E9C9A98969493918F8D8B8987868482807E7D7B7A7876757372706E6D6B6A + 686765646261605E5D5B5A5856555352504F4D4C4A494746454342413F3E3C3B + 3A3837363534333202310007302F2D2B2A292800022701260125022404230224 + 01260129022A0129012802290004282725230222000321201F00021E031D0010 + 1E2023272B30374251626D6E6A66646202630264000565646566670002680369 + 0268026700206665646261605F5E5D5B5A5958575655545251504F4E4D4B4A49 + 474645444342044000073F3E3D3A373534000233000332302F00022E00072D2C + 2B2A29282700032603250124012202210320011F021E021D021C021B00041A19 + 181703160315021401130314021301120111021000050F0E0D0C0B00030C010D + 010C020B00060C0D0E1011140216000311090500030403050306060708080207 + 00000050AFADACAAA9A7A5A3A19F9D9C9A98959392908E8C8A88868482807E7C + 7B7977757472716F6D6B6A6967666462615F5E5C5B595856555352504F4D4C4A + 494746454342403F3D3C3B3A3837363433323130032F022E00072C2A28272625 + 240002230222000D23242527292B2E32373A3938370002380004373633310230 + 022F012E022D012B022A000F2C2E32363C424C5765707778746F6C00066A0269 + 056A02690268002267666564636261605F5E5D5B5A5958575655545251504F4E + 4C4B4948474544434240023F034000073F3E3B3836353300023201310130022F + 00052E2D2C2B2A000228032703260004242322210320021F021E021D031C0003 + 1B1A190004170316021504140213021201110210010F010D050C020D00080C0B + 0C0D0E10111402160003110A050003040305030604070C080000004DAEACABA9 + A7A6A4A2A09D9B9A989593918F8D8B89868482807E7C7B79777573716F6E6C6B + 6967666463615F5E5C5B595857555452504F4D4C4A494746444342403F3D3C3B + 39383635343331302F00022E012D022C022B00052A2927252400042302240009 + 26282C2F34373A3D41000244014304420003413F3E00023D00073E3F403F3C3A + 37000236000A383A3F444C555F686F76027A000477726F6C056B056A03690268 + 016702660165016302620160015F025E001B5D5B5A5958575655535251504F4D + 4C4A494746444241403E3C3D3F00024100073F3E3C3936343200043102300006 + 2F2E2D2C2B2A02290228022700052625242322000321021F031E031D021C0003 + 1B1A19000318031702160115041402130212000411100F0E050D010E010D030C + 00050D0E1012140002160003110A050003040305020604070D080000004EADAB + A9A7A6A4A2A09E9B99979592908E8C89878582807E7C7A78767472716F6D6B6A + 68666462615F5E5C5A595856555352504F4D4B4A494746444341403F3D3C3B39 + 383635343231302F2E2D2C2B022A022902270126042500122627292B2D303337 + 3B3F42444546474847460345014403430003444546000247000345413F00023D + 000B3E41464D555E676D71737700027A00057874706D6C00026B036A06690268 + 016702660003656463000262000C61605F5E5D5B5A58575554530251000D504F + 4D4C4B4947464543413E3D00023B013C013F02410006403F3C39353302310432 + 0131022F00032E2D2C00032A0229022800032726250002240006232221201F1E + 021F041E00031D1C1B00021A0219011802170216021502140115021401130212 + 000311100F00040D030E010D020C00050D0F1012140002160003120A05000304 + 0205030604070D080000004BACAAA8A6A4A2A09E9C999794928F8D8A88868381 + 7F7D7A78767472706E6C6A6866656361605E5D5B595856555351504E4D4B4A49 + 4746444341403E3D3B3A39373635333231302E2D2C2B2A000229012802270426 + 000E27282B2D2F3235383B3E4042444606470246064501460147034900034846 + 430003410009444950575F676D7173000274000977797A7874716E6C6B00026A + 07690268026702660003656463000262000A61605E5D5B5A585653510250024F + 00074E4D4B4A484645000244000443413F3E023D013E01400242000641403D3A + 3634053302320130022F012E012C022B032A0003292827000226022500052423 + 22212000021F0120031F021E011D011C021B00031A1918000217021601150214 + 031501140313000412110F0E020D040E00080D0C0D0E0F10121402160003120B + 0500030402050306030709080209030800000046ABA9A7A5A3A09E9C99979491 + 8F8C898785827F7D7B78767472706D6B6A68666462605E5C5B59585654535150 + 4E4C4B49484645444241403E3D3B3A383736343332312F2E2D2C022A01290628 + 000E292A2C2E3033363B3E414445464702480349014803470246044500044647 + 4849034A000E484745444345484D545C646C71740276000D7574757678797875 + 716E6C6B6A0003690668026702660265000D646362605F5E5C5A585653515000 + 024D034E00054C4A484644000243014402450143024204410008424342413E3C + 393702350234023300063231302F2E2D032B022A022901280127032600032524 + 220002210520021F00031E1C1B00021A00031918170005160215031601150214 + 0005131211100F00040E020F010E020D00050E0F1012150002170003130B0500 + 0204030502060407040807090208010900000043A9A8A5A3A19E9C9A9794918E + 8B898683817E7C797674726F6D6B69676563615F5D5B5957565453514F4E4C4B + 494746454342403F3E3D3C3A393736343332302F2E2D2C00032A0015292A2B2C + 2E2F31323436393C3F4244474A4B4C4D4C00024B034A02490148014705460147 + 02480149014A024B014A01490247000B4647494E5359616970757900027A000F + 78777574757677797875726F6C6B6A000269066802670266000D65646362615F + 5C5A595855535100034F024D024E00054D4A4947460003450008464847464544 + 4342024101420243000742403D3A3836350002340133013202310130012F022E + 012D022C022B012A022901280127022600042524232203210220031F00031E1D + 1B00021A0119021802170118021706160115021400041312110F030E00040F10 + 0F0E020D00050E0F1112150002170003130C0600020403050206030705080A09 + 0000003FA8A6A4A19F9C999794918E8B888683807D7B787572706D6B68666462 + 605E5C5A58565453514F4E4C4B494746444342403F3D3C3B3938373634333230 + 2F2E2D00022C022B00102C2D2F3033373B3F42444648494B4C4D024E034F024E + 00034D4C4B00024A0003494849000248014703480149024A014B034A04490011 + 4C4F545B626970757A7C7D7E7D7B79777600027401750176027800087673706D + 6B6A69680567026602650008636261605F5E5B57035501530150034F0150024F + 0150024F00034C4B4A00054900074A48474644424000023F000A404243423F3C + 3A38363504330332000431302F2E022D00032C2B2A0003290003282726000225 + 0124012204210120041F011D011C021B021A0219041802170118021702160115 + 0214000313111000040F0210000D0F0E0D0E101113151718140D070002040205 + 0306030703080C0900000035A6A5A29F9D9A9794918E8B8885827F7C79767371 + 6E6B696663615F5D5B59575553514F4D4C4A494746444341403E3D3B3A383736 + 35000234000332302F00042E022F000C313234383B3F43474B4E515202530154 + 0253025201510150024F014E024D014C024B034A0149054A054B034A000C4B4D + 4F52575D636A71787C7F038100077F7E7D7B797776000274000C757677787673 + 706D6B6A68660564016302620004605F5E5C035B000359565400025500055451 + 4F4E4F00025103520005514F4E4D4C00024B034A000648474544413F023E0007 + 3F4143423F3B38000237013602350234023303320131012F022E00042D2C2B2A + 0229000328272600022501240123022202210220031F011E011D021C031B031A + 041902180217011602150003141312000210010F02100211010F030E00041011 + 131602180003150D0700020402050306030703080509040A030900000033A5A3 + A19D9B9895928E8B8885827E7B7875726F6C696764625F5D5A58565452504E4C + 4A4847454442413F3E3C3B3938373534330004310330000F313436393B3E4144 + 484C4F52545657000358025700085655545352504F4E024D024C014B024C044B + 034C014B044C000F4B4C4D5052565C61676D74797E8184000285000A84838280 + 7F7D7B7977760374000B7677787774716E6B69666100045F035E015C025B025A + 035901580156035501540152025001510252000753545352514F4E00024C014B + 024A00074948464543414000033F014102430004403D3A390338013701360235 + 01340233000332313000022F00032E2D2B00022A022901270126022502240123 + 022201210420021F011E011D051C021B031A0219021802170116021500051412 + 11100F0002100211000F100F0E0F101113161819150E07050400020503060207 + 03080609070A0000002FA4A19F9B9895928F8B8884817E7B7774716E6B686562 + 5F5D5A585653514F4D4A4947454342403F3D3C3B393836353400023203310011 + 32333536383B3F44494D5052545658595A00035B015A0259000A585756555453 + 5251504F024E024D054E054D024C00114D4E505254575B60656C72787D818486 + 87000288001C8786858382807F7D7B7977757473747577787775726F6C68635D + 5A59025A0159025A045903580157065601550154025301520453000652504E4D + 4C4B024A000849484746454442410340000741434443403D3B00033901380237 + 00033635330002320231022F00032E2D2C00032B00042A292726022502240123 + 022201210320021F011E011D041C011D021C011B021A03190218021700051615 + 1413110003100211000312111000020F000B111214161819160F080504000205 + 0206030702080509090A0000002FA2A09D9996938F8C8885817E7A77736F6C69 + 6663605D5A585553514F4D4B48464442403E3D3C3B3A39373534333231000232 + 000E3335383D4145484A4E5255585A5C055D025C00035B5A5900025801570156 + 025501540253035208510150014F024E00124F505152565A5E63676C71777C81 + 8587898A028B00148A89888786858382807F7D7B797674727172747602770008 + 7573706C67615B58045702580257045801570556025701560155025402530252 + 025100064F4E4D4C4B4A0249014802470004464544430442000743454443403C + 3A000339023801370135023302320131023000032F2E2D00032C00032B292800 + 0326022501240223012202210120021F011E031D011C021D021C011B021A0419 + 031800071716151412111000021103120110020F000B111214161819170F0805 + 0400020502060207030804090A0A00000024A09E9B9794908D8985817E7A7773 + 6F6B6864615E5B585553504E4C4A48464441403E3C3B033A023B013901360334 + 000F36393D40454A4F535658595B5C5D5E00025F025E025D015C025A01590258 + 025707560255015602550254065300105456585B5F63696E74797E8185888A8C + 038D028C00108B8A89888786858482817F7D7B787571026E0003707376000277 + 00097674706C67605B5857000256015701580359025A02590157055602570004 + 58575554025202510250024F024E00044C4B4A49034802470146014404430144 + 0246000544413E3B3A0003390004383735340233013202310004302F2E2D032C + 00032B29280003270126012502240223022201210220021F011E041D021C021B + 051A011902180006171615141312021102120003131211000210000B11121416 + 181A17100905040002050206020703080309070A020B020A000000229F9C9995 + 928E8A86827E7A77736F6B6763605C595653504E4B494745444342413F3E023C + 00133D4044474846403D3F4145494E5155585B5D5E00035F045E015D025C025B + 035A0359035804590258025701580557001258595C5D6063676B6F74797E8286 + 898B8D8E048F018E028D00168C8B8A89888786858482817F7C7875716D6A6C70 + 73760277000B7675726E69635F5C5A595800025A045B015A0259015805570358 + 015701550453025201510250024F024D00034C4B4A0002490248014705450146 + 0247000545423F3B3A00023902380004373635340233013202310008302F2E2D + 2C2B2A29032803270126022501240223012201210320021F021E031D021C051B + 011A0219000518171615140005120003131211000210000911121416191A1710 + 090004050206030701080309070A030B020A000000199D9A97938F8B87837F7B + 77736F6B67635F5B5855524F4C4A47000245024401460147024800064746484B + 5157025B000B57514E4F515457595B5C5E00045F015E015D035C025B025A025B + 025C015D015C025B035A015B015A02590158025900155A5B5C5D5F616366696D + 7074787C7F8386898C8D8F00039001910390018F018E028D00068C8B8A898887 + 0286001B8482807C78726F6E6C6B6D7073767778777673706C68645F5C5B5A00 + 025B055C025B045A0659015701550254000355545300025202510150024F0004 + 4E4D4B4A034902480547000C484744413E3C3B3A383738370236013502340006 + 333231302F2E022D00032C2B2A00022904280127022602250124022301220321 + 0220021F011E021D011C011B021C031B021A0005191817161500021302120004 + 131413120210000911131517191A1811090003050306030701080309030A080B + 010A000000189B9995918D8984807C78746F6B67635F5B585552504D4B490248 + 00064A4B4E51545602580004595A5D6002620160015D025A025B015C025D015E + 025D015E025D00045C5B5C5B075C025D025E015D015C025B025A035C00145D5E + 60616366696B6F72767A7D818386888A8C8D028F019008910190028F00038E8D + 8C00028B000C898887868583807D78726D6C036D00056E70737677000278000A + 7774726F6A65605D5C5B025C025D045E015D045C000B5B5A5B5C5B5A59575655 + 560002550254015301510250024F00044E4C4B4A044901480347000748494845 + 413E3D00023C013903380237013602340133013202310130012F022E012D022C + 012B042A022902280327000426252423022202210004201F1E1D021C021B031C + 021B011A0119021800061715141312130314011303110008131517191B191209 + 03050206020703080209040A090B000000159A97938F8B86827D7975706C6863 + 605D5A5856545300045100075356585B5E606200026305620161025F055E045D + 015C015D035C035D045E015D025C025D025E025D025E00165F61636567696C6F + 7275787B7E8185888A8B8C8D8E8F0290049106920291029000038F8E8D00028C + 000B8A8988868482807D79757100026E026F00066E6D6F727678027900087776 + 73706A645F5D045C00095D5E5D5E5F605F5E5D00045C035D00045B5A59570355 + 015601550254000A535251504F4E4C4B4A490448000447464748024900084643 + 41403F3D3B390438013702340233013202310330022F012E042D012C022B012A + 0229022800082726252423222120021F00031E1D1C00041B031C021B00061A19 + 18171614031301140215011302110009121315171A1B1A130A00030502060207 + 03080209040A090B000000139895918D88847F7B76716D686562605F5E5D5C00 + 045B00075C5D5F60626364000363026202610260015F045E035D015E075F0260 + 035F065E00185F6061626465676A6C6F7276787C7E818486888A8B8D8F900291 + 0290089107920191029000108F8E8D8C8B89878583807E7C7A78767502730008 + 71706E6C6D71757702790007787674716B646000025E035D045E00056062615F + 5E00045C035D00055C5B5A5856000255015602550354000452514F4E024D0003 + 4B4948000447000346474900024A000749464442403E3C000239000538393837 + 350004340433033201310130022F00102E2D2C2B2A292A292827262524232120 + 021F021E011D011C041B051C00061B1A191816150414021501130211000A1213 + 15171A1B1A130A0602050206020702080309030A070B020C010B000000129794 + 908B86817D78736E6A656463646564630562016301620263036201610360015F + 095E025F01600161026207610160015F026000176162646667696B6D6F717477 + 7A7E818487888A8C8D8E8F00039001910492059104920191079201910290000A + 8F8D8C8B888682807F7D037C001A7B7A77757371706D6B6C707477797A797775 + 726E696462605F5E025D035E0005606261605F00025D015C015B045C00045B5A + 595703560355000656555452514F024E014C014A02480249014A0249014A024B + 00084A474542403E3C3A0239013A023902380437013602350234000333313000 + 022F012E012D022B012A0229022800062726252423220220021F021E011D031C + 011B011C031D011C011B021A0003191715000414021501140212000A13141517 + 1A1C1A130A0602050206020702080209030A040B060C010B0000000E96928E89 + 847F7A75706B6764656702680167016503640263016202610260025F015E065D + 015E015F02600861036002610003626364000265001267686B6E717477797B7E + 80828487898C8D8F0290049103920191069201910E92000A91908F8E8C8A8987 + 8481037E037F00067E7D7A76726F026E00076D6A6B6E73777900027A000B7877 + 74716C6763615F5E5D00045E0460025F015E015C025B015C025D00045C5A5957 + 025600045756555602570008555452504F504F4D024B034C044B000B4C4A4743 + 403F3E3D3C3B3C00023D023C013B013A02390003383736000235000334323000 + 032E00042D2C2B2A042900032827260002250003242321000220041F021E031D + 021E021D00071C1B1A1918161500021401150216000D151312131416181A1C1B + 140B060002050206020702080209030A040B070C0000000D94908C87827D7873 + 6E69656467000269000368676400036300046261605F025E035D025C025D025E + 00035F606100036201610360035F00156061626466686B6D6F7174777B7E8285 + 87898A8B8D00028E00038F9091000292019301920393079203930C9202910008 + 908F8E8D8B8987850284000D82818081828381807E7C78736E00026C00086D6C + 6A6B6F747879027A000C797876736E6863605E5C5D5E035F035E025F0003605F + 5D00025C015D025E00045D5A595807570004565554530352000351504F00024E + 014D014C044B00084C4B48444241403F023E023F023E00033D3C3B0002390237 + 000636353433312E052D012C012B032A01290128022700052625242322000221 + 0620011F011E021F021E021D00051C1B1A191700031501160217011503130009 + 1516181B1C1B150B060002050206010703080209020A030B090C00000013938F + 8B85807B76706B666364686968676563620002610160015F025E045D025E015F + 0360025F0006605F605F605F026000136160616365686B6F7275787B7F818487 + 8A8D8F0002900291059207930194049302920193019203930992000A91908F8E + 8D8B8987858403830184058500098483817E7B7976726E00046C00146B6D7175 + 78797A7B7A7977746F6863605E5C5D5F0360015F025E015F0260015F035D015E + 025F015D025A0159015702560357015601540353025400085352504F4E4D4C4B + 034A014B024C00074B48464442414000033F013E023D00043B3A393703360135 + 02330131012F052E012D012C022B022A00042928272602250124012302220121 + 012004210420021F011E011D021C00041B191716021501160217011603130009 + 1516181B1D1C150B060002050206010702080309020A030B060C030D00000012 + 918E89847F79746E696461626768676564620360025E015D025E025F02600361 + 0160015F025D025E026000166163646667686A6E71757A7E8285878A8D8E9091 + 929303940D93039401930194089304920291000A908F8E8C8B89868584820281 + 0004838485860388000D87868482807E7C79787673706E00046D00056E727678 + 7A00037B000B7A7875716C6663605E5F600002620161015F025E015F0260015F + 035E00055F605E5B5900025A0158025502560003555452000251015302540003 + 53504E00024D014C014B024A000F494B4C4D4E4D4B49464341403F3E3D00023C + 023B013A0138023702360005353433323100052F012E012D022B022A00032928 + 2700032601250124022301220821032000081F1E1D1C1B1A181703160218000D + 161413141516181B1D1C160C060002050206010702080209020A030B040C060D + 0000000D908D88827D77726C67615E5F64000266000464636160025F015E025D + 035E025F016004610018605F60626466686A6C6F7174777A7E8185888B8E8F90 + 929302940595029406930C94039303920291000D908F8E8C8A89878685838281 + 820002830004848587880389000E88878583817E7D7C7B7A7977747203700008 + 6F6E707477787A7B027C00087B7977746F696561025F0005606263626000025F + 00056062636261000260025F00075E5B595A5B59560004550154015302520005 + 535453524F00034D024C014A0249014B014C034E00074D4A464342403E00043C + 00043B3A393802370236013501340233013201310230022F00042E2D2C2B022A + 01290228032702260003252322000421032202210220021F00061E1D1C1B1917 + 0216011702180008171413141517191B021D0003170D07000205010602070208 + 0209020A020B040C070D0000000A8F8B86817B76706A655F025C016102650007 + 646361605F5E5D00025C035B00075C5D5F6163656700026800126A6D70727579 + 7C7F818386898B8C8F909293039401950696019502940193029402930E940292 + 000A908F8E8D8C8A87858380027E017F02810005838487888900048A00098987 + 86858482807E7D00027C00067D7B797776740473000872747576787A7B7D027C + 00077A7875706A656100025F016103630162026001610163036400066361605F + 5E5D035B0159015705560155015404530003524F4E00044D014C024B024D014E + 024F00074D4A464341403E00043C00033B3A3900033802370136013503340132 + 02310004302F2E2D022C012B012A022905280003272624000223062204210120 + 011F021E00041D1B1A180317000418191815021400041617191B021D0004170E + 07050206020701080309020A020B030C080D000000188E8B85807A746E69635D + 59585D6265646361605F5D5C5B5A03580017595B5F646A6E717476797C7F8285 + 87898B8D8E8F9091920002930294039507960395039403930494059302940006 + 9594918D89860284000383807D00027B027A00107C808487898B8C8D8C8A8887 + 868483810280017F037E037D00077C7A78777675760003770175027300037579 + 7C00027D000B7C7B7976716A64615F6061000363026200036162640003650006 + 646361605E5D045B02590358025701550354000453525150034F0150014F024E + 014F014E034F00074C48454342403E00023D023E013D013C023B00063A393837 + 3635033401330232000431302F2E022C00032B2A290003280329000328272600 + 022501240323022205210120021F00071E1C1A19181718000219000E18161516 + 191D1E1F201E180E07050306010701080209020A030B020C050D040E0000000E + 8D8A847F79736D68625C575559600263000962615F5E5C5B5A5958000257000F + 585A5F69737B7F828487898B8C8E8F0002910392029303940595029604970196 + 02950494029301920293029202910190028F01910192029400058F87817E7D00 + 027F017E027C037D00048083888A038C00058B89858281000480017F027E017D + 027E027D00047C7B7A79057A000379777300026F000F73787C7D7E7D7C7B7873 + 6D686563620006630262016301640265026400056261605E5C00025A025B045A + 0003595856000455025401530252015301520251055000044F4C474502430142 + 01410440000A3F3E3D3C3B3A3837363503340333000532302F2E2D00022C012B + 012A03280129012A0229000328272600022501240123072202210006201F1E1D + 1B1903180010191A1916171F293135332E251B0E07050306010701080209020A + 020B030C040D050E000000168D89847E78726C67615C5652555C626362605F5E + 5C5B035A01590258000C5A616F7E86898B8D8E8F909102920193099403950296 + 0697000396959400039301920191039000058F8E8D8C8A00028900038A8C9000 + 0293000590898381800002820181027F0180028100048285888A028B00048987 + 847F027E017F01800281017F027D017E027F017D017B037A017C027E000B7D7C + 7A78746F6C6E74797C00037E00097D7C7976716D696665000263026206630264 + 000763646362605E5B00025A025C015B035C00045B5A58570358025702550254 + 00055352515051000250025100074E4A4846454443000242000B41403F3E3D3C + 3B3A3837360005350234000433312F2E022D00032C2B2A000329042A00052928 + 2625240002230422022302220121022000041F1E1C1A031800101A1B1A171D2E + 48595F5747311F0F08050206020701080209020A020B030C030D060E0000000B + 8D89837E78716B66615B550002510159016002620003605F5E00025C025B025C + 00095A595B6374848B8E8F000290019102920293029408950596039702960003 + 95949300029100058F8E8D8B8A0003890003878685000283000B84868A8E9193 + 928F8B88850002840183028204830003848586000288000386848200027F0003 + 808182000283000782807F8081807E00027C017D017F0281000D7F7D7A777472 + 6F6E71757A7C7E00027F000C7E7D7B7875716D69666463620263056402630162 + 02630004615F5D5C025B035C015D035E015D015C045B00035957550002540003 + 535251000250035102520006504D4B484544024202410004403F3E3C033B0139 + 01380637000636353432302F022E022D012C052B022A00042928262502240823 + 0222000621201F1E1C1A031900101A1B1A1823406D8995846640230F08050206 + 010702080209020A020B020C030D070E000000158C89837D77716B65605B544F + 4E555E626361605E5D00035C000B5D5E5D5B5C6475858D8F9000029103920293 + 019403950003969596000295069602950194019302920008918E8C8B8A878483 + 0281018201830382000D80818386898C8E919493918D88000386018502830006 + 8281828384850286018404810004828385860287000385838200048104830004 + 817D787502720171026F00057174777B7E00037F000A7E7C7977736F6B686564 + 0263016401630464016303620160015F045D015E035F016001610260025E015D + 015C025A0003585553000352015103500251015202530007514E4B4745444100 + 0340000541403F3E3D00023C00033B3A3900053800073736353332313000032F + 012E042D012C022B00042A292827022602250624022300072221201F1D1B1A00 + 021900101A1C1B18284D84A9B3A07A4A270F08050206010702080209020A010B + 020C030D080E000000158C88837D77716A645F59544E4C515B62646261605F00 + 025D00045C5E5F5E025D00056372838C90000391029203930194029504960195 + 0496019502930003918F8C00048A0188028600048583807E027D017E017F0380 + 000D7F808285888B8D909495938F89000286000487858382028101840585000E + 827F8082848587888A8B8A8885840282018301850286000683817E7A75740373 + 0007716F6E7073797D000280027F00097D7B78746F6A67656400036302620163 + 01640265000363626000025F00046065676A036B00066A686663615F025C0004 + 5A5857560253000452555859025A0003595653000354000353504F00024D0006 + 4B4744424345034700124643403E3C3D3F42434544413C383634333203310130 + 022F012E022F01300233000634312F2A28260225032401250224022301250128 + 022A00052927221E1D00021C0004192A528E02B30009AD8352301B15100D0900 + 0208000A090C11131614130F0E0D040E050F000000108C88837D77716A645E58 + 534D4A4E5861026300096261605F5E5D5E5F6000025E0006616D7F8A8F900391 + 02920293029401950196039501940293001292918F8D8C8985807F8082838281 + 8281807E067D017E038000108183878A8C8F939695908B878687858202810182 + 03850384018202810005838587888900038A0003898784000283000B84868784 + 7F7D7C7A7877760002750172016F026C000371787D00048000077E7C78726C67 + 65000264016302610260000C616365666463626368707A800282028000097E7C + 78726C645E5B59000257000E5554575D656C7174736F675F5A570256015A0160 + 0265001C60574D4749505A5F615D554A444349535B5F61605A51473E38363433 + 023201310130022F000B30353F484E4F4A40332A26000225022404250028282D + 3641484C4A463D3228221D1A2A528EB3B4B08B62493C383125190E0A0C16242F + 332F2619110D040E050F000000108C89837D77716A645E58524C484A545E0363 + 00106261605E5D5E5F605F5E606979888F90049101920493029402930007918F + 8D8C8B89870002850182017E027B017C067D037C017E027F00047E7D7E800281 + 00078082868A8C8F930002960007938E8A8785838000027F0180018302850184 + 03830282000383858700038802870003888684000283018502860183027E0009 + 7D7C7B7A787776737000026D000470777C8002810007807F7D79736C66000364 + 0003626162000263016401660267001666656467738496A0A3A2A19E9D9B9790 + 86796C635D5A0258002F5C677586929A9D9B9488796B60595C687D898D826F59 + 4D52657A85887E6D594E546576848C8F8C84766452433A3634000233000E3231 + 302F3240556B797C705C413002260425000826272B34465A6D79027F000B796C + 5A4532251D2B528FB30002B400039A7F73000270000F67523A20111326455B66 + 5B4629160D00020E070F0000000C8D89837D77716A645E58524C024700034F5B + 620004630161015F025E015F026100065F606674848D02900391029201910190 + 028F028E00048D8A88860285000C83828182807D7B7C7B7A797A037C027D0008 + 7E7F8081807F7E800383001084878B8D8F939697958F8A858382807F027E0180 + 0183028402830184018502840185018602870186038501840382018402850182 + 0380001D7F7D7C7A797673706F7071777C80818281807E7B77716C6967666566 + 6800026901680269000C686766656B7B94AEBDC2C1C002BF0010BEBCB7AC9D88 + 74645D5A5E6D829AACB702BC0013BBB8AE9D887262647596ABB3A38764566180 + 9D0002AD00129B7F6561718BA1ACB1B2B0ADA18E735843370234013301310230 + 000C2F364A6C8FA4A997795036280227012602270008282A384F6D8A9CA402A7 + 000BA49C8B715236222D538FB30002B40013AFA3A0A1A29A87673F1F1D366588 + 998967391B00030E050F0210000000118E8A847E77716B655E58524C47454B56 + 6000036300106462615E5D5E60626160636D7D8A8F9004910004908D89870286 + 0287018601850384018202800004817F7D7C027D027C017D027E017F03800004 + 818284850283018501870388000B8A8C8D8F929698948D87820002810008807E + 7C7B7D8083850286000387888700038500078687888785828100028001820384 + 0181018002810180017D027B00037A777300027100057375797D80000382000F + 817F7D7A76726D6967686A6C6D6C6A0002690268000667666C7F9EBD04CC05CB + 0010C9BDA78C72615E6A83A1BAC6C7C3C0C102C50028BCA78A706C7EA5BFC3B8 + 987264779CB9C1BCA2816E7792AFBDBEB9B5B7BCBDB29774523E353433320331 + 000438517AA502BA0006B08B5A3A2A29042800162A344C7195AEB7B4ADACB0B4 + B09A774F2F30538FB3B402B50012B3AFB1AEADAC8F6235283F769FAFA077411D + 020E040F0410000000128E8A857F78726B655F58524C474346515D6202630264 + 01620160025D015F0262000760616876858D9000049100048F8A858102800181 + 048300038483810002800282058003810003808183000284000385878800028A + 0189048A0289028A018D0192029700069289837F7E7F0280037F000380838600 + 0388018A01890288028601870289000986838180818283848300028100118281 + 7F7C7A7C7B78757475787A7B7E8182000283000882807E7C7975706B026A0006 + 6D6E6F6D6B690267036800046E81A2C202CD02CC0003C9C5C60003CC0009CBC0 + A5826A66799AB90002C80005C1B0A7ABBC0002C70007BEA3817583AAC40002C3 + 0005A7877D91B10002C10016B69477748DAEC0BFB7A3989EB1BEBDB390674838 + 36350233023200043A5480AC02BA0006B8915D3B2A2903280006292E416690B3 + 02B70015A28E8C99B0B4B5988D6C657BA3B3B4B5B6A99D9BA90002AD000DAA81 + 4A323D6B91A2916C3C1B0E00050F0410000000128F8B867F79726C666059534D + 4742434B586002630010646563615D5C5E6162605F636E7F8B8F0291000A9291 + 908B847E7B7A7B7E028000038182810002800004818485840383018503860185 + 018603880189018A048B00058A89888785000284000A868A909698948C86827F + 028004820006818385878889038B000C89868587898A88868482818202830006 + 82818081807E027B027D017C027A017B017C027D00037F818200028300088281 + 807D7A77726D026C016E026F00036E6B690002670168026900046F82A3C302CD + 0003CCC6B20002A801B501C502CC0010CBB895767087ABC7C8C6AC92848BA4C0 + 02C70006B38F7E86ABC502C40004B9A39CAB03C1000EA47F6D7CA0BFC0BD9F7F + 6E7895B502BD0006A47A553E37350234023200043A5480AB02BA0008B9935F3D + 2D2C2B2A0229000F334E7CA8B8B7A780625C749AB4B5AD0004FF01E102B40007 + B5A887706F88A90002AD000C935C3735567785785731180E020F071000000019 + 908C86807A736D67615A544E48434146535E6263646564625E00025C00095F61 + 605F606877878F00029102920009908B837B7776787B7E00057F000580838689 + 8800028701880189038A01890188048702890388000587858483810002800004 + 83878D9402980007938E87807E7F810002830184038502840187018B028C000E + 8A8786878889888785838283828103800281017F027C017F0281027F037E0004 + 7F808183028400088382807E7B78736F026D026E00046F6D6A68026700076869 + 6A6F83A3C30002CD0010CCB89B888697B0C9CCCBC5A5827B91B602C80007BE9B + 7C6B7491B60002C70007BC9A858BACC6C50002C401BE01B903C10006B38E6D69 + 84AC02C10007B48C65515D7FA90002BD000FB1875D41373534333231395480AB + BA0002B9000D9A6E5245433F38322E39588BB40002B800079665433D5886AE00 + 02B504FF01E102B40007B595684B4A6B9B0002AD000C9C68392E446470654526 + 150E020F05100111011000000015918D87817B746E68625B554F494440424D5A + 6062630002650005635F5C5B5D000260025F00046370818D029200069392908A + 81790275000E787A7D7F8081828385878A8C8B8A038900068A8B8A8784820281 + 00038284850002830585001D84838283868A919799979188807C7D7E80828588 + 87848384888C8D8C8A000387038800038785830003820581001B828180818485 + 848381807F7E7F8081838485848381807D7974706E00056D016A016802670169 + 026A00047083A3C302CD0008CCB18D7670819EBE02CB000FCAAE8D8497BAC8C9 + B99472606A88B10002C70006C09E888DADC602C402C301C202C10007BFA07960 + 6688B10002C10007AF835A445173A30002BD0008B58C5F423735333202310004 + 3A5480AB03B90016AA8B776D6A655A4B3D425F92B7B8B58E59352F4C7CA902B5 + 04FF01E102B40003B28B58000238015C019202AD000C9F6C3B2E477181724825 + 130E020F0410021101100000000E928E88827C766F69635D57504B4502400023 + 49575F6162656665615C5B5C5F61605E5F697A8A91939493918A807977787C7E + 82858700058900058A8B8A89870002860005888988837E00027C00037D7F8300 + 0584001C85888A89868584868A909698968E857E7B7A7B7D80868A898887898B + 028D018B01880287000688898887868502840003858483000282028301850286 + 01870288000486848281027F00047E808284038500098482817E7A76716E6D00 + 026C026D00056B6A69686900026A000E6F83A3C3CECDCBAF8870667691B803CB + 000EB5928797BAC9CABC9875626C8AB302C70006BF9E878CADC602C402C303C2 + 0018B69069566186AFC1C0B1875F485577A5BEBDB38A5D413635023200073132 + 3B5580ABBA0003B90017AEA4A09E988B755A516391B7B8B7905D39324F80ABB5 + B60004FF01E103B4018E015C023E0161019502AD000B9D69393252859885532A + 1300030F021005110000001A938F89837D77716B645E58524C46413F45525D61 + 62646766625E025B00035E616000025E00056473849094000295000F938E8682 + 7F808384878A8B8C8B89860002840285018403830005868887817E00027D0003 + 7E80840002860005848382848900028D018B0289000A8A8D919598968E85817F + 027E000380838800028B000A8A8B8C8E8D8C8987868703880187028802890003 + 888784000283018501870289038A0005898784818000037F0004808284850286 + 00098583827F7C77726E6D00026C036D016C016A026900068FB4B7C1D1E102E7 + 0008E6D0A87765738DB403CB000EB79485AADBEEF1EEDAAC787F9BBC02C80007 + DDCBC2C6CCC7C60002C501E003E10010DAA368535C99D6EBEEEBD39E626989B0 + 02BE000EAC82583E3534333266999EABC1D005BA02B802BA0007B39F7F6772B7 + E00002EC0007DFB4684B658FB40002B504FF000AE1B6D1E7E4CE8E5876A102AD + 01C301AF029B0007A599AD9861321600030F021005110000001A94908B857F79 + 726C66605A544E48423F424D5A6061636667645F025B000A5D60615F5E616C7D + 8C940296000595938F8C88000486028800088786837F7D7E80810382000B8385 + 8786827F7E7D7E8185000288018602840187018C0290018E038C00038E909400 + 02980009938E8B87848384868800038B000A8C8D8E8D8A87858485860288000D + 898B8C8D8E8C8A88858385888B00038C00058B8986817E00027F038000038284 + 8500038600078483807C76716E00026D016E026F00036D6B6A00026801B30AFF + 0006FDC4818EB5CC02CB0003B89EDC0007FF0004EFB4B2C802C904FF0005E9C8 + C7C5D70004FF0005F69F786DD20007FF0003ECA6A40003BE00059D734F3C3600 + 0335019A04FF01F403BB0004BAB0AAAF02BA02B900039FB0F50006FF0004FDC3 + 8BA602B501A704FF01EB01F205FF0003DA9AAE0002AD01EF03FF0007EB9DAF9D + 69371800030F0110041102120000000F95928C86807A746E68625C564F494400 + 023F001647545D6062656765615D5B5C5F61605F606776889296029700099694 + 918E89878483820002810007807E7C7B7D808200028302820004848685830380 + 000A8184898B8A878687898E0290018D018A0288000A8A8D92989A9995928C87 + 0285000486888A8B028A000E8B8C8B8885848382838587898C8D028F00088D8B + 89858385898C028D00078C8A87837F7E7F000481000382848500038700068584 + 817D756F026C016D026F00036E6D6900036701B30CFF0004F2A4B8CC02CB01BD + 01EE09FF0005FED6CAC9B80004FF0005E9C8C6C7F70004FF0004D7B29EEA09FF + 01FE01CF02BF0005AA8660463A000437019B04FF01F402BB0007BAAB8E8088A2 + BA0002B901D40AFF0005E9B7B5AD8C000CFF0005DEAEAD9CEC0003FF0008ECA2 + AFA3713B1A0F0210041103120000001796938D87827C76706A645E58514B4641 + 3E424D585E616400026701640160025D015E0261026000066570828F96970298 + 000796938F8984817E00027D00037E7F7D00027C00037E818400028502820284 + 01830482000583878B8D8B0002880189018B028D00038B8682000280000B8388 + 8F969A9B9996908A8500028401860189028A028900038A898600028400068281 + 8285888A028B00098E8F8D8C8A8684858A00028C00058B8A8885820002810009 + 83848382818283858700028800078685827E78726F00026E027000076E6C6967 + 6869B5000DFF01F101C202CC01CB01E504FF0003ECD8EC0004FF0004F9C4B49E + 04FF0004EDC8C6DD04FF0004EABDB6E004FF0003E9D1E80004FF0008F7B8A68B + 6B4E3F3A02380237019B04FF01F401BB02BA00099C725D6488AFB9C6FE0003FF + 0004FAD0D5F704FF0004D0A38A6906FF01F901FB04FF0005FEB69B79E70003FF + 0008EDA7AFA778401D0F0210021105120000001098948F89837E78726C66605A + 534D4842023E000A46535C60626769676360025E001761636261636B7B8B9497 + 989997948F87817C7A797A7C7E00037F00078082858785828000028102800381 + 01830187028B00038A888900038A00048885827F027E000F82878D93999C9B97 + 918A848283858800028B01880286000484838486038701880489018D02900008 + 8E8B8785868A8B8A028800038786850004860184018302810003838587000288 + 0007878684807C767300037000086F6D6A6867696CB704FF01FB02E701EB01F6 + 05FF0004E1CDCCCE04FF0005E07F8FA0D90004FF0003C895810005FF0003E6CA + FB0003FF0004FDA39FAF04FF0005DB697B90D20004FF0009BD816852433C3A39 + 38000237019B04FF01F401BB02BA00089A6E575F84ACB9E604FF00057F5E7796 + F80003FF0004F1785E4605FF0004BF8C88DB04FF000FB56D4DB5C0C2CCD1ACAF + AC7F45200F00021002110512000000189996918B85807A746E68625C554F4A44 + 3F3D424D595E6064026900166663605F61636463646874849196989998948D84 + 7E7A027900047A7E80810282000581828485830003810180017F027E027D0004 + 818587880287000688898A88858402830282000584868B909600029B000D958E + 878281828386898B8884830002820005858A8D8E8C00048A00068B8E9192908C + 02870004898C8B88038600088788898887868483028200038385870002880007 + 878684827E787300037000036E6C6A00026900036B6EB80004FF01F703CE01C6 + 01EB04FF01F702CD01D604FF00059F6A737E980004FF0003D3776B0006FF01F6 + 04FF0004BC6B73AB04FF000593525B68860004FF0005CA5C4F443D00023A0239 + 000338379B0004FF01F403BB0008A683717996B5B9F703FF0006E9353F4D5AC8 + 04FF0003633A2E0004FF0005E650544E7A0004FF0008B43926150C1D468303AF + 0003854922000310021104120113000000209A97928D87817C76706A645E5751 + 4C46413D3F48555B5D61686B69666260616403650006676E7D8C95980299000B + 968F86817E7B7C7D808182000283018202810280018102830003817F7D00037C + 00037F8385000387000788898B8985838500028600068586888A8E94029A0003 + 92898300027F0008818284888B89848102800007858B8F91908F8E00038C0005 + 909293928C00028700058B8D8C8987000286000688898A898886028503830185 + 018702880007878685837E766F00026D00036E6D6C00026A00046B6D6FB804FF + 0003F7CFCE0002CD01D705FF0003D0C5D50004FF0005866465696D0004FF0003 + D76461000AFF0005F15E5557AC0004FF0005754A4B4F530004FF0007CF47423F + 3C3B3A000439019C04FF01F701CC02CB0005C9B19EA3B30002BA04FF0006C92F + 31353B9F04FF00035D27240004FF0005C52D2F2E480004FF0004AE17102F03FF + 019603AF0003884A23000210021103120313000000119C98948E89837E78726C + 66605A544E494300023E000A4450595B5F666B6C686402610163016603670005 + 6B7787939900029A000898948E88827D7E80048200048382807E027C00057F83 + 858482000281038000038284850003870006898B8A8786870288038900088A8D + 92999A93898302800282018301850288001C84818082858A8E919291908E8D8E + 919395928C87888C8E8D8B8A898A028C00038A88870002860185018402830184 + 0186038800068786837E766E026B026C016B026A00046C6E70B804FF0003F7CF + CE0002CD01D105FF0003CEAFC60004FF000590646362660004FF0003D15D5E00 + 0AFF019B014E024C01A004FF017E01490247014C04FF01C9024000033F3D3C00 + 033B00033A3B9D000AFF0003F7DCBC0002BA01FD03FF01D2022D00032C2D9D00 + 04FF00035221220004FF0005C61C1D1F460004FF019E0208014603FF0007A0AC + AFAC844A23000210011103120413000000219D9A95908A857F7A746E68625C56 + 504B45403E414B565A5C636A6D6A666261636700036900066A728291989A029B + 000498948F8902830003848382000281000482838180027F0181018405850184 + 0183028200038384860002880003898B8A00028902880189018A038C00078E93 + 989A968C84000280038100058387898783000282001285888C909291908D8C8E + 919596928C898B8D028E048F00048E8C89870486018401830281018401870288 + 0006878684807870046B00076968696B6D6FB70004FF0003F5C3C80002C701C6 + 05FF0003BB93A20004FF0005B86564628D0004FF0003B65E5F0009FF0006F45F + 504F4E7F04FF01AB01490247017B04FF01AA01420241013F023E023D023C019D + 0CFF0004ECAEA1E603FF0006F93C2E2D2CD103FF0004FC31222304FF0005F42B + 1E1F7A0004FF01780207016203FF0008A292A49372411F100211021205130000 + 001A9F9B97928C87817C76706A645E58524D48423F404853595A5F67026D0006 + 68636163676A036B0005707D8D979A00029C00089B98948F8987868404820283 + 00038283840002830185028602870008868584828182848702880289048A018B + 018D038E00088F92979A99918883038200138182858987858486888B8E919290 + 8D8A8B8F930002960008918B898C8F909192029100048F8D8B88028602870003 + 86848100027E000B82868889888785827B736D00026C00086B6968696B6D6FB7 + 04FF0006F2A6AAABAAA905FF0004A47B74F003FF0005FA9B6680E80004FF0003 + 83605F0004FF01E201E604FF0006C854504F53EE03FF0005F9884B69E40004FF + 00076D45444341403F00023E00033D3C9D000DFF0003BE73A60004FF0004C447 + 359604FF01C10222012305FF0004CD5E75F504FF01360207018403FF0008A466 + 726752311A10021102120313021400000022A19D99938E89837E78726C66605A + 554F4A45403F454F57595C646C6F6B656263666A026C00126B6E7888949A9C9D + 9C9B97938D888583828302820006838485868786028401850186028702860185 + 01830281018301860288000387888900028B018A018B028D00158C8D8E91969A + 9C968C868382838182848889888A8C00028D018F02910190018E028C000A9093 + 9594908B898C8F9102920006908F8D8B89880389000488868480027D00038085 + 8800028900068786837E766F026D00086C6A68696A6D6EB604FF0006EE888B8C + 8A9305FF00048C6D6BA00BFF0004CB62605E04FF0003DA82E70004FF0005C652 + 4E4D8D000BFF000DC24746454341403F3E3D3C3B9C0004FF0005EE8082A2EF00 + 04FF0004EB4C48DE0AFF01FC014D03230CFF01C4010A020701A503FF0008AE36 + 3C372D1F141002110112031303140000002AA29E9A95908B85807A746E69635D + 57514C47423F424A54585A616A706E686463666A6D6C6B6D73819099039D0006 + 9C9A968F89840383028201850487018601850284018504870286000F85838284 + 86878687898B8C8B8C8D8C00028B00088D91969A9D9A91880384000483828487 + 0288018B028E00038D8E90000391000C8F8D8F9192918D89888B8E900291018E + 018C028B038C00068B8988868480027D000B8085888A8988878580787100026E + 00086D6C696A6B6D6EB704FF01EC017502770175019D05FF00056F696A6BAD00 + 09FF0005D86A605E5C0004FF0004D66975EA04FF01C50151024D019C09FF01D1 + 01500246000A4443403F3E3D3C3B399C04FF01E602410140017305FF00044733 + 45E008FF0003F86F2600032304FF01B301FB05FF0003F5400B00020701BC03FF + 0009BC171A1917141110110002120313031400000013A4A09C97918C87827C76 + 716B655F59544E49440002400016454F56595E676F706B666364696D6C6B6C70 + 7B8B979D029E00069D9B98938C87028400048281828506860285018603870186 + 018502870009858384868887898B8C00028D018C028D000B8C8D8F92979B9D9C + 948B8400028200098180828487898B8D8C00028A018D018F0390028F00098E8C + 8B8988898C8F90000291018F018E038F000D8E8D8B88868482807E7F82868900 + 028A0006888786827B73027000036F6D6B00026A00036B6DB70004FF01EB016D + 026E017201DF04FF0003E1696B00036D00038ED5FD0004FF0007E3A565605E5D + 5B0004FF0005D5626073EF0004FF0007C5514E4C75CCFC0004FF0004DD934946 + 0245000A444341403F3D3C3A399C04FF0005E5383736560005FF014C02300003 + 3A98E70004FF0005F5B54B2A2700032404FF00036F60DD0003FF0004D74D150B + 020701DA03FF0003D60C0D00020E010F01100211021202130314011500000023 + A5A29D98938E89847E79736D68625C56514C46423F424A53575B636B706E6965 + 63676B00036C00056E7584939C00039E00069D9B979089840281018201830286 + 028502840285028600088788898886878987028500068688898B8D8E04900291 + 000C929395979A9C9D978D868382038101830187038A00048988898B048D028E + 018C038A00138B8C8F9192949594939291908F8C898785838100028000048284 + 8789028A0288000487847D750370016E016B026A00036B6DB70004FF01F302A1 + 01B801E905FF0003B16D6E00026F00086D6C6B708589867202650005625F5D5C + 5B0004FF0015D563625E5A58555351504F4E4D4B4A536E747057470003460245 + 000A444341403F3E3D3B3A9C04FF0005E539373BB50005FF013B03310232000A + 4D616052322E2D2B27250224000426282520021D00081F4855442521160C0208 + 01F703FF01F7010C020D00030E0F10000211011203130214021500000014A6A3 + 9F9A95908B86807B756F6A645E59534E49440240000E454F565A5E666E6F6B66 + 6364686B026C00066D717E8E9A9E029F00069E9C99928A82027F000382848500 + 02860185028401850287000588898A8B89000287028802870006888B8D8F9192 + 02940193029401950396000E97989B9D9A918985838281828488028C018D018B + 0389028A001A8B8C8D8E8D8B8C8D8E909395979899979592908E8D8B89888684 + 0283000884858688898B8A890288000486807873027100076F6C6B6A6C6EB800 + 0DFF01EF017A026F026E00056D6B6A696700036600046766615D035C04FF000E + D563625F5A57555352504F4E4D4C034B014A0149024803470007464544434241 + 4000023F00033D3C9D0004FF0004FCE5E4F905FF01CF0133073201310230000B + 2F2D2B282524252728262100021D00081F2022252622160C020805FF010C020D + 00040E0F101102120113041402150000002CA8A5A09C97928D88827D77726C67 + 615B56514B46423F424B54585B616A6E6D68646366696B6C6D707887969D039F + 00059D9992888000027C00047F82848603870286018702880389018802860003 + 87888900028A00038D8F91000293029403920194019603970008989A9E9C948C + 888703860003888C8F000290018D028B018C018E038F018E028F000790919395 + 97989900029A000C989592908E8D8C8A898A898802870005888786888900028B + 01890288000D87837D777372706E6D6E7072BA000CFF0004F892706E036D016C + 026A0169016802670006686967635F5D025E04FF01D5026300075F5956555352 + 5000024F024E014D024C014B014A04490004484745440243024202410003403F + 9F000DFF016E02330132023101320233001A3231302F2E2C2926242527292722 + 1E1D1F2022252622170C080705FF010C010D020E00030F101100021201130314 + 031500000025A9A6A29E99948F8A847F7A746F69635E58534E49444041475157 + 595D656D6E6A666365686B00026D00066F7480909B9F02A000059E9A91877E00 + 027A00057B7E8185870002880389028800058786848382000283000886888A8B + 8D90929302910190018F028E0003919597000398019B029F00059A93908C8900 + 02880003898C8F0002910005908F9192930002940393000395989900029A039B + 000B9A9894918F8E8F8E8C898A00038C00048B8A898802860188028B018A0388 + 000686827D77747202710004727577BC0BFF01E2018A026F016E036D016C026A + 026903680007696865615F60610004FF01D502640007615B595755525000024F + 00034E4F4E00034D014C014B034A00054948474645000344024300034241A000 + 0BFF0003F6863500023301320231013202330232000631302F2D2A2602250010 + 272928231E1D1F2022252623180C080705FF00050C0D0E0F1000021101120213 + 02140315011600000021AAA7A39F9A96918C86817C76716B66605B56504B4642 + 40454E55585A616A6F6C670002640021676A6C6D6E717A89979EA0A1A09C9286 + 7C78797A7C7E81838588898A88868584810002800181028200068587898A8D8F + 02910003908F9000028F0004909396980299000A9A9CA0A19F9A958E88870288 + 00038A8D8F00028E000690949697999A029900039A9B9C00069B000499979390 + 028E0290018F028D028F00058E8C8B89870002840004878B8C8A028800068988 + 85807A750271000672747779A4CE05CD02CC0004C7B29070036F036E016D016B + 0269016A02690368000367666400036302C602C5000CAB6465635F5B58555351 + 4F4E034F014E024F014E014D034C00044B4A49480347000646454442417D02B9 + 03B804B70006A981473635340233023201330234001A333231302F2D2B272526 + 282A28231E1D1F2123252723180D080702A503A600060C0D0E0F101102120213 + 0214021502160000002EACA9A5A19C97938E88837E79736E68635D58534D4844 + 41434B5357585D676E6F6A656465696B6C6D6E7481929CA002A100069E968A7F + 797A027C000E7B7D7F818486888784807F7E8082028300088486888A8C8F9193 + 0394029500049495969703980003999B9E0002A000109C948C85838485878A8C + 8D8F9295989A059C00059B9A989798000499000397959100028F000492949392 + 0291001A908E8B8A87848284878B8C8B88898A8987827C767170717376780279 + 00067674737473720271017202710170046F016E016B04690368026700056867 + 666564000263000E626160626465635F5B585653514F024E034F00055051504F + 4E00024D014C014B024A00074948474645434200024000043F3E3C3B023A0239 + 01380237033602350334023502340007333231302E2B280002260014282A2924 + 1F1E1F2123252723190D080708090A0B020C00050D0E0F101100021201130314 + 0115031600000016ADAAA6A29E99948F8A85807B76706B65605A55504B460243 + 000A495156575A636C706D6702640168016B026C000C6D717B8B99A0A2A1A09A + 8E810279047C027E001380818486827C7B7D828688898B8D8E90929495000296 + 02970198029701960395001694929496999DA09C938B868486888A8C8D8E9091 + 9497039A00059B9C9B9996000294019604970003989795000294019501960295 + 000E9493908C898784838486898C8D8C028A00108B8A88847E77717071727374 + 7677757402720171087000056F706F6D6A000268026901680467000668676664 + 626102620260000B616465645F5A575554525000024E034F015001510250014E + 014D024C014B024A01490247000445434140033F013E013C043A000339383700 + 0336013702360635001E34333231302E2C282627282A2925201E1F2023252723 + 190D080708090A0B020C00050D0E0F101100021201130214011504160000003A + AFACA8A49F9B96918C87827D78726D68625D58534D484443474F5557585E686F + 6E696563666A6C6B6C6E7584959EA1A2A19D92857C797A7B7C7D037E00048083 + 8683027F000683898D8F9192029301940496039503960013949392918F8D9194 + 989CA19F98928D898A8D8F00038D00058F909395960002950197029901970195 + 02930394000395969900029A029902980006979694918D880285000684858788 + 8A8C028D000F8C8B8C8B8985807873727372706F71000374017202710270036F + 026E026F0009706F6E6C6A696A69680004670004686764620260016201630262 + 000C63656665615C58575554514F044E034F00044E4D4C4B024A024900074847 + 464543414000033F013E013C043A013901380237013602370236013501340335 + 00093635343332312F2C290002270015292B2A26201E1F2123252723190D0807 + 08090A0B0C00020D00050E0F101112000213011402150216021700000026B0AD + AAA5A19D98938E89847F7A75706A655F5A55504A4643454D5356575A636B6F6C + 66636468026A000D6B6D727E8F9BA1A2A19F978B8100027D00047E8081820484 + 000786848283878D900002920004939493940395019401930392000494969594 + 02930006929194989B9F02A300039E999300028E000391928F00028D00038E8F + 910002930003919294000296019501930291000692939496979A049C00079B99 + 9795928D87000284018701880389018A018C038E028D00108C8A868078747374 + 726F6D6E71737473027201710170026F036E0170036F026E016C026B01690268 + 0467000666636162636402650164026502660009635E5A575554524F4E00024D + 014C034D00044E4D4C4B034A000749484645444341000240033E013C053B013A + 01390338033701360235033602350006343231302D2A02270129022B01270121 + 021F001121222527241A0E080708090A0B0C0D0E0F0002100111011202130114 + 02150216021700000017B1AFABA7A39F9A95918C87827D77726D67625D58524D + 4800024500034A5256000258015E0167026E000D6964636568696A6B6F778796 + 9F0003A100059C938B87840003830184028701850484000385888C00038F0290 + 01910193089401960398019703980015999A9DA1A4A5A19C98939192938F8C8D + 8E8F9192910002920193039401930292000693949597999B039D000B9C9B9996 + 928E898584878A00028C018B028A018C018E028F028E00058D8B867F78000374 + 01720170026F00057072737473000272027102720171047000036F6D6E00026D + 016C01690368036700056663626365000466016503660009645F5A5756545351 + 4F00044D014E024F00034E4D4C00024A0005494847464500024400044342413F + 033E053D013C013B023A0139033805370236000E35343332302E2A2827292B2C + 2721021F001121232527251B0E080708090A0B0C0D0E0F000210000311121300 + 02140215021602170000001CB3B0ADA9A4A09C97938E89847F7A746F6A645F5A + 544F4A4645495056025800095B636C6E6B6562636600026900076A6D737F909C + A10002A200149F9A938D87848281828584828182838485878A8B038C00038F92 + 9400039500059697989798000899000A98999BA0A3A5A39D989302910005928F + 8D8C8D00048F0193019502960195019602950006949596989A9C039D000F9C9B + 999694908C8987888A8D8F8E8C00028B00058C8E8F908F00028E00068B87807A + 767503740004737273740275000574737271730002750173047100036F6C6B00 + 036C016A0369026801670165026303640265036602670004645E595702560004 + 55545351065000074F4E4D4B4A49480002470003454445000244014301410340 + 01410240013F023E013D023C013B013A0339023803370136023500053433312F + 2C000228012A022C01280122021F001121232628251B0F080708090A0B0C0D0E + 0F00021000041112131402150216021701180000001CB4B2AEAAA6A29E999590 + 8B86817C77726C67625D57524D4845474E540258000A595F686D6C6763626568 + 026900066B6F788898A002A20014A19D968D8682807E7F8281807F8183858687 + 8889028800038A8E910004930194019603970598029703960010999EA3A5A39C + 958F8D8E8F8D8B898A8D028E00058F949899980003970198019A029B049D019B + 019A029900059693918F8D00028B018C018E029000038F8D8C00028B018D018F + 0290028F00078D89847E79767500067602750174017302720005747776747200 + 03710004706C6A6B026C026B016A036901670166026403630164016502660167 + 0268000B66615D5B5A5958575654520004510003504F4E00024C014A01490248 + 0147064601450144034302420141013F023E023D013C023B013A013903380337 + 00073635343332302C00022900052A2C2D292300021F001121232628251C0F08 + 0708090A0B0C0D0E0F00021000041112131402150116021702180000001DB6B3 + B0ACA8A49F9B97928D88837E79746F6A65605A55504A47464A51560002580009 + 5B636B6E6A6562646700036900056C7381939D0003A200079F978D8784838200 + 0283018202810003838587000288028702860009888B8D8E8F8E8D8F91000293 + 01940395019603970396000A989DA1A4A39C918A898A028D018B0289018C028D + 00038E959900029C029B019C019D049F00049E9D9B980396000394929000038F + 000490919091029000038E8D8C00028B018E039000068F8E8B857F7903750006 + 767576777675027400097372737577767473720002730004716D6A6B026C026D + 00066C6B6A69686702660165016302620164016502660368000964605D5B5A59 + 5756530003510250024F00054E4D4C4A49000248054702480147014602450007 + 44434241403F3E00023D00043C3B3A390638013702360008353433302D2A292A + 022D00172A23201F21232628261C10080708090A0B0C0D0E0F10110002120003 + 131415000216011703180000001DB7B5B1ADA9A5A19D9994908B86817C76716C + 67625D57524D4846474D540002580009595F686E6D6863646600036800066A6F + 7A8C9AA002A20009A09B948E8B8785848300028100058385888A8B00028A0189 + 0688038A00058C909193940003960198019904980297000C999DA1A29E938C89 + 8A8C8D8C028900068B8D8E92989C039F019E049F019E019D029B000399969400 + 02950004949392930494019201910390018E018B028900038C90910002900005 + 8F8B857D77000374000373727300027402730272000773747778777574000373 + 0172016F066D016C016B036A0005696867666300026100056263646567000268 + 000965605C5A58575554520004510150024F00074E4D4C4A4948490002480549 + 00114847464544434241403F3E3D3C3B3A393800023701380239023800073736 + 353433312E00022A00052B2D2E2A24000220000821242628261E110902080009 + 090A0B0C0D0E0F1011000212000413141516021703180000001EB9B6B3AFABA7 + A39F9B96928D88837E79746F6A655F5A554F4B47464A5156025800095C656D6F + 6A656365670002680006696E7585959E03A2000D9F99928C868381807F808386 + 8800038A0189048B038A018D028E000390939400029501960297029801970196 + 02970005959291959B0002A00005988F8B8A8C00028E028D00068F9193969B9E + 049F019D019B0299029B0299000497959394029501960498000497959391038F + 018D018A0286018A018F03910005908D877E7600027301720271017201730272 + 02710009727375777877757473000472000371706F00036E00036C6A6900026A + 000569686766640004620263016602680007645E5A5856555400025304520151 + 0150024F00044E4D4B4A0449044A00074948474644434200024100043F3E3C3B + 023A000339383700023601370138023901380237000C363534322F2B2A2B2D2E + 2B250220000822242628271F120A02080009090A0B0C0D0E0F10110002120004 + 131415160217031800000026BAB8B4B1ADA9A5A19C98948F8A85817C77716C67 + 625C57524D4846484E55575859606B6F6D670264016601680269000F6C717D8E + 9BA1A3A2A19C938A827E7D00027B00057C80848687000386018A018D0290028F + 01900391019201930294029502960003959492000291000E92908D8B8F969FA3 + 9F9893908F9002910006909193949799039A029C000F9A949193989A99989593 + 929394969800039A0005999896929000028D00078C8A8785868A8F000391000D + 908E898279747372717273727000036F00097173767879787574720002700172 + 0174027301710270016E016B0269026A01680266026501640563000B65676965 + 5E595857555453000354000353525100035000054F4E4C4B4A00074901480246 + 000345434100034000033E3D3B00043A01390137023500133638393A39383736 + 353433302C2A2B2D2F2C26000221000822242729281F120A0208000D090A0B0C + 0D0E0F1011121314150002160117021802190000001ABBB9B6B3AFABA7A39E9A + 96928D88837E79746F6A655F5A55504B0247000E4C525657585D676E6F6A6564 + 6567026800156B6F7786969FA2A3A29E978D85807E7B7A7B7D7F810004830188 + 018D028F018E038F018D018C028D018E018F0392000491908F8D028C018F018E + 028C00039198A10002A500039F999300028F029000038F919400059301950297 + 000995908D91989A9997940004910003939597000299001E9896938F8C8A8887 + 868584868A8E919291908F8C867F79767372747574720371000C727476787978 + 7673716F70720373000A7271706F6C6B6A6B6967026502660365000F64636264 + 676966605B5958575655560002550004535251500251025000034E4D4B000249 + 02480147024800074746454442403F00024000033E3C3A000239023A01390137 + 023501370139023A023900073837363533302D00022B000E2D2F2D2722212325 + 27292820120A0208000D090A0B0C0D0E0F101112131415000216011702180219 + 0000001FBDBAB7B4B1ADA9A5A09C98948F8A85817C77726C67625D58534D4947 + 49505500025700095A626C706D676463660002670007696C727F909CA10002A3 + 0007A19D978F87817C00027B00047D7E80820284001085888B8A8887898B8987 + 858687888B8E0290018E018C038A018B038D000B90959CA3A7A6A199918B8A00 + 038B00048F92918F02900191029201910190028E000693999B989591048F0290 + 000992969794918F8C89860003840007858486898D90920002910009908E8A85 + 7F7A76747500027701760174037300087475777978767471026F000371727100 + 0272000571706F6E6D00026C016A016705660265000C62616264686A68645F5D + 5A590357000456555352045102520005504E4C4A490003480007494847464543 + 4100044000033E3C3B00023A02390138013702360138013A023B00043A393837 + 0236000334312D00022B000E2D2F2D2823222325282A2820130A02080008090A + 0B0C0D0E0F110212000413141516021701180219011A0000001BBEBCB9B6B2AE + ABA7A29E9A96918D88837E79746F6A65605B56504B000248014C015302570009 + 585E68706F6A6563650002670007686A6F798998A00003A30008A19D978E8680 + 7E7F03800016828485868889878584878A898785868788898C8E8D8B0289000A + 8A8C8F919293969BA0A502A70009A0958C86858688898E0002930190058F000C + 8E8F9195999C9B969491908F048E000D919495928F8E8B878482838586000285 + 0004878A8F920291000F908F8C89837E797778797A7978777500037401750277 + 0005767471707100027202710370016F036E016C016A04670009686766646261 + 63656900026A00066764605C5A58025701560154025203510352000A514E4C4B + 4A4948494A48024700044543414002410003403E3D00023B013A023902380237 + 0138013A023B023A00073938373635322E00022C000E2E302E2823222426282A + 2821130A0208000B090A0B0C0D0E10111213140002150116021701180219011A + 0000002ABFBDBAB7B4B0ADA9A5A19D98948F8B86817C77726D68635E59534E4A + 47494F5456575A636E716D67646503670007696D7482939EA20002A30010A29F + 9A9288817E808281808183858688028902870188028B000488878889028A018C + 028E000D8C8D8E909497999A9B9DA0A2A60002A8000DA1968C86858687898D92 + 95939100028F000E908F8E8F93999C9D9C9795939290038F000F909294959391 + 8F8B878381828587860002840187018D029202910007908E8B86807B7A00027B + 027A02780176037401750276017502730006727374737170036F036E00046D6B + 6A680569016801670265000366686A00026B00066A66615C5A58025601550254 + 01530152025103520005504E4C4B4A000249000E4A4947464746444241424140 + 3F3E023D013C023B013A0239000338393A00043B00073A39383736332E00022C + 000F2E302F2924232426282A2921140A08000209000A0A0C0D0E0F1011121314 + 02150116021701180119021A0000002BC1BFBCB9B6B2AFABA7A39F9B96928D88 + 837F7A75706B65605B56514C48474B505456585F6A716F6A6665670003680006 + 6B707A8B9AA002A30013A29F9A9187807C7E81828182838485878A8C8B00028A + 028B028A038C00038D8F9000028F0012909295989B9D9E9FA0A2A3A6A8A9A49A + 8E870285000987898D939795918E8D00028E00048F91969B029E019B01970396 + 01940292000393949600029700099593908C888481828500028602840004868C + 9192039100058F8C87817D00037C027A02780276027703750474000675767471 + 706F0270026E00036D6C6A000269016A026B026C00046B6A69680269016A026B + 00066A67625D595804570256015402530152025100064F4D4B4A494802490003 + 48464500024700044644434203410140023F013E023D013C023B033A013B023C + 00033B3A39000238000336332F00022C001D2E31302A25232527292A2922140B + 08090A0B0C0D0E0F1011121314151600021701180219021A0000001DC2C0BDBB + B8B4B1ADA9A5A19D9994908B86817C77726E68635E59544F4A000247000A4B50 + 55575C676F716C6802660167026800076A6D7482949EA20002A3000B9F998D82 + 7D7B7C7F8082840003850005878B8D8E8D00028B028C018E038F019001920293 + 029400079597999B9D9E9F0002A0000EA1A3A6A7A69E91898687888A8C910295 + 0009918C8B8D8E9093979B00029D019B01980299000F9896959698999A999896 + 948F8B88850002830484000685888D92939202910005908D88837F00037C0006 + 7B7A7877767702790377047602770174017102700271036E016C026B016C036D + 026C016A066900096A6B6A68645F5A5857000558000756555452514F4D00024C + 014B0449014802470348000347454300044202410140023F00043E3D3C3B023A + 013B033C00073B3A393837343000022C001F2E31302B25242527292A2922150B + 08090A0B0C0D0E0F101112131415161718000219021A011B00000029C3C2BFBC + B9B5B2AEABA7A39F9B97928D89847F7A75706B66615C57524C4846474C52575B + 626C706E6A000366000F6768696B6F7A8C9BA2A4A3A0988B8000027B027C0003 + 7D80850003860003888C8F000290028F00079092939493949500069602970003 + 999A9B00029C029B00079DA0A4A5A1948A000286000E888A8C909496928C8A8B + 8E929598029B029C029B019A01980297000C989B9C9B99979694908B88870285 + 0184028200058486898E9200029302920007908E8A85807C7A00027B00057A78 + 77787A00027B027900037A787700047601740372017301720470046F00046E6C + 6B690366016702680169016A026B00056965615D5B00025A0359000858575553 + 51504F4E024D014C014B044A0349024A00044947464502440243014201410240 + 00083F3E3C3B3A393A3B023C013B023A000439373531022D012F0231000B2C26 + 242527292A2923160C00020900100A0B0C0D0E0F10111213141516171819021A + 021B0000002AC5C3C0BDBBB7B4B1ADA9A5A19D9995908B87827D78736E69645F + 5A554F4A4645484F56595E686E6F6B6702650267000768696C748496A00002A3 + 0005A19B8F837D00027C027B00088085888A8B8D909205940295000394939200 + 039300079291929193949500029602970296001B979BA0A5A39A8F8987898B8C + 8F9294928E8C8E93989B9A9998999C00029D00059A9695969800029B00099A97 + 959495928E8A8900028801870385000586888C9194000293000B92918F8A847F + 7A78797A780002770178017B047C00047B7A7774057300067475767574730272 + 027000066F6E6C6A68660264016503670168016A026C00076A66625E5C5B5900 + 02580257000355535100054F024E014D034C014D044C00054B49484645000244 + 024301420240023F00033D3C3A000239013A013C023D013C023B00043A383631 + 022E012F023200052E2724252700022900042823170D0209000B0A0B0C0D0E0F + 1011121415000216000317181900021A021B0000002AC6C5C2BFBCB9B6B3AFAB + A8A4A09B97938E8985807B76716C67625D58524D4945464B53585B626B6E6C67 + 0264016602670019686A707D8F9CA2A3A29E968C8682817E7D8085898C8E8F90 + 92000393019202910190018D028B028C018B028A00068B8D9092939502960397 + 0008999CA1A6A7A0958D028A000E8D8E90939493919092989C9D9B9A0298019B + 029E019B0297029900059A99989795000294000393908D00048B018A01880387 + 00038B9093000294000793928F8A837D79000278017903780179017A047C0004 + 7B7975730272000B737476777877767573717000036E00056D6C6A6865000264 + 01660267001368696B6D6C6A65615D5C5A5856555655545251000450024F014E + 034D024E024D024C00054A4846444300044201410140023F00083E3D3C3B3A3B + 3C3D023E00113D3C3B3A3937322F2E3032332F2825262700022900042824180D + 0209000D0A0B0C0D0E0F101112141516170002180119021A011B011C00000027 + C7C6C3C1BEBBB8B5B1ADAAA6A29E9995918C87827E79746F6A65605B55504B47 + 45495056595E6700026D000568656465660002670014696D768797A0A2A3A19C + 968E8783807F8084888B048D038E038D00058C8987888A00048B00068E909395 + 96970499000D9A9B9DA2A7A9A59E979290919300029401950194029301950199 + 029B029A000799989A9E9F9E9B00039C000A9B9A9896959493918F8E028C000A + 8D8E8D8A8786878A8E930295000B9493908A837D7A7877787900057A037B0012 + 7977747271727374777877767472706F6E6D036E00036D6B6900026601670168 + 0469016B026C000769635E5B5A5957000356015501540253025202510150024F + 054E014D014C024B00054A4744434200044300074241403F3E3D3C00023B013C + 023E013F013E023D000C3C3B3A3733302F303334302A022601280129022A0003 + 26190D000209000E0A0B0C0D0E0F10111314151617180219021A011B011C0000 + 002EC9C7C5C2BFBCBAB6B3AFACA8A4A09C98938F8A85817C77726D68635D5853 + 4E4946474D54585B626A6D6A666465660267000F686B717F919DA2A3A29F9A90 + 87827F00027E000480858889028A018B028C028D018E028F028E018F01910492 + 019301940295019602970498000A9A9DA2A7A9A8A5A09A950294019602970008 + 9695949596979899029B00039A9B9D00029F019E039F00049D9B989602950003 + 928F8C00028D028C028D01890286000487898D920395000F94918D87827E7B78 + 797B7C7D7C7A790003780005777674727100027200087375767573727170056E + 026F016E016C036A01690268000367686A00026C000469635E5B025A01590258 + 0157015603540153025202510250014E034D024C034B00034947450003440145 + 01440243000642413F3E3D3C023B013D013E033F013E023D000B3C3B3834312F + 313334312B0002270129012A022C0003271A0E000209000F0A0B0C0D0E0F1012 + 1314151617181900021A011B021C0000002BCAC9C6C4C1BEBBB8B5B2AEABA7A2 + 9E9A96928D88837F7A75706B66605B56514C48464A5156595F676D6C69000266 + 01670168026900066B6E788999A102A2000FA09B91888281807E7F8386898B8D + 8E00038F01910192049301940495029401920190028F0190039200139395979A + 9FA5A9AAA9A6A09A9695969798979600029502960004989A9C9D029C029D019E + 019F02A000049F9D9A9703950192018E028C00038D8C8B00028C01890286000E + 87888B9195969594928F8B85807D027A017C027D00047C7A7877027600047778 + 7572027000066F707375747302720171026F027003710007706E6D6B6A676500 + 0264000966696C6D6A66615D5B00025A02580003575655000254025300035453 + 52000251014F014D044C014B024A000349474600024502460145034300054240 + 3F3E3D00023C013D013E0240023F000D3E3D3C3B3935312F313335312B000227 + 0129012B022D0003281B0E00020900110A0B0C0D0E0F1112131415161718191A + 1B00021C011D00000021CBCAC8C5C3C0BDBAB7B4B0ADA9A5A19D9994908B8682 + 7D78736E69635E59544F4A00024700094D54585C646B6E6B6800026700126869 + 6A6B6D7482939EA1A2A19D978F8A8683028100058486888C8E000290038F0003 + 9091920002910292029302920003918E8A00028800118A8D8E8F929596989BA1 + A6AAABA9A39D970002950197019903980297000496979A9B049D029C019E02A0 + 00039F9B9800029502960003938F8D00028E018D028A018B018903870004888B + 9094029600079593908B837F7D00047B00057A79787775000273000476787672 + 027000036F70730002750474037303720007716F6D6C6B696600026300096465 + 686B6D6C67625D00025B015A0258015701560355015402550006545251504E4C + 024B034C00044B4A494802470346014503430242000741403F3E3D3E3F000340 + 023F000C3E3D3C3A363230313435322C022800072A2B2D2E291C0E0002090011 + 0A0B0C0D0E101112131415161718191A1B00021C011D0000002CCDCBC9C7C4C1 + BFBCB9B6B2AFABA7A39F9B97928E8984807B76716C67615C57524D48474B5257 + 5960686E6D6A03670009696A6C6D717B8B99A00002A100069F9C97918C860284 + 000C8687888A8B8C8B8A8988898B028D00038C8D8E00028F00058E8F908E8A00 + 028800068A8C8E9092950296000C989DA4A9ABAAA59F98959496029802990198 + 019902980005999A9B9C9D00039C000D9E9FA09D9A989798999793908F000290 + 00048E8C8B8A058900038B8F93000396000594918B827D00027C00047B7A7977 + 03760274017502780176017303720174017602780477000876757372706F6E6C + 026B00036A6967000365000866686B6D6C67615D025C00035B59580002570656 + 000554514F4E4D00044C014D014C024B014A0349024802470145024402430005 + 4241403E3D00023E013F034000113F3E3D3C3B373331323436332D29282A2B00 + 022E00032A1C0F000209000F0A0B0C0D0F1011121314161718191A00021B011C + 021D0000002DCECDCBC8C6C3C1BEBAB7B4B1ADAAA6A29E9A95918C87827E7974 + 6F6A655F5A55504B47494E55585D656C6E6B680002660013686A6B6C6F768393 + 9DA0A1A09E9B97908A8685000386018702860285028401860189058B028D018C + 018E029000098D8B8C8D8F9193959800029900099A9EA3A8ABA9A6A099000295 + 0198029B00039A999A00029B00049998999A029B029A019B019D029F00039E9C + 9B00039A0197019304910003908E8C00028A058C000A8E9295979695938D857F + 027D00047C7A7977037500037374760002790178037701780579000978777675 + 74726F6E6D00026C036B016A016904680169016B026D00096963605D5C5B5A59 + 58000257045600045553524F044E00034F4E4F00024E014D024C024B02490005 + 4847464544000243000442413E3D023B00033C3D3F000240023F000B3E3D3B38 + 3432333536342E00022900192A2C2E2F2B1E100A090A0B0C0D0F101112131516 + 1718191A1B00021C021D0000002DCFCECCCAC7C5C2BFBCBAB6B3B0ACA8A4A09C + 98948F8A85807C77726D68635D58534E49484C53575B616A6F6D69000266000A + 67686A6C6E727C8B999F02A000069F9D98918984028302840283038200078386 + 888A8B8C8D00028C018E028F019102930004929192940295000396989A00039B + 00139DA1A5A9AAA8A39C9697999D9C9A999A9B9C990002970198049900039A9B + 9D00039E029D00049C9A969302920391000C908E8C8D8F908F8D8B8C91950297 + 000C9694908983807E7D7B7A787502740273000476797A7B037C00037B7A7800 + 047600077574737271706E00036D016C026D036C026B00036A6B6C00026E0007 + 6B66625E5C5B590002580557015601550254015305520251000C504F4E4D4C4B + 4A494847464402430006424342403E3C023B00043C3D4041024000273F3E3D3C + 383532333537352F2A292B2D2F302C20110A090A0B0C0D0F1011121415161718 + 191A1B00021C021D0000002AD1CFCDCBC9C7C4C1BEBCB8B5B2AEABA7A39F9B96 + 928D88837F7A75706B66615C56514C494A50565A5E66026D016A016702650013 + 67696B6D707683939C9FA09F9C968D85807F80000282000A83848587898A8C8E + 8F900291029001910393029501940293000694959493959703980004999CA0A6 + 02AA01A6019F029800049A9D9C9A0299029A0198029501970299029A0299019B + 019D029E039D00059B97959493000392000C91908F909291908C898B90950298 + 001D9796928D87827F7E7C7B79767472717274777A7C7D7E7C78757372717300 + 02740173027202710170026F0170026F016E026D016C016B026A016B016D026E + 00086B66605D5B5A585702580157015602570156025503560155035400045251 + 4F4E024C014A0249000547464544430003420243000342403F00023E013F0140 + 0341024000273F3E3D3A363334363736302B2A2B2D2F312D21120B090A0B0C0E + 0F1011131415161718191A1B1C00021D011E00000049D2D1CFCDCAC8C6C3C0BD + BAB7B4B1ADA9A5A19D9995908B86827D78736E69645F59544F4B4A4E55595C62 + 6A6E6C6865646567696B6E727D8D999EA09F9C968D86817F808285888B8D8F00 + 0291039203910004908E8F90029103920190018E028F00048E8D8F920295000A + 9697999EA5AAACA9A39B0299019A019902980499029801970298019B019C029A + 019B019D039E00049F9E9C990296019702960195029402930008918F8E8B8A8C + 91950398000C97948E87817E7D7C7B7A77740273000A74757778797C7D7B7773 + 027101720173027401730271017205710006706F6E6C6B6A0369016B016C026E + 00086B65605C5A5958570258000457555657045601570156025500065453514F + 4D4B024903480005474645444300034201430244014301420341034202410006 + 403F3E3D3B3702340020363836312B2A2C2E30322E22130B090A0B0D0E0F1011 + 131415161718191A1B1C021D011E0000002BD3D2D0CECCCAC7C5C2BFBCB9B6B3 + AFACA8A4A09C98938E8985807B76716C67625C57524D4A4D545A5C5F6700026D + 016A01670264000966686A6D707787959D00029F00059E9A928B840002800005 + 8285898D8F000490018F018E038D018A0288028900198A8C8D8E8C8B8C8F8E8F + 91939798999A9B9FA5AAACAAA59E9A00029902980499019A029B00039A999B00 + 029E00059C9B9C9E9F0002A00004A19F9D9A0298000A999A9B9A989795928E8B + 028A00058B8E929598000299000598958F867E00037B00037A79760002750176 + 04770006787B7D7C78750273047401730372027100067271706F6E6D026B026A + 036B00086C6D6E6D68635E5A0358000359585600025503570256025504540004 + 514D4B4903470007484948474645430002420243000444454443034104420141 + 024000253F3E3B373435363837312C2B2C2E30322F23130B090A0B0D0E0F1011 + 1314151617191A1B1C00021D021E00000046D4D3D1CFCDCBC9C6C4C1BEBBB8B5 + B2AEAAA7A39F9A96918C88837E79746F6A655F5A554F4B4C52595B5D656C6F6C + 6865646567696C6E7480909B9E9F9E9C968D85807F80838603880289028A0289 + 00048B8C89860385000986888A8C8D8E919495000296000497999A9B029A0009 + 9CA1A7ABAAA6A09B9800039701980199029A00039B9C9D00029C00069FA2A19E + 9D9E04A000049F9D9C9A029900099B9D9E9D9A96928F8C00028A00068B8D9092 + 9497039900049690887F037B017A017902770004797A797702760006787A7C7B + 79760274017502740273047202710170016F036E026D016C036D00096C6D6E6F + 6E6B665F5A0002580004595A5856025503570256000355545300025400095351 + 4D4A484746474800024A00044948464403430344014301410340024101430242 + 000641403F3E3C380235001F373938322C2B2C2E30323024140B090A0B0D0E0F + 10111314151617191A1B1C00021D021E00000030D5D4D2D0CECDCAC8C5C3C0BD + BAB7B4B1ADA9A5A19D98948F8B86817C77726D68625D58524E4C50575B5D636B + 706F6A660265000967686A6D717A89979D00029F00049D978D85028000047F80 + 82830282000C83858788898A8D8E8C8987860285000886888A8B8E9295970296 + 0010959697969594959BA2A9AAA8A29B989702960197019A049C00049D9C9DA0 + 02A301A0049F00039E9C9A00059900089A9C9D9B9792908E028D00038E8F9000 + 0291019301960399000597928A817B00027A000779777677797A790002750008 + 7678797B79777574027501740173027104720171027001710270016F026E026D + 016E036D00076E706F6B645E5900025700055A5B5A5857000656015501530352 + 000551504E4B49000348014A024B00044A4846450544000343424000033F0003 + 40414300024202410004403F3C3902360020373938332D2B2D2E30333025150B + 090A0B0D0E0F10121314151618191A1B1C1D021E011F0000002CD6D5D3D2D0CE + CCC9C7C5C2BFBCB9B6B3AFABA8A4A09B97928E89847F7A75706B65605A55504D + 50565B5D616A0271016D0168026600096768696B6E7482919B00029F00089E9A + 928B878582810280000F7F7E80838587888A8D908F8D8B8A8900028801870288 + 0005898C91929000038F0190029102920010979FA8AAA9A49E9896959496999D + 9E9D029C00039B9C9F0002A201A102A000089F9D9B9998999A99039800069998 + 9693919002910392019102900003929598000299000597948D837C0002790178 + 01770276000A77787775747778797A780576000573716F707100037202700271 + 0003706F6E00026D066C016E026F00046A625C590258015A025C00065A585755 + 54550356000354514F00024E00054F4E4D4C4B00024A034B014A024801470246 + 0345000344434100024001410242014401430242000541403F3D390002360137 + 0239001D342E2C2E2F31333126150C090A0B0D0E0F11121314151618191A1B1C + 1D00021E011F00000025D7D6D4D2D1CFCDCBC8C6C4C1BEBBB8B5B2AEAAA6A29E + 9A95918C87827D78736E68635D585300024F000C545A5D60677074706B676667 + 02680012696C707B8A979D9F9E9C98928D898582807F027D0011808485868788 + 8B8E908F8D8C8B898886840002850188018C058D000F8E8F929493969EA7AAA9 + A59F9A98970002960199029D019C049B00039DA0A10003A000039E9B9A000299 + 00049A9B9A98039700069694939293950296000894918F8E8F919498029A0005 + 98958F857C000378000676757475767702750177027800037978760003770004 + 767472710272000473727170026F00036E6C6B00026C016B036A02680169016B + 026E00076A635D5B59585A00025C000D5A58565453545556575552504F000350 + 014F024E024C044B024A02490248024700034645440004430344014302420007 + 41403D3A373637000239001E352F2D2E3032343227160C090A0B0D0E0F111213 + 14161718191A1B1C1D1E021F00000031D8D7D5D4D2D0CECCCAC8C5C3C0BDBAB7 + B4B0ADA9A5A19D98948F8A85807B76716B66605B56514F53595D5F646D74736E + 6A00056800066B6D7583929B029E00099D9A958F898583828000027E01820285 + 00058687888A8C00028E028D000B8C8A878382848687898A8C00038D00038E8F + 930002950003969CA40002A90009A6A09B9A999897989B00039C039B019C019E + 039F000B9E9D9B9A999A9C9D9C999700029600109796949597999896928E8D8E + 8F919498029A0006999691887E79027800087776747576787776037504770176 + 02770276027403730005726F6E6D6B00026A026B000F6A696A68666566696D6E + 6C66615E5B000259025B00035A58560002540255035601540453025200045150 + 4F4E024D014C014D024C014B014A034900034847460002450444014502440009 + 434241403E3B38373800023A000B36302E2F3133353228170C00020A000F0B0D + 0E0F111213141617181A1B1C1D00021E021F00000032D9D8D6D5D3D2D0CDCBC9 + C7C4C2BFBCB9B6B3AFABA7A39F9B96928D88837E79746E69645E59545052585D + 5F62697274706D6A0269026800076A6C717C8C989C00029D00049A948C850481 + 028001830185028601870289018A0389028B00068885817F828502870008888A + 8D8E8F9091920293000A9599A0A7A8A59E989798029902970199039B019C029D + 039E019D019C059B029C00039D9B990002970399029A000498969390028F0290 + 000491949799029A000598938B807A0002780177017602740177027A000B7876 + 7576797A7976747576000277017601750273000772716F6E6D6C6B00036A0269 + 000D6A68656465686D6F6E6A65605C00025900055A5C5B5A5800035602550156 + 035702560155025400065351504F4E4D034C014B014902480249000448474645 + 02440143024402450144014302420006413E3B383738023A000B37312E2F3033 + 353329180D00020A00100B0D0E0F111213141617191A1B1C1D1E021F01200000 + 0026DAD9D8D6D4D2D1CFCDCBC9C6C3C1BEBBB8B5B1AEAAA6A29E9994908B8681 + 7C77726C67615C5602520006575C5F61656E027300036F6C6A00036900076A6C + 6F7786949A00029C00059A938A817D00027E00057F808284850002860387000C + 8684838487898683817F818403850004888A8C8E0291000A908F9092959AA3A7 + A39A02940196029800069695979A9B9D029E049D019C029B029C029D00059C9B + 9C9D9C00029B00069D9E9D9C99940291039201910290001B9396989A9B99958E + 847D7A7978777576787B7C797776787B7C7A7500027200057476777574000273 + 01720171026F000F6E6D6C6B696867686968656465696D00026F00076A645F5B + 58575900025B025A000459585756025501580259000357565500025400065250 + 4F4D4C4A03490004484645460247024601450244000443424344024502440008 + 4342413F3C393739023B01370132032F000632353329180D020A00110C0D0E0F + 111213141617191A1B1C1D1E1F00022000000033DBDAD9D7D5D4D2D0CECCCAC8 + C5C2C0BDBAB7B3B0ACA8A4A09C97928D88837F7A756F6A645F595452555A5E5F + 626A7274716D6B00036A000E6B6C6F74808F989B9C9A958D847F027D00047E80 + 838503870004868483820280000881858886848382830285028400048688898C + 029000178D8A8B8E91959FA6A59D9897999B99969596989B9D9F9E00029D019C + 029B000B9A9B9D9EA09F9D9C9DA0A10003A0001E9F9D9B97939293949392908E + 8D9094989A9B9A97928A84807D7B7A797A7C027E017C017A027900047B7C7A75 + 0271000573757675730002720271037000056F6D6B6968000367016602640003 + 666A6D00026E000469615C5902570005585958595B00025A0004585655560258 + 00035755540003520003514F4D00024B00034A49480002470446034502440243 + 00034243440003450009444342413F3C39383900023B000338322F00022E0006 + 3135342A190D020A00110C0D0E0F111214151617191A1B1C1D1E1F0002200000 + 0027DCDBD9D8D7D5D3D2D0CECCC9C7C4C2BFBCB9B6B2AFABA7A39F9A95908B86 + 817D78726D67625C56000253001C575C5F61677175736F6C6A696A6B6D6F727B + 89959A9B9A98938D8680027E0008808184878887858304820004838688870386 + 0387028500048687888A028D000C8987888B8F959FA7A8A4A09D029C019A0296 + 0017979A9C9D9E9D9C9B9A999A9B9C9E9FA0A1A0A1A2A4A3A000029E019D029B + 00089A97969593918F8D028C00048F93979A029B000A9895908B86817F7E7D7E + 037F00037E7D7B00027A00037B7A76000274017602770006767371706F700371 + 0003706E6C00026B0003696867000266000467696B6D026E000469625C590258 + 015902580159035B01590158035601550154025301510252000351504E00024D + 00034C4B4900044802470446014502440243000544454645440002430013413F + 3C3A38393B3C39332F2E2F3135342B1A0E00020A00130C0D0E0F111214151617 + 191A1B1C1D1E1F2021000000002FDCDBDAD9D8D6D4D3D1CFCDCBC8C6C3C1BEBB + B8B4B1ADA9A5A19D98938E8984807B75706A655F59545254595D60656E000275 + 0019716C6867686B6D7072778390989A9B9A98938C837F7E8082850004860185 + 02840003858687000288028701880189028A0188028701880189028A00118B8A + 8886878A8F97A1A8ABA8A4A09C9B980002960004989A9C9B029C00079B9A9998 + 999A9B00029C00039EA2A40002A50005A4A19C999A00029C00089D9C9B989491 + 8E8C028B00058D8F93979A00029C00079996938E88838100047F027E027F000E + 7D7A797A79777677797A79777470026E016F0470016F036E016D016C026B036A + 016C016D026F00076B645F5C5B5A5B00065A0005595756555400025202530252 + 02510004504F4E4F024E014C044B024902480005474645444300024201430144 + 034500064443413F3D3A0239001F3B3C3933302F303336352C1B0E0A0B0C0D0E + 0F111214151618191A1B1D1E1F000220012100000028DDDCDBDAD8D7D5D4D2D0 + CECCCAC8C5C3C0BDBAB6B3AFACA8A49F9B96918C87827D78736D68625C570252 + 000A555B60646A7275726D6702640009676B7072757E8B969A00029B00089996 + 8E847E7D7F810283000482838788068902880189028A00068B8A88878889038A + 0389028A000C8B9099A3A9ABA9A59E999796039501970299049A0199029A019B + 019A029900139BA0A2A4A3A29F9B9A9C9E9F9E9D9A9794918E00028C000F8E8F + 9092969A9C9D9A97948F88838100027F00097D7C7B7C7E7F7D79770002780277 + 0007787A7B7976747200037102700171017304720010716F6E6D6B6A696B6D6F + 706E68635F5D025C015B0559000356555400025302520006535453525150024F + 014E034F014D024C014B014A0249024700054644434241000240001541434546 + 45444342403D3B393A3B3C3A343130323400023600152D1C0F0A0B0C0D0E0F11 + 1214151618191A1C1D1E1F000220012100000030DEDDDCDBD9D8D7D5D3D2D0CE + CBC9C7C4C1BEBBB8B5B1AEAAA6A29E99948F8A85807B76706A655F5954515258 + 5E62666E027400216E67605E61676D71747A8693999B9A99958D827B7A7C7E80 + 7F7E81878A8C8B8A890003880189028B028A01890287000388898A00048B000D + 8E908E8D919AA3A9ACA9A39B960003940393019603980007999A9B9C9D9C9A00 + 029900049B9E9FA103A202A0029F00099E9C9B98969593929100039000188F90 + 94999C9D9B98948F8983807F7E7C7978797C7D7C7976037701760178027A0178 + 01760375017601750274000B75767574737271706F6C6A00026900096B6D6F70 + 6F6A65605D00025C00035A585700025801570155045304540003535251000250 + 044F00044E4C4B4A024902480004474645440243014202410142014303460006 + 454443413E3B023A00043B3D3A3502310007323537362D1C0F00020A00110C0D + 0E10111214151718191B1C1D1E1F20000221000001DE01DD02DC003BDAD9D7D6 + D4D3D1CFCDCBC8C6C3C0BDBAB7B4B0ADA9A5A09C97928D88837E78736D68625C + 565251555C60636A72747069615C5E646B6F7376818E9700029A000599948B81 + 7A000279017B037E000381878A00028C00068B88868586880489000487868586 + 0288018B028C00108E9193918F9299A1A8ABA9A2999493950396000997989997 + 95979A9C9D00029E00049C9A9B9D02A001A201A402A50005A4A29F9C9A000299 + 001598979697969593918F8D8E93989C9D9C999590888200027F000B7E7B7876 + 77797B7C79777800037900067A7B7A7877780279027A0278000B77767572706F + 6E6F6E6D6C00026B00096C6D6E706F6A64605C00035B01590358015601540353 + 0154055501540253015202510005504F4E4C4B00044A02490003484746000245 + 02440005434445464700024600144543423F3C3A3B3C3D3B363130323538372E + 1D0F020A00110C0D0E10111214151718191B1C1D1E1F2000022100000058DFDE + DDDCDBDAD8D7D5D4D2D0CECCCAC8C5C2BFBCB9B6B3AFABA7A39E9995908B8680 + 7B75706A655F59545152585E61676F74726C656162666A6E71747B8994999A99 + 968F87807D7B7C7F808284878A8B8C8D89858485868703880004878685870288 + 018B028D00098F9193929092979FA60002AB0003A69F9B00029A039B029A0007 + 9B99989A9C9D9E00029D029C019E01A103A402A50005A4A3A19D9A0002970298 + 0299000B9A9997938F8D8C8D91979B00029D00059A9690878100027E00037D7B + 780002760006787B7C7B7A7B027C017D037E027C027B037A000779777674726F + 6D00026C016D046E036D016E026F00046C66625E035C015A0258025702560004 + 555455560357025602550154015302520250014F024D024C014B024A01490247 + 02450244014502460347000646454443403D023B000D3C3E3C36312F31353837 + 2E1E0F00020A00110C0D0E101112141517181A1B1C1D1E1F2000022100000031 + E0DFDEDDDCDBDAD8D7D5D3D2CFCDCBC9C7C4C1BEBBB8B5B1ADA9A5A19C97938E + 88837E78736D68625C565251565D60646C000273000D6E676566686B6D707277 + 82909700029A001298958E86807D7C7F82848688898A8B8D8A86048501860387 + 0388001587898C8E8F909192919091959CA4A9ABAAA59F9C9A00039B0299019C + 019D049E019D019C029B00079CA0A4A6A5A3A20003A000039F9C990002970003 + 9A9B9C00029B00049895918E028C000C8D91969B9D9E9B979189827F027E017C + 017A027800037A7D7E00027D017E017F0480027F00047E7C7977037600057573 + 716F6E00026C00036D6E6F00036E036D00086E6F706E6964605D025C015A0458 + 02590158015704580007595857565554530002520250014F014E024D00034B4A + 49000248000347464400024300034445460005470014464443413E3B3C3D3E3D + 37312E303538372F1F10020A00100C0D0E101112141517181A1B1C1D1F200221 + 012200000041E0DFDEDDDCDBDAD9D7D6D4D3D1CECDCBC8C6C3C0BDBAB7B3B0AC + A8A39F9A95908B86817B76706B655F595451545A60636A71746F6865676A6C6D + 6F71747D8A959900029A0009979188807C7B7D82860004870003888A89000287 + 02880187028601870189028C00048A888A8C028E048F00198D8E91979EA5AAAB + A69E989596989794969B9FA1A2A09E9D9C00029B00079C9FA4A5A3A09E00039D + 00069B999897999D029E00069C9894918F8D028E000C8F91969A9D9F9D99948D + 8580027F00067E7D7C7B7C7E047F0280017F017E037D00057C79747172000273 + 000772716F6D6C6D6E00036F026D000C6B6A6B6C6D6E706E69635F5D025C015A + 03580004595B5C5B035A0259025800045655545203510150024F00054E4D4C4B + 4900034800034746450002440145024602470248000647464544413F023C0008 + 3D3E3D37312F3135023800163020110B0A0C0D0E101112141517181A1B1C1E1F + 202102220000004EE1E0DFDEDDDCDBDAD9D7D5D4D2D0CECCCAC7C5C2BFBCB9B5 + B2AEAAA6A29D98938E89837E79736D67625C565253595F63676F74716A67686A + 6C6D6E7072788592989A99979188827E7D7E838687860284018503870008898A + 89878685868A028E018C028A018B028C00118E8F908E8C8B8D9299A2A9ABA69B + 928F91000295000893959A9FA2A3A2A0029F019D029C00069FA3A4A29F9D029C + 000C9A989695969A9FA19F9B9690028E018F01910290000B9295999D9F9D9A95 + 8E858000027E037D00037B7A7B00037E017D027C017B0479000677746F6E7072 + 0271000B6F6D6B6A6D6F6E6D6C6A69000268000C696A6C6D6F6E68625F5D5C5D + 035B035A015B015A0358000557565554520002510004504F504F044E024D014C + 024A02490248000347464500034602470248002847464544423F3D3C3E3F3E39 + 3231333639383120110B0A0C0D0E101112141617181A1B1C1E1F202102220000 + 02E10035E0DFDEDDDCDBDAD8D6D5D3D1CFCDCBC9C6C3C1BEBBB7B4B0ACA8A4A0 + 9B96918C86817C76706A655F595453585E62656C73746F6A6900026B00086D6E + 6F7176808D960299000898948D86827F80820284000983818284868788898800 + 04860188018B028E018D018C038B00058A8C8F919000028E00118F9399A1A7AB + A89E948F90949594959A9F0002A30005A2A1A09F9D00029C00059FA2A3A19E00 + 029D00039B9997000296000A999DA1A29F9A948F8E9102930192029100039498 + 9C00029E00059B968E847D00027B037A00097977787C7D7C7B79780003770004 + 7876726F026D00067072706F6D6C026900036B6C6A00026901680267000D6869 + 6A6B6D6F6E6A64615F5E5D00035C00055B5A59585600045400065352514F4E4F + 0350014F034C034D014C024B01490548054704480005474645434000023D013E + 023F00053A3433343700023900163122120B0A0C0D0E101112141617181A1B1C + 1E1F20210222000001E201E102E002DE0030DDDCDBD9D7D6D4D2D1CFCDCAC8C5 + C3BFBCBAB6B3AFABA7A29E99938F89847E79736D68625C5654575D6163697175 + 726E026B000A6A6C6D6F71747B8893980299000496908781037E017F02810280 + 0003838586000288000B8581828485878A8C8D8E8F00038E00048F9093950296 + 000697989A9CA1A502AA0005A39B9594960002970006989CA0A2A09F029E019C + 029A00069C9FA1A2A19F029E019D039C00089D9FA0A19F9C9996029300109596 + 9593929193969A9D9E9B978F847C037A0009797A7978797C7E7D790002770006 + 7675777876720270017102730170016E026D016A036903670268000E696A6B6C + 6D6E706F6B66625F5D5C035B00055C5A59575500035202510250024E014F0350 + 00064E4C4B4A4C4D024C024B0003494748000349014802470248024902480008 + 47464543413E3D3E023F00053B3634353700023900163323130B0A0C0D0E1011 + 12141617181A1B1D1E1F202102220000002CE3E2E1E0DFDEDDDCDBDAD9D7D5D3 + D2D0CECCC9C7C4C1BEBCB8B5B1ADA9A5A09B96918C86817C76706A655F590256 + 00145B6063666D74736F6C6B6A6B6C6E707377829097029900049791867F037C + 017E037F0004808284860287018402800007818386888A8C8E00039001920193 + 0294000395969700029A029B00089DA1A7ABA9A39D990297000698999DA09F9C + 039A000599989A9C9F0002A0029E019F01A005A10004A09F9E9C029B019A0199 + 0398000F969492919396999D9E9C9991877D7A00027B027A027900057B7E807E + 7A0004780279000478757475027601750171026E00046F6D6A6903680003696B + 6C00026D026E026F001271706B65605D5B595A5B5C5D5C5A5856545303520351 + 0350034F00064D4C4B4D4E4D034C014A0249024A000449484746024701480249 + 00094847464544413E3D3E00023F013C01370235001937393A3324130B0A0C0D + 0E101113141617181A1B1D1E1F2022000223000001E301E202E101E002DE0031 + DDDCDBD9D8D6D4D3D1CFCDCBC9C6C3C0BDBAB7B3AFABA7A39E99948F89847E79 + 736D68625C5756595F63656A7174716E6C00026B000F6C6E7072757D8B95999A + 98948C8681000280028100067E7D7E8082830284018301810280000782868889 + 8A8C8E00028D018E0291038F019101940296000995969AA2A8AAA69E98000294 + 000795979B9E9D9A98000299000B98999C9D9E9D9B999A9C9F0002A1019F029E + 019C029B00059C9D9E9D9C00029A0003989693000392000994989C9E9D9A948B + 8100027D000B7E7C7A797A7C8081807D7C00057A017802770278000377767200 + 026F000571706E6D6C00026D016E026F0170056F027000046C655F5C0259015A + 015C025D00065C5B595857560255045301520251015001510250044F014E024D + 014C014B024A024901470146044501470249014801470246000344423F00023E + 023F001D3C37353638393A3425140C0A0B0D0E101113141617191A1C1D1E1F20 + 2200022300000007E4E3E2E1E0DFDE0002DD002FDCDAD9D7D5D4D3D1CECCCAC8 + C5C2BFBCB9B5B1ADA9A5A19C97928C87817C76706B655F5956575D6265686F75 + 74706E00026C00096D6E6F717379869198000299000C97928E88848384827F7B + 7C7E027F018001810282000380818300028702860005888A89888A00028D018A + 0289018A018D0290000F8F90939CA5A9A49A938F909395989B00029C029B000B + 9A989A9C9D9C9A9796989A00029B0004999798990298000A9A9D9FA09F9D9B9A + 97940491000393979B00029E00089B968F888381807D027A000C7B7E8182817F + 7E7C79787978027700087879787675747271027300037271700006710170016E + 036D00066F706D665F5B025900075B5C5D5E5D5C5A0002580257015601550553 + 035203510004504F4E4C034A0349000348474500054301460249024800064746 + 4543403E033D001D3A363436383A3B3526150C0A0B0D0E101113141617191A1C + 1D1E1F2122000223000002E4002BE3E2E1E0DFDEDDDCDBDAD8D6D5D3D1CFCECC + C9C6C3C1BEBBB7B4B0ABA7A39E99948F8A847F79736D67625C00025700095C62 + 65676D7476737000036D00086E6F707276808D96029900059896938D88000285 + 0183017E027A017C037D017F01810383000784878684838588000289018A028D + 00068B898685888A028B00128C8F97A1A7A49A928F9092939495979A9C9E029C + 049B0198029700049A9B99960294019602970003989B9E0002A000089F9D9B98 + 94908F900291000D92969A9D9E9C98928B8582817E00027B017D01800381000C + 7F7E7B787778777677797A7804770276000375737100067000036F6E6C00026B + 00096C6E6F6E67605C5A5900025B035C00035B59570004560003545352000253 + 000454535251035000044F4E4C4A024801490348024701450544014703490148 + 024700084543403E3C3B39370233001A35383A3B3627150C0A0B0D0F10111314 + 1617191A1C1D1E202122022300000004E5E4E3E202E10033E0DFDEDDDCDBD9D8 + D6D5D3D1CFCDCBC8C5C3BFBCB9B6B2AEAAA6A19C97928D87817C76706A655F59 + 575A6064666A727675727000036E00126F7071737B8893989A999895918B8784 + 817D0279017B017D027F00038183850003860009878583818386898A8C00028D + 00148C8985838487898A8D8F959FA7A69E948F8E9091029000089194999D9E9D + 9B99029A000398979900029C019A02960297000798999B9E9F9E9D00029C0005 + 9A95908E8F0002910019909194999C9E9D99938B837F7E7C7A7B7E8081807F7E + 7D7B790004780179027B017A0179037A00047875726F076D00036E6D6C00026A + 00086B6E6F6E69635E5B055A0003595857000255035601550153025202530152 + 02510350024F014D014C034B024A014902480147014604450147034903480024 + 4644413F3C393734323336383A3B3628160C0A0B0D0F101113141617191A1C1D + 1E2021220223000001E502E40006E3E2E1E0DFDE02DD0023DCDAD9D7D6D4D2D0 + CECCCAC7C5C1BEBBB8B4B0ACA8A49F9A948F8A847F79736D68625C0002580005 + 5C6265686F000275000374727000046F0006717277839097039A001C97928B85 + 807D7A77787A7C7E8183858688898A8987848283868A8C8D028E00118D898583 + 85878A8D909398A0A7A9A3999200038F018D028C00078F949B9D9C9A97000398 + 000597999B9D9A0002980299000698999C9E9C9A029900069A99959190910292 + 000E909193979B9E9D9A948D847F7D7C027B017E0280017E047C017B027C017D + 037C017B037A000679787572706F036E00046D6C6B6C036E016D026C016E026F + 00046C66615C025A025900065857555453540456015504540253015203510250 + 014F024E014D024C014A0148044702450003444546000249014A014902480008 + 4644423F3D3B39360234001C36383A3B3729170C0A0B0D0F101113141617191A + 1C1D1F202122232400000005E6E5E4E3E20002E1002FE0DFDEDDDCDBDAD8D7D5 + D3D2CFCDCBC9C6C3C0BDBAB7B3AFABA6A19C97928C87817C76706B655F595759 + 5F63676D74000276000374727100037000067172757E8B95039A00089891887F + 7A787778027A0004797C808402860188018B028D00078C8987888A8D8F000391 + 0190018D028B000E8D8F929497999CA2A9ABA79E958F028E048D01900197029C + 0003999798000299000798999B9D9C9A9900029A0299000A9A9B9997989A9B9A + 979404920005908F91959A00029E00079B97918B84807F00027E027F00037E7C + 7B00037C00077E7F807F7D7B790002780277000376747100027003720170016F + 026E026F027000046F6E6D6E027000056D67605C5900025A0008585655545253 + 5455025602570156025501540253015203510150034F024E00044C4B4A470346 + 0147044501470149024A0249000648464542403F023E001D3C383637383A3B37 + 29170D0B0C0D0E101113141617191A1C1D1F202123000224000001E601E502E4 + 01E302E20028E1E0DFDEDDDCDBD9D8D6D4D3D1CFCDCAC8C5C2BFBCB9B5B1ADA9 + A49F9A958F8A847F79736D68615C025700055B61666B72000278000376747200 + 0471000672747A859198029A00129790857C7877797C7E7C797B7F8386878A8E + 0390018F028E00038F90920003930192039100049396999A029B000A9DA3A9AC + AAA2978E8B8D028E00048F8E9198029C00059A97989B9C00039B019D019C029B + 00039D9E9B00029801990298019A029D00059C9894919000029100058E8C8E94 + 9900029E00079C98948F88828100038000057F7D7C7B7C00027D00077E7F807E + 7B797600027700087675716F6D6F717402750173017206710004706E6D6E0270 + 00056C655F5A5900025A00065856555453540255000654555657555402520151 + 0250014F0450034F014E024D014B014A0249014801490548044A000649484745 + 4240023F001E403F3B3837383A3B382A180D0B0C0D0E101113141617191B1C1D + 1F2022230224000001E602E502E40006E3E2E1E0DFDE02DD002FDCDAD9D7D5D4 + D2D0CECCC9C7C4C1BEBBB7B3AFABA7A29D98928D87817C76706B645E5956585E + 65696F7679787674730003720273001876808C96999A989289817C7B7E828380 + 7E7C7D8084878B8E048F048E018F029001910190039101930197039A000D999A + A0A8ACABA4968D8A8D909100029001920197029A000498979A9D029E019D019C + 049D000EA0A19E99979697989C9E9D9A96930390000E8E8A898D93989D9F9D99 + 948E8680027E027F017E017C037B00097C7B7C7D7E7C7A787600027700037674 + 7000026E00036F717400027500037473720002710270000C6F6E6C6B6C6F706D + 66605B59025B000359565500025400045657565502540005555251504F00044E + 01500151025201510250024F014E014D024C014B054A0249014A014B024A0008 + 49484745423F3E3F0241001E3D3837393A3B382B180E0B0C0D0E101113141617 + 191B1C1E1F2022232425000001E702E601E502E40036E3E2E1E0DFDEDDDCDBDA + D8D6D5D3D1CFCDCBC8C6C3C0BDB9B5B1ADA9A5A09B95908A847F79736E67615C + 57565B63676B717779787674037202730005757B87939800029A0007968F8780 + 7D7E810002820007817F7E8082858900028B038A018902880004898A8C8B028C + 00058E8F909296000399000C98999FA6AAACA6998E8A8C900492019303950197 + 019B029D049E00039F9E9F0002A100169E9A959493969B9C9995949392918F8A + 87888C92979B029E00079A958D837C797A00027C017B017902780279000E7879 + 7A7B7A797877767574737271037000037172730002720171026E016D026C000F + 6A69686A6D706E68625C5A5B5C59560002550005565758575600025500035451 + 5000024F014E014D024E015001520253000352515000024F024E014D024C024B + 024A0349014A024B024A0005494746433F00023D002040413D3937393A3C382B + 190E0B0C0D0E101113141618191B1C1E1F202223242500000004E8E7E6E502E4 + 01E302E2002FE1E0DFDEDDDCDBD9D8D6D4D2D0CECCCAC7C5C2BFBBB7B3AFABA7 + A39E98938D87827C76716B655F59565A6166686D7400027A0003777573000272 + 000773747578828F9700029A001498938A817C7A7B7C7F807F80818385878887 + 85840285000386878800028902870007888B8E909396970003980008999DA2A7 + ABA89D92028C00128F939492908F9194979B9D9C9B9D9E9FA0A1029F02A0000A + 9E9A95929094999A97930294000A93908C8785878A8E9499029E00059B958D82 + 7A0002760277017601750476000375787A00027B000579787674730002720273 + 0171046F000470716F6D036A02690005686665676B00026E000369625C00025A + 00055B5856555600065700035655520002510250034F00085052535452514F4E + 034D014C034B014A024903480149024B024A0005494846434000023E001E4142 + 3E3937383A3C392C190E0B0C0D0E1011131516181A1B1C1E1F21222402250000 + 02E801E701E602E50006E4E3E2E1E0DF02DE002ADDDCDAD9D7D5D3D2D0CECBC9 + C6C3C0BDBAB6B2AEAAA5A09B95908A857F79736D68625B57585F65686C74027C + 00037A77730002720008737475777E8A9499029A0008968F877F7B7A7C7F0280 + 018202850286028801850281018201860388018703840004878A8E9102940393 + 000495979BA302A9000DA1958D8A8C929594919092979B00029E029C00039E9F + A00002A1019F039D00099B9996949396999A99000297001495918C8986848586 + 898F979D9E9C9790857B767503740003757675000374000B777A7C7B79787773 + 706F710002730171026E026F0004706F6D6B0568000A67656465686D6E69615C + 025900055A595756570003580159025801570155035302520151025001510352 + 0004514F4D4C024B024A0449024802470148014A034B024A0004494744410240 + 0242001C3F3937393B3C392C1A0E0B0C0D0E1011131516181A1B1D1E20212324 + 0225000002E801E701E603E50006E4E3E2E1E0DF02DE0038DDDBDAD8D6D5D3D1 + CFCDCAC8C5C2BFBCB8B4B0ACA8A39E98938D88827C76706A645E59585C63686C + 757E7F7C79757372737576777B869198029A000B99958E867F7D7E8081828500 + 0488028900218682808286888786858382838486898E91908D8C8D9092969EA6 + A9A4998F898A8E00029302920008959B9FA19F9D9E9F029E029F019C019A029B + 029C019A0298019A029B00089A9897948F8A88850283001182848B949B9E9D99 + 938A817B78767475770002790005777574767900027C00047A79787402700172 + 02740171026E026F027000036E6B690002680367016602650006686D6F6A625D + 035A015902580359035A0003595755000254025300035251500004510003504E + 4C00024B00034A4948000247000348494A00024901480149024A034B00064A49 + 4846444202410243001C3F3A38393B3C3A2D1A0E0B0C0D0E1011131516181A1B + 1D1E202123240225000001E902E801E701E602E501E401E302E20033E1E0DFDE + DDDCDAD9D8D6D4D3D1CECCCAC7C4C1BEBAB7B3AEAAA6A09B96908B857F79736D + 67615B585A60676C747D817F7B787500027401750277000479818D96039A0004 + 98938B8302800281018301860388028901880185028200048386878603840283 + 00178587898C8E8C8A898B8E909299A1A7A69C918A898D91920002910006949B + 9FA1A09E029D019C019B029C00049A999C9D029F019E039D00119C9B97949392 + 8F8B88848281808289939A00029E00079A968F88817C7800027700117A7C7D79 + 76747577797B7A7978757372730002740171016F036E00066F706F6D6B6A0369 + 026A0269000A6B6E706D67625F5D5B59055800065A5B5A595653035201510650 + 00034F4E4D00044B00034A49470002480149024B034A044B014A014802460144 + 0141023F01410243001E3F3A38393B3C3A2E1B0E0B0C0D0E1011131516181A1B + 1D1F202123242526000002E902E801E701E602E50005E4E3E2E1E00002DF002A + DEDCDBDAD9D7D5D3D2CFCDCBC9C6C3C0BCB9B5B1ACA8A39E99938E88827C7670 + 6A645E59585D646A717B028100077E7A7775747577000278000A7E899498999A + 99958D8503800004818284860387000388868500028400058587898785000286 + 0285000687898B8C8B8A0289000D8B8D8F90959EA5A7A1968D8A8C000290028F + 000692999D9F9E9C069B00049A9B9EA002A201A1019F029D00049B9994910290 + 00138F8B8885838280828891999D9E9B97928B837D000379017B027C00037875 + 7300027401760278017702760175017303740172026F00036E6D6E000270016F + 016E026D066C000C6D6F71706B66625E5B5A585703560159025A000359555100 + 0350034F014E054F014E044D014C014B094A034B000749474542403E3C00023B + 000D3F4243403A38393B3C3A2F1C0E00020B00100D0F1012131516181A1B1D1F + 202123240226000002E902E801E702E601E501E402E30034E2E1E0DFDEDDDCDB + DAD8D6D5D3D1CFCDCAC8C5C1BEBBB7B3AFABA6A19C96918B857F79736D67615B + 575960676E788082807C797602750176027800047B85909703990006958E857F + 7D7E027F0180018103830484000885888A8C8A888A8B028900158A8C8E8D8B8A + 8B8C8D8F9091959DA4A8A59B918C8D00028F028E000390959900029B039C019B + 019C039D019E02A102A201A0019C0399000398949000028E00058D8B88858300 + 0382000E8790979C9E9C98938C837C797778027A017901760473000774767776 + 7576750002740275017302710170026F03720170026F00036E6D6C00036B0008 + 6C6F71706A645F5C0259015701560255000756595A5957545000024E014F034E + 034D014E014F0250014F024E014C024B00064A4B4A49484703480149024A000E + 4744423E3C3B39383A3F4243403B023900063B3C3A2F1D0F020B00100D0F1012 + 131517181A1B1D1F202223250226000001EA01E903E801E701E602E501E401E3 + 02E2003CE1E0DFDEDDDCDBD9D7D6D4D2D0CECCC9C6C3C0BDBAB5B1ADA8A39E99 + 948E88827C76706A645E58575B636A737D82817D7A77767576777879808C9497 + 0299000B958D837B797B7C7B7A7D80000381000B82838485888A8D8C8B8C8D00 + 038C028E018C028A000F8E9092939596999EA4A9A8A0948E8C00028D018E0290 + 000692949597999B039A019E02A101A0019F029D00049E9C989603970192018F + 028C00058B8A898684000283001384888F969B9E9D99948C837B777576787978 + 7600057401750176027504760277017502740175047401720171026F00036E6D + 6C00046B00076E706F69625D5A0002580157035501570258000457565350054E + 014D024C00054B4C4D4F4E00024D014B014A0248034900034846450002460147 + 0148024A000E484543413F3E3C3B3D404344413C0239001A3B3D3B311E100B0C + 0D0F1012141517181A1C1D1F212224252627000002EA02E901E801E702E602E5 + 0006E4E3E2E1E0DF02DE002EDDDCDAD9D7D5D3D2CFCDCBC8C5C2BFBCB8B4AFAB + A6A19C97918B857F79736D67615B56575C646E7A81827F7B7876027500077677 + 787D8791960002980006958C80787576037700037C8082000281000482858687 + 0288028900038A8C8D00028C000F8D8E8D8B8A8C929597989A9B9C9FA40002A8 + 0007A298908C8A8B8F00029202900025929497989796989DA09F9B9896979A9B + 9A98979695918E8B8A8B8A8987848385868A8F949A00029D00099A948C827975 + 7475760002770175037601750576017702780004797A79780277037600057574 + 71706F00026E016D016C026B026A016C026F000769625D5A5859580003560257 + 0356000354514F00054E00054D4C4A494A00034D00034C4B4A000249044A0148 + 0247000C4647494A4B4A4948474544430241014202440141013D0239001A3B3D + 3C311E100B0C0D0F1012141617191A1C1E20212324252627000002EA02E902E8 + 01E702E602E50006E4E3E2E1E0DF02DE002DDDDBDAD8D6D4D3D1CFCCCAC7C4C1 + BEBAB6B1ADA9A49F99948E88827D77706A645D5854565D68758082807C797700 + 0275000D7677787A828C949798968E8278000274000A7576787F838583828386 + 0387018402830005868A8B8A8B00048D00078E919598999A9B00029C00129DA0 + A4A7A49C938E8A8B8F93928F8E9092940397000A999C9D9B979291939899029A + 0007979593908D8B8A00028B00118A89868487898A8D92989C9D9B968E847A00 + 047501740275017701780779037A027B00037A7877000276000D757675737170 + 6F6E6D6C6B696800026700076A6E6F6B65605C00025A01590157055602570003 + 55525000034F034E014D014C024A014C044D014C064B014A014803460003484A + 4B00024C014B014A024901470145024300044445423D023A00183C3E3C311E10 + 0B0C0D0F1112141618191B1C1E20212324260227000001EB03EA01E902E801E7 + 01E602E502E40037E3E2E1E0DFDEDDDCDBD9D7D5D4D2D0CECBC9C6C3C0BCB8B4 + B0ABA6A19C96918B85807A736D67605A55535762707D83827E7B787675767700 + 0278000A7D879195979690867C7602750003767A800002840004828082850284 + 000983817F8084888A898B00028C00058D909294960003970499001E9A9FA4A6 + A19A928C8A8C90918F8E8F919396989B9C9B9A98959290929597029800059694 + 92908E00038B00058C8B8A888700038900158A8F969B9D9C9791887E77757473 + 727374777A7C7D00027C037A0179037A00047B7A78770276000975767472706F + 6D6B690002680267000F66676A6D6F6D67625E5C5A5956555600025703580004 + 565452510250034F024E014C034B024C024B064A0008484643424346494B024D + 014C024B00034A494600024402450143013E023A00063C3E3C311E10020C0012 + 0E0F1113141618191B1D1E20212324262728000002EB02EA02E901E801E702E6 + 02E50005E4E3E2E1E00002DF0023DEDDDCDAD9D7D5D3D1CFCDCAC7C5C1BEBBB6 + B2AEA9A49F99948E88827D76706A645D5700025300125B6A798384807D7A7775 + 767778777A838D9302950004938C837B0377017A017E028000067E7D8082807E + 037D00037F8488000289018A028C00048D9092930392001F9496979694959AA1 + A5A49C938C898B8F91908E8F909295989B9C9B98969593000292019401950294 + 01930192029100048E8C8B8A048B028A000F8887898E949A9D9C99938A7F7774 + 72000270000471727578027A01790178037600047576787A027B000D79787775 + 7473716D6C6B6A6968000269016A0269000B6A6B6E6F6D67615E5C5A58000256 + 01580159025A000558565554530002520151034F014E024D014B014A03490147 + 0548024700084644413F4144484B034D024C00034B4A470004450143013F023B + 001A3C3E3D331F110C0D0E1011131416181A1C1D1F21222425262728000003EB + 02EA02E901E801E702E602E50006E4E3E2E1E0DF02DE002CDDDBDAD8D6D4D3D1 + CECCC9C6C3C0BDB8B4B0ACA7A29C97918B85807A746D67605A55525663748185 + 837E7B78037600137877787E89919495938F867C76757677797B7C00027B000D + 7E807E7B797A7B7F848889888A00038C018E0290000791909193969897000296 + 019A01A002A400069D948D8B8D900292000391929300029401960199029A0199 + 029701960194039202910007929392918F8D8B000289000B8A8B8C8B8A878688 + 8C929800029C000799948B8178747100026F0006707273757675027302720273 + 000374787A00027B000779777471706F6C000268026900036B6C6E00026D016C + 036B000C6D6F6E6A65615E5C5856575803590003575554000353000352514F00 + 024E034D014B014A024901480547000D4645464544413F4143474B4D4E00034D + 00054C4B4846450002460144013F023B00063D3F3E342112020D00120E101213 + 1517181A1C1E1F21222425272829000001EC02EB03EA01E902E801E702E602E5 + 002EE4E3E2E1E0DFDEDDDCDBD9D7D5D4D2D0CDCBC8C5C2BEBAB7B2AEA9A49F9A + 948E88827D77706A645D5753545E6D7C02840004807D79770276000C7877787B + 858E92949390877B02730274001275787B7A797B7E7D7B797B7D8084878A898A + 038C00038D8F910002930003949597000298029900079C9FA3A5A19B96000392 + 0493029500069495969899980397019501920391000992949594928F8D8B8A00 + 048B00038C8B89000287000C8A90969B9C9A968E857C76730271017301750376 + 00047573727002710004727376780279000377736F00036C000C6967686A6C6D + 6F706F6E6C69026700096A6D6F6D6964605C5900025701580157035601550153 + 02520253000451504F4D044C014B014A02490147014803470146014502460007 + 4543414244474B00044E024D014B0149044601450140023C00063E403F362313 + 020D00120F1112131517191B1C1E2021232426272829000002EC02EB03EA02E9 + 0003E8E7E60002E501E402E30031E2E1E0DFDEDDDBDAD8D6D5D3D1CFCCCAC7C4 + C0BDB9B5B1ACA7A29D97918B85807A736D67605A55535864748084827E7B7800 + 0277037800047A818A910293000591897D74720003740178027C027A017C027D + 00067C7E818283850289038B00048A8B8E91039301940395000B97999B9EA2A5 + A6A29D9793000491000492959796039501960197029500079695939293949600 + 029500059392908E8D00038E028C00148D8C898685888E959A9C9B9790867C76 + 73727374047600047573716F026E00096F707274767776716D00036B02690003 + 6A6D6E00026F00056E6D6C69660002640167016C026F00056B655F5B59000357 + 0156015503560003545253000254000452504E4D044C014B024A014905480247 + 0004484746440243000444474B4E034F024E00044C4A4746024701460141023D + 013F0241000337241400020E00120F1112141617191B1D1F202223252628292A + 000001ED01EC02EB03EA02E901E801E702E602E50004E4E3E2E102E00023DFDE + DDDBD9D8D6D4D2D0CECBC8C5C2BFBBB7B3AEA9A49F9A948E88827D76706A635D + 5700025300035A687A0002830004807C7978027702780018797E868E9293928C + 817773747574777C7D7B7A7C7F807F81038401850288028900068887888B8D8E + 038F000E908F9092979A9DA1A5A7A5A099930490019101940297029502940195 + 029401950196039502970195029201930192029102920190018F028E000F8C87 + 8382868D93999C9B9890867A74000271000370727300027400057573716F6D00 + 026C000A6E6F7073757776716D6B036A016B016C026E016D026C026B000C6967 + 6667696D706E69635D590458015702550256015404530003524F4E00044D024E + 00034D4C4B00064A034900034746450002440003474B4F000350024F00034D4B + 48000247000348474200023E00063F4241392615020E00121011131416181A1C + 1D1F212223252728292A000001ED02EC02EB03EA01E902E801E702E601E501E4 + 02E30031E2E1E0DFDEDDDCDAD9D7D5D3D1CFCDCAC7C4C1BDB9B5B1ACA7A29D97 + 918B85807A736D66605A54515360748284817E7B790002770178027900047B82 + 8B90029200048E877D760275000374767900037A017D01810382018302840185 + 0187028601850284000386898B00038A018B028C000C8D8F94979A9EA3A7A6A2 + 9B95059200039395960002940004959798970295029601970196029701940292 + 0494029500069492908E8A8402810004858B9198029C00079992877A736F6E00 + 026D00086F70727473706F6E026D000A6E6F7073767876716D6B0269016B026D + 016E016D026B026C016D016C026A00086B6D6F706D67605B0258015902580157 + 0355025401520353000552504F4E4F00035001510150024F014E024D034C024B + 014A0249014802470148014C02500251025000084E4C494748494843023F0140 + 024200173A27150F0E1012131517191B1C1E202123242627292A2B00000002ED + 02EC02EB03EA01E902E801E702E601E501E402E30030E2E1E0DFDEDDDCDAD8D6 + D5D3D1CFCCC9C6C3BFBBB7B3AFAAA59F9A948E88827D767069635D5752515B6E + 7E8583807D7A03780179027A00157E878E9192908B837C7876747678797A7C7F + 818281000280002181828485848281828386898A88878687898A8B8D9093969B + A2A7A8A49E989594930002940193029400099395989B9D9A9896950003960295 + 01940293029502960297000695928E8B87840281000D858A90969B9C9A94897C + 736F6D00026C00036D6F7100027401710170026F016E026F0010717477787671 + 6D6A68696C6E6F706F6E046F00056E6D6C6D6E00027000056D68615C59000558 + 015603550154015202530254015302520553025202510004504F4E4D044C034B + 00074A494A4D505152000251000C504F4D4A48494A4944403F41024300033B28 + 1600020F001011131416181A1B1D1F2022232527282A022B000001EE02ED02EC + 02EB02EA02E901E802E701E602E50005E4E3E2E1E00002DF002CDEDDDBD9D8D6 + D4D2D0CDCAC8C4C1BDB9B5B1ACA7A29D97918B858079736C66605A5451556477 + 8283817E7B790278001F797A797C838B9092918E89827B76757677787A7C7E7F + 807F7E7F80818384830002810007838486878889880002860188018A028C000B + 8D8F93989FA5A7A5A09A9500029200039395930003920196019B029E00039C99 + 96000294019505940195019602970298002096938F8B8886848183868A8F949A + 9C9B958C7F75706E6D6C6D7072747572706E046D000D6F72757776726E6A6869 + 6D6F72000273027201710270016E036D000A6E6F706E69625D5A595802570158 + 0456015503530154015602550156015503540153025202510005504F4E4C4B00 + 064C034B00044E5152530252000951504E4B494A4B4A4500024000064244433A + 27160210001011131517181A1C1E1F2123242527282A022B000001EE03ED02EC + 02EB02EA02E901E801E702E602E50028E4E3E2E1E0DFDEDDDCDAD9D7D5D3D1CF + CCC9C6C3BFBBB8B3AFAAA59F9A948E88827C767069635D56025100085B6D7D83 + 817E7C7A0378027900047B80898E02910019908C847B747273747577797B7C7E + 7F80828182838483818385000286000487898B8A0289018B018D028E00068F91 + 94979CA102A5000DA199928E8D9195938F8E91969B00029C00039B9996000294 + 059500159698999A999795928F8B888685848385888A8D929800029B0006978E + 8378716E036C00076E707374716E6C00036B000E6C6D70737675736F6B696A6D + 707202740012737271706F6E6C6A696A6C6E6D69635E5B590458025602570156 + 035404550156015404530152025100055251504E4D00024C054D034C00034F52 + 5300025402530010524F4C4A4B4C4B4742414243403524160211001012141618 + 191B1D1E202224252628292B022C000002EE02ED02EC02EB03EA01E901E802E7 + 02E601E501E402E3002AE2E1E0DFDEDDDCDAD8D6D4D2D0CDCBC8C5C1BEBAB6B1 + ACA8A29D97918B857F79736C666059535054647702820013807D7A797778797A + 7B7E868C9091908D847A73000270000A72737577787B7E818485028400038687 + 860002840186018702880003898B8C00028D048F000B91939495979BA1A39F96 + 8E00028A00078F95938E8D9196000398029901980396029701980299000C9B9C + 9B9793908E8C89868586058700038A909600029B00079891867B736E6C00026A + 00076C6E7072706D6B00036A00096B6E7274767573706E00026C00176D707173 + 7472716F6E6D6B68666465686C6E6B65605C5A00035901580257000359585700 + 0255035604550254015502540353000352515000054F034E034D000350525400 + 035500065453514E4B4C024D01480143024200173F382B1D141112131517191B + 1C1D1F2123242627292A2C00022D000003EE02ED01EC03EB03EA01E901E802E7 + 02E60006E5E4E3E2E1E002DF0021DEDCDBD9D7D5D4D1CFCCC9C6C3BFBCB8B3AF + AAA5A09A948E88827C766F69635C5600025100085D718083817E7B790277000D + 797A7B7D838A8F91908D877D76000270027100077274777A7D80830003840385 + 0003838182000484000485888A8C028D028C00198E8F908F90959DA19E97918D + 8E939796918F9194959698999A000499059A029B000398938F00028D001B8B87 + 8586888A89868482868D959A9B99938A7E756F6C69686A6C6E000271016E026B + 026A00036B6F74000277000775716F6E6D6E6F00047100116F6D6B6968676462 + 6162666B6F6C67605D00025A0459035A01580157035801570356025502560155 + 01540453015201510450014F034E034D014F01530556000355535000024D000A + 4E4F4A45423F372B1E1602120006131416181A1C021E00092022232527282A2B + 2C00022D000001EF02EE03ED01EC03EB03EA0003E9E8E70002E602E50031E4E3 + E2E1E0DFDEDDDCDAD8D6D5D3D0CECBC8C5C1BEB9B5B1ACA8A29D97918B857F79 + 726C665F595351586B7E84837F7C790002770178017A027C000380878D000290 + 00068E898077706F027000067174777A7B7C027E027F0380000B7D7A7B7D7E7D + 7C7E82858700028802870288038900098F99A0A19B969291920002950191028E + 00059093979A9C00029D029E00039D9B990003970298000994918F8E8D8C8886 + 8900028B01870183027F0014848B93999B9A958D8278716D6A696A6C6F72736F + 026D016C026B00076F74777875716F00026D016F0370000A6E6D6B6966656465 + 646302620008666B6F6D66605D5A0459015A015C025B015A025900045A595857 + 035603570156055501540352025301520150034F024E00035055570003580257 + 000D55524F4E50514D46413A2C1E15000212001213141617191B1D1E1F212324 + 2627292A2C2D022E000002EF03EE02ED02EC02EB02EA02E901E801E702E60004 + E5E4E3E202E10030E0DFDEDDDBDAD7D6D4D2CFCCCAC7C3C0BCB8B4AFAAA5A09A + 948E88827C756F69625C555155657A8485817E7B7877787A027C00047D838A8E + 028F000B8A81766E6D6F7071747677000278017A027C017B027C00067B797778 + 7A7C027B00077C7F8285868584000283000B828384868D97A0A29D979000028C + 000A8E908F8D8E91969B9E9F02A0000CA19F9C98949192949593908F0390000E + 8F8D8C8D8C8884818081858B9297029B0007968F867D75706D00026B00056C6E + 71737000026E016D026C016F01730277000A75726E6C6B6D6E6D6C6B026A0004 + 69666463026501640263000A666B6F6E68625D5A59580259015B015C075B015A + 0259025A035B035A0259015A0158025701560257000456555455025400035556 + 5800055A0024595754515052534F473F342418121113141517181A1C1D1F2022 + 242527282A2B2C2D2E2F000002EF03EE02ED03EC02EB02EA01E901E802E702E6 + 0006E5E4E3E2E1E002DF0020DEDCDBD9D7D5D3D1CECBC8C5C1BEBAB6B1ADA7A2 + 9D97918B857F78726C655F58025300085F73828584807D7A0278017A037C0003 + 80878C00028E00098C84786D6B6D717374000373000476797C7B037A00077978 + 7778797A7B00027C00047E8083840383001982818285898F979FA29E97918B8A + 8B8E8F9092969A9C9D9C9D00029E00069C989591909202940192028F01910393 + 000591908E8A8600028200068486898C9096029B000D97928B837B74716E6D6C + 6D6F7000026F0018706F6E6D6E71757674716E6B6A6B6C6A696A6B6C6B686564 + 026503640167016C026F00046A645F5C025A00035B5C5D00035E015F09600261 + 0260025F00055E5D5C5A5900025806570003585A5B00025C015D015C025D025C + 015A015602530008545551483C2D1F1502120008141517181A1B1D1F02210009 + 23252628292A2C2D2F000230000001F003EF01EE03ED02EC02EB03EA01E901E8 + 02E702E6002CE5E4E3E2E1E0DFDEDDDCDAD8D6D4D2CFCDCAC7C3C0BCB8B4AFAA + A5A09A948E88817B756F69625B5553596A7D02850015827F7C7978797C7D7C7E + 848A8D8E8C877C716A6C700002740005726F70737800027B017A037901780277 + 001976777A7D7C7D7F8284838485868586898D92989EA2A19D979000028B0005 + 8E9091939600029803970299019702940293001295969594929394969593918E + 8D8A87858689028A000F8B8F949A9B98948E877F7873716F6D00026C00126D6E + 7072716F6E6D6F737572706D6C6B6C6B026900066B6E6F6D6B68026600066564 + 6364676C027000086B6662615F60626302640165026603670266066502640008 + 6362605F5D5A5856025502540008555456595C5E5F60055F00245E5C59565556 + 57524737261A151314151718191B1D1F212223252628292A2B2D2E2F30310000 + 02F002EF03EE01ED03EC03EB02EA0003E9E8E70002E60004E5E4E3E202E1002F + E0DFDEDDDBD9D7D5D3D1CECCC9C5C2BEBAB6B2ADA8A29C97918B847E78726C65 + 5E5853546175838683807C7A78797B00027D000C7E82888C8D8C8980756C6A6E + 02720008706D6E72767A7B7A04790005777573757900027D00037C7E82000286 + 01880189028A00138B8C8F92979DA2A4A29D948C8A8D8F919293940002930294 + 00079593929193959600039802970005969594918F00038D028C018B028C018B + 028900168C92989B99959089817A7573726F6E6D6E6F7173716F026D00057074 + 75727000046D016C026A016C016F0270000E6D6B686766656465676C70716E6B + 026901680169026A076B016A02690268056700096665646261605E5B5A000259 + 015803570004585C5F6105620361000B5F5B5856585953443020170002150008 + 1617191A1B1D1F210223000A242627292A2C2D2E2F300231000001F102F002EF + 02EE02ED03EC02EB02EA01E901E802E702E60006E5E4E3E2E1E002DF0029DDDC + DAD8D6D4D2D0CDCAC7C3C0BCB8B4AFAAA59F9A948E87817B756E68615B55535A + 6D808684817D7A00027800077A7C7E7D7F858A00028C000E8A83796E696A6E6F + 6E6D6F727679027A0379000D7877757475797C7D7C7D82868800038901880289 + 000E8B8E949CA1A4A39F978F8B8D8F91029201910290019202940192028F0003 + 93969800039A0005999896939000028E00038F8E8F00039000038F8D8A000286 + 000F8990969A9995918B847D79777674730002720005737475737000026E0005 + 707476747000046E016D026C016D016F027000046F6E6C6A0269026A00056C6F + 7374730002710270046F046E026D016C016B026A036904680267026600036564 + 620003610260025F0004606162630664000C6362605C58565758503F2A1C0216 + 00171718191B1C1D1F202223252627292A2C2D2E2F3031323300000001F102F0 + 03EF02EE02ED02EC02EB02EA02E901E802E701E601E502E4002FE3E2E1E0DFDE + DDDBD9D7D6D4D1CFCCC9C5C2BEBAB6B2ADA8A29C97918A847E78716B645E5753 + 56657A8586827F7B79000278017B027D00037E828800028C00088A867D726A69 + 6B6D026E0010707376797A797A7B7A79787776777A7C037D0181018403860185 + 03840005878C93999F0002A200039F999200038E0190029100188F8E8F929596 + 9491929598999A9997969593918F90929392049100038F8B870002830003878E + 94000299000996918C867F7B7978770006760174017202700005717476747000 + 026E016F016E046D00036E707100027201710270017101720273017503760275 + 01740273017202710370026F026E00036D6C6B00026A01690768026701660465 + 0364026302640765000C64635F5A555455544A37241A02170012181A1B1C1E1F + 202123242627292A2C2D2E2F023102330134000002F102F003EF02EE02ED02EC + 02EB02EA02E901E802E701E601E502E4002EE3E2E1E0DFDEDCDAD9D7D5D3D0CD + CAC7C4C0BCB8B4AFAAA59F9A948D87817B746E67615A55545E72818584807C79 + 0278017A037D000C80868B8C8B8881776D696A6C026E00056F7275797A00027B + 00097C7B79787978797C7E00037F00038183840002850284001285878B8F9498 + 9CA0A19E97908C8B8A8C8E8F0290000791949799989697000298000497969491 + 039000088F9093969593908F029000118E89838082868C92989A97928D87807B + 7900037701780277000C76757473727172747573706F026E00096D6C6D6E7072 + 747577000478057903780177027602750003747372000371000B706F6E6D6B69 + 68666463620005610262000461605F5E035D025C035D025F0160056100055F5D + 59534F00024E00054B402E201A00021900051A1C1D1E20000222000E23252627 + 292A2C2D2E30313233340235000003F102F002EF02EE03ED02EC02EB02EA01E9 + 01E802E702E60005E5E4E3E2E10002E00024DFDDDCDAD8D6D4D1CFCCC9C5C2BE + BAB6B2ADA8A29C96908A847E77716A645D575358687B02840007817D7A787779 + 7C00027D00037F858A00028C00088A867D736C6A6B6D026C00046F73787C027D + 00087E7D7C7B7C7B7C7F028102820003838485000486000D898C8F9296989B9F + A09C948D890002880007898D919394969800029901980196029700069592918F + 8E8F038E0005909495938F00028C00138E8F8D88838183858990969A97938E89 + 827D7A00027900057879787674000273027202710173027401720170026F0008 + 6E6F717477797A7B057D047C017B027A01790178027700147675737271706F6D + 6B6865625E5A5754514F4E4D034C024D00044E4D4B4A024805470007484A4C4D + 4F5051000350000B4F4D494441403F3B32251D00021B021C00141E1F20222324 + 252627292A2B2D2E2F31323334350236000004F102F002EF01EE04ED01EC03EB + 01EA01E903E801E701E602E50025E4E3E2E1E0DFDEDDDBD9D7D5D3D0CDCBC7C4 + C0BCB8B4AFAAA59F99938D87807A746D676059000254000B5F738185827E7B78 + 77787A00027D00037E848A00028D00078C89827A726D6B00026C00066B6E7378 + 7C7F03800181018003810283038402850003878889000288000D8A8C8F919597 + 9A9D9F9D96908C00038900058D9093959600029700079593929394928E00028D + 018E018F038E019002920190018D028C028D00048B8886850284000B878E9599 + 98938F8A847F7C00027B00067A79777573720573000574757776750002760005 + 77787A7C7E00027F0480027F017E037D00187C7B7A79777675736F6A68676663 + 5E58534D48423D3935320230012F022E022F00063031302F2E2D052C00062D2E + 2F3133350536000435343330022E001C2C2A25201D1C1D1E1F20212224252627 + 28292B2C2D2E30313233343502360137000001F203F103F002EF02EE03ED01EC + 02EB02EA01E902E802E70005E6E5E4E3E20002E102DF0028DEDCDAD8D6D4D2CF + CCC9C6C2BEBAB6B1ADA7A19B95908A837D76706A635C5653596B7D85837F7C78 + 0277000E797B7C7D81888D8E8D8B87817A73046D00066F72777B7D7E027F0280 + 0281028202810482018502860283000E8586888C9194969A9D9F9B958E890287 + 0010888A8D90939493918F909192918C8B8C038F0190029102920005918F8E8C + 8A0004890006878482858C930298000C94908B86817E7D7C7B7A787702750176 + 017702780003797A7C00027E027F0280028105820481000F807F7D7C7B7A7775 + 726F6D69645B5100024D000C4C48413B342E2A25221F1D1C061B021C031D051C + 031D021E0120012102220723012203210120011F021E011F0120022100032223 + 24000226000E27292A2B2D2E2F3031323334353602370138000002F203F102F0 + 02EF03EE02ED02EC03EB01EA01E902E801E702E60033E5E4E3E2E1E0DFDEDDDB + D9D7D5D3D0CECBC7C4C0BCB8B4AFAAA49E98928C868079736C665F5853556478 + 8485817D797776777900027A00037D848B00028E000D8D8A8681797270717071 + 727476000278027900067A7B7C7D7E7D027C017D037C00037F817F00027C0005 + 7E7F82878C00028F000793999E9D988E8600028100148284888D90918E8B8C8D + 9092918D8B8C8E8F909302940293000792908D8A878688000289000F86828184 + 8A909697938F8B8783807F000280017F017E037D017E01800281000382838400 + 02850186058504840183028202810010807D7976736F69635C56524D463B2F2B + 022C00072A25211D1B191700021604150416021705180419031A021B041C041D + 041E041F01200221000322232400022501260128022900082A2C2D2E30313233 + 023400033536370002380139000001F301F204F102F002EF02EE02ED03EC02EB + 01EA01E902E802E701E601E502E4002DE3E2E1E0DFDEDCDAD8D6D4D2CFCCC9C6 + C2BEBAB6B1ACA6A09B958F89827C756F68625B55545D718185837F7B78000276 + 0007777675767D858900028A00088988847F7774737202710172037300067475 + 76777879037A027B017A027900037B7D7C00037B001A7C7F858889888C939C9D + 968B837D7C7E81878C8D8C8987888B8F0292000F8F8E8D8E8F9194969594928F + 8D8B890002870004898A87830281000E84898D9294918D8985807E8083850286 + 0187028602870288068902880387018601850284001982817F7D7B777069625B + 534A423A332F2C27211A18191A191800021606150216031704180219041A031B + 031C051D041E031F03200121022203230004242526270228000D2A2B2C2D2E2F + 3031323334353600023701380239013A000001F302F203F103F002EF02EE02ED + 03EC02EB01EA01E902E802E701E601E502E4002DE3E1E0DFDEDDDCDAD7D5D3D0 + CECBC8C4C0BCB8B3AFA9A39E98928C857F78726B645E5753596A7D8584817D79 + 770002760010747270747A7E7F80828485827C76747303710272000371727300 + 02750276000C7778797B7C7B7A797B7C7D7C037B001B7E82858483868E989B94 + 88807C7B7C8085898A89878586888D9091000290028E00088F91949594918F8C + 028A038B00038C8A8500028200048385878A028B000A898886827D7B7D83878A + 048B028C018B028C038B028A02890288001A878684817E7A75706B665E534940 + 38312A241F1C1B191816151403150516021703180219031A031B031C031D031E + 041F0420042103220323022402250226012701280229000D2A2B2C2D2E2F3031 + 323334353600023701380239023A013B000002F303F202F103F001EF03EE02ED + 03EC01EB01EA02E902E802E70031E6E5E4E3E2E1E0DFDEDDDBD9D6D4D2CFCCC9 + C6C2BEBAB5B1ABA5A09A948E88817B746E67605A545664788485827F7B787600 + 0275000973706F707375777A7E00028300037F77730003720173027403730474 + 00067577797B7C7B027A00047B7C7D7C037B017C017F03810007858D979B9589 + 8000027C00057D7E81848600028702860004878B8E90028F00138E8D8E909394 + 928F8D8C8B8C8E8F8E8D8A86850002860007858684817B787B00027E00077C7B + 7D83888B8C00048D018E038D028C028B00188A89888785827E7972695F574E47 + 41393028231F1C1A18170716021703180319021A031B021C031D031E031F0320 + 022104220523042403250326022702280229012A022B012C012D022E00072F30 + 3132333435000236013701380239023A023B013C000003F302F202F103F003EF + 02EE02ED02EC02EB01EA01E902E803E70006E6E5E4E3E2E102DF0028DDDCDAD8 + D6D4D1CECBC8C4C0BCB7B3AEA8A39D97918A847E77706A635C56555E72818584 + 817D7976027402750007737173777A7D81000284017E01760271017401750277 + 00037675740004730007727376797C7D7C00027B00037C7D7E00057C000D7E80 + 8283878F979C988D837E7C00027D00057E80838789000388018C028E028D028B + 00068C9092949290058F00058E8D8C8B8A000389000F87837E756861656D7276 + 7A7E83888B00028C018D028E018F028E00188D8C8B898785827F7A746D655C50 + 4439312B27231F1C191803170116031702180319021A031B021C031D021E031F + 0220022104220223042404250426042704280329032A022B012C012D022E022F + 013002310005323334353600023701380139023A023B033C013D000001F402F3 + 03F203F101F003EF02EE03ED02EC02EB01EA01E902E802E70004E6E5E4E302E2 + 002EE0DFDEDDDBD9D7D5D2D0CDC9C6C2BEBAB5B0ABA59F9A948D87807A736D66 + 605A565A6A7C8485837F7A7774727377027800047C8285870289000B867E7671 + 7275787A79767400027202710272000674777B7F807F027D017F0280027F0380 + 000E828486888C91989C9B9288817E7D027E00057F82878B8C00028B000A8D8E + 8D8B8987888C90930295029301920190058E018D018C038B00138781796B5647 + 4850586069727B81858788898B00028C00148B898784817C77716B645C52483F + 362D26201C1A02190218011703180219031A021B031C021D031E021F03200221 + 03220223022404250226042704280429042A052B022C022D032E012F02300231 + 02320133013402350136013702380139013A023B023C023D033E000001F403F3 + 03F202F103F002EF02EE03ED02EC01EB02EA01E902E802E70030E6E5E4E3E2E1 + E0DFDEDCDAD8D6D3D1CECBC8C4C0BCB7B2ADA8A29C96908A837D766F69635D58 + 576274828684817C797502720006777B7D82888D028F000C8E8A827B75737578 + 7A79757104700006727476797C80028201810182038401830182028300158485 + 87898A8D91969B9D9890877F7D7E7F8081868B00028D000B8C8D8E8C8A868487 + 8C9194000396002095938F8D8E909192908E8F908F8981786548312C30363D48 + 54606A707375787C027E00117B77726D665E564E463F362F2924201D1A000619 + 021A031B021C031D011E031F0220032102220323022403250226032702280329 + 022A052B032C052D062E032F0230043101320233023402350136013702380239 + 013A023B023C023D023E033F000002F403F302F203F102F003EF01EE03ED03EC + 0003EBEAE90003E801E701E602E5002DE4E3E2E1DFDEDDDBD9D7D5D2CFCCC9C6 + C2BEB9B5B0AAA49F99928C867F79726C66605A565C6D7E8586837E7B77000274 + 0006787C7E82898F02910005908D877F77000273017602790174026F03710006 + 737678797B7E028101820184028600048583818202830015848687898B8F949A + 9D9A93887E7B7C7E7F8184888900028A018B028D00068A8582868D9203930294 + 0005939190919200049300099596948E867A613F2500021B000B1D21272F3842 + 484B4F545900025D000E59544E47413A332D2824211E1C1B031A021B041C011D + 021E031F0320022103220223022402250226022703280229032A022B032C042D + 032E032F0730053104320333033402350236023702380139013A033B023C013D + 033E033F0340000001F502F403F303F202F103F001EF03EE02ED02EC02EB01EA + 01E903E801E701E602E5002CE4E3E2E0DFDEDCDAD8D6D4D1CECBC8C4C0BBB7B2 + ACA7A19B958F89827C756F68635D57596679848685817C7802740006797E7F81 + 878E0391000C8F8B82797372747778747071037201740177037800057B7F8183 + 85000287018601840282000F83848587888A8C8F93979B9A93877D00027A0010 + 7C7F828485848587898D8C898482868D028F028E019203940293001092939599 + 9A9B9A97928B7B5E3A20161402150009181A1E2326282B2E3200023600093431 + 2D292623211E1D00051C021D031E011F03200221022202230324022503260227 + 03280129022A032B022C022D032E032F03300431043206330534063503360337 + 03380239033A013B023C023D033E023F03400441000002F502F402F303F202F1 + 03F002EF03EE01ED03EC02EB01EA01E902E802E70029E6E5E4E3E2E1E0DFDDDC + DAD7D5D2CFCCC9C5C2BDB9B4AFA9A49E98928B857E78716B655F595761748200 + 0286000C827D787473787E7F80848B9002920007918E88807975740002750003 + 73717200027301720174027602750005787C7F82850003860017858483848587 + 88898B8C8D8F929699948A807C7B7D8083000284000B838486888B8C89858488 + 8D00038E019002930194029500049496989C039F000A9D9A958C7857341E1614 + 0215011602170006191A1B1C1E1F03210120011F021E051D021E021F02200221 + 02220323012402250326022702280329022A022B022C032D022E032F02300331 + 023203330434033503360A3706380439043A023B033C023D023E033F02400541 + 0442000002F503F402F303F202F102F003EF02EE01ED04EC02EB01EA01E902E8 + 02E70028E6E5E4E3E2E1E0DEDDDBD8D6D3D1CECBC7C3BFBAB6B1ACA6A09A948E + 88817B746E68625C585D6D7E0286000C837E797573777D7F8082898F0392000B + 908D878079747372706F710003720003737475000272000574777B7E81000282 + 0181038001810183028401850286000987898C90959690888100027E01810183 + 02840005838485888C00028E00048B8A8D9002920016939493909195999B9EA0 + A2A3A2A19E9B94876C492C1C021702180319021A021B021C011D041E031F0220 + 022102220223022403250226022702280129032A022B022C022D032E022F0230 + 033102320333023403350336033703380539093A083B053C033D043E033F0240 + 044104420643000003F502F403F302F203F102F002EF03EE03ED02EC01EB02EA + 01E902E802E70030E6E5E4E3E1E0DFDDDCD9D7D5D2CFCCC8C5C1BCB8B3AEA8A3 + 9D97918A847E77716A655F595A67798486847F7B7776787C0280000481878E92 + 02930007918F8B857D757100036F01700371000B72737472717275787A7B7C00 + 037B00037D7F800002810180027F000E80828587898F95948E857F7E81820284 + 000B838485898E92949392949500049600069492959CA1A303A502A4000AA29F + 9A8E795939251C1A021B021C021D021E021F0420022102220223022403250126 + 022702280329022A022B022C012D032E022F0230023103320233033402350336 + 033702380339043A043B033C063D0D3E063F05400341054205430744000001F6 + 02F503F403F303F202F102F002EF03EE02ED02EC02EB01EA01E902E802E7002D + E6E5E4E3E2E1DFDEDCDAD8D6D3D0CDCAC7C3BEBAB5B1ABA5A09A938D87817A74 + 6D68625B5A6275828685817E7A00027900077C7F8081858C9100029300089291 + 8D88807872700272017301720271017201730374017501770279017803770003 + 787B7E000280017F017D027B00037C7F8200028400098991948F86807E808200 + 0384000685878A8E9395039602970198019A029C00049DA0A4A702A8000CA7A6 + A5A4A29C917D62432D21021E021F032002210222032302240225022603270228 + 0229022A022B022C022D022E022F023002310232023303340235023602370338 + 0239033A033B023C033D043E043F0640104108420543074409450244000002F6 + 03F502F402F303F203F102F002EF03EE02ED02EC02EB01EA01E903E80028E7E6 + E5E4E3E1E0DFDDDBD9D7D5D2CFCBC8C4C0BCB7B3ADA8A29C96908A847D77706A + 645E5B60707F0286000783807D7B7A7B7E0002810011848A90939493918F8A83 + 7A74727475767500027301740175027601770179037A01770375000376787C00 + 027E017D017C027B00037C7E810002820006868F94918A850282000383858600 + 02870010898C8F91939496989A9D9FA2A4A6A7A804AA000DA9A7A5A19B8F7D63 + 47312622210002220223022402250226032702280229022A022B022C022D022E + 022F0230023102320233023402350236033702380239023A033B033C033D033E + 033F034003410342074319440A450B460345000002F603F503F402F302F203F1 + 03F002EF02EE02ED03EC02EB01EA01E902E80029E7E6E5E4E3E2E1E0DEDCDAD8 + D6D3D0CDCAC6C2BEB9B5B0AAA59F99938D87807A746D67615D5F6A7982000284 + 0003817E7C00027B017E0281000483878E930295000B93908B837A7573757778 + 77000275017603770008787A7C7B7977757402750176017A067C000F7D7F8283 + 8489919695918B8684858800038B000E8E919395979A9EA0A2A5A7A8AAAB03AC + 02AB000BAAA9A69F9485735E4734290003250226022702280229022A032B022C + 022D022E022F0230023102320233023402350236023702380239023A033B023C + 023D023E033F03400341034203430444034507462547044807470346000001F7 + 02F603F502F403F301F204F102F003EF02EE02ED03EC01EB02EA01E902E80031 + E7E6E5E4E3E1E0DFDDDBD9D7D4D1CECBC8C4C0BBB7B2ADA7A29C96908A837D77 + 716B65605F636E777D80817F7D7B7C7E820002830003858C9200029600059592 + 8C827900027401760377000476787A7B037A00077B7C7B797675760002770178 + 017C027E00037D7F800002810006838688898E95029A001497918B888A8E9293 + 94979A9D9FA1A3A6A8A9AAAB02AC02AD000EAEADACABA8A49B8B76604E3F332C + 02280229022A022B022C022D022E022F02300231023202330234023502360237 + 02380239023A023B033C023D023E023F02400341024203430344034503460347 + 054805491B4A134906480347000001F703F602F503F403F302F203F102F002EF + 03EE02ED02EC02EB01EA01E903E8002AE7E5E4E3E2E1E0DEDDDBD8D6D3D0CDC9 + C6C2BDB9B4AFAAA49E99938D87817B746E6863605E61676E757A037B00037C7E + 82000384000B8A91969796948F847B767700027902780003797B7E0002800003 + 7F7D7C00027D017C027B017C027D00037E808200028401860188028900178B8D + 8F91959A9D9E9C98949294989B9D9EA1A4A6A7A8A90002AB01AC04AD03AE000C + ADAAA49C907E67503F36302D032C012D012E032F023001310232023303340235 + 0236023702380239023A023B023C023D023E023F024002410342024302440345 + 0346044702480349044A054B044C074D084E084D074C104B044A054903480000 + 02F703F602F502F403F303F202F103F002EF02EE02ED03EC02EB01EA01E902E8 + 0025E7E6E5E4E3E2E1DFDEDCD9D7D4D1CECBC7C4BFBBB6B2ACA7A19C96908A84 + 7E78726C67625D00025A000F5D63696E72777A7D818485848990950002980008 + 97928B837F808180027E00037F818500038701850283018403850486000F8789 + 8B8C8E909192939496979A9DA00002A1019F029D00079EA0A2A4A5A7A90002AA + 02AB02AC01AD03AE000DADAEADABA69C8E7D6B5645393200032F023002310132 + 0233013402350236023703380239023A023B023C023D023E023F024002410242 + 0343024402450346024702480349034A044B024C034D054E054F075007510850 + 0B4F034E074D074C034B044A0449000001F802F703F602F503F403F302F202F1 + 03F002EF02EE02ED03EC02EB01EA01E902E80026E7E6E5E4E2E1E0DFDDDAD8D6 + D3D0CDC9C5C1BDB8B4AFAAA49F99948D88827C76706B65605B5702550008575B + 626A72787E8302860009898F95999A9997938E00028C00088B89878687898B8C + 038B00048A8B8D8E068F019001910293019502960197029900069A9C9D9FA1A2 + 05A30006A4A5A6A8A9AA02AB02AC03AD000FAEADACAAA8A39B8F7D6855473D36 + 330002320133023401350236013702380239023A023B023C023D023E023F0240 + 024102420243024404450246024702480349024A034B024C034D034E044F0450 + 03510752085302540A53075207510350044F054E064D024C044B044A000001F8 + 03F702F603F502F403F302F203F102F003EF02EE02ED02EC02EB01EA02E90029 + E8E7E6E5E4E3E2E1DFDEDBD9D7D4D1CECBC7C3BFBBB6B2ADA7A29D97918B8580 + 7A756F6A645F5A5652000250000C5259636C757E8587898F9599029B00149A98 + 979594908B8887888A8B898887898A8D9093069401950196029702980199019A + 029B00069C9D9FA0A1A203A403A50004A6A7A9AA03AB01AD02AC000FABAAA8A5 + A09992877A6A58483D38360002350003363738000239013A023B023C013D023E + 023F0240024102420343024402450246034702480249024A024B034C024D024E + 044F025002510452055304540655055609570756045508540553035202510550 + 034F054E024D034C024B034A000002F802F703F603F502F403F303F202F102F0 + 03EF01EE03ED02EC02EB01EA02E90036E8E7E6E5E4E2E1E0DFDDDAD8D6D3D0CD + C9C5C1BDB9B4AFAAA5A09B958F89847F79746E69645F5A56514E4D4E535A6370 + 7D84888E9599039C029B00049A97928B02870189028B018902860005888B8F92 + 95000696029702980199039A029C00049D9E9FA002A20003A3A4A50004A601A7 + 02A802A90012A8A7A5A39F9A948C82766B60554B423C3938023900043A3B3C3D + 023E013F0240014102420243024402450246034702480249024A024B034C024D + 034E024F0350035102520353035402550456075704580959025A0359035A0459 + 075806570256045503540353035203510450044F024E024D034C034B000002F8 + 03F703F603F502F403F302F202F103F002EF02EE02ED02EC03EB01EA01E902E8 + 0029E7E6E5E3E2E1DFDEDCD9D7D4D1CECBC7C4BFBBB7B2ADA8A39E98938D8883 + 7D78736E69645F5B56524F00024C000A4D525C6B767F88939A9D029E029D0004 + 9C9B9792029000049293949202900004919395970498039702980299049A019B + 029C019D019E039F01A102A203A30014A2A09F9E9C9996928D87807870665C53 + 4B45413E033C013D013E023F0003404142000243014402450146024702480249 + 024A024B034C024D024E024F0350025102520353035402550356025705580259 + 055A075B0B5C015D015C025D095C055B045A0559025804570256035502540553 + 025203510250024F034E024D024C024B000004F802F703F602F503F402F303F2 + 02F103F002EF02EE03ED02EC01EB01EA02E9002CE8E7E6E5E4E3E1E0DFDDDBD8 + D5D2D0CDC9C6C2BDB9B5B0ABA6A19C97918C87827D78736E6965605C5854504D + 024B00084F57606A7889979E02A0039E019D019B0499029A0199019807970296 + 05940195029601970196029502940395019406930013928F8B87827D77716B65 + 5F59544E494541403F00023E00083F40414243444546024701480249024A014B + 014C034D024E014F0250045102520253035403550256035703580359035A025B + 055C025D085E0F5F0160095F045E065D025C045B025A03590358025703560255 + 04540253035202510250034F024E014D034C000004F802F703F603F502F403F3 + 03F202F102F002EF03EE02ED02EC01EB02EA02E9003BE8E7E6E5E3E2E1E0DEDC + D9D7D4D1CECBC8C4C0BCB7B3AEAAA5A09B95908B86817D78736E6A65615D5956 + 53504D4C4D505662768B999F9E9C9A999700029602950294000D9392918F8D8C + 8B8A898887868400028302820008838586878482807D037C00047A7774720271 + 001072716F6B66615C57524E4B48464443410340014102420143024501470248 + 0004494A4B4C024D014E024F0150025102520253015403550356035703580459 + 025A025B035C035D035E055F05600661176206610460055F025E025D035C025B + 045A0259025803570356035501540253035202510250014F024E034D014C0000 + 01F903F803F703F603F502F403F302F202F103F002EF03EE02ED02EC01EB01EA + 02E9002FE8E7E6E5E4E3E2E1DFDDDAD8D5D3D0CDCAC6C2BEBAB6B1ADA8A39E9A + 95908B86817D7874706B67635F5C595653504E00024D00045360758702900019 + 8C88858281807F7D7B79787674716E6C6B696766656462616000025F00096063 + 656663605D5958000257000655524F4D4C4D024E00074D4B4846444241000540 + 000F4142434445464748494A4B4C4D4E4F000250015101520253015402550156 + 025702580259035A035B035C035D045E035F0360046103620563066418650664 + 0463046203610360025F035E025D035C035B025A025902580357035601550254 + 0353025201510250024F034E014D000002F903F803F702F603F503F403F301F2 + 04F102F002EF03EE02ED02EC01EB01EA02E901E802E60031E5E3E2E1DFDEDCD9 + D7D5D2CECCC8C4C1BDB9B4B0ACA7A29E9994908B86827E7975706D6965625F5C + 595654514F50545F6B00027300166E686461605E5C5B59575553514F4D4C4A48 + 47464544024301420141024200074445464543424000043F013E023D00033C3D + 3E00063F024000164142434445464748494A4B4C4D4E4F505152535455560257 + 02580159025A015B025C025D035E045F02600461046203630464046504660967 + 106809670666046503640363036202610260035F025E025D045C025B025A0259 + 025803570156025502540153025202510350024F024E000003F903F803F703F6 + 02F503F402F302F203F103F002EF02EE02ED03EC0004EBEAE9E802E7002DE6E4 + E3E2E0DFDDDBD8D6D3D0CDCAC7C3BFBCB8B4AFABA6A29D9995908B87837F7B76 + 736F6B6865625F5C5A5855000253001655595B5A5753514E4D4C4A4948464544 + 4241403F3E3D023C013B033A0539013A013B063A033B033C00063D3E3F404142 + 02430145024601480149024A000E4B4D4E4F50515253545556575859025A015B + 015C025D015E025F0260026102620363046402650466046704680769086A136B + 096A0469036805670266036503640163036203610260035F025E025D025C025B + 025A0259035801570256015502540253025202510250034F000001FA03F902F8 + 04F702F603F502F403F302F203F102F002EF03EE02ED02EC01EB02EA0043E9E8 + E7E6E5E3E2E1E0DEDCD9D7D5D2CFCCC9C6C2BFBBB7B3AFAAA6A19D9994908C88 + 84807C7975716E6B686663615E5C5A585756555352504E4D4B4A494847464544 + 4300024201410240023F013E033D083C033D023E023F02400004414243440245 + 01470148024900104A4B4C4D4E4F5051535455565758595A025B00045C5D5E5F + 0260016102620163026402650266026703680469056A056B076C086D126E066D + 076C046B046A0369036802670366036502640263026203610260025F025E025D + 025C025B025A0159025802570256015503540253025201510250024F000001FA + 04F902F803F703F603F502F403F303F202F102F003EF02EE02ED01EC01EB02EA + 02E90041E8E7E6E4E3E2E1DFDDDBD9D6D4D1CECBC8C5C1BEBAB6B2AEAAA5A29E + 9995918E8A86827F7B7875726F6C6A676563615F5D5B59585655535251504F4E + 4D4C4B4A49000248014702460245014403430A42014302440245024600034748 + 4900024A00124B4C4D4E4F505152535455565758595A5B5D025E00065F606162 + 636402650166026701680269026A036B046C046D036E086F09700E7100037071 + 700002710770056F056E046D036C036B046A0269036803670166036502640263 + 026202610260025F025E025D015C025B025A0259015802570256025502540253 + 015202510250014F000002FA03F904F801F704F603F502F402F303F202F103F0 + 02EF02EE02ED02EC01EB02EA0045E9E8E7E6E5E3E2E1E0DEDCDAD8D5D3D0CDCB + C7C4C1BDBAB6B2AEAAA6A29E9B97938F8B8885817E7B787673706E6C6A686664 + 62605F5D5C5A595857565554535251504F4E4D00024C024B014A03490A480149 + 024A024B024C00034D4E4F00025000165152535455565758595A5B5C5D5E5F60 + 6162636465660267000368696A00026B026C026D026E026F0370037106720973 + 14740B73067203710570036F036E036D036C026B036A02690368026702660265 + 02640263026202610260025F015E025D025C015B025A02590258025702560155 + 02540253015202510250000003FA03F903F803F702F603F503F402F303F202F1 + 03F001EF03EE03ED01EC01EB02EA0041E9E8E7E6E4E3E2E1DFDDDBD9D7D5D2CF + CDCAC7C4C0BDBAB6B2AEABA7A3A09C9995918E8B8784817F7C79777573716F6D + 6B696765646361605F5E5D5C5B5958575600025500035453520002510250024F + 094E034F0250015102520003535455000256000E5758595A5B5C5D5E5F606162 + 63640265016601680269016A016B026C00036D6E6F0002700271027202730374 + 047506761D770776077503740373047203710370036F036E026D046C026B016A + 0269036802670266026502640163026202610160025F035E015D025C025B025A + 0159025802570156025502540153025202510150000004FA03F903F802F703F6 + 03F503F402F302F203F102F003EF02EE02ED01EC01EB02EA0041E9E8E7E6E5E4 + E3E2E0DFDDDBD8D6D4D2CFCCCAC6C3C0BDB9B6B2AFACA8A5A19E9B9794918D8B + 888583807E7B7977767472706E6C6B6A68676665646362605F5E5D00025C0004 + 5B5A595802570256065502540555025601570158025900035A5B5C00025D000A + 5E5F606162636465666702680006696A6B6C6D6E026F01700271000372737400 + 02750276027703780679077A087B0F7A08790678047703760475037403730272 + 03710370026F036E036D026C016B026A03690268026701660265026402630262 + 01610260025F025E025D015C025B025A02590158025701560255015402530252 + 0251000005FA02F903F803F703F602F503F403F302F203F102F002EF03EE02ED + 01EC01EB02EA0040E9E8E7E6E5E4E3E1E0DEDCDAD8D6D4D1CECCC9C6C3C0BDBA + B6B3B0ADAAA6A3A09D999693918E8B89868482807E7C7A7877757372716F6E6D + 6C6B6A6867666564026300046261605F025E025D025C045B015A055B025C025D + 015E025F000360616200026300096465666768696A6B6C00026D016E016F0270 + 00057172737475000276027701780279017A047B037C067D0F7E0B7D087C057B + 037A0579047803770376037502740273037202710370026F036E026D016C026B + 026A0269036801670266026502640263016202610260015F025E025D015C025B + 015A025902580257015601550254025301520251000006FA02F903F803F703F6 + 02F503F402F303F202F103F001EF03EE02ED01EC02EB02EA0043E9E8E7E5E4E3 + E2E1DFDDDBDAD7D5D3D1CECCC9C6C4C0BEBAB7B4B2AFABA8A5A29F9C99979492 + 908D8B89878583817F7E7C7A79777675747271706F6E6D6C6B6A696867000266 + 0165026401630562026106620263026401650166026701680169026A00036B6C + 6D00026E00046F70717202730003747576000277000378797A00027B027C027D + 027E037F0480088103820A810A80047F057E057D037C037B047A037903780377 + 0276027503740273037202710270026F026E026D026C026B026A036901680267 + 0166026502640263016202610160025F025E015D025C025B025A015901580257 + 025601550254025301520151000002FB04FA03F903F803F702F603F502F403F3 + 02F203F103F002EF01EE03ED01EC01EB02EA003DE9E8E7E6E5E4E3E2E1DFDDDB + D9D7D5D3D0CECCC9C7C4C1BEBBB9B6B3B0ADAAA8A5A29F9D9A989693918F8D8B + 8A8886848281807E7D7C7A797877767574000272000571706F6E6D00026C016B + 026A036909680269026A026B016C026D016E026F017002710005727374757600 + 02770178027900037A7B7C00027D027E017F028001810382038305840C850984 + 0683048204810580047F037E037D037C037B037A027904780277027602750274 + 0373027202710270026F026E016D036C026B016A026902680267026601650264 + 0163026202610160025F025E015D025C015B025A025902580157015602550154 + 02530252000001FC03FB02FA04F903F802F703F603F503F402F303F202F103F0 + 02EF02EE02ED01EC01EB02EA003EE9E8E7E6E5E4E3E2E0DEDDDBD9D7D5D3D1CE + CCCAC7C5C2BFBDBAB8B5B2AFADAAA8A5A3A09E9C9997969492908E8D8B898886 + 85848281807F7E7D7C7B797802770003767574000273017202710270036F026E + 076F0270027101720273017402750176027701780179027A017B017C027D027E + 017F018002810182028302840285038603871188068706860485038404830482 + 04810380027F037E037D037C037B037A03790178037701760275037402730272 + 01710370026F016E026D026C026B026A01690268016702660265026401630262 + 01610260015F025E025D015C025B025A01590258025701560255015402530152 + 000001FC03FB03FA03F903F803F703F603F502F403F302F202F103F002EF02EE + 02ED01EC02EB01EA01E902E8003FE7E6E5E3E2E1E0DEDDDBD9D7D5D3D1CFCDCB + C8C5C3C1BEBCB9B7B4B2AFADABA8A6A4A2A09E9C9A9897959392908E8D8B8A89 + 88878584838281807F7E7D7C7B00027A01790278027703760875037602770378 + 0179027A017B027C017D027E017F028001810282028301840185028601870288 + 0389048A038B0A8C078B048A0589048803870386048503840383028203810280 + 037F037E037D047C017B037A0279027802770276027502740273027202710270 + 026F016E026D026C026B016A0269026802670166016502640263026201610260 + 015F025E025D015C025B025A0159025801570256015502540253000002FC03FB + 03FA03F903F803F703F603F502F403F302F202F103F002EF02EE01ED02EC02EB + 01EA01E902E80039E7E6E4E3E2E1E0DEDCDBD9D7D5D4D2CFCDCBC9C7C5C2C0BE + BCB9B7B5B3B0AEABAAA8A6A4A2A09E9D9B9A989795949291908F8E8C8B8A8988 + 870002850004848382810280017F027E027D047C067B037C027D037E027F0280 + 018102820283018402850186028702880189028A028B028C038D048E0D8F068E + 038D038C048B048A0389038803870386038503840283028202810280037F037E + 037D027C037B027A0279017803770276017502740273027202710270016F026E + 026D026C016B026A0269016802670266026501640263016202610160025F025E + 015D025C025B015A0259025801570156025502540153000002FC04FB03FA03F9 + 02F804F703F602F503F402F303F201F103F003EF02EE01ED02EC02EB003EEAE9 + E8E7E6E5E4E3E2E1DFDEDCDBD9D7D6D4D2D0CECCCAC8C6C4C1BFBDBBB9B7B5B3 + B1AFADABAAA8A6A4A3A1A09E9D9B9A99979695949391908F8E8D8C8B028A0004 + 898887860285028402830582048103820283038402850286028703880189028A + 018B028C028D038E028F029005910D9206910390038F028E048D048C038B028A + 0289048801870386038502840283028202810380037F027E037D027C027B027A + 0279027802770276027502740173027202710270016F026E026D026C016B026A + 0269016802670266016502640263016202610260015F025E015D025C025B015A + 015902580257015602550254000004FC03FB02FA03F903F804F702F603F502F4 + 03F303F202F103F001EF03EE01ED01EC03EB003DEAE9E8E7E6E5E4E3E2E1E0DE + DDDBD9D8D6D5D3D1CFCDCBC9C7C5C3C1BFBEBCB9B7B6B4B3B1AFADACAAA9A7A6 + A4A3A1A09F9D9C9B9A999896959493929100029000048F8E8D8C028B028A0289 + 0588048705880389028A028B028C038D028E018F029003910392039303940295 + 0194089508940393039203910290048F038E038D028C028B038A038902880187 + 0386028502840283028203810280037F027E037D027C017B037A027901780277 + 0276027502740173027202710170026F026E026D016C026B026A016902680267 + 0266016502640163026201610260025F015E025D015C025B025A025901580157 + 025602550154000001FD03FC03FB03FA03F902F804F703F603F502F403F303F2 + 02F102F001EF03EE01ED02EC02EB01EA01E902E80039E7E6E5E4E3E2E1E0DEDD + DBDAD8D7D5D4D2D0CECCCBC9C7C6C4C2C0BEBCBBB9B8B6B5B3B1AFAEACABAAA9 + A7A6A5A3A2A1A09F9E9C9B9A999897000296000395949300029201910290028F + 058E068D048E038F029003910392029303940395039604970B98079703960395 + 03940393029203910290038F038E028D028C028B038A02890188038702860285 + 02840283028202810280037F027E037D027C027B017A03790278017702760275 + 01740273027201710270026F026E026D016C026B016A02690268026701660265 + 01640263026202610160015F025E025D025C015B015A02590258015701560355 + 000001FD03FC03FB04FA03F903F803F703F603F502F403F302F202F102F003EF + 02EE01ED01EC03EB0005EAE9E8E7E60002E50037E4E3E2E1E0DFDDDCDAD9D7D6 + D5D3D1CFCECCCBC9C7C6C4C2C0BFBDBCBAB9B8B6B4B3B2B0AFAEACABAAA9A8A7 + A6A5A3A2A1A09F9E9D9C9B00029A019902980197029602950494039302920693 + 039403950396049703980399079A059B019A029B089A02990398039703960395 + 02940293039202910290028F028E028D028C038B028A01890388018703860185 + 02840283038202810280027F037E027D027C027B027A01790278027702760275 + 01740273017202710270026F026E016D026C026B016A02690168026702660165 + 02640263016202610260015F025E015D025C025B015A02590158025701560255 + 000001FD03FC05FB03FA03F902F804F703F602F503F402F303F202F102F003EF + 02EE01ED01EC03EB0004EAE9E8E702E60031E5E4E3E2E1E0DFDEDCDBD9D8D7D5 + D4D2D1CFCECCCBC9C8C6C5C3C1C0BFBDBCBBB9B8B7B5B4B3B2B1AFAEADACABAA + A9A8A70002A50006A4A3A2A1A09F029E019D029C029B029A03990B980599039A + 069B049C0A9D039E049D079C029B039A02990298039702960395029402930292 + 02910290028F028E028D028C028B028A02890288028702860285028402830282 + 02810280027F037E027D017C027B027A02790178027702760275027402730172 + 02710170026F026E026D026C016B026A02690168026701660265026401630262 + 02610160025F025E025D015C015B025A0259015802570256000002FD04FC03FB + 03FA03F903F803F703F604F501F403F303F202F102F003EF02EE01ED01EC02EB + 02EA0003E9E8E70002E60030E5E4E3E2E1E0DFDEDDDCDAD9D7D6D4D3D2D0CFCE + CCCBC9C8C6C5C4C2C1C0BFBDBCBBBAB8B7B6B5B4B3B2B1B0AFAEADAC02AA0004 + A9A8A7A602A501A402A301A201A102A0039F039E0E9D049E0A9F0DA0059F049E + 049D039C029B029A0299039801970296029502940293029202910290028F028E + 028D028C028B028A0289028801870286028501840383028202810280037F027E + 027D027C027B017A0279017802770276027502740173027202710270016F026E + 026D016C026B026A0169026802670166026502640163026202610160025F015E + 025D025C015B025A0159025801570256000004FD03FC02FB05FA02F903F803F7 + 04F602F502F403F302F203F102F003EF02EE01ED01EC03EB0003EAE9E80002E7 + 0006E6E5E4E3E2E102E0001EDFDDDCDBD9D8D7D6D4D3D2D1CFCECDCCCAC9C8C6 + C5C4C3C2C0BFBEBDBCBA02B90004B8B7B5B402B30003B1B0AF0002AE0003ADAC + AB0002AA01A902A801A701A602A503A403A304A203A101A206A10EA208A305A2 + 05A102A0059F029E029D029C039B029A02990198029702960295029402930292 + 02910290028F028E028D018C028B028A02890288018702860285038401830282 + 02810280027F037E017D027C027B027A01790278027702760275017402730272 + 02710170026F026E016D026C026B026A01690268016702660265016402630262 + 01610260015F025E025D015C025B015A025902580257000004FD04FC04FB02FA + 03F903F803F703F603F502F403F302F202F103F002EF03EE01ED01EC02EB02EA + 01E901E802E70005E6E5E4E3E20002E1002BE0DFDEDDDCDBD9D8D7D6D5D4D2D1 + D0CFCDCCCBCAC9C8C6C5C4C3C2C1C0BFBEBDBCBBBAB9B8B7B6B5B4B3B20002B1 + 01B001AF02AE01AD01AC02AB01AA02A903A804A706A61CA505A405A302A202A1 + 03A0029F029E039D029C029B029A019902980297029602950294019302920391 + 0190028F028E028D028C018B038A018902880287028601850284028302820281 + 0280027F027E027D027C027B017A027902780277017602750274027302720271 + 0170026F016E026D026C026B016A026902680167016602650264026301620261 + 0160025F025E025D015C025B015A025901580257000005FD03FC04FB03FA02F9 + 04F803F702F603F502F403F303F202F103F001EF03EE02ED01EC01EB03EA01E9 + 01E802E70004E6E5E4E302E20003E1E0DF0002DE001DDDDBDAD9D8D7D6D5D4D2 + D1D0CFCECDCCCBCAC9C8C6C5C4C3C2C1C0BFBE0002BD0007BCBBBAB9B8B7B600 + 02B501B401B302B201B101B002AF02AE02AD02AC04AB03AA10A90BA804A705A6 + 03A503A402A302A202A103A0029F029E029D029C019B029A0299029802970196 + 029502940293029202910190028F028E028D028C028B028A0289018802870186 + 038502840183028202810280027F027E027D027C027B017A0279027801770276 + 027502740273027201710270016F026E026D026C026B016A0169026802670266 + 016502640263016202610160025F025E015D025C015B025A02590258000006FD + 03FC03FB04FA02F903F803F704F602F503F402F303F202F103F001EF03EE01ED + 02EC02EB02EA01E902E80004E7E6E5E402E30003E2E1E00002DF0015DEDDDCDB + DAD9D8D7D6D5D4D3D2D1D0CFCECDCCCBC90002C80008C7C6C5C4C3C2C1C002BF + 0005BEBDBCBBBA0002B901B801B702B601B501B402B302B201B102B003AF03AE + 05AD07AC0DAB04AA03A905A803A702A602A503A402A302A202A102A0029F029E + 019D029C029B019A0299029802970196029502940293029202910290028F028E + 018D028C028B028A0189028802870186028502840283028202810280017F027E + 027D027C027B027A0279017802770276027501740273027201710270026F026E + 026D016C026B026A0169026801670266026502640163026201610260025F015E + 025D025C015B025A01590258000006FD04FC03FB04FA03F902F803F703F602F5 + 03F403F302F202F103F001EF04EE02ED01EC02EB01EA02E901E801E702E601E5 + 02E40003E3E2E10002E00015DFDEDDDCDBDAD9D8D7D6D5D4D3D2D1D0CFCECDCC + CB0002CA0007C9C8C7C6C5C4C30002C20004C1C0BFBE02BD01BC02BB01BA01B9 + 02B801B702B602B501B402B302B203B103B004AF06AE07AD08AC04AB02AA01A9 + 02AA02A902A802A702A603A502A402A302A201A102A0019F029E029D019C029B + 019A0299039801970296039501940293029201910290028F028E028D018C028B + 028A0189028802870286018502840283028202810280017F037E017D027C027B + 027A0279017802770276027502740173027202710170026F026E026D026C026B + 016A0269026801670266016502640263026201610260025F015E015D025C025B + 025A02590001} + PopupMenu = pmTrayIcon + Visible = False + OnMouseDown = ImageMouseDown + OnMouseMove = ImageMouseMove + OnMouseUp = ImageMouseUp + end + object lbVersion: TLabel + Left = 320 + Top = 180 + Width = 53 + Height = 15 + Caption = 'version' + Color = clBlack + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWhite + Font.Height = -15 + Font.Name = '‚l‚r ‚o–¾’©' + Font.Style = [fsBold] + ParentColor = False + ParentFont = False + end + object Memo: TMemo + Left = 0 + Top = 0 + Width = 105 + Height = 228 + Align = alLeft + PopupMenu = pmTrayIcon + TabOrder = 0 + end + object Panel1: TPanel + Left = 0 + Top = 228 + Width = 427 + Height = 82 + Align = alBottom + TabOrder = 1 + object edFound: TEdit + Left = 4 + Top = 8 + Width = 454 + Height = 20 + BorderStyle = bsNone + Color = clBtnFace + TabOrder = 0 + end + object edWord: TEdit + Left = 4 + Top = 28 + Width = 454 + Height = 20 + BorderStyle = bsNone + Color = clBtnFace + TabOrder = 1 + end + object edPrev: TEdit + Left = 4 + Top = 48 + Width = 454 + Height = 20 + BorderStyle = bsNone + Color = clBtnFace + TabOrder = 2 + end + end + object btnOK: TButton + Left = 192 + Top = 204 + Width = 125 + Height = 21 + Caption = 'OK' + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = '‚l‚r ‚oƒSƒVƒbƒN' + Font.Style = [] + ModalResult = 1 + ParentFont = False + TabOrder = 2 + Visible = False + OnClick = btnOKClick + end + object MainMenu: TMainMenu + Left = 80 + Top = 40 + object File1: TMenuItem + Caption = '&File' + object miHook: TMenuItem + Caption = '&Hook' + ShortCut = 16456 + OnClick = miHookClick + end + object miUnhook: TMenuItem + Caption = '&Unhook' + Enabled = False + ShortCut = 16469 + OnClick = miUnhookClick + end + object N2: TMenuItem + Caption = '-' + end + object miConfig: TMenuItem + Caption = '&Config' + OnClick = miConfigClick + end + object N6: TMenuItem + Caption = '-' + end + object miDdeTest: TMenuItem + Caption = '&Dde Test' + OnClick = miDdeTestClick + end + object miTest: TMenuItem + Caption = 'T&est' + OnClick = miTestClick + end + object N1: TMenuItem + Caption = '-' + end + object miExit: TMenuItem + Caption = 'E&xit' + OnClick = miExitClick + end + end + end + object pmTrayIcon: TPopupMenu + AutoHotkeys = maManual + AutoPopup = False + OnPopup = pmTrayIconPopup + Left = 144 + Top = 88 + object miInstallMODI: TMenuItem + Caption = 'MODI‚̃Cƒ“ƒXƒg[ƒ‹....' + Visible = False + end + object miGroup: TMenuItem + Caption = 'Ž«‘ƒOƒ‹[ƒv(&G)' + end + object miClickOnly: TMenuItem + Caption = '‰EƒNƒŠƒbƒNŒŸõ(&N)' + OnClick = miClickOnlyClick + end + object miIncSearch: TMenuItem + Caption = 'ƒCƒ“ƒNƒŠƒƒ“ƒ^ƒ‹ƒT[ƒ`(&I)' + Visible = False + OnClick = miIncSearchClick + end + object miEnablePopup: TMenuItem + Caption = 'ƒ|ƒbƒvƒAƒbƒvŒŸõ‚ð—LŒø(&E)' + OnClick = miEnablePopupClick + end + object miOCRText: TMenuItem + Caption = '”FŽ¯ƒeƒLƒXƒg‚Ì•\Ž¦(&T)' + Visible = False + OnClick = miOCRTextClick + end + object N4: TMenuItem + Caption = '-' + end + object miOption: TMenuItem + Caption = 'Ý’è(&O)...' + OnClick = miOptionClick + end + object miReadMe: TMenuItem + Caption = 'à–¾‘‚ð•\Ž¦(&M)' + OnClick = miReadMeClick + end + object miAbout: TMenuItem + Caption = 'ƒo[ƒWƒ‡ƒ“(&V)...' + OnClick = miAboutClick + end + object miCheckLatest: TMenuItem + Caption = 'ÅV”Å‚ÌŠm”F' + OnClick = miCheckLatestClick + end + object N5: TMenuItem + Caption = '-' + end + object miClose: TMenuItem + Caption = 'ƒƒjƒ…[‚ð•Â‚¶‚é(&C)' + OnClick = miCloseClick + end + object miReload: TMenuItem + Caption = 'DokoPop!‚̍ċN“®(&R)' + OnClick = miReloadClick + end + object miExit2: TMenuItem + Caption = 'DokoPop!‚̏I—¹(&X)' + OnClick = miExitClick + end + end + object BootTimer: TTimer + Enabled = False + Interval = 1500 + OnTimer = BootTimerTimer + Left = 128 + Top = 144 + end + object TestTimer: TTimer + Enabled = False + Interval = 100 + OnTimer = TestTimerTimer + Left = 208 + Top = 161 + end + object tmMenuClose: TTimer + Enabled = False + Interval = 10 + OnTimer = tmMenuCloseTimer + Left = 40 + Top = 168 + end + object tmNotify: TTimer + Enabled = False + OnTimer = tmNotifyTimer + Left = 40 + Top = 273 + end + object tmPopup: TTimer + Enabled = False + Interval = 100 + OnTimer = tmPopupTimer + Left = 96 + Top = 273 + end + object tmMouseMove: TTimer + Enabled = False + Interval = 100 + OnTimer = tmMouseMoveTimer + Left = 144 + Top = 273 + end + object tmMODIInstallCheck: TTimer + Enabled = False + Interval = 3000 + OnTimer = tmMODIInstallCheckTimer + Left = 192 + Top = 276 + end + object tmMODINotify: TTimer + Enabled = False + OnTimer = tmMODINotifyTimer + Left = 232 + Top = 273 + end +end diff --git a/DCHookTest/DCHookMain.h b/DCHookTest/DCHookMain.h new file mode 100644 index 0000000..7f86722 --- /dev/null +++ b/DCHookTest/DCHookMain.h @@ -0,0 +1,197 @@ +//--------------------------------------------------------------------------- +#ifndef DCHookMainH +#define DCHookMainH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include "../DCHook/DCHook.h" +#include +#include +#include +//--------------------------------------------------------------------------- +#include "Util.h" +#include "StringLib.h" + +#define WM_POPUP (WM_APP+0x200) +#define WM_NOTIFYICON (WM_APP+0x201) +#define WM_TOGGLE (WM_APP+0x202) +#define UM_SHORTCUT (WM_APP+33) +#define WM_MOVESEND (WM_APP+0x208) // DCH_MOVESEND‚Ì‘ã‚í‚è‚ÉPostMessage‚Å‘—‚é + +class TDCHookMainForm : public TForm +{ +typedef TForm super; +__published: // IDE ŠÇ—‚̃Rƒ“ƒ|[ƒlƒ“ƒg + TMainMenu *MainMenu; + TMenuItem *File1; + TMenuItem *miExit; + TMenuItem *miHook; + TMenuItem *miUnhook; + TMenuItem *N1; + TMenuItem *miTest; + TMemo *Memo; + TSplitter *Splitter1; + TPaintBox *PaintBox; + TPanel *Panel1; + TMenuItem *miDdeTest; + TEdit *edFound; + TEdit *edWord; + TEdit *edPrev; + TPopupMenu *pmTrayIcon; + TMenuItem *miExit2; + TMenuItem *miAbout; + TMenuItem *N5; + TMenuItem *N6; + TMenuItem *miOption; + TMenuItem *miGroup; + TMenuItem *N4; + TMenuItem *miEnablePopup; + TTimer *BootTimer; + TImage *Image; + TTimer *TestTimer; + TButton *btnOK; + TLabel *lbVersion; + TMenuItem *miClickOnly; + TMenuItem *miReload; + TMenuItem *miClose; + TTimer *tmMenuClose; + TTimer *tmNotify; + TTimer *tmPopup; + TMenuItem *miReadMe; + TMenuItem *miIncSearch; + TTimer *tmMouseMove; + TMenuItem *N2; + TMenuItem *miConfig; + TMenuItem *miInstallMODI; + TTimer *tmMODIInstallCheck; + TTimer *tmMODINotify; + TMenuItem *miCheckLatest; + TMenuItem *miOCRText; + void __fastcall miHookClick(TObject *Sender); + void __fastcall miUnhookClick(TObject *Sender); + void __fastcall miExitClick(TObject *Sender); + void __fastcall miTestClick(TObject *Sender); + void __fastcall miDdeTestClick(TObject *Sender); + void __fastcall FormCreate(TObject *Sender); + void __fastcall miAboutClick(TObject *Sender); + void __fastcall miOptionClick(TObject *Sender); + void __fastcall pmTrayIconPopup(TObject *Sender); + void __fastcall miEnablePopupClick(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall BootTimerTimer(TObject *Sender); + void __fastcall ImageMouseUp(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall FormKeyPress(TObject *Sender, char &Key); + void __fastcall TestTimerTimer(TObject *Sender); + void __fastcall btnOKClick(TObject *Sender); + void __fastcall ImageMouseDown(TObject *Sender, TMouseButton Button, + TShiftState Shift, int X, int Y); + void __fastcall ImageMouseMove(TObject *Sender, TShiftState Shift, int X, + int Y); + void __fastcall miClickOnlyClick(TObject *Sender); + void __fastcall miReloadClick(TObject *Sender); + void __fastcall miCloseClick(TObject *Sender); + void __fastcall tmMenuCloseTimer(TObject *Sender); + void __fastcall tmNotifyTimer(TObject *Sender); + void __fastcall tmPopupTimer(TObject *Sender); + void __fastcall miReadMeClick(TObject *Sender); + void __fastcall miIncSearchClick(TObject *Sender); + void __fastcall tmMouseMoveTimer(TObject *Sender); + void __fastcall miConfigClick(TObject *Sender); + void __fastcall tmMODIInstallCheckTimer(TObject *Sender); + void __fastcall tmMODINotifyTimer(TObject *Sender); + void __fastcall miCheckLatestClick(TObject *Sender); + void __fastcall miOCRTextClick(TObject *Sender); +private: // ƒ†[ƒU[éŒ¾ + //void __fastcall IdleHandler(TObject *sender, bool &done); + + bool BootUp; + bool Capturing; + POINT CapPoint; + class TDCHookLoader *hDll; + + int SavedWidth; + + // Popup Configuration // + bool GroupOpen; + AnsiString GroupName; + bool CtrlClose; + bool IgnoreJ; + bool Banner; + int CaptureMode; // 0:conventional 1:use AMODI + bool AMODIAvail; // AMODI available or not + AnsiString AMODIPath; + bool MouseIncSrch; +public: // ƒ†[ƒU[éŒ¾ + __fastcall TDCHookMainForm(TComponent* Owner); + void EvCopyData(TMessage&); + void InitAMODI(); + void Start(); + void MenuClosed(); + void ShowNotify(); + void EvToggle( TMessage & ); + void EvShortcut( TMessage & ); + void EvGetVersion( TMessage & ); + + // Hooking // + bool Hook(); + void Unhook(); + + // Popup Control // + POINT CursorPoint; + void SetupConfig(); + void SetupConfig2(); + void SetupAMODI(); + bool EnablePopup; + bool DoPopup( const tchar *text, const tchar *prevtext, bool movesend ); + tchar *PopupText; + int PopupLoc; + bool PopupMoveSend; + void EvPopup(TMessage &); + int DoPopupRetry; + void EvMoveSend(TMessage &); + void EvMoveSend(bool enable); + + // Tray Icon Control // + void RegisterTrayIcon( bool flag ); + void EvNotifyIcon( TMessage & ); + void SaveConfig(); + void EnableClickOnly( bool enable ); + void DokoPopMenu( bool all ); + + // PDIC Control // + void __fastcall miDicGroup(TObject *Sender); + void OpenDicGroup( const char *name ); + TDdeClientConv *OpenPdic( const char *topic ); + void ClosePdic( TDdeClientConv *dde ); + + // WM_COPYDATA control // + HWND FindPdic( ); + LRESULT SendCopyData( HWND hwnd, int message, const char *str ); + + void NotifyAMODI(); + + void Reboot(); + +protected: + BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, EvCopyData) + VCL_MESSAGE_HANDLER(WM_POPUP, TMessage, EvPopup) + VCL_MESSAGE_HANDLER(WM_MOVESEND, TMessage, EvMoveSend) + VCL_MESSAGE_HANDLER(WM_NOTIFYICON, TMessage, EvNotifyIcon) + VCL_MESSAGE_HANDLER(WM_TOGGLE, TMessage, EvToggle) + VCL_MESSAGE_HANDLER(UM_SHORTCUT, TMessage, EvShortcut) + VCL_MESSAGE_HANDLER(WM_GET_VERSION, TMessage, EvGetVersion) + END_MESSAGE_MAP(TForm) +}; +//--------------------------------------------------------------------------- +extern PACKAGE TDCHookMainForm *DCHookMainForm; +//--------------------------------------------------------------------------- + +extern bool Reboot; + +#endif + diff --git a/DCHookTest/DCHookTest.bpr b/DCHookTest/DCHookTest.bpr new file mode 100644 index 0000000..825bde7 --- /dev/null +++ b/DCHookTest/DCHookTest.bpr @@ -0,0 +1,634 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=1 +AutoIncBuild=1 +MajorVer=2 +MinorVer=0 +Release=23 +Build=77 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1041 +CodePage=932 + +[Version Info Keys] +CompanyName=Doko Pop Project +FileDescription=DokoPop for Windows +FileVersion=2.0.23.77 +InternalName=DokoPop +LegalCopyright=Copyright (c) DokoPopProject +LegalTrademarks= +OriginalFilename=DKPP.EXE +ProductName=DokoPop +ProductVersion=2.0 +Comments= + +[Excluded Packages] +$(BCB)\Bin\dclite50.bpl=Borland Integrated Translation Environment + +[HistoryLists\hlIncludePath] +Count=16 +Item0=K:\Borland\CBuilder5\Bin\;$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +Item1=K:\Borland\CBuilder5\Bin;$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +Item2=$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +Item3=R:\Borland\CBuilder5\Bin\;C:\Borland\CBuilder5\Bin\;$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +Item4=R:\Borland\CBuilder5\Bin;C:\Borland\CBuilder5\Bin\;$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +Item5=C:\Borland\CBuilder5\Bin\;$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +Item6=C:\Borland\CBuilder5\Bin;$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +Item7=..\..\Filer;$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +Item8=$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl;D:\units\ +Item9=$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl;..\..\units +Item10=$(BCB)\include;$(BCB)\include\vcl;..\..\units +Item11=$(BCB)\include;$(BCB)\include\vcl;..\..\units +Item12=$(BCB)\include;$(BCB)\include\vcl;..\..\units;$(BCB)\include\vcl;..\..\units +Item13= +Item14=$(BCB)\include;$(BCB)\include\vcl +Item15=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=13 +Item0=K:\Borland\CBuilder5\Bin\;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item1=K:\Borland\CBuilder5\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item2=$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item3=R:\Borland\CBuilder5\Bin\;C:\Borland\CBuilder5\Bin\;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item4=R:\Borland\CBuilder5\Bin;C:\Borland\CBuilder5\Bin\;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item5=C:\Borland\CBuilder5\Bin\;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item6=C:\Borland\CBuilder5\Bin;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item7=..\..\Filer;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +Item8=$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib;D:\units\ +Item9=$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib;..\..\units +Item10=$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib;..\..\units +Item11=$(BCB)\lib\obj;$(BCB)\lib;$(BCB)\lib +Item12= + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=10 +Item0=USE_UNICODE;DCHOOK +Item1=USE_UNICODE;DCHOOK;_DEBUG +Item2=USE_UNICODE;_DEBUG;DCHOOK +Item3=USE_UNICODE;UNICODE;_UNICODE;_DEBUG;DCHOOK +Item4=USE_UNICODE;_DEBUG +Item5=USE_UNICODE +Item6=_DEBUG +Item7=_DEBUG;USE_UNICODE +Item8=_UNICODE +Item9=DEBUG + +[HistoryLists\hlIntOutputDir] +Count=2 +Item0=obj +Item1=.\obj + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication= +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + + + diff --git a/DCHookTest/DCHookTest.cpp b/DCHookTest/DCHookTest.cpp new file mode 100644 index 0000000..40ac715 --- /dev/null +++ b/DCHookTest/DCHookTest.cpp @@ -0,0 +1,67 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop +USERES("DCHookTest.res"); +USEFORM("DCHookMain.cpp", DCHookMainForm); +USEUNIT("StringLib.cpp"); +USEFORM("PopupConfig.cpp", PopupConfigDlg); +USEUNIT("Util.cpp"); +USEFORM("Notify.cpp", NotifyForm); +USERC("icon.rc"); +USEUNIT("mustr.cpp"); +USEUNIT("HookDLl.cpp"); +USEUNIT("HookLoader.cpp"); +USEUNIT("DCHookLoader.cpp"); +USE("..\Diary.txt", File); +USEUNIT("prgprof.cpp"); +USEFORM("MODINotifyDlg.cpp", MODINotifyDialog); +USEUNIT("prgconfig.cpp"); +USEFORM("OCRTextFrm.cpp", OCRTextForm); +//--------------------------------------------------------------------------- +#include "prgconfig.h" +#include "DCHookMain.h" +//--------------------------------------------------------------------------- + +WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) +{ +#if __PROTO + SYSTEMTIME st; + GetSystemTime(&st); + if ( (st.wYear>=2016 && st.wMonth>=12) || st.wYear>=2017){ + int ret = MessageBox(NULL, "ŽŽì”Å‚ÌŽg—pŠúŒÀ‚ªØ‚ê‚Ü‚µ‚½BV‚µ‚¢DokoPop!‚ð“üŽè‚µ‚Ä‚­‚¾‚³‚¢", APPNAME, MB_YESNO); + if (ret != IDNO){ + ShowLatestVersion(); + return 0; + } + } +#endif + + HWND hwnd = FindPrev(); + if ( hwnd ){ + if (CheckVersion(hwnd)<0){ + // The older version already lauched. + MessageBox(NULL, "DokoPop!‚ª‚·‚Å‚É‹N“®‚µ‚Ä‚¢‚Ü‚·B\rŒÃ‚¢ƒo[ƒWƒ‡ƒ“‚ÌDokoPop!‚ðƒAƒ“ƒCƒ“ƒXƒg[ƒ‹‚µ‚Ä‚­‚¾‚³‚¢", APPNAME, MB_OK); + return 0; + } + MoveToTop( hwnd ); + return 0; + } + try + { + Application->Initialize(); + Application->Title = "DokoPop"; + Application->CreateForm(__classid(TDCHookMainForm), &DCHookMainForm); + Application->Run(); + } + catch (Exception &exception) + { + Application->ShowException(&exception); + } + if (Reboot){ + _WinExec(Application->ExeName.c_str(), SW_SHOW, 0); + } + return 0; +} +//--------------------------------------------------------------------------- + + diff --git a/DCHookTest/DCHookTest.dfm b/DCHookTest/DCHookTest.dfm new file mode 100644 index 0000000000000000000000000000000000000000..d29f0c2705e77939b7e4f8bbd7b71cdcb5a01b3c GIT binary patch literal 468 zcmY+A(N2Rf6ov~7kZtN7!7Jj8W;}wDHDKIEMs=5paFk|UyL2_qD-(DmU%(3=$$K53 z0ejK(Ki_};lhf}$B6z--dT2cQ)DR*O9$N$px%SNZ?p?#9GCq(GA4OPZfFy0xdmm9;vmH2Dva;^;9?O^NWZ~# z(=cUA$}{moV5bH(XvXMYPOWCi8m!}j74oDIWnA8t59O>$h}A2D0qRYGKikeUp}cx| zM{}0>5)uV-nSnewjOY&7HUb&)G}rI@)u`VgL*$UZ#x|k;06nVrKdl`5*igaR#FT;8 tZtqsQ%L5@+U0!L_G1xae|7Wq?rqVU(vo=CI>k@OaqpF4G#NBIDogYJBkMjTk literal 0 HcmV?d00001 diff --git a/DCHookTest/DCHookTest.h b/DCHookTest/DCHookTest.h new file mode 100644 index 0000000..4cee011 --- /dev/null +++ b/DCHookTest/DCHookTest.h @@ -0,0 +1,27 @@ +//--------------------------------------------------------------------------- +#ifndef DCHookTestH +#define DCHookTestH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TForm1 : public TForm +{ +__published: // IDE ŠÇ—‚̃Rƒ“ƒ|[ƒlƒ“ƒg + TMainMenu *MainMenu1; + TMenuItem *File1; + TMenuItem *Exit1; + TMenuItem *Hook1; + TMenuItem *Unhook1; + TMenuItem *N1; +private: // ƒ†[ƒU[éŒ¾ +public: // ƒ†[ƒU[éŒ¾ + __fastcall TForm1(TComponent* Owner); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TForm1 *Form1; +//--------------------------------------------------------------------------- +#endif diff --git a/DCHookTest/DCHookTest.mak b/DCHookTest/DCHookTest.mak new file mode 100644 index 0000000..9f0a76b --- /dev/null +++ b/DCHookTest/DCHookTest.mak @@ -0,0 +1,184 @@ +# --------------------------------------------------------------------------- +!if !$d(BCB) +BCB = $(MAKEDIR)\.. +!endif + +# --------------------------------------------------------------------------- +# IDE SECTION +# --------------------------------------------------------------------------- +# The following section of the project makefile is managed by the BCB IDE. +# It is recommended to use the IDE to change any of the values in this +# section. +# --------------------------------------------------------------------------- + +VERSION = BCB.05.03 +# --------------------------------------------------------------------------- +PROJECT = DCHookTest.exe +OBJFILES = DCHookTest.obj DCHookMain.obj StringLib.obj PopupConfig.obj Util.obj \ + Notify.obj +RESFILES = DCHookTest.res icon.res +MAINSOURCE = DCHookTest.cpp +RESDEPEN = $(RESFILES) DCHookMain.dfm PopupConfig.dfm Notify.dfm +LIBFILES = +IDLFILES = +IDLGENFILES = +LIBRARIES = Vclx50.lib vcl50.lib +PACKAGES = vcl50.bpi +SPARELIBS = vcl50.lib Vclx50.lib +DEFFILE = +# --------------------------------------------------------------------------- +PATHCPP = .; +PATHASM = .; +PATHPAS = .; +PATHRC = .; +DEBUGLIBPATH = $(BCB)\lib\debug +RELEASELIBPATH = $(BCB)\lib\release +USERDEFINES = +SYSDEFINES = NO_STRICT +INCLUDEPATH = ..\..\Filer;$(BCB)\Lib;$(BCB)\include;$(BCB)\include\vcl +LIBPATH = ..\..\Filer;$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib +WARNINGS= -w-par -w-8027 -w-8026 +# --------------------------------------------------------------------------- +CFLAG1 = -O2 -H=dchooktest.csm -Vx -Ve -X- -a4 -5 -b- -k- -vi -c -tW -tWM +IDLCFLAGS = +PFLAGS = -$Y- -$L- -$D- -v -JPHNE -M +RFLAGS = +AFLAGS = /mx /w2 /zn +LFLAGS = -D"" -aa -Tpe -GD -s +# --------------------------------------------------------------------------- +ALLOBJ = c0w32.obj sysinit.obj $(OBJFILES) +ALLRES = $(RESFILES) +ALLLIB = $(LIBFILES) $(LIBRARIES) import32.lib cp32mt.lib +# --------------------------------------------------------------------------- +!ifdef IDEOPTIONS + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +!endif + + + + + +# --------------------------------------------------------------------------- +# MAKE SECTION +# --------------------------------------------------------------------------- +# This section of the project file is not used by the BCB IDE. It is for +# the benefit of building from the command-line using the MAKE utility. +# --------------------------------------------------------------------------- + +.autodepend +# --------------------------------------------------------------------------- +!if "$(USERDEFINES)" != "" +AUSERDEFINES = -d$(USERDEFINES:;= -d) +!else +AUSERDEFINES = +!endif + +!if !$d(BCC32) +BCC32 = bcc32 +!endif + +!if !$d(CPP32) +CPP32 = cpp32 +!endif + +!if !$d(DCC32) +DCC32 = dcc32 +!endif + +!if !$d(TASM32) +TASM32 = tasm32 +!endif + +!if !$d(LINKER) +LINKER = ilink32 +!endif + +!if !$d(BRCC32) +BRCC32 = brcc32 +!endif + + +# --------------------------------------------------------------------------- +!if $d(PATHCPP) +.PATH.CPP = $(PATHCPP) +.PATH.C = $(PATHCPP) +!endif + +!if $d(PATHPAS) +.PATH.PAS = $(PATHPAS) +!endif + +!if $d(PATHASM) +.PATH.ASM = $(PATHASM) +!endif + +!if $d(PATHRC) +.PATH.RC = $(PATHRC) +!endif +# --------------------------------------------------------------------------- +$(PROJECT): $(IDLGENFILES) $(OBJFILES) $(RESDEPEN) $(DEFFILE) + $(BCB)\BIN\$(LINKER) @&&! + $(LFLAGS) -L$(LIBPATH) + + $(ALLOBJ), + + $(PROJECT),, + + $(ALLLIB), + + $(DEFFILE), + + $(ALLRES) +! +# --------------------------------------------------------------------------- +.pas.hpp: + $(BCB)\BIN\$(DCC32) $(PFLAGS) -U$(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -O$(INCLUDEPATH) --BCB {$< } + +.pas.obj: + $(BCB)\BIN\$(DCC32) $(PFLAGS) -U$(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -O$(INCLUDEPATH) --BCB {$< } + +.cpp.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(WARNINGS) -I$(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -n$(@D) {$< } + +.c.obj: + $(BCB)\BIN\$(BCC32) $(CFLAG1) $(WARNINGS) -I$(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -n$(@D) {$< } + +.c.i: + $(BCB)\BIN\$(CPP32) $(CFLAG1) $(WARNINGS) -I$(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -n. {$< } + +.cpp.i: + $(BCB)\BIN\$(CPP32) $(CFLAG1) $(WARNINGS) -I$(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -n. {$< } + +.asm.obj: + $(BCB)\BIN\$(TASM32) $(AFLAGS) -i$(INCLUDEPATH:;= -i) $(AUSERDEFINES) -d$(SYSDEFINES:;= -d) $<, $@ + +.rc.res: + $(BCB)\BIN\$(BRCC32) $(RFLAGS) -I$(INCLUDEPATH) -D$(USERDEFINES);$(SYSDEFINES) -fo$@ $< +# --------------------------------------------------------------------------- + + + + diff --git a/DCHookTest/DCHookTest.rc b/DCHookTest/DCHookTest.rc new file mode 100644 index 0000000..b8eeb55 --- /dev/null +++ b/DCHookTest/DCHookTest.rc @@ -0,0 +1 @@ +0 ICON "dkpps.ico" diff --git a/DCHookTest/DCHookTest.res b/DCHookTest/DCHookTest.res new file mode 100644 index 0000000000000000000000000000000000000000..0832256a5a6f98b497be4e58ab0543e19d835dcc GIT binary patch literal 2040 zcmchX&uddb5XZkUfv68`3I#!sKEy*6DYX_9FaBs+C~6z5R8N*-Ypu31#7gjF{uuv& z+#f>z6p!BQv4_(2GrL*ylBOyioOIso?96;;W_Pxdl)}yhW;sCL&qR9>pMtklD&wW- zG{qu?@52R!?KUx^sV(uRb~^~ZEaA4g-7W?z!h{QgZ>Y;Qp;oI^ZnYXgk^Gvyyxz&_ z_$OJp?~h-SMdu*1tTV7Nq$gQ65Rlhx-6M|?6_bW}LdPp1UBtkPpZ!IDWgY7KlWqV3 zzvpitKHo{*<41che?PuoVTk{|KHRUx{6BKtf^%)g!PwSElg=HE!DZ(T%I;8_Jdnn| zF&6*A7Hb&p6q;i6Q`uSUPtWlI< z9Bcq>H(aXJVcKl^vn1)5#UxunPrNTk1kLWmZejxb6zNNqK6s>ZyujLHMD{MC-QEfZTSRMEbrh{HNFimo2=eq ze?>;4nkK-AIjdMcV6$2pc0vk5N$ex!mR{;I{*Uq9_MUbE4SKh#xAn$%c5*M(6rEk8 z=0Us~af4@a9rQf@Gdwo5NxnT~lQXqW1Krg*d{=t8?FOy(c%G((+o> Ver.2.00 << + EMODI‘Ήž‚É‚æ‚èAƒ|ƒbƒvƒAƒbƒvŒŸõ‚ª‚Å‚«‚é‚Æ‚±‚낪‘‚¦‚½ + Eƒ}ƒEƒXˆÚ“®‚É‚æ‚éPDIC–{‘̂̃Cƒ“ƒNƒŠƒƒ“ƒ^ƒ‹ƒT[ƒ`‹@”\‚̒ljÁ + +>> Ver.1.23 << + EDDE‚Å‘—M‚·‚éƒf[ƒ^‚ÌŒ`Ž®‚ª³‚µ‚­Žw’肳‚ê‚Ä‚¢‚È‚©‚Á‚½(CF_TEXT->CF_UNICODETEXT) + +>> Ver.1.22 << + EƒNƒŠƒbƒN‚·‚é‘Ώۂ̃EƒBƒ“ƒhƒE‚ª”ñUnicode‚Å‚ ‚éê‡“®ì‚µ‚È‚©‚Á‚½ + +>> Ver.1.21 << + EŽ«‘ƒOƒ‹[ƒv‚Ì‘I‘ð‚ª³‚µ‚­“®ì‚µ‚È‚¢–â‘è‚ðC³ + +>> Ver.1.20 << + EPDIC/Unicode Ver.5.0.x‚ɑΉž + +>> Ver.1.15 << + EPDIC/Unicode Ver.0.83‚ɑΉž + Edialog‚̏o‚éêŠ‚ðDesktopCenter¨ScreenCenter (ƒ}ƒ‹ƒ`ƒ‚ƒjƒ^‘Ήž) + +>> Ver.1.14 << + EDokoPop!‚ÉŠÖ‚µ‚Ă͒ʏí‚̃o[ƒWƒ‡ƒ“”ԍ†‚ð•t‚¯‚邱‚Æ‚É‚µ‚½ + - DokoPop!‚̓À”łƐ³Ž®”Å‚ÌŽÀÛ“I‚ȈႢ‚ª–³‚¢‚½‚ß + - DokoPop!‚̓I[ƒvƒ“ƒ\[ƒX‚Å‚ ‚èAPDIC–{‘Ì‚Æ‚Í•Ê”z•z‚Å‚ ‚邽‚߁A + PDIC–{‘Ì‚Æ“¯Šú‚·‚éƒÀ”Å‚ÆŒ¾‚¤“K“–‚È‹æØ‚肪–³‚¢‚½‚ß + Eƒo[ƒWƒ‡ƒ“”ԍ†‚Ífor Win32”Å‚Æ‹¤’ʉ»iƒ\[ƒXƒR[ƒh‚ª“¯‚¶‚½‚߁j + * •¶‚̍Ōã‚Ì’PŒê‚ªƒqƒbƒg‚µ‚È‚©‚Á‚½iDokoPop!‚̍ŐV”Å‚ª•K—vj + yŒ´ˆöz + @Žæ“¾‚µ‚½•¶Žš—ñ‚̍Ōã‚ɃSƒ~‚ª•t‘®‚µ‚½‚±‚Æ‚É‚æ‚èA‚»‚ê‚ðPDIC‚ª’ʏí‚̃eƒLƒXƒg + @‚Æ”FŽ¯‚µ‚Ä‚µ‚Ü‚¢A•¶‚̍Ōã‚̃sƒŠƒIƒh‚ª’PŒê’†‚Ì•¶Žš—ñ‚Æ‚µ‚ďˆ—‚³‚ꂽ‚½‚߁B + +>> Ver.0.10 << +EÅ‰‚ÌŒöŠJ + +-------------------------------------------------------------- diff --git a/DCHookTest/HookDLl.cpp b/DCHookTest/HookDLl.cpp new file mode 100644 index 0000000..e269c7d --- /dev/null +++ b/DCHookTest/HookDLl.cpp @@ -0,0 +1,4 @@ +#include +#pragma hdrstop +#include "HookDll.h" + diff --git a/DCHookTest/HookDLl.h b/DCHookTest/HookDLl.h new file mode 100644 index 0000000..740280b --- /dev/null +++ b/DCHookTest/HookDLl.h @@ -0,0 +1,22 @@ +#ifndef __HookDll_h +#define __HookDll_h + +class THookDllI { +public: + virtual ~THookDllI(){} + virtual bool Load(HWND hwnd) = 0; + virtual void Unload() = 0; + virtual bool IsLoaded() = 0; + + virtual bool Init(HWND hwnd) = 0; + virtual void Uninit() = 0; + virtual int Config( int clickonly, int keyaction, int keyflag ) = 0; + virtual int Config2( struct TDCHConfig *cfg ) = 0; + virtual int Capture( ) = 0; + virtual int CaptureAsync() = 0; + virtual int CaptureAsyncWait() = 0; + virtual int Debug() = 0; +}; + + +#endif diff --git a/DCHookTest/HookLoader.cpp b/DCHookTest/HookLoader.cpp new file mode 100644 index 0000000..3ce0430 --- /dev/null +++ b/DCHookTest/HookLoader.cpp @@ -0,0 +1,294 @@ +#include +#pragma hdrstop +#include "stdafx.h" +#include "HookLoader.h" +#include "../DCHook64/DCHook64.h" +#include "Util.h" + +#define HOOK64_SUBDIR 0 // x64ŠÖ˜Aƒtƒ@ƒCƒ‹‚Ísub directory x64‚Ö + +HWND hwnd64; + +THookLoader::THookLoader(const char *dllname) + :DllName(dllname) +{ + hDll = NULL; + DCHInit = NULL; + DCHConfig = NULL; + DCHConfig2 = NULL; + DCHCapture = NULL; + DCHWaitForCaptureResult = NULL; + DCHUninit = NULL; +#ifdef _DEBUG + DCDebug = NULL; +#endif + + hThread = NULL; + dwThreadId = 0; +} +THookLoader::~THookLoader() +{ + Uninit(); +} +bool THookLoader::Load(HWND hwnd) +{ + if (hDll) + return true; + + hDll = LoadLibrary( DllName ); + if ( !hDll ) + { + GetLastError(); +#ifndef _DEBUG + DBW("Cannot load DLL:%s",DllName); +#endif + // DKPPHK.DLL ‚ª‚È‚¯‚ê‚Î DCHOOK.DLL‚ðload + DllName = "DCHOOK.DLL"; + + hDll = LoadLibrary( DllName ); + if ( !hDll ){ + DBW("Cannot load DLL:%s",DllName); + return false; + } + } + + DCHInit = (FNDCHInit)GetProcAddress( hDll, "Init" ); + DCHUninit = (FNDCHUninit)GetProcAddress( hDll, "Uninit" ); + DCHConfig = (FNDCHConfig)GetProcAddress( hDll, "Config" ); + DCHConfig2 = (FNDCHConfig2)GetProcAddress( hDll, "Config2" ); + DCHCapture = (FNDCHCapture)GetProcAddress( hDll, "Capture" ); + DCHWaitForCaptureResult = (FNDCHWaitForCaptureResult)GetProcAddress( hDll, "WaitForCaptureResult" ); +#ifdef _DEBUG + DCDebug = (FNDebug)GetProcAddress( hDll, "Debug" ); +#endif + + if (!DCHInit || !DCHUninit || !DCHConfig || !DCHConfig2 || !DCHCapture || !DCHWaitForCaptureResult){ + FreeLibrary(hDll); + hDll = NULL; + return false; + } + +#if 0 +#ifdef USE_UNICODE + const char *pVxdPath = NULL; +#else + AnsiString VxdPath; + if (!WindowsNT){ + // for Windows9x + VxdPath = ExtractFilePath( Application->ExeName ); + char path[256]; + GetShortPathName( VxdPath.c_str(), path, sizeof(path) ); + VxdPath = path; + VxdPath += "HK95D.VXD"; + } + const char *pVxdPath = VxdPath.data(); +#endif + + if ( !DCHInit( hwnd, DllName, WindowsNT, pVxdPath ) ){ + FreeLibrary( hDll ); + hDll = NULL; + DBW("Cannot initialized DLL"); + return false; + } +#endif + + return true; +} + +void THookLoader::Unload() +{ + if (!hDll) + return; + DCHUninit(); + FreeLibrary(hDll); + hDll = NULL; + DCHUninit = NULL; +} + +bool THookLoader::Init(HWND hwnd) +{ + DBW("Init"); + return DCHInit(hwnd, NULL, NULL, NULL); +} +void THookLoader::Uninit() +{ + if (DCHUninit) DCHUninit(); +} + +int THookLoader::Capture() +{ + if (!hDll) + return 0; + return DCHCapture(NULL, NULL, true, false); +} +int THookLoader::CaptureAsync() +{ + if (!hDll) + return 0; + int ret = DCHCapture(NULL, NULL, true, true); + int result = DCHWaitForCaptureResult(false, 0); + DBW("result:%d", result); + if (result != 0){ + // wait data‚ ‚è + OpenThread(); + } + return ret; +} +int THookLoader::CaptureAsyncWait() +{ + return 0; +} + +void THookLoader::OpenThread() +{ + DBW("OpenThread: %08X", hThread); + if (hThread) return; + + ThreadEnd = false; + hThread = CreateThread(NULL, 0, cbWaitCaptureThread, this, CREATE_SUSPENDED, &dwThreadId); + ResumeThread(hThread); +} + +DWORD WINAPI THookLoader::cbWaitCaptureThread(LPVOID This) +{ + ((THookLoader*)This)->WaitCaptureThread(); + return 0; +} + +void THookLoader::WaitCaptureThread() +{ + DCHWaitForCaptureResult(true, 3000); + hThread = NULL; +} + +static const char *MyWinTitle = ""; +inline HANDLE __WinExec( const char *cmd, int show, const char *dir=NULL ) +{ + return WinExecEx(cmd, show, dir, MyWinTitle); +} + +//#ifdef _DEBUG +#if 0 +const char *StrDCHK64EXE = "..\\dchk64\\x64\\Debug\\dchk64.exe"; // for debug +#else +#if HOOK64_SUBDIR +const char *StrDCHK64EXE = "x64\\DKPUHK64.exe"; +#else +const char *StrDCHK64EXE = "DKPUHK64.exe"; +#endif +#endif + +THookLoader64::THookLoader64(HWND hwnd_recv) + :hwndRecv(hwnd_recv) +{ + hwndTarget = NULL; + hProc = NULL; + LoadPending = false; +} +THookLoader64::~THookLoader64() +{ + if (hProc) + CloseHandle(hProc); + Unload(); +} +bool THookLoader64::Load(HWND hwnd) +{ +#if 1 // Find already launched hook executer. + HWND hwndFound = FindWindow("dchk64", "DCHK64"); +// HWND hwndFound = FindApp("dchk64", "DCHK64", ""); + if (hwndFound){ + DBW("x64:Found %08X already launched exe", hwndFound); + hwndTarget = hwndFound; + hwnd64 = hwndTarget; + return true; + } +#endif +#if 1 + char param[280]; + wsprintf(param, "%s %08X", StrDCHK64EXE, hwndRecv); + hProc = __WinExec(param, SW_HIDE, 0); // Launch dchk64.exe + if (!hProc){ + DBW("Launch failed: %s", param); + return false; + } + LoadPending = true; + //WaitForInputIdle(hProc, 3000); +#endif + return true; +} +void THookLoader64::Unload() +{ + if (!hProc) + return; + Uninit(); + TerminateProcess(hProc, 0); + CloseHandle(hProc); + hProc = NULL; + LoadPending = false; +} +bool THookLoader64::Init(HWND hwnd) +{ + DBW("x64:Init hwndTarget=%08X", hwndTarget); + if (!hwndTarget){ + DBW("Init failed"); + return false; + } + DBW("x64:Init"); + HDCInitParam p = {hwnd}; + return Send(HDC_Init, &p, sizeof(p)) ? true : false; +} +void THookLoader64::Uninit( ) +{ + if (!hwndTarget) + return ; + Send(HDC_Uninit, 0); + LoadPending = false; +} +int THookLoader64::Config( int clickonly, int keyaction, int keyflag ) +{ + if (!hwndTarget) + return false; + HDCConfigParam p = {clickonly, keyaction, keyflag }; + return Send(HDC_Config, &p, sizeof(p)); +} +int THookLoader64::Config2( struct TDCHConfig *cfg ) +{ + if (!hwndTarget) + return false; + return Send(HDC_Config2, cfg, sizeof(*cfg)); +} +int THookLoader64::Capture() +{ + if (!hwndTarget) + return false; + return Send(HDC_Capture, 0); +} +int THookLoader64::CaptureAsync() +{ + if (!hwndTarget) + return false; + return Send(HDC_CaptureAsync, 0); +} +int THookLoader64::CaptureAsyncWait() +{ + if (!hwndTarget) + return false; + return Send(HDC_CaptureAsyncWait, 0); +} +int THookLoader64::Debug() +{ + if (!hwndTarget) + return false; + return Send(HDC_Debug, 0); +} + +int THookLoader64::Send(int msg, void *data, int len) +{ + COPYDATASTRUCT cds; + memset(&cds, 0, sizeof(cds)); + cds.dwData = msg; + cds.lpData = data; + cds.cbData = len; + return (int)SendMessage(hwndTarget, WM_COPYDATA, 0, (LPARAM)&cds); +} + diff --git a/DCHookTest/HookLoader.h b/DCHookTest/HookLoader.h new file mode 100644 index 0000000..0787498 --- /dev/null +++ b/DCHookTest/HookLoader.h @@ -0,0 +1,91 @@ +#ifndef __HookLoader_h +#define __HookLoader_h + +#include "../DCHook/DCHook.h" +#include "HookDll.h" + +class THookLoader : public THookDllI { +public: + THookLoader(const char *dllname); + ~THookLoader(); + virtual bool Load(HWND hwnd); + virtual void Unload(); + virtual bool IsLoaded() + { return hDll!=NULL; } + + virtual bool Init(HWND hwnd); + virtual void Uninit(); + virtual int Config( int clickonly, int keyaction, int keyflag ) + { return DCHConfig(clickonly, keyaction, keyflag); } + virtual int Config2( struct TDCHConfig *cfg ) + { return DCHConfig2(cfg); } + virtual int Capture(); + virtual int CaptureAsync(); + virtual int CaptureAsyncWait(); + virtual int Debug() +#ifdef _DEBUG + { return DCDebug(); } +#else + { return 0; } +#endif +protected: + HANDLE hThread; + DWORD dwThreadId; + bool ThreadEnd; + void OpenThread(); + static DWORD WINAPI cbWaitCaptureThread(LPVOID This); + void WaitCaptureThread(); + +protected: + const char *DllName; + HINSTANCE hDll; + FNDCHInit DCHInit; + FNDCHUninit DCHUninit; + FNDCHConfig DCHConfig; + FNDCHConfig2 DCHConfig2; + FNDCHCapture DCHCapture; + FNDCHWaitForCaptureResult DCHWaitForCaptureResult; +#ifdef _DEBUG + FNDebug DCDebug; + #define COMPSIZE 16 + char share[ COMPSIZE ]; +#endif +}; + +class THookLoader64 : public THookDllI { +public: + THookLoader64(HWND hwnd_recv); + virtual ~THookLoader64(); + virtual bool Load(HWND hwnd); + virtual void Unload(); + virtual bool IsLoaded() + { return hProc!=NULL; } + + virtual bool Init(HWND hwnd); + virtual void Uninit() ; + virtual int Config( int clickonly, int keyaction, int keyflag ); + virtual int Config2( struct TDCHConfig *cfg ); + virtual int Capture(); + virtual int CaptureAsync(); + virtual int CaptureAsyncWait(); + virtual int Debug(); + void SetTarget(HWND hwnd) + { hwndTarget = hwnd; } + bool WaitFor() const + { + return WaitForInputIdle(hProc, 500)==0; + } + bool IsPending() const { return LoadPending; } + void Notify64() { LoadPending = false; } + +protected: + int Send(int msg, void *data=NULL, int len=0); + + HWND hwndRecv; // receive window handle (=main window handle) + HWND hwndTarget; // main window handle of pdhk64.exe + HANDLE hProc; + bool LoadPending; +}; + +#endif + diff --git a/DCHookTest/MODINotifyDlg.cpp b/DCHookTest/MODINotifyDlg.cpp new file mode 100644 index 0000000..5062db4 --- /dev/null +++ b/DCHookTest/MODINotifyDlg.cpp @@ -0,0 +1,102 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "MODINotifyDlg.h" +#include "Util.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" + +// ŽQlFhttps://msdn.microsoft.com/ja-jp/library/5a4x27ek(v=vs.110).aspx +#define URL_DNF_INSTALL "https://www.microsoft.com/ja-JP/download/details.aspx?id=40773" +#define URL_MODI_INSTALL "http://support.microsoft.com/kb/982760" + +TMODINotifyDialog *MODINotifyDialog; +//--------------------------------------------------------------------------- +__fastcall TMODINotifyDialog::TMODINotifyDialog(TComponent* Owner) + : TForm(Owner) +{ + LinkClicked = false; + modiInstalled = false; + amodiRunable = false; +} +//--------------------------------------------------------------------------- +void __fastcall TMODINotifyDialog::FormCreate(TObject *Sender) +{ + MoveCenter(Handle, NULL); + reMsgId = GetDlgCtrlID(reMsg->Handle); + //SetWindowLong(Handle, GWL_USERDATA, (LONG)reMsg->Handle); + SendMessage(reMsg->Handle, EM_AUTOURLDETECT, (WPARAM)TRUE, 0 ); // RichEdit 2.0 only + DWORD emask = SendMessage(reMsg->Handle, EM_GETEVENTMASK, 0, 0); + SendMessage(reMsg->Handle, EM_SETEVENTMASK, 0, emask | ENM_LINK); + + modiInstalled = MODIInstalled(); + amodiRunable = AMODIRunable(); + + SetMessage(); +} +//--------------------------------------------------------------------------- +void TMODINotifyDialog::SetMessage() +{ + if (modiInstalled && !amodiRunable){ + reMsg->Lines->Add( +"yd—vz •¶Žš”FŽ¯‚ðŽg—p‚·‚é‚É‚Í .NET Framework 4.5.1 ˆÈã‚ª•K—v‚Å‚·\n" +"\n" +URL_DNF_INSTALL"\n" +"\n" +"ƒŠƒ“ƒNæ‚©‚çƒCƒ“ƒXƒg[ƒ‹‚ðs‚Á‚Ä‚­‚¾‚³‚¢\n" +"\n" +"¦ƒŠƒ“ƒNæ‚ªŒ©‚‚©‚ç‚È‚¢ê‡‚Í\".NET Framework ƒCƒ“ƒXƒg[ƒ‹\"‚ÅŒŸõ‚µ‚Ä‚­‚¾‚³‚¢B\n" +"¦•¶Žš”FŽ¯‚ðŽg—p‚·‚é‚ƃ|ƒbƒvƒAƒbƒvŒŸõ‚ª‚Å‚«‚éƒAƒvƒŠ‚ª‘‚¦‚Ü‚·B\n" + ); + } else { + reMsg->Lines->Add( +"yd—vz MODI‚ªƒCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ä‚¢‚Ü‚¹‚ñII\n" +"\n" +"MODI‚ªƒCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ä‚¢‚é‚ƁAƒ|ƒbƒvƒAƒbƒvŒŸõ‚ª‚Å‚«‚éƒAƒvƒŠ‚ª‘‚¦‚Ü‚·B\n" +"\n" +URL_MODI_INSTALL"\n" +"\n" +"ƒŠƒ“ƒNæ‚É‚ ‚é‚¢‚¸‚ê‚©‚Ì•û–@‚ŃCƒ“ƒXƒg[ƒ‹‚ðs‚Á‚Ä‚­‚¾‚³‚¢B\n" +"¦’ʏí‚́u•û–@‚Qv\n" +"¦MODI‚Í\"Microsoft Office Document Imaging\"‚Ì—ª‚Å‚·\n" +"¦ã‹LƒŠƒ“ƒN‚ªŠJ‚¯‚È‚¢ê‡‚Í \"MODI\" \"ƒCƒ“ƒXƒg[ƒ‹\" ‚È‚Ç‚ÅŒŸõ‚µ‚Ä‚Ý‚Ä‚­‚¾‚³‚¢\n" + ); + } +} +void __fastcall TMODINotifyDialog::tmInstallCheckTimer(TObject *Sender) +{ + bool _modiInstalled = MODIInstalled(); + bool _amodiRunable = AMODIRunable(); + if (_modiInstalled && _amodiRunable){ + // ready to go + Close(); + } else { + if (modiInstalled!=_modiInstalled || amodiRunable!=_amodiRunable){ + modiInstalled = _modiInstalled; + amodiRunable = _amodiRunable; + SetMessage(); + } + } +} +//--------------------------------------------------------------------------- +void TMODINotifyDialog::EvNotify( TMessage &msg ) +{ + if (msg.WParam==reMsgId){ + NMHDR *nmhdr = (NMHDR*)msg.LParam; + if (nmhdr->code==EN_LINK){ + ENLINK *enlink = (ENLINK*)nmhdr; + if (enlink->msg == WM_LBUTTONDOWN){ + bool dnf = modiInstalled && !amodiRunable; + HINSTANCE hInst = ShellExecute(Handle, NULL, dnf ? URL_DNF_INSTALL : URL_MODI_INSTALL, NULL, NULL, SW_SHOWNORMAL); + if ((int)hInst>32){ + LinkClicked = true; + } + } + } + } +} + + diff --git a/DCHookTest/MODINotifyDlg.dfm b/DCHookTest/MODINotifyDlg.dfm new file mode 100644 index 0000000..49178ff --- /dev/null +++ b/DCHookTest/MODINotifyDlg.dfm @@ -0,0 +1,44 @@ +object MODINotifyDialog: TMODINotifyDialog + Left = 199 + Top = 120 + BorderStyle = bsDialog + Caption = 'DokoPop!' + ClientHeight = 263 + ClientWidth = 486 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = '‚l‚r ‚oƒSƒVƒbƒN' + Font.Style = [] + OldCreateOrder = False + OnCreate = FormCreate + PixelsPerInch = 96 + TextHeight = 12 + object reMsg: TRichEdit + Left = 14 + Top = 12 + Width = 458 + Height = 213 + TabStop = False + Anchors = [akLeft, akTop, akRight, akBottom] + ReadOnly = True + TabOrder = 0 + end + object btnClose: TButton + Left = 206 + Top = 233 + Width = 75 + Height = 25 + Anchors = [akBottom] + Cancel = True + Caption = 'Close' + ModalResult = 2 + TabOrder = 1 + end + object tmInstallCheck: TTimer + OnTimer = tmInstallCheckTimer + Left = 328 + Top = 232 + end +end diff --git a/DCHookTest/MODINotifyDlg.h b/DCHookTest/MODINotifyDlg.h new file mode 100644 index 0000000..4a50f29 --- /dev/null +++ b/DCHookTest/MODINotifyDlg.h @@ -0,0 +1,37 @@ +//--------------------------------------------------------------------------- + +#ifndef MODINotifyDlgH +#define MODINotifyDlgH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TMODINotifyDialog : public TForm +{ +__published: // IDE ŠÇ—‚̃Rƒ“ƒ|[ƒlƒ“ƒg + TRichEdit *reMsg; + TButton *btnClose; + TTimer *tmInstallCheck; + void __fastcall FormCreate(TObject *Sender); + void __fastcall tmInstallCheckTimer(TObject *Sender); +private: // ƒ†[ƒU[éŒ¾ + BEGIN_MESSAGE_MAP + VCL_MESSAGE_HANDLER(WM_NOTIFY, TMessage, EvNotify); + END_MESSAGE_MAP( TForm ) + void EvNotify( TMessage &msg ); + int reMsgId; + bool modiInstalled; + bool amodiRunable; +public: // ƒ†[ƒU[éŒ¾ + __fastcall TMODINotifyDialog(TComponent* Owner); + void SetMessage(); + bool LinkClicked; +}; +//--------------------------------------------------------------------------- +extern PACKAGE TMODINotifyDialog *MODINotifyDialog; +//--------------------------------------------------------------------------- +#endif diff --git a/DCHookTest/Notify.cpp b/DCHookTest/Notify.cpp new file mode 100644 index 0000000..6c00977 --- /dev/null +++ b/DCHookTest/Notify.cpp @@ -0,0 +1,66 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "Notify.h" +namespace popenable { +#include "popenable.h" // generated by bmp2rgn +} +namespace popdisable { +#include "popdisable.h" // generated by bmp2rgn +} +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TNotifyForm *NotifyForm; +//--------------------------------------------------------------------------- +__fastcall TNotifyForm::TNotifyForm(TComponent* Owner) + : TForm(Owner) +{ + hRgn = NULL; +} +//--------------------------------------------------------------------------- +void __fastcall TNotifyForm::FormShow(TObject *Sender) +{ + Setup(); + if (hRgn) + DeleteObject(hRgn); + if (enable){ + hRgn = ExtCreateRegion (0, + sizeof(popenable::bmp2rgn_rgnBytes), + &popenable::bmp2rgn_rgnData); + } else { + hRgn = ExtCreateRegion (0, + sizeof(popdisable::bmp2rgn_rgnBytes), + &popdisable::bmp2rgn_rgnData); + } + SetWindowRgn( Handle, hRgn, TRUE ); +} +//--------------------------------------------------------------------------- +void TNotifyForm::Setup() +{ + EnableBmp->Visible = enable; + DisableBmp->Visible = !enable; + TImage *bmp = enable ? EnableBmp : DisableBmp; + Width = bmp->Width; + Height = bmp->Height; + bmp->Top = 0; + bmp->Left = 0; +// ReleaseCapture(); + SetCapture( Handle ); // capture‚Å‚«‚È‚¢B‚È‚ºH +} +void __fastcall TNotifyForm::FormMouseMove(TObject *Sender, + TShiftState Shift, int X, int Y) +{ + ReleaseCapture( ); + Close(); +} +//--------------------------------------------------------------------------- +void __fastcall TNotifyForm::FormDestroy(TObject *Sender) +{ + DeleteObject( hRgn ); +} +//--------------------------------------------------------------------------- + + diff --git a/DCHookTest/Notify.dfm b/DCHookTest/Notify.dfm new file mode 100644 index 0000000..c5f7f0c --- /dev/null +++ b/DCHookTest/Notify.dfm @@ -0,0 +1,1211 @@ +object NotifyForm: TNotifyForm + Left = 913 + Top = 701 + BorderStyle = bsNone + ClientHeight = 50 + ClientWidth = 240 + Color = cl3DLight + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = '‚l‚r ‚oƒSƒVƒbƒN' + Font.Style = [] + OldCreateOrder = False + OnDestroy = FormDestroy + OnMouseMove = FormMouseMove + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 12 + object EnableBmp: TImage + Left = 0 + Top = 0 + Width = 241 + Height = 25 + Picture.Data = { + 07544269746D617056490000424D56490000000000003600000028000000F000 + 00001A000000010018000000000020490000C30E0000C30E0000000000000000 + 0000FDFBFDFDFBFDFDFBFDC9EC7BC9EC7BB0DE3BA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + ACDE30C9EC7BC9EC7BFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDC3E86CA7DF25A3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DACDE30C9EC7BFDFBFDFD + FBFDFDFBFDC9EC7BA7DF25A3E11DA3E11DA3E11D96BC43779140697E3C697E3C + 697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E + 3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C69 + 7E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C + 697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E + 3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C69 + 7E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C + 697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E + 3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C69 + 7E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C + 697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E + 3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C69 + 7E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C + 697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E + 3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C69 + 7E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C + 697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E + 3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C69 + 7E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C + 697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E + 3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C69 + 7E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C697E3C869B39 + A4DD21A3E11DA3E11DA7DF25C9EC7BFDFBFDC9EC7BA7DF25A3E11DA3E11DA3CD + 479DC7419DC7418F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F727272595959697E3C869B39A3E11DA3E11DADDE32C9 + EC7BC2E766A3E11DA3E11DB1DB56AAD44FC0C0C0CFCFCFCFCFCFDADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADBDBDBDBDBDBDBDBDBDBDBDBDADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADBDBDBDCDCDCDDDDDDDDDD + DDDDDDDDDBDBDBDADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADACFCFCFC0C0C0A2A2A2 + 818181697E3C869B39A3E11DA3E11DC9EC7BA7DF25A3E11DA7DF25BCE463E6E6 + E6EDEBEDF5F3F5FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFDFCFD + FEFCFEFEFCFEFEFCFEFEFCFEFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFCFDFEFCFEFEFDFEFEFEFEFEFEFEFEFEFEFEFDFEFEFCFEFDFCFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDF5F3F5E6E6E6C0C0C0818181779140A4DD21A3E11DB0 + DF3AA3E11DA3E11DBFE45EFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFCFDFEFDFEFEFEFEFFFEFFFFFEFFFEFEFEFEFDFEFEFCFEFEFC + FEFEFDFEFEFDFEFEFEFEFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FEFFFFFEFFFEFEFEFEFDFEFEFDFEFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFEFCFEFEFEFEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFEFFFEFEFEFEFEFEFEFDFEFEFCFEFDFCFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFEFCFEFEFDFEFEFEFE + FFFEFFFFFEFFFFFEFFFFFEFFFFFEFFFFFEFFFFFEFFFEFCFEFEFCFEFEFCFEFEFC + FEFDFCFDFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFEFCFEFEFCFEFEFCFEFEFCFEFDFCFDFDFCFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFC + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFEFCFEFEFDFEFEFDFEFEFDFEFEFDFE + FEFDFEFEFDFEFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFCFDFDFCFDFEFCFEFEFDFEFEFDFEFEFDFEFEFDFEFEFCFEFDFCFDFDFCFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + E6E6E6B4B4B48181818CAE44A3E11DA3E11DA3E11DA3E11DC9EC7BFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFEFDFEFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + FFFEFEFEFEFDFEFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFDFCFDFEFCFEFF + FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFEFFFEFEFEFEFEFEFEFDFEFEFDFEFEFD + FEFEFDFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFF + FFFEFFFFFEFFFEFEFEFEFDFEFEFDFEFEFEFEFFFEFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFFFEFDFEFEFDFEFEFCFEFDFCFDFDFCFDFEFCFEFEFDFEFFFEFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFEFFFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFDFEFEFDFEFEFDFEFEFCFEFDFCFDFEFCFEFEFDFEFCFC + FCFBFBFBFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFFFFFFFFFFFFFFFFEFFFEFEFEFA + FAFAFCFCFCFEFEFEFCFCFCFDFCFDFFFEFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFEFFFEFEFEFEFDFEFDFCFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDF5F3F5CFCFCF8F8F8F8CAE44A3E11DA3 + E11DA3E11DA3E11DC9EC7BFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFEFCFEFFFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFEFFFEFEFEFEFEFE + FEFEFEFFFEFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFBBBBBBBBBBBBBBBBBBDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFDFDFDFE + FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFEFFFEFDFEFEFCFEFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDDADADAB4B4B496BC43A3E11DA3E11DA3E11DA3E11DC9EC7BFDFBFDFDFB + FDFDFBFDFDFBFDFEFDFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999DDDDDDFFFFFFFFFFFFFFFFFF + FFFFFF888888FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE555555888888FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE44 + 4444888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 777777888888EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEE + EE555555888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF444444BBBBBB333333666666DDDDDDFFFFFFFFFFFFDDDDDD666666DDDDDD + FFFFFF555555888888FFFFFFFFFFFF888888888888FFFFFFFFFFFF9999998888 + 88FFFFFFFFFFFFFFFFFFFFFFFF99999911111100000000000000000000000088 + 8888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFF + FF999999000000888888FFFFFFFFFFFFDDDDDD888888FFFFFFFFFFFFBBBBBB33 + 3333CCCCCCFFFFFF888888444444888888FFFFFFFFFFFF444444444444222222 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDDDDD + DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFCCCCCC888888888888999999EEEEEEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFEEEEEE666666444444777777EEEEEEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC888888888888999999EEEEEEFF + FFFFFFFFFFFFFFFFFFFFFFDDDDDDAAAAAAFFFFFFFFFFFFFFFFFFEEEEEEBBBBBB + 999999888888999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFEFD + FEFEFCFEFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDE6E6E6B4B4B496BC43A3E11DA3 + E11DA3E11DA3E11DC9EC7BFDFBFDFDFBFDFDFBFDFEFCFEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF444444000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF999999222222333333DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA111111666666FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB666666111111BBBBBBFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999222222333333DDDDDDFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF444444BBBBBBEEEEEE8888882222 + 22CCCCCC999999111111777777DDDDDDFFFFFFBBBBBB333333666666FFFFFF88 + 8888888888EEEEEE333333222222999999FFFFFFFFFFFFFFFFFFFFFFFF111111 + CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFF + DDDDDD333333444444EEEEEEDDDDDD888888111111CCCCCCCCCCCCBBBBBB0000 + 00FFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFDDDDDDAAAAAA + 888888888888999999FFFFFFFFFFFFFFFFFFFFFFFF9999991111117777778888 + 88333333111111AAAAAAFFFFFFFFFFFFFFFFFFFFFFFF666666888888EEEEEE66 + 6666777777FFFFFFEEEEEE888888DDDDDDFFFFFFFFFFFFFFFFFFFFFFFF999999 + 111111777777888888333333111111AAAAAAFFFFFFFFFFFFFFFFFFBBBBBB2222 + 22FFFFFFFFFFFF999999111111444444777777888888999999FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDFEFDFBFDFDFBFDFDFBFD + FDFBFDE6E6E6B4B4B49DC741A3E11DA3E11DA3E11DA3E11DC9EC7BFDFBFDFDFB + FDFDFCFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFCCCCCCFFFFFF444444BBBBBBFFFFFFFFFFFFFFFFFF + FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE6666661111 + 11DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFCCCCCC000000AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFBBBBBB111111AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFEEEEEE666666111111DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEDD + DDDD444444BBBBBBFFFFFFCCCCCCBBBBBB222222333333EEEEEECCCCCCFFFFFF + FFFFFFEEEEEEFFFFFF888888CCCCCC888888888888BBBBBB777777EEEEEEEEEE + EEFFFFFFFFFFFFFFFFFFFFFFFF222222888888FFFFFF777777CCCCCCFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8888882222224444444444 + 44444444222222888888FFFFFFFFFFFFFFFFFFFFFFFF66666633333333333399 + 9999999999222222EEEEEEFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8888888888 + 88FFFFFFEEEEEE444444222222666666888888888888999999FFFFFFFFFFFFFF + FFFFFFFFFF111111999999FFFFFFFFFFFFFFFFFFAAAAAA111111AAAAAAFFFFFF + FFFFFFFFFFFF666666888888EEEEEEAAAAAA222222666666111111666666CCCC + CCFFFFFFFFFFFFFFFFFFFFFFFF111111999999FFFFFFFFFFFFFFFFFFAAAAAA11 + 1111AAAAAAFFFFFFFFFFFFFFFFFF222222CCCCCCFFFFFFEEEEEEFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFEFDFEFDFBFDFDFBFDFDFBFDE6E6E6B4B4B496BC43A3E11DA3 + E11DA3E11DA3E11DC9EC7BFDFBFDFDFBFDFEFDFEFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB1111119999 + 99444444BBBBBBFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFF666666333333FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF666666555555FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB111111EE + EEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF666666333333 + FFFFFFFFFFFFFFFFFFFFFFFFAAAAAA444444444444BBBBBBFFFFFF1111114444 + 44111111333333444444444444FFFFFFFFFFFF99999922222200000000000022 + 2222222222444444444444333333888888FFFFFFFFFFFFFFFFFFFFFFFFCCCCCC + 333333888888333333BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFEEEEEE77 + 7777EEEEEE888888666666BBBBBBBBBBBBBBBBBB666666888888FFFFFFFFFFFF + FFFFFFFFFFFFEEEEEE111111444444FFFFFFFFFFFF444444999999FFFFFF0000 + 00FFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFEEEEEE888888FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFF + FFFFFFFFFFFFFFCCCCCCEEEEEEFFFFFFFFFFFFFFFFFFEEEEEE66666644444433 + 3333222222999999EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCEEEEEEFFFFFFFFFFFFFFFFFF7777 + 77888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFDFDFBFD + FBF9FBE6E6E6B4B4B49DC741A3E11DA3E11DA3E11DA3E11DC9EC7BFDFBFDFDFC + FDFBFAFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFCCCCCC111111222222888888BBBBBBBBBBBBBBBBBB + BBBBBB000000FFFFFFFFFFFFFFFFFFEEEEEEDDDDDDFFFFFFFFFFFFFFFFFFEEEE + EE222222888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFF + FFFFFFFFFF888888222222FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999 + DDDDDDFFFFFFFFFFFFFFFFFF555555999999FFFFFFFFFFFFFFFFFFEEEEEEDDDD + DDFFFFFFFFFFFFFFFFFFEEEEEE222222888888FFFFFFFFFFFFFFFFFFFFFFFF44 + 4444111111666666AAAAAA444444FFFFFF444444BBBBBBFFFFFF444444FFFFFF + FFFFFFFFFFFFFFFFFFCCCCCC333333222222666666DDDDDD333333888888FFFF + FFFFFFFFFFFFFFEEEEEE666666DDDDDDFFFFFF888888111111444444999999EE + EEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFEEEEEE5555553333337777772222224444444444 + 44444444222222888888FFFFFFFFFFFFFFFFFFFFFFFF555555888888222222EE + EEEEFFFFFF999999555555FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8888888888 + 88FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB444444FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB444444FFFFFFFFFFFFEEEEEEFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFAF9FAF5F4F5F5F3F5E6E6E6B4B4B496BC43A3E11DA3 + E11DA3E11DA3E11DC9EC7BFDFBFDFDFCFDFDFCFDFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCC + CC000000333333444444444444444444444444444444FFFFFFFFFFFFFFFFFFAA + AAAA111111CCCCCCFFFFFFFFFFFFFFFFFF999999222222FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFBBBBBB000000FFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFDDDDDD000000DDDDDD999999888888FFFFFF88888855 + 5555FFFFFFFFFFFFFFFFFFAAAAAA111111CCCCCCFFFFFFFFFFFFFFFFFF999999 + 222222FFFFFFFFFFFFFFFFFFFFFFFFAAAAAA000000444444DDDDDD1111114444 + 44111111333333444444444444FFFFFFFFFFFFBBBBBBEEEEEE333333222222CC + CCCC888888333333DDDDDDEEEEEECCCCCCFFFFFFFFFFFFFFFFFF888888111111 + 888888BBBBBB222222888888666666111111666666FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF888888000000666666BBBBBBBBBBBBBBBBBB666666888888FFFFFFFFFFFF + DDDDDD333333CCCCCCFFFFFF999999AAAAAA999999BBBBBB444444FFFFFF0000 + 00FFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44444400000044444433 + 3333111111444444444444777777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF000000FFFFFFFFFFFF222222222222555555888888BBBBBBFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF6F4F6 + F5F3F5E6E6E6B4B4B496BC43A3E11DA3E11DA3E11DA3E11DC9EC7BFDFBFDFEFC + FEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888333333FFFFFFFFFFFFFFFF + FFEEEEEE000000CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFF + FFFFFFFFFFBBBBBB000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999777777 + FFFFFF222222999999FFFFFFBBBBBB333333FFFFFFFFFFFFFFFFFFFFFFFF8888 + 88333333FFFFFFFFFFFFFFFFFFEEEEEE000000CCCCCCFFFFFFFFFFFFFFFFFFFF + FFFF111111BBBBBBEEEEEEDDDDDDBBBBBB333333888888CCCCCCFFFFFFFFFFFF + FFFFFF000000FFFFFFFFFFFFCCCCCC111111CCCCCCCCCCCCFFFFFFBBBBBB4444 + 44FFFFFFFFFFFFFFFFFFFFFFFF999999000000777777888888FFFFFFFFFFFFFF + FFFFDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6666660000000000000000 + 00000000000000888888FFFFFFFFFFFFFFFFFF999999111111CCCCCCCCCCCC11 + 1111888888888888333333BBBBBB000000FFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8888888888 + 88FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB333333BBBBBBBBBBBBCCCCCCFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF333333CCCCCCFFFFFFFFFFFFCCCCCC + AAAAAA888888CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFDFCFDF6F4F6F5F3F5DADADAB4B4B49DC741A3E11DA3 + E11DA3E11DA3E11DC9EC7BFDFBFDFEFCFEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEBBBBBBBBBB + BBAAAAAA111111BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFFFFFFFFFFFFFF + FFFFFFFFFF444444555555888888888888888888222222888888FFFFFFFFFFFF + FFFFFFFFFFFFBBBBBB000000FFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE999999FFFFFFFFFFFFDDDDDDCC + CCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF444444555555888888888888888888 + 222222888888FFFFFFFFFFFFCCCCCC4444441111113333331111113333337777 + 77888888888888555555222222CCCCCCFFFFFF44444444444444444444444422 + 2222222222444444444444444444777777FFFFFFFFFFFFFFFFFFBBBBBBBBBBBB + 666666777777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFEEEEEE111111DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFAAAAAACCCCCCCCCCCC999999CCCCCC3333331111114444444444 + 44FFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFF888888555555FFFFFFFFFFFF666666888888888888 + 888888888888DDDDDDFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBBBBBBBBBBBBBBBBBBB88 + 8888333333DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6666662222 + 22000000222222444444BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF6F4F6 + F5F3F5E6E6E6B4B4B496BC43A3E11DA3E11DA3E11DA3E11DC9EC7BFDFBFDFDFC + FDFCFBFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFCCCCCC444444444444444444111111333333444444444444 + 444444444444444444FFFFFFFFFFFFFFFFFFFFFFFFBBBBBB0000008888888888 + 88888888777777EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFF + FFFFFFFFFFBBBBBB000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFBBBBBB000000888888888888888888777777EEEEEEFFFFFFFFFFFFEEEEEEBB + BBBB333333888888DDDDDD777777333333EEEEEE999999222222BBBBBBFFFFFF + FFFFFFBBBBBB888888888888888888444444444444888888888888888888BBBB + BBFFFFFFFFFFFFFFFFFF44444444444444444400000022222200000033333399 + 9999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFF0000000000000000000000000000000000 + 00000000000000000000000000BBBBBBBBBBBB00000000000000000000000000 + 0000444444BBBBBB444444FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD + DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB4444 + 44FFFFFFFFFFFF999999888888888888888888888888DDDDDDFFFFFFFFFFFFFF + FFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFBBBBBB8888887777774444443333331111114444444444441111118888 + 88FFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888888888BBBBBBCCCCCCFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFAF9FAF5F4F5F5F3F5DADADAB9B9B99DC741A3E11DA3 + E11DA3E11DA3E11DC9EC7BFDFBFDFDFBFDFAF8FAFEFEFEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFF888888777777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFF333333888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFDDDDDD888888DDDDDDFFFFFFFFFFFFCCCCCC444444FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF333333888888FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF444444BBBBBBFFFFFFFFFFFF8888 + 88333333666666EEEEEEFFFFFFFFFFFFFFFFFFBBBBBB88888888888888888844 + 4444444444888888888888888888BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFF555555999999FFFFFFEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF888888666666BBBBBBBBBBBBFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFF888888666666FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFF444444BBBBBBFFFFFFFFFFFFBBBBBB444444FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFDDDDDD555555FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB + BBBB444444FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF999999555555FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F6F7F5F3F5 + F5F3F5E6E6E6C0C0C0A3CD47A3E11DA3E11DA3E11DA3E11DBFE45EFDFBFDFDFB + FDF7F6F7FCFBFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC999999FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDEEEEEEFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFDDDDDDEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF999999DDDDDDFFFFFFFFFFFFFFFFFF666666EEEEEEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999999999FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAAAAAAAFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999 + 444444444444444444FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC888888FFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF777777BBBBBBFF + FFFFFFFFFFDDDDDD888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD888888FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDAAAAAAFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFAF8FAF6F4F6F5F3F5F5F3F5E6E6E6B1DB56A8D34DA3E11DA3 + E11DA7DF25A3E11DADDE32C9EC7BFDFBFDFBF9FBF8F6F8FCFBFCFFFEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFEFEFEFEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAF8FAF6F4F6F5F3F5F5F3F5 + F5F3F5EDEBEDB1DB56A3E11DA3E11DB0DF3ABBE255A3E11DA3E11DC9EC7BC9EC + 7BFDFBFDFBF9FBF7F6F7FAF9FAFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFF + FFFEFFFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFDFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFDFDFDFDFCFDFCFBFCFC + FBFCFCFBFCFDFCFDFDFCFDFDFCFDFDFCFDFCFCFCFCFBFCFCFBFCFBFAFBFBFAFB + FAF9FAF9F8F9F9F8F9F9F7F9F9F7F9F9F8F9FAF8FAFAF9FAFAFAFAFBFAFBFBFA + FBFBFAFBFCFBFCFCFCFCFDFCFDFDFDFDFEFDFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFFFEFFFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFEFF + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFFFEFFFFFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FEFFFEFEFEFEFEFEFEFEFEFEFEFEFEFDFEFEFDFEFDFDFDFDFDFDFDFDFDFEFDFE + FEFDFEFDFDFDFDFCFDFCFBFCFBFAFBFBFAFBFCFBFCFDFCFDFDFDFDFCFCFCFAF9 + FAF7F6F7F6F4F6F5F3F5F5F3F5F5F3F5F5F3F5C2E86FB1DF41A3E11DA3E11DC9 + EC7BC9EC7BA4E01FA3E11DA3E11DC6EA72C9EC7BFDFBFDFDFBFDFDFBFDFDFCFD + FEFCFEFEFDFEFEFDFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFDFEFEFDFEFEFDFEFEFDFEFEFCFEFEFCFEFEFCFEFEFCFEFD + FCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFD + FDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFCFDFDFCFDFDFCFDFEFCFEFEFCFEFEFCFEFEFCFEFDFCFDFDFCFDFDFCFDFDFC + FDFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFEFCFEFEFCFE + FEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFDFEFEFDFEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFDFBFDFDFBFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDFEFEFD + FEFEFDFEFEFDFEFEFDFEFEFDFEFEFDFEFEFDFEFEFCFEFEFCFEFEFCFEFEFCFEFE + FCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFDFCFDFDFCFDFDFCFD + FDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFC + FDFDFBFDFDFBFDFDFBFDFDFCFDFDFCFDFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + C7EB78BCE258A3E11DA3E11DACDE30C9EC7BFDFBFDC3E86CA4E01FA3E11DA3E1 + 1DB0DE3BC3E86CC9EC7BC9EC7BC8EC7BC9EC7BC9EC7BC9ED7BC9EC7CC9EC7CC9 + EC7CC9EC7BC9EC7BC9EC7BC9EC7CC9EC7BC9EC7CC9EC7BC8EC7AC9EC7BC9EC7B + C9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC8EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC + 7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9 + EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7B + C9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC + 7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9 + EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7B + C9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC + 7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9 + EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7B + C9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC + 7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9 + EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7B + C9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC + 7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9 + EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC8EC7AC9EC7BC9EC7BC9EC7B + C9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC + 7BC8EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9 + EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7B + C9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC7BC9EC + 7BC9EC7BC9EC7BC9EC7BC9EC7BC2E766A7DF25A3E11DA3E11DA7DF25C9EC7BFD + FBFDFDFBFDFDFBFDC3E86CA4E01FA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA9DF2AC9EC7BFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDC9EC7BB9E2 + 50A7DF25A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3 + E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11D + A3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E11DA3E1 + 1DA3E11DA3E11DA3E11DA3E11DA3E11DA7DF25C2E766C9EC7BFDFBFDFDFBFDFD + FBFD} + Visible = False + end + object DisableBmp: TImage + Left = 0 + Top = 24 + Width = 241 + Height = 25 + Picture.Data = { + 07544269746D617056490000424D56490000000000003600000028000000F000 + 00001A000000010018000000000020490000C30E0000C30E0000000000000000 + 0000FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDF1CFCDEAAEA4E9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DEAAEA4 + EFC5C2FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFBF3F3EBBAB6E89B + 96E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE2928DE38E8AE38E8AE38E8AE9958DEAA39EEFC5C2FDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDEBBAB6E9958DE9958DCD8F898181815959594C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C + 4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C4C6A5654 + C2837DE2928DE9958DEBBAB6FDFBFDFDFBFDFDFBFDEBBAB6E9958DE9958DA2A2 + A28F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F8F + 8F8F8F8F8F8F8F8F8F8F7272725959594C4C4C6A5654E38E8AE9958DF0CCC3FD + FBFDFBF1EFE39592E9958DCFCFCFB9B9B9C0C0C0CFCFCFCFCFCFDADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADBDBDBDBDBDBDBDBDBDBDBDBDADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADBDBDBDCDCDCDDDDDDDDDD + DDDDDDDDDBDBDBDADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADADA + DADADADADADADADADADADADADADADADADADADADADADADACFCFCFC0C0C0A2A2A2 + 8181814C4C4C6A5654E9958DEAA39EFDFBFDEBBAB6E9958DEBBAB6EDEBEDE6E6 + E6EDEBEDF5F3F5FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFDFCFD + FEFCFEFEFCFEFEFCFEFEFCFEFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFCFDFEFCFEFEFDFEFEFEFEFEFEFEFEFEFEFEFDFEFEFCFEFDFCFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDF5F3F5E6E6E6C0C0C0818181595959C2837DE9958DF3 + D4CBEAA39EE9958DFBEBE9FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFCFDFEFDFEFEFEFEFFFEFFFFFEFFFEFEFEFEFDFEFEFCFEFEFC + FEFEFDFEFEFDFEFEFEFEFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FEFFFFFEFFFEFEFEFEFDFEFEFDFEFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFEFCFEFEFEFEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFEFFFEFEFEFEFEFEFEFDFEFEFCFEFDFCFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFEFCFEFEFDFEFEFEFE + FFFEFFFFFEFFFFFEFFFFFEFFFFFEFFFFFEFFFFFEFFFEFCFEFEFCFEFEFCFEFEFC + FEFDFCFDFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFEFCFEFEFCFEFEFCFEFEFCFEFDFCFDFDFCFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFC + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFEFCFEFEFDFEFEFDFEFEFDFEFEFDFE + FEFDFEFEFDFEFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFCFDFDFCFDFEFCFEFEFDFEFEFDFEFEFDFEFEFDFEFEFCFEFDFCFDFDFCFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + E6E6E6B4B4B4818181727272E9958DEBAFABE9958DE9958DFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFEFDFEFEFEFEFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE + FFFEFEFEFEFDFEFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFCFDFDFCFDFEFCFEFF + FEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFEFFFEFEFEFEFEFEFEFDFEFEFDFEFEFD + FEFEFDFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFF + FFFEFFFFFEFFFEFEFEFEFDFEFEFDFEFEFEFEFFFEFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFEFFFEFDFEFEFDFEFEFCFEFDFCFDFDFCFDFEFCFEFEFDFEFFFEFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFEFFFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFDFEFEFDFEFEFDFEFEFCFEFDFCFDFEFCFEFEFDFEFCFC + FCFBFBFBFFFFFFFFFFFFFFFFFFFEFEFEFFFFFFFFFFFFFFFFFFFFFEFFFEFEFEFA + FAFAFCFCFCFEFEFEFCFCFCFDFCFDFFFEFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFEFFFEFEFEFEFDFEFDFCFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDF5F3F5CFCFCF8F8F8F727272E9958DE9 + 958DE9958DE9958DFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFEFCFEFFFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFEFFFEFEFEFEFEFE + FEFEFEFFFEFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFBBBBBBBBBBBBBBBBBBDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFDFDFDFDFDFDFE + FEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFEFFFEFDFEFEFCFEFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDDADADAB4B4B4818181E9958DE9958DE9958DE9958DFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFEFDFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999DDDDDDFFFFFFFFFFFFFFFFFF + FFFFFF888888FFFFFFFFFFFFFFFFFFFFFFFFEEEEEE555555888888FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE44 + 4444888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + 777777888888EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEE + EE555555888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF444444BBBBBB333333666666DDDDDDFFFFFFFFFFFFDDDDDD666666DDDDDD + FFFFFF555555888888FFFFFFFFFFFF888888888888FFFFFFFFFFFF9999998888 + 88FFFFFFFFFFFFFFFFFFFFFFFF99999911111100000000000000000000000088 + 8888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF777777CCCCCCFFFFFF999999999999FFFF + FF777777FFFFFFEEEEEE999999FFFFFFDDDDDD888888FFFFFFFFFFFFBBBBBB33 + 3333CCCCCCFFFFFF888888444444888888FFFFFFFFFFFF444444444444222222 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDDDDD + DDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFCCCCCC888888888888999999EEEEEEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFEEEEEE666666444444777777EEEEEEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC888888888888999999EEEEEEFF + FFFFFFFFFFFFFFFFFFFFFFDDDDDDAAAAAAFFFFFFFFFFFFFFFFFFEEEEEEBBBBBB + 999999888888999999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFEFD + FEFEFCFEFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDE6E6E6B4B4B4818181E9958DE9 + 958DE9958DE9958DFDFBFDFDFBFDFDFBFDFDFBFDFEFCFEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF444444000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF999999222222333333DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAA111111666666FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB666666111111BBBBBBFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999222222333333DDDDDDFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF444444BBBBBBEEEEEE8888882222 + 22CCCCCC999999111111777777DDDDDDFFFFFFBBBBBB333333666666FFFFFF88 + 8888888888EEEEEE333333222222999999FFFFFFFFFFFFFFFFFFFFFFFF111111 + CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF88 + 8888333333FFFFFF888888888888CCCCCC222222FFFFFF666666555555FFFFFF + DDDDDD333333444444EEEEEEDDDDDD888888111111CCCCCCCCCCCCBBBBBB0000 + 00FFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFDDDDDDAAAAAA + 888888888888999999FFFFFFFFFFFFFFFFFFFFFFFF9999991111117777778888 + 88333333111111AAAAAAFFFFFFFFFFFFFFFFFFFFFFFF666666888888EEEEEE66 + 6666777777FFFFFFEEEEEE888888DDDDDDFFFFFFFFFFFFFFFFFFFFFFFF999999 + 111111777777888888333333111111AAAAAAFFFFFFFFFFFFFFFFFFBBBBBB2222 + 22FFFFFFFFFFFF999999111111444444777777888888999999FFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDFEFDFBFDFDFBFDFDFBFD + FDFBFDE6E6E6B4B4B48F8F8FE9958DE9958DE9958DE9958DFDFBFDFDFBFDFDFB + FDFDFCFDFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFCCCCCCFFFFFF444444BBBBBBFFFFFFFFFFFFFFFFFF + FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE6666661111 + 11DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFCCCCCC000000AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFBBBBBB111111AAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFEEEEEE666666111111DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEDD + DDDD444444BBBBBBFFFFFFCCCCCCBBBBBB222222333333EEEEEECCCCCCFFFFFF + FFFFFFEEEEEEFFFFFF888888CCCCCC888888888888BBBBBB777777EEEEEEEEEE + EEFFFFFFFFFFFFFFFFFFFFFFFF222222888888FFFFFF777777CCCCCCFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF444444AAAAAA444444AAAAAAAAAA + AA777777BBBBBB333333EEEEEEFFFFFFFFFFFFFFFFFF66666633333333333399 + 9999999999222222EEEEEEFFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8888888888 + 88FFFFFFEEEEEE444444222222666666888888888888999999FFFFFFFFFFFFFF + FFFFFFFFFF111111999999FFFFFFFFFFFFFFFFFFAAAAAA111111AAAAAAFFFFFF + FFFFFFFFFFFF666666888888EEEEEEAAAAAA222222666666111111666666CCCC + CCFFFFFFFFFFFFFFFFFFFFFFFF111111999999FFFFFFFFFFFFFFFFFFAAAAAA11 + 1111AAAAAAFFFFFFFFFFFFFFFFFF222222CCCCCCFFFFFFEEEEEEFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFEFDFEFDFBFDFDFBFDFDFBFDE6E6E6B4B4B4818181E9958DE9 + 958DE9958DE9958DFDFBFDFDFBFDFDFBFDFEFDFEFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB1111119999 + 99444444BBBBBBFFFFFFFFFFFFFFFFFFFFFFFF000000FFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFF666666333333FFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF666666555555FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB111111EE + EEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF666666333333 + FFFFFFFFFFFFFFFFFFFFFFFFAAAAAA444444444444BBBBBBFFFFFF1111114444 + 44111111333333444444444444FFFFFFFFFFFF99999922222200000000000022 + 2222222222444444444444333333888888FFFFFFFFFFFFFFFFFFFFFFFFCCCCCC + 333333888888333333BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFF44 + 4444444444444444444444444444444444444444444444444444444444FFFFFF + FFFFFFFFFFFFEEEEEE111111444444FFFFFFFFFFFF444444999999FFFFFF0000 + 00FFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFEEEEEE888888FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFF + FFFFFFFFFFFFFFCCCCCCEEEEEEFFFFFFFFFFFFFFFFFFEEEEEE66666644444433 + 3333222222999999EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFCCCCCCEEEEEEFFFFFFFFFFFFFFFFFF7777 + 77888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFCFDFDFBFD + FBF9FBE6E6E6B4B4B48F8F8FE9958DE9958DE9958DE9958DFDFBFDFDFBFDFDFC + FDFBFAFBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFCCCCCC111111222222888888BBBBBBBBBBBBBBBBBB + BBBBBB000000FFFFFFFFFFFFFFFFFFEEEEEEDDDDDDFFFFFFFFFFFFFFFFFFEEEE + EE222222888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFF + FFFFFFFFFF888888222222FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999 + DDDDDDFFFFFFFFFFFFFFFFFF555555999999FFFFFFFFFFFFFFFFFFEEEEEEDDDD + DDFFFFFFFFFFFFFFFFFFEEEEEE222222888888FFFFFFFFFFFFFFFFFFFFFFFF44 + 4444111111666666AAAAAA444444FFFFFF444444BBBBBBFFFFFF444444FFFFFF + FFFFFFFFFFFFFFFFFFCCCCCC333333222222666666DDDDDD333333888888FFFF + FFFFFFFFFFFFFFEEEEEE666666DDDDDDFFFFFF888888111111444444999999EE + EEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFFBBBBBB8888883333338888883333338888 + 88333333666666666666BBBBBBFFFFFFFFFFFFFFFFFF555555888888222222EE + EEEEFFFFFF999999555555FFFFFF000000FFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8888888888 + 88FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB444444FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB444444FFFFFFFFFFFFEEEEEEFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFAF9FAF5F4F5F5F3F5E6E6E6B4B4B4818181E9958DE9 + 958DE9958DE9958DFDFBFDFDFBFDFDFCFDFDFCFDFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCC + CC000000333333444444444444444444444444444444FFFFFFFFFFFFFFFFFFAA + AAAA111111CCCCCCFFFFFFFFFFFFFFFFFF999999222222FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFBBBBBB000000FFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFDDDDDD000000DDDDDD999999888888FFFFFF88888855 + 5555FFFFFFFFFFFFFFFFFFAAAAAA111111CCCCCCFFFFFFFFFFFFFFFFFF999999 + 222222FFFFFFFFFFFFFFFFFFFFFFFFAAAAAA000000444444DDDDDD1111114444 + 44111111333333444444444444FFFFFFFFFFFFBBBBBBEEEEEE333333222222CC + CCCC888888333333DDDDDDEEEEEECCCCCCFFFFFFFFFFFFFFFFFF888888111111 + 888888BBBBBB222222888888666666111111666666FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFEEEEEEBB + BBBB888888333333888888333333888888333333666666666666BBBBBBEEEEEE + DDDDDD333333CCCCCCFFFFFF999999AAAAAA999999BBBBBB444444FFFFFF0000 + 00FFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44444400000044444433 + 3333111111444444444444777777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF000000FFFFFFFFFFFF222222222222555555888888BBBBBBFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF6F4F6 + F5F3F5E6E6E6B4B4B4818181E9958DE9958DE9958DE9958DFDFBFDFDFBFDFEFC + FEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888333333FFFFFFFFFFFFFFFF + FFEEEEEE000000CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFF + FFFFFFFFFFBBBBBB000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999777777 + FFFFFF222222999999FFFFFFBBBBBB333333FFFFFFFFFFFFFFFFFFFFFFFF8888 + 88333333FFFFFFFFFFFFFFFFFFEEEEEE000000CCCCCCFFFFFFFFFFFFFFFFFFFF + FFFF111111BBBBBBEEEEEEDDDDDDBBBBBB333333888888CCCCCCFFFFFFFFFFFF + FFFFFF000000FFFFFFFFFFFFCCCCCC111111CCCCCCCCCCCCFFFFFFBBBBBB4444 + 44FFFFFFFFFFFFFFFFFFFFFFFF999999000000777777888888FFFFFFFFFFFFFF + FFFFDDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFCCCCCC4444443333331111113333331111113333 + 33111111222222222222444444CCCCCCFFFFFF999999111111CCCCCCCCCCCC11 + 1111888888888888333333BBBBBB000000FFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8888888888 + 88FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB333333BBBBBBBBBBBBCCCCCCFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF333333CCCCCCFFFFFFFFFFFFCCCCCC + AAAAAA888888CCCCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFDFCFDF6F4F6F5F3F5DADADAB4B4B48F8F8FE9958DE9 + 958DE9958DE9958DFDFBFDFDFBFDFEFCFEFDFDFDFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEEBBBBBBBBBB + BBAAAAAA111111BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBFFFFFFFFFFFFFF + FFFFFFFFFF444444555555888888888888888888222222888888FFFFFFFFFFFF + FFFFFFFFFFFFBBBBBB000000FFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEEEEEE999999FFFFFFFFFFFFDDDDDDCC + CCCCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF444444555555888888888888888888 + 222222888888FFFFFFFFFFFFCCCCCC4444441111113333331111113333337777 + 77888888888888555555222222CCCCCCFFFFFF44444444444444444444444422 + 2222222222444444444444444444777777FFFFFFFFFFFFFFFFFFBBBBBBBBBBBB + 666666777777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFF66 + 6666999999444444BBBBBB444444BBBBBB444444888888888888FFFFFFFFFFFF + FFFFFFFFFFFFAAAAAACCCCCCCCCCCC999999CCCCCC3333331111114444444444 + 44FFFFFFFFFFFFFFFFFFFFFFFF888888888888FFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFF888888555555FFFFFFFFFFFF666666888888888888 + 888888888888DDDDDDFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBBBBBBBBBBBBBBBBBBBB88 + 8888333333DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6666662222 + 22000000222222444444BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCFCFCF6F4F6 + F5F3F5E6E6E6B4B4B4818181E9958DE9958DE9958DE9958DFDFBFDFDFBFDFDFC + FDFCFBFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFCCCCCC444444444444444444111111333333444444444444 + 444444444444444444FFFFFFFFFFFFFFFFFFFFFFFFBBBBBB0000008888888888 + 88888888777777EEEEEEFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB000000FFFFFFFF + FFFFFFFFFFBBBBBB000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFBBBBBB000000888888888888888888777777EEEEEEFFFFFFFFFFFFEEEEEEBB + BBBB333333888888DDDDDD777777333333EEEEEE999999222222BBBBBBFFFFFF + FFFFFFBBBBBB888888888888888888444444444444888888888888888888BBBB + BBFFFFFFFFFFFFFFFFFF44444444444444444400000022222200000033333399 + 9999FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888 + 888888FFFFFFFFFFFFFFFFFFFFFFFF9999991111111111113333331111113333 + 33111111222222222222999999FFFFFFBBBBBB00000000000000000000000000 + 0000444444BBBBBB444444FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD + DDDDDDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBBBBBB4444 + 44FFFFFFFFFFFF999999888888888888888888888888DDDDDDFFFFFFFFFFFFFF + FFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFBBBBBB8888887777774444443333331111114444444444441111118888 + 88FFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF888888888888BBBBBBCCCCCCFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFAF9FAF5F4F5F5F3F5DADADAB9B9B98F8F8FE9958DE9 + 958DE9958DE9958DFDFBFDFDFBFDFDFBFDFAF8FAFEFEFEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFF888888777777FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFF333333888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFDDDDDD888888DDDDDDFFFFFFFFFFFFCCCCCC444444FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF333333888888FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF444444BBBBBBFFFFFFFFFFFF8888 + 88333333666666EEEEEEFFFFFFFFFFFFFFFFFFBBBBBB88888888888888888844 + 4444444444888888888888888888BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFF555555999999FFFFFFEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFF888888666666BBBBBBBBBBBBFFFFFFFFFFFFFF + FFFF777777555555BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBDDDDDDFFFFFF + FFFFFFFFFFFFFFFFFF444444BBBBBBFFFFFFFFFFFFBBBBBB444444FFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFDDDDDD555555FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000BBBBBBFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBB + BBBB444444FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000 + BBBBBBFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FF999999555555FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEF7F6F7F5F3F5 + F5F3F5E6E6E6C0C0C0A2A2A2E9958DE9958DEAA39EE9958DFBEBE9FDFBFDFDFB + FDF7F6F7FCFBFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCCCCCC999999FFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDEEEEEEFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFDDDDDDEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFF999999DDDDDDFFFFFFFFFFFFFFFFFF666666EEEEEEFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999999999FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAAAAAAAAAAAAFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF999999 + 444444444444444444FFFFFFFFFFFFFFFFFFDDDDDD888888FFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF777777BBBBBBFF + FFFFFFFFFFDDDDDD888888FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDD888888FFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDDDDDDAAAAAAFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFAF8FAF6F4F6F5F3F5F5F3F5E6E6E6CFCFCFB4B4B4E9958DEB + AFABEBBAB6E9958DF0CCC3FDFBFDFDFBFDFBF9FBF8F6F8FCFBFCFFFEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFEFEFEFEFEFEFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFEFEFAF8FAF6F4F6F5F3F5F5F3F5 + F5F3F5EDEBEDCFCFCFE5A39DE9958DF3D4CBF7E6E2E9958DE9958DFDFBFDFDFB + FDFDFBFDFBF9FBF7F6F7FAF9FAFCFCFCFEFEFEFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFF + FFFEFFFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFDFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFDFDFDFDFCFDFCFBFCFC + FBFCFCFBFCFDFCFDFDFCFDFDFCFDFDFCFDFCFCFCFCFBFCFCFBFCFBFAFBFBFAFB + FAF9FAF9F8F9F9F8F9F9F7F9F9F7F9F9F8F9FAF8FAFAF9FAFAFAFAFBFAFBFBFA + FBFBFAFBFCFBFCFCFCFCFDFCFDFDFDFDFEFDFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFFFEFFFEFEFEFEFE + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFEFF + FEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFFFEFFFFFE + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FEFFFEFEFEFEFEFEFEFEFEFEFEFEFEFDFEFEFDFEFDFDFDFDFDFDFDFDFDFEFDFE + FEFDFEFDFDFDFDFCFDFCFBFCFBFAFBFBFAFBFCFBFCFDFCFDFDFDFDFCFCFCFAF9 + FAF7F6F7F6F4F6F5F3F5F5F3F5F5F3F5F5F3F5F5F3F5E9D5D3E9958DEAA39EFD + FBFDFDFBFDEAB3AEE9958DEAA39EFDF9F7FDFBFDFDFBFDFDFBFDFDFBFDFDFCFD + FEFCFEFEFDFEFEFDFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFEFE + FEFEFEFEFEFEFEFEFDFEFEFDFEFEFDFEFEFDFEFEFCFEFEFCFEFEFCFEFEFCFEFD + FCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFD + FDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFCFDFDFCFDFDFCFDFEFCFEFEFCFEFEFCFEFEFCFEFDFCFDFDFCFDFDFCFDFDFC + FDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFD + FCFDFDFCFDFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFE + FEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFDFEFEFDFEFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFDFEFEFD + FEFEFDFEFEFDFEFEFDFEFEFDFEFEFDFEFEFDFEFEFCFEFEFCFEFEFCFEFEFCFEFE + FCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFEFCFEFDFCFDFDFCFDFDFCFD + FDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFCFDFDFC + FDFDFBFDFDFBFDFDFBFDFDFCFDFDFCFDFDFCFDFDFCFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FBF9FBF9E5E4E89B96E9958DEFC5C2FDFBFDFDFBFDFBF3F3EAB3AEE9958DE995 + 8DF1CFCDFBF3F3FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFD + FBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFD + FDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFB + FDFDFBFDFDFBFDFDFBFDFDFBFDFBF1EFEBBAB6E9958DE9958DEBBAB6FDFBFDFD + FBFDFDFBFDFDFBFDFBF3F3EAB3AEE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE39592EEC5BBFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDFDFBFDF7E3 + DEEBBAB6E79E9BE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9 + 958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958D + E9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE9958DE995 + 8DE9958DE9958DE9958DE9958DE79E9BEBBAB6FBF1EFFDFBFDFDFBFDFDFBFDFD + FBFD} + Visible = False + end +end diff --git a/DCHookTest/Notify.h b/DCHookTest/Notify.h new file mode 100644 index 0000000..23e10c5 --- /dev/null +++ b/DCHookTest/Notify.h @@ -0,0 +1,33 @@ +//--------------------------------------------------------------------------- + +#ifndef NotifyH +#define NotifyH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TNotifyForm : public TForm +{ +__published: // IDE ŠÇ—‚̃Rƒ“ƒ|[ƒlƒ“ƒg + TImage *EnableBmp; + TImage *DisableBmp; + void __fastcall FormShow(TObject *Sender); + void __fastcall FormMouseMove(TObject *Sender, TShiftState Shift, int X, + int Y); + void __fastcall FormDestroy(TObject *Sender); +private: // ƒ†[ƒU[éŒ¾ + HRGN hRgn; +public: // ƒ†[ƒU[éŒ¾ + bool enable; + __fastcall TNotifyForm(TComponent* Owner); + void Setup(); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TNotifyForm *NotifyForm; +//--------------------------------------------------------------------------- +#endif + diff --git a/DCHookTest/OCRTextFrm.cpp b/DCHookTest/OCRTextFrm.cpp new file mode 100644 index 0000000..69a35d9 --- /dev/null +++ b/DCHookTest/OCRTextFrm.cpp @@ -0,0 +1,46 @@ +//--------------------------------------------------------------------------- + +#include +#pragma hdrstop + +#include "OCRTextFrm.h" +#include "Util.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma link "TntStdCtrls" +#pragma link "TntStdCtrls" +#pragma resource "*.dfm" +TOCRTextForm *OCRTextForm; +const char *sOCRText = "OCRText"; +//--------------------------------------------------------------------------- +__fastcall TOCRTextForm::TOCRTextForm(TComponent* Owner) + : TForm(Owner) +{ + VCL_SIZEABLE(); +} +//--------------------------------------------------------------------------- +void __fastcall TOCRTextForm::FormShow(TObject *Sender) +{ + LoadForm(sOCRText, this, NULL); +} +//--------------------------------------------------------------------------- +void __fastcall TOCRTextForm::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + SaveForm(sOCRText, this, NULL); +} +//--------------------------------------------------------------------------- +void TOCRTextForm::SetText(const wchar_t *text) +{ + int wlen = wcslen(text); + char *buf = new char[wlen*2+1]; + if (!buf) return; + BOOL defchar = FALSE; + WideCharToMultiByte( CP_ACP, 0, + text, wlen, + buf, wlen*2+1, 0, &defchar ); + memo->Text = buf; + delete[] buf; +} + + diff --git a/DCHookTest/OCRTextFrm.dfm b/DCHookTest/OCRTextFrm.dfm new file mode 100644 index 0000000..8018b87 --- /dev/null +++ b/DCHookTest/OCRTextFrm.dfm @@ -0,0 +1,27 @@ +object OCRTextForm: TOCRTextForm + Left = 192 + Top = 133 + BorderStyle = bsDialog + Caption = '”FŽ¯ƒeƒLƒXƒg' + ClientHeight = 343 + ClientWidth = 567 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = '‚l‚r ‚oƒSƒVƒbƒN' + Font.Style = [] + OldCreateOrder = False + OnCloseQuery = FormCloseQuery + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 12 + object memo: TMemo + Left = 0 + Top = 0 + Width = 567 + Height = 343 + Align = alClient + TabOrder = 0 + end +end diff --git a/DCHookTest/OCRTextFrm.h b/DCHookTest/OCRTextFrm.h new file mode 100644 index 0000000..f010df7 --- /dev/null +++ b/DCHookTest/OCRTextFrm.h @@ -0,0 +1,26 @@ +//--------------------------------------------------------------------------- + +#ifndef OCRTextFrmH +#define OCRTextFrmH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +//--------------------------------------------------------------------------- +class TOCRTextForm : public TForm +{ +__published: // IDE ŠÇ—‚̃Rƒ“ƒ|[ƒlƒ“ƒg + TMemo *memo; + void __fastcall FormShow(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); +private: // ƒ†[ƒU[éŒ¾ +public: // ƒ†[ƒU[éŒ¾ + __fastcall TOCRTextForm(TComponent* Owner); + void SetText(const wchar_t *text); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TOCRTextForm *OCRTextForm; +//--------------------------------------------------------------------------- +#endif + diff --git a/DCHookTest/PopupConfig.cpp b/DCHookTest/PopupConfig.cpp new file mode 100644 index 0000000..c4383e8 --- /dev/null +++ b/DCHookTest/PopupConfig.cpp @@ -0,0 +1,228 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "PopupConfig.h" +#include "Util.h" +#include "prgprof.h" +#include "../DCHook/DCHook.h" +//--------------------------------------------------------------------------- +#pragma package(smart_init) +#pragma resource "*.dfm" +TPopupConfigDlg *PopupConfigDlg; +//--------------------------------------------------------------------------- +__fastcall TPopupConfigDlg::TPopupConfigDlg(TComponent* Owner) + : TForm(Owner) +{ + MODIAvail = true; +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::cbGroupOpenClick(TObject *Sender) +{ + bool f = cbGroupOpen->Checked; + edGroupName->Enabled = f; + lbGroupName->Enabled = f; +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::FormShow(TObject *Sender) +{ +#if USE_DDE + cbGroupOpenClick( this ); + + // Add groups to combo-box // + TAppIni ini; + if ( !ini.hroot ){ + return; + } + + ini.ReadValues( PFS_GROUP, edGroupName->Items ); + + if (!cbGroupOpen->Checked ){ + int sel = ini.ReadInteger( PFS_COMMON, PFS_GRPSEL, -1 ); + edGroupName->ItemIndex = sel; + } +#else // !USE_DDE + // WM_COPYDATA‚̏ꍇ‚́AŽ«‘ƒOƒ‹[ƒvŽw’è‚Í‚Å‚«‚È‚¢ + cbGroupOpen->Enabled = false; + lbGroupName->Enabled = false; + edGroupName->Enabled = false; + lb1->Enabled = false; + lb2->Enabled = false; +#endif + if (fWow64) + cbUse64->Visible = true; +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::FormCloseQuery(TObject *Sender, + bool &CanClose) +{ + if (ModalResult!=mrOk) return; + + if (cbToggleKey->ItemIndex != 0){ + if (cbToggleKey->ItemIndex-1 == cbPopupKey->ItemIndex){ + // “¯‚¶ƒL[‚ÍŠ„‚è“–‚Ä‚ç‚ê‚È‚¢ + Application->MessageBox("ƒ|ƒbƒvƒAƒbƒvŒŸõ‚ƉEƒNƒŠƒbƒNŒŸõON/OFF‚Í“¯‚¶ƒL[‚ðŠ„‚è“–‚Ä‚ç‚ê‚Ü‚¹‚ñ",Caption.c_str(),MB_OK); + CanClose = false; + return; + } + } +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::cbCaptureModeChange(TObject *Sender) +{ + bool f = cbCaptureMode->ItemIndex != 2; +#if 0 + lbScaling->Enabled = f; + lbScaleNormal->Enabled = f; + tbScaling->Enabled = f; + lbScaleMax->Enabled = f; +#endif + lbAMODIPath->Enabled = f; + edAMODIPath->Enabled = f; + btnBrowse->Enabled = f; +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::btnHelpClick(TObject *Sender) +{ + ShowManual(Handle); +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::actHelpExecute(TObject *Sender) +{ + ShowManual(Handle); +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::lbDebugDblClick(TObject *Sender) +{ + miShowAMODI->Visible = true; +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::miShowAMODIClick(TObject *Sender) +{ + ShowAMODI(); +} +//--------------------------------------------------------------------------- +void __fastcall TPopupConfigDlg::cbDPISettingClick(TObject *Sender) +{ + bool setting = cbDPISetting->Checked; + lbScaling->Enabled = setting; + lbScaleNormal->Enabled = setting; + tbScaling->Enabled = setting; +} +//--------------------------------------------------------------------------- +/* +Ctrl+‰EƒNƒŠƒbƒN +Shift+‰EƒNƒŠƒbƒN +Alt+‰EƒNƒŠƒbƒN +Ctrl+Shift+‰EƒNƒŠƒbƒN +Ctrl+Alt+‰EƒNƒŠƒbƒN +Shift+Alt+‰EƒNƒŠƒbƒN +Ctrl+¶ƒNƒŠƒbƒN +Shift+¶ƒNƒŠƒbƒN +Alt+¶ƒNƒŠƒbƒN +Ctrl+Shift+¶ƒNƒŠƒbƒN +Ctrl+Alt+¶ƒNƒŠƒbƒN +Shift+Alt+¶ƒNƒŠƒbƒN +¶ƒNƒŠƒbƒN+‰EƒNƒŠƒbƒN¨‹p‰º +*/ +int KeyCombTable[] = { + KF_CONTROL, + KF_SHIFT, + KF_MENU, + KF_CONTROL + KF_SHIFT, + KF_CONTROL + KF_MENU, + KF_SHIFT + KF_MENU, + KF_CONTROL + KF_LEFTCLICK, + KF_SHIFT + KF_LEFTCLICK, + KF_MENU + KF_LEFTCLICK, + KF_CONTROL + KF_SHIFT + KF_LEFTCLICK, + KF_CONTROL + KF_MENU + KF_LEFTCLICK, + KF_SHIFT + KF_MENU + KF_LEFTCLICK, + KF_MIDCLICK, + KF_CONTROL + KF_MIDCLICK, + KF_SHIFT + KF_MIDCLICK, + KF_MENU + KF_MIDCLICK, + KF_CONTROL + KF_SHIFT + KF_MIDCLICK, + KF_CONTROL + KF_MENU + KF_MIDCLICK, + KF_SHIFT + KF_MENU + KF_MIDCLICK, + //KF_LRCLICK, + 0 +}; +// key combination -> index +int KeyCombToIndex( int keycomb ) +{ + int i; + for (i=0;KeyCombTable[i];i++){ + if (keycomb == KeyCombTable[i]) + return i; + } + return -1; +} +int IndexToKeyComb( int index ) +{ + if (index < 0) + return 0; + return KeyCombTable[index]; +} +void TPopupConfigDlg::SetPopupKey( int keycomb ) +{ + cbPopupKey->ItemIndex = KeyCombToIndex( keycomb ); +} +int TPopupConfigDlg::GetPopupKey( ) +{ + return IndexToKeyComb( cbPopupKey->ItemIndex ); +} +void TPopupConfigDlg::SetToggleKey( int keycomb ) +{ + cbToggleKey->ItemIndex = KeyCombToIndex( keycomb )+1; +} +int TPopupConfigDlg::GetToggleKey( ) +{ + return IndexToKeyComb( cbToggleKey->ItemIndex-1 ); +} + +void TPopupConfigDlg::SetDPIDetect(bool dpi_detect) +{ + cbDPISetting->Checked = !dpi_detect; +} +bool TPopupConfigDlg::GetDPIDetect() +{ + return !cbDPISetting->Checked; +} +void TPopupConfigDlg::SetScaler(int scale) +{ + if (scale<120){ + tbScaling->Position = 0; + } else + if (scale<144){ + tbScaling->Position = 1; + } else { + tbScaling->Position = 2; + } +} +int TPopupConfigDlg::GetScaler() +{ + switch (tbScaling->Position){ + default: return 0; + case 1: return 120; + case 2: return 144; + } +} + +void TPopupConfigDlg::SetCaptureMode(int mode) +{ + switch (mode){ + case CM_TEXT | CM_IMAGE: cbCaptureMode->ItemIndex = 0; break; + case CM_IMAGE: cbCaptureMode->ItemIndex = 1; break; + case CM_TEXT: cbCaptureMode->ItemIndex = 2; break; + } +} +int TPopupConfigDlg::GetCaptureMode() +{ + switch (cbCaptureMode->ItemIndex){ + default: case 0: return CM_TEXT | CM_IMAGE; + case 1: return CM_IMAGE; + case 2: return CM_TEXT; + } +} + diff --git a/DCHookTest/PopupConfig.dfm b/DCHookTest/PopupConfig.dfm new file mode 100644 index 0000000..14e7ab9 --- /dev/null +++ b/DCHookTest/PopupConfig.dfm @@ -0,0 +1,331 @@ +object PopupConfigDlg: TPopupConfigDlg + Left = 414 + Top = 142 + BorderStyle = bsDialog + Caption = '‚Ç‚±ƒ|ƒbƒv‚̐ݒè' + ClientHeight = 419 + ClientWidth = 306 + Color = clBtnFace + Font.Charset = SHIFTJIS_CHARSET + Font.Color = clWindowText + Font.Height = -12 + Font.Name = '‚l‚r ‚oƒSƒVƒbƒN' + Font.Style = [] + OldCreateOrder = False + PopupMenu = pmDebugMenu + Position = poScreenCenter + OnCloseQuery = FormCloseQuery + OnShow = FormShow + PixelsPerInch = 96 + TextHeight = 12 + object lb1: TLabel + Left = 40 + Top = 54 + Width = 240 + Height = 12 + Caption = 'Žw’肵‚È‚¢ê‡‚́APDIC–{‘Ì‚ªŒ»ÝŠJ‚¢‚Ä‚¢‚é' + end + object lb2: TLabel + Left = 40 + Top = 70 + Width = 136 + Height = 12 + Caption = 'Ž«‘ƒOƒ‹[ƒv‚ðŽg—p‚µ‚Ü‚·' + end + object lbGroupName: TLabel + Left = 40 + Top = 91 + Width = 87 + Height = 12 + Caption = 'Ž«‘¸ÞÙ°Ìߖ¼(&N)' + end + object Label1: TLabel + Left = 24 + Top = 120 + Width = 107 + Height = 12 + Caption = 'ƒ|ƒbƒvƒAƒbƒvŒŸõ(&P)F' + FocusControl = cbPopupKey + end + object Label2: TLabel + Left = 24 + Top = 144 + Width = 122 + Height = 12 + Caption = '‰E¸Ø¯¸ŒŸõON/OFF(&R):' + FocusControl = cbToggleKey + end + object lbAMODIPath: TLabel + Left = 27 + Top = 302 + Width = 139 + Height = 12 + Caption = 'AM&ODI‚̏ꏊ(ã‹‰ŽÒŒü‚¯)' + Enabled = False + FocusControl = edAMODIPath + end + object lbScaling: TLabel + Left = 40 + Top = 386 + Width = 53 + Height = 12 + Caption = 'Šg‘å—¦(&M)' + Enabled = False + FocusControl = tbScaling + Visible = False + end + object lbScaleNormal: TLabel + Left = 117 + Top = 387 + Width = 24 + Height = 12 + Caption = '•W€' + Enabled = False + Visible = False + end + object lbScaleMax: TLabel + Left = 319 + Top = 366 + Width = 24 + Height = 12 + Caption = 'Å‘å' + Visible = False + end + object lbDebug: TLabel + Left = 264 + Top = 8 + Width = 20 + Height = 12 + Caption = ' ' + OnDblClick = lbDebugDblClick + end + object cbGroupOpen: TCheckBox + Left = 24 + Top = 32 + Width = 249 + Height = 17 + Caption = 'Ž«‘ƒOƒ‹[ƒv‚ðŽw’è‚·‚é(&G)' + TabOrder = 1 + OnClick = cbGroupOpenClick + end + object cbCtrlClose: TCheckBox + Left = 24 + Top = 224 + Width = 233 + Height = 17 + Caption = 'CtrlƒL[‚𗣂µ‚½‚çÎ߯Ìß±¯Ì߂ð•Â‚¶‚é(&C)' + TabOrder = 6 + Visible = False + end + object btnOK: TButton + Left = 12 + Top = 379 + Width = 75 + Height = 25 + Caption = 'OK' + Default = True + ModalResult = 1 + TabOrder = 14 + end + object btnCancel: TButton + Left = 112 + Top = 379 + Width = 75 + Height = 25 + Cancel = True + Caption = 'Cancel' + ModalResult = 2 + TabOrder = 15 + end + object edGroupName: TComboBox + Left = 136 + Top = 88 + Width = 145 + Height = 20 + ItemHeight = 12 + TabOrder = 2 + end + object cbBanner: TCheckBox + Left = 24 + Top = 8 + Width = 225 + Height = 17 + Caption = '‹N“®Žž‚ɃXƒvƒ‰ƒbƒVƒ…‚ð•\Ž¦‚·‚é(&B)' + Checked = True + State = cbChecked + TabOrder = 0 + end + object Memo1: TMemo + Left = 32 + Top = 168 + Width = 257 + Height = 49 + TabStop = False + Alignment = taCenter + BorderStyle = bsNone + Color = clBtnFace + Lines.Strings = ( + '¦"‰E¸Ø¯¸ŒŸõ"‚Ƃ́Aƒ}ƒEƒX‚̉EƒNƒŠƒbƒN‚¾‚¯‚Å' + 'ƒ|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤‹@”\‚Å‚·' + '¦‘g‚ݍ‡‚킹‚É‚æ‚Á‚Ă̓AƒvƒŠƒP[ƒVƒ‡ƒ“‚Æ' + '‹£‡‚µ‚Ä‚µ‚Ü‚¤ê‡‚ª‚ ‚è‚Ü‚·B') + ReadOnly = True + TabOrder = 5 + end + object cbPopupKey: TComboBox + Left = 152 + Top = 115 + Width = 130 + Height = 20 + Style = csDropDownList + ItemHeight = 12 + TabOrder = 3 + Items.Strings = ( + 'Ctrl+‰EƒNƒŠƒbƒN' + 'Shift+‰EƒNƒŠƒbƒN' + 'Alt+‰EƒNƒŠƒbƒN' + 'Ctrl+Shift+‰EƒNƒŠƒbƒN' + 'Ctrl+Alt+‰EƒNƒŠƒbƒN' + 'Shift+Alt+‰EƒNƒŠƒbƒN' + 'Ctrl+¶ƒNƒŠƒbƒN' + 'Shift+¶ƒNƒŠƒbƒN' + 'Alt+¶ƒNƒŠƒbƒN' + 'Ctrl+Shift+¶ƒNƒŠƒbƒN' + 'Ctrl+Alt+¶ƒNƒŠƒbƒN' + 'Shift+Alt+¶ƒNƒŠƒbƒN' + '’†ƒNƒŠƒbƒN' + 'Ctrl+’†ƒNƒŠƒbƒN' + 'Shift+’†ƒNƒŠƒbƒN' + 'Alt+’†ƒNƒŠƒbƒN' + 'Ctrl+Shift+’†ƒNƒŠƒbƒN' + 'Ctrl+Alt+’†ƒNƒŠƒbƒN' + 'Shift+Alt+’†ƒNƒŠƒbƒN') + end + object cbToggleKey: TComboBox + Left = 152 + Top = 140 + Width = 129 + Height = 20 + Style = csDropDownList + ItemHeight = 12 + TabOrder = 4 + Items.Strings = ( + '‚È‚µ' + 'Ctrl+‰EƒNƒŠƒbƒN' + 'Shift+‰EƒNƒŠƒbƒN' + 'Alt+‰EƒNƒŠƒbƒN' + 'Ctrl+Shift+‰EƒNƒŠƒbƒN' + 'Ctrl+Alt+‰EƒNƒŠƒbƒN' + 'Shift+Alt+‰EƒNƒŠƒbƒN' + 'Ctrl+¶ƒNƒŠƒbƒN' + 'Shift+¶ƒNƒŠƒbƒN' + 'Alt+¶ƒNƒŠƒbƒN' + 'Ctrl+Shift+¶ƒNƒŠƒbƒN' + 'Ctrl+Alt+¶ƒNƒŠƒbƒN' + 'Shift+Alt+¶ƒNƒŠƒbƒN') + end + object cbIgnoreJ: TCheckBox + Left = 24 + Top = 248 + Width = 225 + Height = 17 + Caption = '‰p”Žš‚Ì‚ÝŒŸõ‚·‚é(&J)' + TabOrder = 7 + end + object edAMODIPath: TEdit + Left = 24 + Top = 317 + Width = 169 + Height = 20 + Enabled = False + TabOrder = 9 + end + object btnBrowse: TButton + Left = 200 + Top = 314 + Width = 68 + Height = 25 + Caption = 'ŽQÆ...' + Enabled = False + TabOrder = 10 + end + object tbScaling: TTrackBar + Left = 146 + Top = 383 + Width = 121 + Height = 20 + Enabled = False + Max = 2 + Orientation = trHorizontal + PageSize = 1 + Frequency = 1 + Position = 0 + SelEnd = 0 + SelStart = 0 + TabOrder = 13 + ThumbLength = 8 + TickMarks = tmBottomRight + TickStyle = tsAuto + Visible = False + end + object btnHelp: TButton + Left = 212 + Top = 379 + Width = 75 + Height = 25 + Caption = '&Help' + TabOrder = 16 + OnClick = btnHelpClick + end + object cbCaptureMode: TComboBox + Left = 24 + Top = 276 + Width = 193 + Height = 20 + Style = csDropDownList + ItemHeight = 12 + TabOrder = 8 + OnChange = cbCaptureModeChange + Items.Strings = ( + '•¶Žš”FŽ¯{•¶Žš’Šo' + '•¶Žš”FŽ¯‚Ì‚Ý' + '•¶Žš’Šo‚Ì‚Ý') + end + object cbUse64: TCheckBox + Left = 24 + Top = 344 + Width = 193 + Height = 17 + Caption = '&64ƒrƒbƒgƒtƒbƒN‚ðŽg—p‚·‚é' + TabOrder = 11 + Visible = False + end + object cbDPISetting: TCheckBox + Left = 24 + Top = 362 + Width = 193 + Height = 17 + Caption = '‰ð‘œ“xÝ’è‚ð‚·‚é(&D)' + TabOrder = 12 + Visible = False + OnClick = cbDPISettingClick + end + object ActionList1: TActionList + Left = 272 + Top = 272 + object actHelp: TAction + Caption = 'Help' + ShortCut = 112 + OnExecute = actHelpExecute + end + end + object pmDebugMenu: TPopupMenu + Left = 264 + Top = 216 + object miShowAMODI: TMenuItem + Caption = 'Show &AMODI' + Visible = False + OnClick = miShowAMODIClick + end + end +end diff --git a/DCHookTest/PopupConfig.h b/DCHookTest/PopupConfig.h new file mode 100644 index 0000000..423bfda --- /dev/null +++ b/DCHookTest/PopupConfig.h @@ -0,0 +1,82 @@ +//--------------------------------------------------------------------------- +#ifndef PopupConfigH +#define PopupConfigH +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +//--------------------------------------------------------------------------- + +enum eCaptureMode { + CM_TEXT = 1, // •¶Žš’Šo + CM_IMAGE = 2, // OCR +}; + +class TPopupConfigDlg : public TForm +{ +__published: // IDE ŠÇ—‚̃Rƒ“ƒ|[ƒlƒ“ƒg + TCheckBox *cbGroupOpen; + TLabel *lb1; + TLabel *lbGroupName; + TCheckBox *cbCtrlClose; + TButton *btnOK; + TButton *btnCancel; + TLabel *lb2; + TComboBox *edGroupName; + TCheckBox *cbBanner; + TMemo *Memo1; + TLabel *Label1; + TComboBox *cbPopupKey; + TLabel *Label2; + TComboBox *cbToggleKey; + TCheckBox *cbIgnoreJ; + TLabel *lbAMODIPath; + TEdit *edAMODIPath; + TButton *btnBrowse; + TLabel *lbScaling; + TTrackBar *tbScaling; + TLabel *lbScaleNormal; + TLabel *lbScaleMax; + TButton *btnHelp; + TActionList *ActionList1; + TAction *actHelp; + TLabel *lbDebug; + TPopupMenu *pmDebugMenu; + TMenuItem *miShowAMODI; + TComboBox *cbCaptureMode; + TCheckBox *cbUse64; + TCheckBox *cbDPISetting; + void __fastcall cbGroupOpenClick(TObject *Sender); + void __fastcall FormShow(TObject *Sender); + void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose); + void __fastcall btnHelpClick(TObject *Sender); + void __fastcall actHelpExecute(TObject *Sender); + void __fastcall lbDebugDblClick(TObject *Sender); + void __fastcall miShowAMODIClick(TObject *Sender); + void __fastcall cbCaptureModeChange(TObject *Sender); + void __fastcall cbDPISettingClick(TObject *Sender); +private: // ƒ†[ƒU[éŒ¾ + bool MODIAvail; +public: // ƒ†[ƒU[éŒ¾ + __fastcall TPopupConfigDlg(TComponent* Owner); + void SetPopupKey( int keycomb ); + int GetPopupKey( ); + void SetToggleKey( int keycomb ); + int GetToggleKey( ); + void SetDPIDetect(bool dpi_detect); + bool GetDPIDetect(); + void SetScaler(int scale); + int GetScaler(); + void SetMODIAvail(bool avail) { MODIAvail = avail; } + void SetCaptureMode(int mode); + int GetCaptureMode(); +}; +//--------------------------------------------------------------------------- +extern PACKAGE TPopupConfigDlg *PopupConfigDlg; +//--------------------------------------------------------------------------- +#endif + diff --git a/DCHookTest/StringLib.cpp b/DCHookTest/StringLib.cpp new file mode 100644 index 0000000..f630822 --- /dev/null +++ b/DCHookTest/StringLib.cpp @@ -0,0 +1,243 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop + +#include "StringLib.h" + +//--------------------------------------------------------------------------- +#pragma package(smart_init) + +// pos‚©‚ç’PŒê‚ðØ‚èo‚· +// pos‚Ístr‚©‚ç‚̃IƒtƒZƒbƒg +// start,end‚Ístr‚©‚ç‚̃IƒtƒZƒbƒg‚ð•Ô‚· +// prevstart‚́Astart‚Ì‚P‚‘O‚Ì’PŒêA–³‚¢ê‡‚Ístart‚Æ“¯‚¶’l +// fLongest‚ªTRUE‚̏ꍇ‚́AÅ‚10Œê‚Ü‚Åget‚·‚é(.)‚ðI‚í‚è‚Æ‚Ý‚È‚· +// about : ‚¢‚¢‰ÁŒ¸‚È‚Æ‚±‚ë‚ðƒNƒŠƒbƒN‚µ‚Ä‚à’PŒê‚³‚¦‚ ‚ê‚ΕK‚¸get‚·‚é +// alnum : ‰p”ŽšˆÈŠO‚Í–³Ž‹ + +BOOL GetWord( const tchar *str, int pos, int &start, int &end, int &prevstart, bool fLongest, int wordcount, bool about, bool alnum ) +{ + if ( !about ) + if ( !IsWordChar( *(str+pos) ) ) + return FALSE; +// while ( *(str+pos) == ' ' || *(str+pos) == '\t' ){ +// pos++; +// } + + // ‰üs‚̏ꍇ‚Í–³‚µ + if ( str[pos] == '\r' || str[pos] == '\n' ){ + return false; + } + + // pos‚ª•¶Žš—ñ‚̏I’[A‚ ‚é‚¢‚Í•¶Žš—ñ‚̏I’[‚©‚ç‚P‚‘O‚̉üs‚Å‚ ‚éê‡‚Í‚¾‚ß // + if ( !str[pos] || (!str[pos+1] && ((tuchar)str[pos] < ' ')) ) + return false; + + const tchar *orgp = str; + const tchar *p = orgp; +rescan: + // ’PŒê‚̐擪‚ð’T‚· // + const tchar *wordtop = NULL; + while ( *p ){ + if ( alnum ){ + // ‰p”Žš‚Ì‚Ý + if ( isalphanum(*p) ){ + // ’PŒê‚ÌŽn‚Ü‚è + wordtop = p; + break; + } + p = NEXT_CHAR(p); + } else { + // •¶ŽšŽí‚ð‹æ•Ê‚µ‚È‚¢ + if ( IsWordChar( *p ) ) + { + wordtop = p; + break; + } + p++; + } + } + if ( !wordtop ) + wordtop = p; + const tchar *wordtail = NULL; + const tchar *wordprev = NULL; + BOOL fSpc = FALSE; + // pos‚É‚ ‚é’PŒê‚Ìstart‚Æend‚ð‹‚ß‚é + while ( *p ){ + if ( !IsWordChar( *p ) || (alnum && !isalphanum(*p)) ){ + // ”ñ’PŒê•¶Žš + if ( orgp + pos < p ){ + // ’PŒê‚̏I‚í‚è + wordtail = p; + break; + } else { + if ( alnum ){ + if ( _ismbblead(*p) ){ + // “ú–{Œê‚̏ꍇ‚́A’Pƒ‚È”ñ’PŒê•¶Žš‚Æ‚Í‚Ý‚È‚³‚¸A + // Å‰‚©‚çscan‚ð‚â‚è’¼‚· + goto rescan; + } + } + } + fSpc = TRUE; + } else { + // ’PŒê•¶Žš + if ( fSpc ){ + wordprev = wordtop; + wordtop = p; + fSpc = FALSE; + } + } + if ( alnum ){ + p = NEXT_CHAR( p ); + } else { + p++; + } + } + + // wordtop‚ªpos‚æ‚èŒã‚ë + if ( (unsigned)wordtop - (about ? 3 : 0) > (unsigned)(orgp + pos) ){ + // ’PŒê‚Ì‹æØ‚肾‚Á‚½A’PŒê‚̍ŏ‰‚ªpos‚æ‚èŒã‚ë‚É‚ ‚Á‚½ + // about = true‚̏ꍇ‚́A‚R•¶Žš•ª‚Ù‚Ç‚¢‚¢‚©‚°‚ñ·‚ð‘«‚µ‚Ä‚¨‚­ + return FALSE; + } + + if ( fLongest ){ +// int wordcount = 10; // 10Œê‚Ü‚Å + while ( *p && *p != '.' ){ + if ( !IsWordChar( *p ) || (alnum && !isalphanum(*p)) ){ + if ( !fSpc ){ + if ( --wordcount == 0 ) + break; + fSpc = TRUE; + } + } else { + fSpc = FALSE; + } + if ( alnum ){ + p = NEXT_CHAR( p ); + } else { + p++; + } + } + wordtail = p; + } + + if ( !wordtail ) + wordtail = p; + start = STR_DIFF( wordtop, orgp ); + end = STR_DIFF( wordtail, orgp ); + if ( start == end ) + return false; + if ( wordprev ){ + prevstart = STR_DIFF( wordprev, orgp ); + } else { + prevstart = start; + } + return TRUE; +} +#if 0 +bool mbGetWord( const tchar *str, int pos, int &start, int &end, bool fLongest, int wordcount ) +{ + ushort c; + const tchar *sp = str + pos; + LD_CHAR( c, sp ); + if ( !mbIsWordChar( c ) ) + return false; + + const tchar *orgp = str; + const tchar *p = orgp; + const tchar *wordtop = p; + const tchar *wordtail = NULL; + BOOL fSpc = FALSE; + while ( 1 ){ + sp = p; + LD_CHAR( c, p ); + if ( (tuchar)c == 0x00 ) + break; + if ( !mbIsWordChar( c ) ){ + if ( orgp + pos < sp ){ + wordtail = sp; + break; + } + fSpc = TRUE; + } else { + if ( fSpc ){ + wordtop = sp; + fSpc = FALSE; + } + } + } + p = sp; + if ( wordtop > orgp + pos ){ + // ’PŒê‚Ì‹æØ‚肾‚Á‚½ + return false; + } + + if ( fLongest ){ +// int wordcount = 10; // 10Œê‚Ü‚Å + while ( 1 ){ + sp = p; + LD_CHAR( c, p ); + if ( (tuchar)c == 0x00 ) + break; + if ( c == '.' ) + break; + if ( !mbIsWordChar( c ) ){ + if ( !fSpc ){ + if ( --wordcount == 0 ) + break; + fSpc = TRUE; + } + } else { + fSpc = FALSE; + } + } + wordtail = sp; + } + + if ( !wordtail ) + wordtail = sp; + start = STR_DIFF( wordtop, orgp ); + end = STR_DIFF( wordtail, orgp ); + return TRUE; +} +bool mbIsWordChar( unsigned short c ) +{ + if ( c < 0x100 ){ + // ”¼Šp•¶Žš + if ( isalphanum( c ) || c == '-' || c == '\'' || + (c >= 0x86 && c <= 0xBF ) ) + return true; + else + return false; + } + // ‘SŠp•¶Žš + if ( + // ‰p”ŽšAƒJƒ^ƒJƒiA‚Ђ炪‚ȁAƒMƒŠƒVƒƒAƒƒVƒA + (c >= 0x824f && c <= 0x8491) || + // Š¿Žš + (c >= 0x889F) || + // ƒAƒ|ƒXƒgƒƒtƒB + (c == CODE_APOSTROPHE) + ) + return true; + else + return false; +} +#endif +//‰p”Žš‚Ì”»•Ê +int isalphanum( tuchar c ) +{ + if ( c >= _t('A') && c <= _t('Z') ){ + return 1; + } + if ( c >= _t('a') && c <= _t('z') ){ + return 1; + } + if ( c >= _t('0') && c <= _t('9') ){ + return 1; + } + return 0; +} + diff --git a/DCHookTest/StringLib.h b/DCHookTest/StringLib.h new file mode 100644 index 0000000..4c3c371 --- /dev/null +++ b/DCHookTest/StringLib.h @@ -0,0 +1,74 @@ +//--------------------------------------------------------------------------- +#ifndef StringLibH +#define StringLibH +//--------------------------------------------------------------------------- + +#include + +// Constants // +#define CODE_APOSTROPHE 0x9188 // f + +// typedefs and macros // +#ifdef USE_UNICODE +typedef wchar_t tuchar; +typedef wchar_t tchar; +#define LD_CHAR(c,p) c = *p++; +#define ST_CHAR(c,p) *p++ = c; +#define MOV_CHAR(p,q) *p++ = *q++; +#define IS_ENDCHAR(c) (!(c)) +#define NEXT_CHAR(p) CharNextW(p) +#undef _tcslen +#define _tcslen wcslen +#define _t(x) L##x +#define mustr __mustr +#include "mustr.h" +#else +typedef unsigned char tuchar; +typedef char tchar; +#define LD_CHAR(c, p) {c = (unsigned char)*(*(unsigned char**)&p)++; if(_ismbblead(c)) c = (unsigned short)(((unsigned short)c << 8) + (unsigned char)*(*(unsigned char**)&p)++);} +#define ST_CHAR(c, p) {if ((unsigned short)c > 0x100) *(*(unsigned char**)&p)++ = (unsigned char)(c >> 8); *(*(unsigned char**)&p)++ = (unsigned char)c;} +#define MOV_CHAR(p, q) { unsigned char c = *(*(unsigned char**)&q)++ = *(*(unsigned char**)&p)++; if ( _ismbblead( c ) ) *(*(unsigned char**)&q)++ = *(*(unsigned char**)&p)++; } +#define IS_ENDCHAR(c) (!((unsigned char)(c))) +#define NEXT_CHAR(p) CharNextA(p) +#define _tcslen strlen +#define _t(x) x +#define mustr(s) (s) +#endif + +typedef unsigned int uint; +typedef unsigned short ushort; + +#define STR_DIFF( p1, p2 ) ( (uint)( (tchar*)(p1) - (tchar*)(p2) ) ) + +// prototypes // +int isalphanum( tuchar c ); +bool mbIsWordChar( unsigned short c ); +BOOL GetWord( const tchar *str, int pos, int &start, int &end, int &prevstart, bool fLongest, int wordcount, bool about, bool alnum ); +bool mbGetWord( const tchar *str, int pos, int &start, int &end, bool fLongest, int wordcount ); + +// inlines // +inline bool IsWordChar( tuchar c ) +{ +#ifdef _UNICODE + WORD ct; + GetStringTypeW(CT_CTYPE1,&c,1,&ct); + return (ct & (C1_ALPHA|C1_DIGIT)) || c=='-' || c==CODE_JPROLONG || c=='\'' || c=='_'; +#else + return isalphanum( c ) || c == '-' || c == '\'' || c >= 0xc0; +#endif +} +#if 0 +inline bool IsNotWordChar( tuchar c ) +{ +#ifdef USE_UNICODE + WORD ct; + GetStringTypeW(CT_CTYPE1,&c,1,&ct); + return (ct & (C1_SPACE|C1_PUNCT|C1_CNTRL|C1_BLANK)) ? true : false; +#else + return !IsWordChar(c); +#endif +} +#endif + +#endif + \ No newline at end of file diff --git a/DCHookTest/Util.cpp b/DCHookTest/Util.cpp new file mode 100644 index 0000000..b482951 --- /dev/null +++ b/DCHookTest/Util.cpp @@ -0,0 +1,690 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop +#include "prgconfig.h" +#include "Util.h" +#include "prgprof.h" + +//--------------------------------------------------------------------------- +const char *AppName = "DokoPop"; +const char *StrVersion = "Ver.2.0.23"; +int VersionValue = 0x020017; // xxyyzz -> xx.yy.zz x=major y=minor(0-255) z=release(0-255) + +#pragma package(smart_init) + +#ifdef USE_UNICODE +const char APPNAME[] = {"DokoPop/Unicode"}; +#else +const char APPNAME[] = {"DokoPop"}; +#endif + +const char *AMODI_EXE_PATH = "amodi.exe"; +//const char *AMODI_EXE_PATH = "\\src\\amodi\\amodi\\bin\\Debug\\amodi.exe"; + +const char *EXMODIST_EXE_PATH = "ExMODIst.exe"; + +bool WindowsNT = false; +bool fWow64 = false; + +HWND hwndMain = NULL; + +HKEY OpenKey( HKEY hkey, const char *keyname ) +{ + HKEY newkey; + if ( RegOpenKeyEx( hkey, keyname, 0, KEY_ALL_ACCESS, &newkey ) == ERROR_SUCCESS ){ + return newkey; + } + return NULL; +} + +HKEY CreateKey( HKEY hkey, const char *keyname ) +{ + HKEY newkey; + DWORD result; + if ( RegCreateKeyEx( hkey, keyname, 0, (LPTSTR)keyname, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &newkey, &result ) == ERROR_SUCCESS ){ + return newkey; + } + return NULL; +} +DWORD GetValueLength( HKEY hkey, const char *name ) +{ + DWORD len = 0; + if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, NULL, &len ) == ERROR_SUCCESS ){ + return len; + } + return 0L; +} +#if 0 +DWORD ReadInteger( HKEY hkey, const char *name, DWORD val ) +{ + DWORD len = sizeof(DWORD); + DWORD v; + if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, (LPBYTE)&v, &len ) == ERROR_SUCCESS ){ + return v; + } + return val; +} +AnsiString ReadString( HKEY hkey, const char *name, const char *def ) +{ + DWORD len = GetValueLength( hkey, name ); + if ( len ){ + char *buf = new char[ len ]; + if ( RegQueryValueEx( hkey, (LPTSTR)name, 0, NULL, (LPBYTE)buf, &len ) == ERROR_SUCCESS ){ + AnsiString s = buf; + delete buf; + return s; + } + } + return def; +} +#endif +TMyIni::TMyIni( HKEY root, const char *soft, bool can_create ) +{ + hroot = can_create ? CreateKey( root, soft ) : OpenKey( root, soft ); +} +TMyIni::~TMyIni() +{ + if ( hroot ){ + RegCloseKey( hroot ); + } +} +void TMyIni::WriteInteger( const char *section, const char *key, int val ) +{ + HKEY hkey = CreateKey( hroot, section ); + if ( hkey ){ + RegSetValueEx( hkey, (LPCTSTR)key, 0, REG_DWORD, (LPBYTE)&val, sizeof(DWORD) ); + RegCloseKey( hkey ); + } +} +int TMyIni::ReadInteger( const char *section, const char *key, int val ) +{ + HKEY hkey = OpenKey( hroot, section ); + if ( hkey ){ + DWORD len = sizeof(DWORD); + DWORD v; + if ( RegQueryValueEx( hkey, (LPTSTR)key, 0, NULL, (LPBYTE)&v, &len ) == ERROR_SUCCESS ){ + return v; + } + } + return val; +} +void TMyIni::WriteString( const char *section, const char *key, const char *str ) +{ + HKEY hkey = NULL; + if ( section ) + hkey = CreateKey( hroot, section ); + if ( !section || hkey ){ + RegSetValueEx( hkey, (LPCTSTR)key, 0, REG_SZ, (LPBYTE)str, lstrlen(str)+1 ); + RegCloseKey( hkey ); + } +} +AnsiString TMyIni::ReadString( const char *section, const char *key, const char *str ) +{ + HKEY hkey = NULL; + if ( section ) + hkey = OpenKey( hroot, section ); + if ( !section || hkey ){ + DWORD len = GetValueLength( hkey, key ); + if ( len ){ + char *buf = new char[ len ]; + if ( RegQueryValueEx( hkey, (LPTSTR)key, 0, NULL, (LPBYTE)buf, &len ) == ERROR_SUCCESS ){ + AnsiString s = buf; + delete[] buf; + return s; + } + delete[] buf; + } + } + return str; +} + +#define NAMEBUFFSIZE 512 +BOOL QueryInfoKey( HKEY hkey, DWORD *maxvalue, DWORD *maxdata ); +BOOL EnumValue( HKEY hkey, DWORD index, AnsiString &name, void *pbuffer=NULL, DWORD *maxlen=NULL, DWORD *type=NULL ); + +void TMyIni::ReadValues( const char *section, TStrings *strs ) +{ + strs->Clear(); + + HKEY hkey = OpenKey( hroot, section ); + if ( hkey ){ + DWORD maxvaluename; + DWORD maxvaluedata; + if ( !QueryInfoKey( hkey, &maxvaluename, &maxvaluedata ) ){ + // “®‚©‚È‚¢III + maxvaluename = 128; + maxvaluedata = 4096; // “K“–II + } + + AnsiString _entry; + char *buf = new char[ maxvaluedata + 1 ]; + for ( int i=0;;i++ ){ + DWORD maxlen = maxvaluedata + 1; + if ( !EnumValue( hkey, i, _entry, buf, &maxlen ) ) + break; + strs->Add( _entry ); + } + delete[] buf; + } +} + +// +// TAppIni class +// +TAppIni::TAppIni() + :super(HKEY_CURRENT_USER, REG_PDICEXE, false) +{ +#ifdef USE_UNICODE + if (!hroot){ + super::super(HKEY_CURRENT_USER, REG_PDICEXE, false); + } +#endif +} + +const char *sLeft = "Left"; +const char *sTop = "Top"; +const char *sWidth = "Width"; +const char *sHeight = "Height"; + +void LoadForm( const char *section, TForm *form, HWND hwnd ) +{ + RECT rc; + if ( hwnd ){ + GetWindowRect( hwnd, &rc ); + } else { + rc.left = rc.top = 0; + } + form->Left = Ini->ReadInteger(section, sLeft, form->Left) + rc.left; + form->Top = Ini->ReadInteger(section, sTop, form->Top ) + rc.top; + RECT rcScr; + GetScreenSize(form->Handle?form->Handle:hwnd, &rcScr); + int sx = rcScr.right - rcScr.left; + int sy = rcScr.bottom - rcScr.top; + + switch ( form->BorderStyle ){ + case bsSizeable: + case bsToolWindow: + case bsSizeToolWin: + form->Width = Ini->ReadInteger( section, sWidth, form->Width ); + form->Height = Ini->ReadInteger( section, sHeight, form->Height ); + break; + } + // ‰æ–Ê‚ÌŠO‚©‚Ç‚¤‚©H + if (form->Left+form->Width >= sx){ + // ‰E’[ + form->Left = sx - form->Width; + } + if (form->Left < rcScr.left){ + // ¶’[ + form->Left = rcScr.left; + } + if (form->Top+form->Height >= sy){ + // ‰º’[ + form->Top = sy - form->Height; + } + if (form->Top < rcScr.top){ + // ã’[ + form->Top = rcScr.top; + } +} +void SaveForm( const char *section, TForm *form, HWND hwnd ) +{ + RECT rc; + if ( hwnd ){ + GetWindowRect( hwnd, &rc ); + } else { + rc.left = rc.top = 0; + } + Ini->WriteInteger( section, sLeft, form->Left - rc.left ); + Ini->WriteInteger( section, sTop, form->Top - rc.top ); + switch ( form->BorderStyle ){ + case bsSizeable: + case bsToolWindow: + case bsSizeToolWin: + Ini->WriteInteger( section, sWidth, form->Width ); + Ini->WriteInteger( section, sHeight, form->Height ); + break; + } +} + +BOOL QueryInfoKey( HKEY hkey, DWORD *maxvalue, DWORD *maxdata ) +{ + char *classname = new char[ 512 ]; // ‚±‚ñ‚È‚à‚ñ‚Å‚¢‚¢‚©‚È‚ŸH + DWORD classnamesize = 512; + DWORD SubKeys; + DWORD MaxSubKey; + DWORD MaxClass; + DWORD Values; + DWORD MaxValueName; + DWORD MaxValueData; + DWORD SecurityDescriptor; + FILETIME LastWriteTime; + if ( ::RegQueryInfoKey( hkey, classname, &classnamesize, + NULL, + &SubKeys, + &MaxSubKey, + &MaxClass, + &Values, + &MaxValueName, + &MaxValueData, + &SecurityDescriptor, + &LastWriteTime + ) != ERROR_SUCCESS ){ + delete[] classname; + return FALSE; + } + if ( maxvalue ) + *maxvalue = MaxValueName; + if ( maxdata ) + *maxdata = MaxValueData; + delete[] classname; + return TRUE; +} +BOOL EnumValue( HKEY hkey, DWORD index, AnsiString &name, void *pbuffer, DWORD *maxlen, DWORD *type ) +{ + char *buffer = new char[ NAMEBUFFSIZE ]; + DWORD buflen = NAMEBUFFSIZE; + if ( RegEnumValue( hkey, index, buffer, &buflen, 0, type, (LPBYTE)pbuffer, maxlen ) == ERROR_SUCCESS ){ + name = buffer; + delete[] buffer; + return TRUE; + } + delete[] buffer; + return FALSE; +} +bool CheckPassword( const char *str ) +{ + AnsiString s; + if ( str ){ + s = str; + } else { + s = Ini->ReadString( "Main", "PW", "" ); + } + return s == "123"; +} +void CheckWOW64() +{ + typedef BOOL WINAPI (*FNIsWow64Process)(HANDLE hProcess, PBOOL Wow64Process); + + FNIsWow64Process _IsWow64Process = (FNIsWow64Process)GetProcAddress(GetModuleHandle("kernel32"),"IsWow64Process"); + if (_IsWow64Process){ + BOOL flag = FALSE; + if (_IsWow64Process(GetCurrentProcess(), &flag)){ + fWow64 = flag; + } + } +} +void MoveToTop( HWND hwnd ) +{ + if ( IsIconic( hwnd ) ) + ShowWindow( hwnd, SW_RESTORE ); + + // Undocumented way + + HMODULE hUser32 = GetModuleHandle("user32"); + if ( hUser32 ){ + typedef void (WINAPI *PROCSWITCHTOTHISWINDOW) (HWND, BOOL); + PROCSWITCHTOTHISWINDOW SwitchToThisWindow = (PROCSWITCHTOTHISWINDOW)GetProcAddress(hUser32, TEXT("SwitchToThisWindow")); + if ( SwitchToThisWindow ){ + SwitchToThisWindow( hwnd, true ); + FreeLibrary( hUser32 ); + return; + } + } + + FreeLibrary( hUser32 ); + + DWORD locktimeout; + /*BOOL changed = */ SystemParametersInfo( SPI_GETFOREGROUNDLOCKTIMEOUT, 0, &locktimeout, SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE ); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, NULL, SPIF_UPDATEINIFILE); + SetForegroundWindow(hwnd); + SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, locktimeout, NULL, SPIF_UPDATEINIFILE); +} +// window(hwnd)‚ðhwndParent‚Ìcenter‚ÖˆÚ“® +// screen‚ÌŠO‚֏o‚éê‡‚Í’²®‚·‚é +void MoveCenter( HWND hwnd, HWND hwndParent ) +{ + RECT rc; + RECT rd; + if (!hwndParent){ + hwndParent = hwndMain; // parent‚ª‚È‚¯‚ê‚Îmain window + } + if (hwndParent){ +#ifndef WINCE + if ( IsIconic(hwndParent) ){ + GetScreenSize(hwndParent, &rc); + } else +#endif + { + ::GetWindowRect( hwndParent, &rc ); + } + } else { + GetScreenSize(hwnd, &rc); + } + RECT rcScr; + GetScreenSize(hwnd, &rcScr); + ::GetWindowRect( hwnd, &rd ); + int width = rd.right - rd.left; + int height = rd.bottom - rd.top; + int left = rc.left + ( ( rc.right - rc.left ) - width )/2; + int top = rc.top + ( ( rc.bottom - rc.top ) - height )/2; + if ( left < rcScr.left ){ + left = rcScr.left; + } + if ( top < rcScr.top ){ + top = rcScr.top; + } + if ( left + width > rcScr.right ){ + left = rcScr.right - (rd.right - rd.left); + } + if ( top + height > rcScr.bottom ){ + top = rcScr.bottom - (rd.bottom - rd.top); + } + ::SetWindowPos( hwnd, (HWND)NULL, left & ~7, top, 0, 0, SWP_NOSIZE | SWP_NOZORDER ); +} +void GetScreenSize(HWND hwndBase, RECT *rcWork, RECT *rcScreen) +{ +#if 0 + if (!PdicMain){ + __assert(false); + MLFXPC_CMN_ASSERT(false); + if (rcScreen){ + SetRect(rcScreen, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); + } + if (rcWork){ + SystemParametersInfo(SPI_GETWORKAREA, 0, rcWork, 0); + } + return; + } +#endif + //__assert(hwndMain!=NULL); + HMONITOR hMonitor = MonitorFromWindow(hwndBase ? hwndBase : (hwndMain ? hwndMain : GetActiveWindow()), MONITOR_DEFAULTTONEAREST); + //__assert(hMonitor!=NULL); + MONITORINFO mi; + memset(&mi, 0, sizeof(mi)); + mi.cbSize = sizeof(mi); + GetMonitorInfo(hMonitor, &mi); + if (rcScreen){ + *rcScreen = mi.rcMonitor; + } + if (rcWork){ + *rcWork = mi.rcWork; + } +} +bool _WinExec( const char *cmd, int show, int waittime, const char *dir) +{ + STARTUPINFO sui; + memset( &sui, 0, sizeof(STARTUPINFO) ); + sui.cb = sizeof(STARTUPINFO); + sui.dwFlags = STARTF_USESHOWWINDOW; + sui.wShowWindow = (WORD)show; + sui.lpTitle = (LPTSTR)""; + PROCESS_INFORMATION pi; + if ( !CreateProcess( NULL, (LPTSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, dir, &sui, &pi ) ) + return false; + bool ret = true; + if ( waittime ){ + int r = WaitForInputIdle( pi.hProcess, waittime ); + ret = r==0; + } + CloseHandle( pi.hProcess ); + return ret; +} +static const char *MyWinTitle = ""; +HANDLE WinExecEx( const char *cmd, int show, const char *dir, const char *title ) +{ + STARTUPINFO sui; + memset( &sui, 0, sizeof(STARTUPINFO) ); + sui.cb = sizeof(STARTUPINFO); + sui.dwFlags = STARTF_USESHOWWINDOW; + sui.wShowWindow = (WORD)show; + sui.lpTitle = (LPTSTR)(title ? title : MyWinTitle); + PROCESS_INFORMATION pi; + if ( !CreateProcess( NULL, (LPTSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, dir, &sui, &pi ) ) + return NULL; + return pi.hProcess; +} +bool LaunchPdic() +{ + TAppIni *ini = new TAppIni; + if ( !ini->hroot ){ + delete ini; + return false; + } + + AnsiString s = ini->ReadString( PFS_COMMON, PFS_PATH, "" ); + delete ini; + if ( s.Length() == 0 ) + return false; + s += "\\"; + s += NAME_PDICEXE; + + return _WinExec( s.c_str(), SW_SHOWNOACTIVATE|SW_MINIMIZE, 500 ); +} +bool MODIInstalled() +{ + HANDLE h = WinExecEx(EXMODIST_EXE_PATH, SW_HIDE); + if (!h){ + dbw("ExMODist exec error: %d", GetLastError()); + return false; + } + WaitForSingleObject(h, INFINITE); + DWORD exitCode = 0; + BOOL r = GetExitCodeProcess(h, &exitCode); + CloseHandle(h); + if (r){ + return exitCode ? true : false; + } + return false; +} +bool AMODIRunable() +{ + return MODIInstalled() && GetDNFVersion()>=451; +} +bool LaunchAMODI() +{ + if (!AMODIRunable()) return false; + + int show = +#ifdef _DEBUG + SW_SHOWNOACTIVATE|SW_MINIMIZE; +#else + SW_HIDE; +#endif + if (!_WinExec( AMODI_EXE_PATH, show, 500)) + return false; + + HWND hwnd = NULL; + for (int i=0;i<30;i++){ + hwnd = FindAMODI(); + if (hwnd) + break; + Sleep(10); + } + return hwnd!=NULL; +} +void TerminateAMODI() +{ + HWND hwnd = FindAMODI(); + if (hwnd){ + PostMessage(hwnd, WM_CLOSE, 0, 0); + } +} +void ShowAMODI() +{ + HWND hwnd = FindAMODI(); + if (hwnd){ + ShowWindow(hwnd, SW_SHOW); + ShowWindow(hwnd, SW_RESTORE); + } +} +static HWND hwndFind; +static const char *findClass = NULL; +static const char *findWindow = NULL; +static const char *findAppName = NULL; +static BOOL CALLBACK EnumWindowsProc( HWND hwnd, LPARAM lParam ) +{ + char buf[80]; + + if (findClass){ + if ( !GetClassName( hwnd, buf, sizeof(buf)-1 ) ) return TRUE; + //DBW("class: %s", buf); + if (strcmp( buf, findClass )) return TRUE; + } + if (findWindow){ + if (GetWindowText(hwnd, buf, sizeof(buf))<0){ + return TRUE; + } + //DBW("wnd: %s", buf); + if (strcmp(buf, findWindow)){ return TRUE; } + } + + if (findAppName){ + COPYDATASTRUCT cd; + cd.dwData = WMCD_EXISTCHECK; + cd.lpData = (void*)findAppName; + cd.cbData = strlen(findAppName)+1; + if ( SendMessage( hwnd, WM_COPYDATA, 0, (LPARAM)&cd ) ){ + goto jfound; + } + } else { +jfound: + hwndFind = hwnd; + return FALSE; + } + return TRUE; +} + +HWND FindApp(const char *clsname, const char *wndname, const char *appname) +{ + hwndFind = NULL; + findClass = clsname; + findWindow = wndname; + findAppName = appname; + EnumWindows( (FARPROC)EnumWindowsProc, 0 ); + return hwndFind; +} +HWND FindPrev() +{ + return FindApp("TDCHookMainForm", NULL, APPNAME); +} +int CheckVersion(HWND hwnd) +{ + int ver = SendMessage(hwnd, WM_GET_VERSION, 0, 0); + if (ver==0){ return -1; } // older than ver.2.0 + return ver - VersionValue; +} +HWND FindAMODI() +{ + static const char APPNAME_AMODI[] = "Auto MODI"; + return FindApp(NULL, APPNAME_AMODI, APPNAME_AMODI); +} +static HWND hwndFound; +static BOOL CALLBACK EnumWindowsProcPS( HWND hwnd, LPARAM lParam ) +{ + char clsname[80]; + if ( !GetClassName( hwnd, clsname, sizeof(clsname)-1 ) ) return TRUE; + if ( strcmp( clsname, "PSPOPUPWIN" ) + && strcmp( clsname, "PSMENU" ) ) return TRUE; + + hwndFound = hwnd; + + return FALSE; +} +// PDIC‚Ìpopup window‚ð’T‚· +HWND FindPopupWindow( ) +{ + hwndFound = NULL; + EnumWindows( (WNDENUMPROC)EnumWindowsProcPS, 0 ); + return hwndFound; +} + +void ShowManual(HWND hwnd) +{ + AnsiString dir = ExtractFileDir( Application->ExeName ); + ShellExecute( hwnd, "open", NAME_DKPPTXT, NULL, dir.c_str(), SW_SHOW ); +} + +void ShowLatestVersion() +{ +#if __PROTO + const char *url = "http://pdic.la.coocan.jp/unicode/dev.html"; +#else + const char *url = "http://dokopop.osdn.jp/"; +#endif + ShellExecute( NULL, _T("open"), url, NULL, NULL, SW_SHOW ); +} + +// ŽQl +// https://msdn.microsoft.com/ja-jp/library/hh925568(v=vs.110).aspx#net_d +// http://www.atmarkit.co.jp/ait/articles/1210/26/news086.html +unsigned GetDNFVersion() +{ + HKEY dnfKey; + if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP", 0, KEY_READ, &dnfKey ) == ERROR_SUCCESS ){ + int version = 0; + HKEY verKey; + if ( RegOpenKeyEx( dnfKey, "v4.0", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){ + version = 400; + RegCloseKey(verKey); + if ( RegOpenKeyEx( dnfKey, "v4", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){ + HKEY fullKey; + if ( RegOpenKeyEx( verKey, "Full", 0, KEY_READ, &fullKey ) == ERROR_SUCCESS ){ + DWORD dwType = REG_DWORD; + DWORD dwByte = 4; + DWORD dwValue = 0; + if ( RegQueryValueEx( fullKey, "Release", NULL, &dwType, (BYTE*)&dwValue, &dwByte) == ERROR_SUCCESS){ +#if 0 + if (dwValue >= 394254){ + version = 461; + } else + if (dwValue >= 393295){ + version = 460; + } else + if (dwValue >= 379893){ + version = 452; + } else +#endif + if (dwValue >= 378675){ + version = 451; + } else + if (dwValue >= 378389){ + version = 450; + } + } + RegCloseKey( fullKey ); + } + RegCloseKey( verKey ); + } + } else + if ( RegOpenKeyEx( dnfKey, "v3.5", 0, KEY_READ, &verKey ) == ERROR_SUCCESS ){ + version = 350; + RegCloseKey(verKey); + } + RegCloseKey(dnfKey); + return version; + } + return 0; +} + +static HWND hWin = NULL; +static const char *clsname = "TDbgMsgForm"; +static const char *winname = "Debug Messenger"; +void dbw( const char *format, ... ) +{ + if ( !hWin ){ + hWin = FindWindowA( clsname, winname ); + if ( !hWin ) return; + } + va_list ap; + va_start( ap, format ); + char buf[ 2048 ]; + wvsprintf( buf, format, ap ); + COPYDATASTRUCT cds; + cds.dwData = 1; // Indicate String + cds.cbData = strlen(buf); + cds.lpData = buf; + SendMessage( hWin, WM_COPYDATA, NULL, (LPARAM)&cds ); + va_end( ap ); +} + diff --git a/DCHookTest/Util.h b/DCHookTest/Util.h new file mode 100644 index 0000000..c2e2a27 --- /dev/null +++ b/DCHookTest/Util.h @@ -0,0 +1,118 @@ +//--------------------------------------------------------------------------- +#ifndef UtilH +#define UtilH +//--------------------------------------------------------------------------- + +/*------------------------------------------*/ +/* Configuration */ +/*------------------------------------------*/ +#define USE_DDE 1 // Popup Search‚́ADDE‚ōs‚¤, + // otherwise uses WM_COPYDATA message. + +#ifdef USE_UNICODE +#define DDE_SERVICE_NAME "PDICU" +//#define REG_PDICEXE_OLD "Software\\ReliefOffice\\PDICU" +#define REG_PDICEXE "Software\\ReliefOffice\\PDIC2" +#define APPREGNAME "DokoPopU" +#define NAME_PDICEXE "PDICU.EXE" +#define NAME_DKPPTXT "DKPU.TXT" +#define NAME_DKPPHKDLL "DKPUHK.DLL" +#define NAME_BMPFILE "DKPU.BMP" +#define FMTS "%ws" +#else +#define DDE_SERVICE_NAME "PDICW" +#define REG_PDICEXE "Software\\ReliefOffice\\PDICW32" +#define APPREGNAME "DokoPop" +#define NAME_PDICEXE "PDICW32.EXE" +#define NAME_DKPPTXT "DKPP.TXT" +#define NAME_DKPPHKDLL "DKPPHK.DLL" +#define NAME_BMPFILE "DKPP.BMP" +#define FMTS "%s" +#endif +extern const char APPNAME[]; + +/*------------------------------------------*/ +/* Type Definitions */ +/*------------------------------------------*/ + +#define WMCD_EXISTCHECK 0x4000 + +#define WM_GET_VERSION (WM_APP+0x300) + +#define foreach(obj, it, type) \ + for (type::iterator it=(obj).begin();it!=(obj).end();it++) + +#ifdef __VCL0_H__ + +#define VCL_SIZEABLE() do {BorderStyle = bsSizeable;} while(0) //TODO: VCL Bug + +class TMyIni { +public: + HKEY hroot; +public: + TMyIni( HKEY root, const char *soft, bool can_create ); + ~TMyIni(); + void WriteInteger( const char *section, const char *key, int val ); + int ReadInteger( const char *section, const char *key, int val ); + void WriteString( const char *section, const char *key, const char *str ); + AnsiString ReadString( const char *section, const char *key, const char *str ); + void ReadValues( const char *section, TStrings *strs ); +}; + +class TAppIni : public TMyIni { +typedef TMyIni super; +public: + TAppIni(); +}; + +void LoadForm( const char *section, TForm *form, HWND hwnd ); +void SaveForm( const char *section, TForm *form, HWND hwnd ); +#endif + +/*------------------------------------------*/ +/* Prototypes */ +/*------------------------------------------*/ +bool LaunchPdic(); +bool MODIInstalled(); +bool AMODIRunable(); +bool LaunchAMODI(); +void TerminateAMODI(); +void ShowAMODI(); + +bool CheckPassword( const char *str ); +void CheckWOW64(); +void MoveToTop( HWND hwnd ); +void MoveCenter( HWND hwnd, HWND hwndParent ); +void GetScreenSize(HWND hwndBase, RECT *rcWork, RECT *rcScreen=NULL); +bool _WinExec( const char *cmd, int show, int waittime, const char *dir=NULL); +HANDLE WinExecEx( const char *cmd, int show, const char *dir=NULL, const char *title=NULL ); +HWND FindApp(const char *clsname, const char *wndname, const char *appname); +HWND FindPrev(); +int CheckVersion(HWND hwnd); +HWND FindAMODI(); +HWND FindPopupWindow( ); + +void ShowManual( HWND hwnd ); +void ShowLatestVersion(); + +unsigned GetDNFVersion(); // get .NET Framework version + +void dbw( const char *format, ... ); + +#ifdef _DEBUG +#define DBW dbw +#else +#define DBW (void) +#endif + +/*------------------------------------------*/ +/* Global Variables */ +/*------------------------------------------*/ +extern const char *AppName; +extern const char *StrVersion; +extern int VersionValue; +extern bool WindowsNT; +extern bool fWow64; + +#endif + diff --git a/DCHookTest/cpd.bat b/DCHookTest/cpd.bat new file mode 100644 index 0000000..d396239 --- /dev/null +++ b/DCHookTest/cpd.bat @@ -0,0 +1,3 @@ +copy \src\DCHook\DCHook\Win32\Release\DCHook.dll DKPUHK.DLL +copy \src\DCHook\DCHook\x64\Release\DCHook.dll DKPUHK64.DLL +copy ..\DCHook64\dchk64\x64\Release\dchk64.exe DKPUHK64.exe diff --git a/DCHookTest/dkpp.bmp b/DCHookTest/dkpp.bmp new file mode 100644 index 0000000000000000000000000000000000000000..c0684f5a22e5942a48f86c4651613180c2fa71d6 GIT binary patch literal 78394 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 literal 0 HcmV?d00001 diff --git a/DCHookTest/dkpp.ico b/DCHookTest/dkpp.ico new file mode 100644 index 0000000000000000000000000000000000000000..caa0a9b59e3a81f2b6c9e009201c2af07e36ced2 GIT binary patch literal 1078 zcmcgrIc~!+5F9xHR1k>u1E~u9i{we^REAGd&xTJ)nbM^TBbynn2+6i`AVpSM?#^D6 zz#-6JhhgX-dEWt#v|Z=;&;Sp2z=5%W`b=$b&lQNQ-ImBCGcmg1N|zdub7sQI3p06C zJ_>1(jN{mj8Ubw8E?psa@(>7g8;Do6>X!W!W7=Xwn(``zL)zvk!tm;U7oz5jcB{lDt@Ke61HMN&a3|J<9M z_SDww*xCu`kHG$owD^mvS2M`9O%cyK>OieL&-Aw?lGMzQ*Trz9`+J_VbtQoZC#lwt zTLe?o4-J^eCb2t(FexL;kmFGDj!T0&H$_+N;}tkRxt@9;^PWfE_pelWzo)<_hejH4 literal 0 HcmV?d00001 diff --git a/DCHookTest/dkpp0.ico b/DCHookTest/dkpp0.ico new file mode 100644 index 0000000000000000000000000000000000000000..8e04880c50abd8883dc75b991fff60aa454abcf1 GIT binary patch literal 1078 zcmcgryKciU3_Pa=JP2s~2liCtFVa7YKFPZleM-lU89fAH??el!6DKV)l=6u@@gW(a zfCd{3LkG#%26(6LI_J9vczXeMTpNfFqQNU?AToAcBAxWa=!!E zY5Jp#%easp^OTkeS3IP&DDacZo~6{NL|U8Pa7G1gS8FheLtl+Y8hPH|xC(gvIbKD| zez&~Tul{-eOaA4Ap8uF%|F3fXPs|Qx=e^_9n+emFXw8nTO+bGHwx2-z43w)Hc1P6b z9WfBK&ok|HiEL_m*w;mIrul522VR_{YQJtZm{$GLfRWv#ZcibM@VeF69{JwyL4JRyz&C+n6374m literal 0 HcmV?d00001 diff --git a/DCHookTest/dkpp2.bmp b/DCHookTest/dkpp2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d11f0b12c164f60ce279810247623392417ecfda GIT binary patch literal 80066 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�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 literal 0 HcmV?d00001 diff --git a/DCHookTest/dkpps.ico b/DCHookTest/dkpps.ico new file mode 100644 index 0000000000000000000000000000000000000000..22c59fc578a2b668c791649386f30ae16124e275 GIT binary patch literal 318 zcmZ{gI}QRd3`Ac9(iSO5MGGaj;7Z$Vn?^woavmWcySzAJ{asWcY^V l-0Y=lMV;r|SKj;a))(Ina6iH08tQf5>303YKlnWEhbPLpK!5-M literal 0 HcmV?d00001 diff --git a/DCHookTest/dkpps0.ico b/DCHookTest/dkpps0.ico new file mode 100644 index 0000000000000000000000000000000000000000..a6ae6b3fdd0058a1431fd5315d3bf7e236b20e6c GIT binary patch literal 318 zcmZ{gF%m){3`8HJ9fef3-_l!nG&vG|8jfZ0N8A896#j(W4OwOgKv1TX@VE!Kx(eR8 z34ya1YUh8HL5rM+h*b)iTC0rK7p-|ED81#hM49!}Xk-6XGdHXU6byGP#$r>|8vEFN fKk_@j+_RSL3Gc_izQOCFcb+u6{^1DjkNM#PnKVB= literal 0 HcmV?d00001 diff --git a/DCHookTest/icon.rc b/DCHookTest/icon.rc new file mode 100644 index 0000000..f691b60 --- /dev/null +++ b/DCHookTest/icon.rc @@ -0,0 +1,2 @@ +2 ICON "dkpps.ico" + diff --git a/DCHookTest/icon.res b/DCHookTest/icon.res new file mode 100644 index 0000000000000000000000000000000000000000..f96a11db316c434ede8faee37b59323870c96765 GIT binary patch literal 412 zcmZ`#F%H5o5OXL}he*(YosJ#(0blCYHBah(OPkdh0TS0W+j%z-{3DK2FHmmb@xohZOKk5w_d zMBA&G2389+8RW1SXIqp{-p4wZW%K*4FMgbX=M{L}UDfA?e`h5Bp!u5Xg&TXKloN5N S`)>+vtHAs^MynK+dcYgkU`=%Z literal 0 HcmV?d00001 diff --git a/DCHookTest/mustr.cpp b/DCHookTest/mustr.cpp new file mode 100644 index 0000000..a0479bf --- /dev/null +++ b/DCHookTest/mustr.cpp @@ -0,0 +1,54 @@ +#include +#pragma hdrstop +#include "mustr.h" + +__mustr::__mustr( const char *str ) +{ + constructor(str, str ? strlen(str) : 0); +} +__mustr::__mustr( const wchar_t *str ) +{ + constructor(str, str ? wcslen(str) : 0); +} +void __mustr::constructor(const char *str, int len) +{ + buffer = (void*)str; + length = len; + type = 1; + newbuffer = NULL; +} +void __mustr::constructor(const wchar_t *str, int len) +{ + buffer = (void*)str; + length = len; + type = 2; + newbuffer = NULL; +} +__mustr::~__mustr() +{ + if ( newbuffer ) delete[] newbuffer; +} +__mustr::operator char *() +{ + if ( type == 1 ) return (char*)buffer; + if ( newbuffer ) return (char*)newbuffer; + + // Unicode to Ansi + + newbuffer = new char[ length*2 + 1 ]; + int size = WideCharToMultiByte( CP_ACP, 0, (wchar_t*)buffer, length, newbuffer, length*2, NULL, NULL ); + newbuffer[size] = '\0'; + return (char*)newbuffer; +} +__mustr::operator wchar_t *() +{ + if ( type == 2 ) return (wchar_t*)buffer; + if ( newbuffer ) return (wchar_t*)newbuffer; + + // Ansi to Unicode + + *(wchar_t**)&newbuffer = new wchar_t[ length*2 + 1 ]; + int size = MultiByteToWideChar( CP_ACP, 0, (char*)buffer, length, (wchar_t*)newbuffer, length*2 ); + ((wchar_t*)newbuffer)[size] = '\0'; + return (wchar_t*)newbuffer; +} diff --git a/DCHookTest/mustr.h b/DCHookTest/mustr.h new file mode 100644 index 0000000..a305601 --- /dev/null +++ b/DCHookTest/mustr.h @@ -0,0 +1,32 @@ +#ifndef __MUSTR_H +#define __MUSTR_H + +// ”Ä—p UNICODE <-> ANSI conversion class + +class __mustr { +protected: + void *buffer; + char *newbuffer; + int length; + int type; +public: + __mustr( const char *str ); + __mustr( const char *str, int len ) + { constructor(str, len); } + __mustr( const wchar_t *str ); +protected: + void constructor(const char *str, int len); + void constructor(const wchar_t *str, int len); +public: + ~__mustr(); + operator char *(); + operator unsigned char *() + { return (unsigned char*)(char*)(*this); } + operator wchar_t *(); + char *str() + { return (char*)(*this); } + wchar_t *wstr() + { return (wchar_t*)(*this); } +}; + +#endif // __MUSTR_H diff --git a/DCHookTest/obj/icon.res b/DCHookTest/obj/icon.res new file mode 100644 index 0000000000000000000000000000000000000000..f96a11db316c434ede8faee37b59323870c96765 GIT binary patch literal 412 zcmZ`#F%H5o5OXL}he*(YosJ#(0blCYHBah(OPkdh0TS0W+j%z-{3DK2FHmmb@xohZOKk5w_d zMBA&G2389+8RW1SXIqp{-p4wZW%K*4FMgbX=M{L}UDfA?e`h5Bp!u5Xg&TXKloN5N S`)>+vtHAs^MynK+dcYgkU`=%Z literal 0 HcmV?d00001 diff --git a/DCHookTest/popdisable.bmp b/DCHookTest/popdisable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a1cf52fb2332412873d04d1c649ba036b569d638 GIT binary patch literal 18774 zcmeI3KaUnw6vme?U_oW9OlbT7#1CLXVL|Dd@C7I=X{bzy4VoYc2_}R{0ag@N!~|`K zS}xhb*eEt4C=d_=`|tg;_`CD$JbU)eym#hZ;XVsU!`d69)A7RgNx^eYpB3JuRtq%qw=rIU+nV~ zhVX_8{C?rw-OoSMMKvOUqpU*RKL6>NGiOemIB|SvLk0GC1wQ)lgYQ527h|gV9Cr1h~nZwkE%|>oU|*~$i5uM02`9Ub{Q?ih+y6lPY(`xT@x;StKvB;?|b#t|=BB%nB z$z(hpJ4H+_>lhr3M%bXIXVJILnQfyW&7w-A&3MWw&9ev3`{J|6+{$MnoR3{0mRX`| zkwz75bze$q7SKM^Pp8w@8_{=l<7bXNh=g?`Wg0?%ciXGqe-4&V1wT4Ec9K~~B0nJL zh&Gv(Z1mDJJ@kNshGPP{Y;lqayg_aq_*ji=MSz20R2yhw#8hR4ZErA(RVapz6 ztQ9it$dMy9Zn^`C*3`FZ@B$Q#Fq+jyL%Hxsw9U~7Sim8e>({T_7#tGBot#>~EtuFl zS?x!TS$s|>bMHn{VLi9RY&JnsYADoMPZES7)G9;pEh#gK4T6ahqBS$-*d1mhSA)=)eJ)*~~$Qn}aR3=L~PLvER2w4F$GfL4cvTbJh5+xk4 zC_zbCGKQ26AjtGo6%9QNcRGkPWJku{=_BtxoLQ483QEg_yjIu_^vwEA6rlOSwd-073ZG+InZyg0KOC*{h1DmBorm@t> zl$S6_oca(<95q@e4x6_eiJ_W;UMY+>#-;OlG98b$e?D!3L=8DoWYQrd(szqRCe3&t zb1VCZgUsAG3qZ^=8*ZsvM1%8MR$2D(#S#!RYawnk5e?oY2uHoRN*Ea9G$S*S$DysM1F zrZS@8u+7XmajfCW&L zh<&xN=^;mc@!~KL1cH55G<;?FW$)Q&yd^2Xqh^+@0@BkIZM5uzLn5Atz=qA1BLYU5 z=MC{$@9SEB9_-I&oh@XcQ?W{DM;BeQG}?D6IO~NF4VY;bq0erkC4NO_lrYDouuZ`i z#*9J@SmvP;SI=~U$)?+B8HX4sFE;eb-4pu=ea>e%KN(N@pix!TlU@w* zt%L|d?u6|ELI7ylG_XeYzMV@b_|hJv{zSqO5C*a~2qk5r93ePV<>Fi0VCj6dBJ`kn zueHW3oH&F%)l&i8YZD1d=>YDAUzGF_M>0v#ntEyCEWn)V%EENWrFe=XNl>Pk7`ONp|TF+-*>y6e&J>S>aqq6gDs~{G&4xyx;fVisK zEVGO|^<`h;gFtYKF$YE5Us^BKSt})(zIBy3^u#?tB2F_-5by;^#DN$fNEv%qLpU*P z%(!jhmo)(Td@ft|;h_-9k@Uf#bUmYrF+H&@yG~El}DZk&Ofc&s*)I652x^X?jkH z)Bh#;)gu9+XZ2zVoVt2=7N7YF2d_B9XZ}P5;px&3`kf0e^ww9`6Q$?)C1G^6CvyGu zk3DfVIN3)P;ADTpX?_U2w#|)?X*3V8QM}_ z^^`dZbr4OFQ(S3*8YDLiQ?fUi7(T#L)iHZlN~X<;!wRW98!9RQ!9H4ac+lP)uFtk z2W50?HRH-k4(mIs8a)e}%)GvFQLO9|ID0ql{h`0(j(-fRrw&N|Z29*1`SWcrU4Vn- uP=VJ~f$_7y`Mav@WR9%X(9jPRI9L^k9B#^gUb%d*(ix)t-&UZ>-hTkR#_e$c literal 0 HcmV?d00001 diff --git a/DCHookTest/popdisable.h b/DCHookTest/popdisable.h new file mode 100644 index 0000000..e24f02f --- /dev/null +++ b/DCHookTest/popdisable.h @@ -0,0 +1,40 @@ +/* This file was Generated by bmp2rgn */ +char bmp2rgn_rgnBytes[240] = +{ + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xea, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xec, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xed, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xee, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xef, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, + 0xef, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0xef, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0xee, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, + 0xee, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0xed, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0xeb, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe9, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00 + +}; + +#if defined (__cplusplus) +RGNDATA& bmp2rgn_rgnData = *reinterpret_cast(bmp2rgn_rgnBytes); +#endif +RGNDATA* bmp2rgn_rgnDataPtr = reinterpret_cast(bmp2rgn_rgnBytes); diff --git a/DCHookTest/popenable.bmp b/DCHookTest/popenable.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8e824907fa7968acbe12c0247f3178a194875cb8 GIT binary patch literal 18776 zcmeI4&ud*p6vxwlz(rT$Ld1dyuEgTP9}A0tx=?fzwHr4=KoEp%B37gu=|T`ULJ>D@ z!5UOr=q9vaX~9-#aiJ^wBU(x=_6LGZn!F#WpSj<6&pU7Ky>stNB~A1WHTzXQxjp%&p+PhyZJhmyO(1L6;5M@BDHcG>APv*~$zc~BZ3-5gNe0#MS*vJ|9 z_={%_UVK#ChQQDmN{^8F+|Dmg@8J5hEo}xib_Ql#z1!?V=g3ab3wte|1=pd#h`4Md-C*7#DME zzwQ};rO*{tLuqc0b>ne(;aMHd-(PtvMLal`5$x{jU9P~ijAMbi2-bDCP`o`p>gXLD zt}>>qC~h7)?P>rFR~dk)4!!v`Abb*-86(tekffhfhS!}BjlhgM9XpG}io8xGjS$6A zwRz6d1*MN3Jqo2i`EF87R?R_OGC`wp8Nb$|%lAT2Nke9qzwzDKC1HE3a+wIyEF*RAoV5if;20b;4 zJ~(HFMoy}til~dJDMCBs%3T@U-O{&V#2GjTZ{rijPSYG&@ zV;zvNZcLei&^+95^_!2u5~>hKN5?3cbtLi&0!K6tJ3EU3mNv=@O=1y(#oxYt`}Fj*AxE&LM@uYm4Ti0A_A(&W!QH1eIiJ(+>qB_9&}$%aP!7IGGz4Cgs+1AV#BsN2;MvZ9bVG z3?WyM2Wv8Ada*$;r59>r0hqC5kHrEN31V4`2ghSh!Pl?k&0rH&88|AdZHU(Q9>JyE=>m~$kb#N4K;;uI*8O|ff!3KO?qv(^%e#E zP>On-;0j? zQhpeMGDmM#e)iR6bMV9 z)j;rwZy-$g_g%;q9dD8U$P%|8@k(auQ;iHrU@&p=0~p_H18e;-{WKDDRTT6{p}W#e zozJ~~w=?|xwCKcZm?KGMIzY;oB7FBrW}5y$rYU>x2RRyrL(C!@n&i!UgY#NeSvHBq z5`dYt5VskKhUgOHN42;L42%gHk(pT1V+>l6t!i1#EtV8(;)E&SnPnvqNK}d`(k(rD zhA^B!+V4KqLgM{fAPHIUVf3iiH;X**ZT3pH8npxEq7Kri?F z!R)zN+K=yL(ZS4$Ii6J2Qpo6?AeT^X6x`cW*6B8L?1+;nu=^TcoI z_EMV9;i<@&kDh9?gaNa*nZgRD>4`xX_)(fo)RdleRK}P!vPOB&Xqv<#|M&+6R6)Q4 zqdXo%f)ZnDio%IS!b1%VjH4f#xHW@FsLB-t#*Z&p+E}6(3s;{^cs&YvB+; zf^)B_l9fPein8P_oA_ZOHV}ag3r^E`Z;{OXhWM=Kb)~-#Hs>>Z&@6N+O7^vn4h^*L zlu`(Z;0+ka+)WcTO^-lakr^506epgDg)zNQf*h(A6#)Z0P{|uMR!~x`>5m{y7AktB zhgy_1{i2>pfhVyMNHW+c%$-{Jh01%Y@-G`rQ?h;p$eub1o#vrmWyS&~8g7u%e!xI( zu~CL`YXh4IP0nXH-|P08cq6N}%HoDKi+L75Eqf4v74%VLV4A3D`X)jmmi8d|*9rmy zSsR3uGEn{z465d0O|!w$=BpK<#+&W6QmFFdyBL)ygrh_T#6?N%{YZvaRn)@3j{>Jn z3LzRrM2w66rJ;)x`cYSLh-o}*hSRjJh63pYY7^roJd~d_k|usgT|-nJITXFKbcdT~-9PhI z(t&e3{qtvg9|^ODN3{8ee(7@wOOlyhYx8#RLOK>uZQ~FtB6AcSV@jlqn%oRfB4ue4 zSK1&&Hj+aqT{=oi&O_S;;7=PT{QSFJ_l^V)4YTKwbL#5mS$yVI=R-fgB0lSrDS8*0 z^O*;F%S+3F(qsIQ(1%(VIe-0QU4peiHc$pQnLU}|GjBMeWoEde>h+SWUmOlHK|aCqAkiCbpRB zNMo7zdQ;X3r?0<%{PLS(uYD?(4|f}-`F{m8#q%@Si5=vd9Ni!0S2)JA3yt)<&)oPR zS6Xinh91mSD{Qt5R4wj(UvWMvXrJS@&%^3d-k#E8dt0{|*en_Ndf^E+m;Jv2325do Wzh;ErEOTjb{+}}dT{)#k$@~w-=R>9d literal 0 HcmV?d00001 diff --git a/DCHookTest/popenable.h b/DCHookTest/popenable.h new file mode 100644 index 0000000..5d20ccb --- /dev/null +++ b/DCHookTest/popenable.h @@ -0,0 +1,28 @@ +/* This file was Generated by bmp2rgn */ +char bmp2rgn_rgnBytes[144] = +{ + 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xed, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0xee, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xef, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0xf0, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, + 0xef, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, + 0xee, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xed, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00 + +}; + +#if defined (__cplusplus) +RGNDATA& bmp2rgn_rgnData = *reinterpret_cast(bmp2rgn_rgnBytes); +#endif +RGNDATA* bmp2rgn_rgnDataPtr = reinterpret_cast(bmp2rgn_rgnBytes); diff --git a/DCHookTest/prgconfig.cpp b/DCHookTest/prgconfig.cpp new file mode 100644 index 0000000..c9096b1 --- /dev/null +++ b/DCHookTest/prgconfig.cpp @@ -0,0 +1,9 @@ +//--------------------------------------------------------------------------- + +#pragma hdrstop + +#include "prgconfig.h" + +//--------------------------------------------------------------------------- + +#pragma package(smart_init) diff --git a/DCHookTest/prgconfig.h b/DCHookTest/prgconfig.h new file mode 100644 index 0000000..3184021 --- /dev/null +++ b/DCHookTest/prgconfig.h @@ -0,0 +1,9 @@ +//--------------------------------------------------------------------------- + +#ifndef prgconfigH +#define prgconfigH +//--------------------------------------------------------------------------- + +#define __PROTO 1 // ŽŽì”Å + +#endif diff --git a/DCHookTest/prgprof.cpp b/DCHookTest/prgprof.cpp new file mode 100644 index 0000000..388d2a5 --- /dev/null +++ b/DCHookTest/prgprof.cpp @@ -0,0 +1,10 @@ +#pragma hdrstop +#define DEFINE_PFS +#include "prgprof.h" + +#pragma package(smart_init) + +TMyIni *Ini; + + + diff --git a/DCHookTest/prgprof.h b/DCHookTest/prgprof.h new file mode 100644 index 0000000..cbe052b --- /dev/null +++ b/DCHookTest/prgprof.h @@ -0,0 +1,37 @@ +//--------------------------------------------------------------------------- + +#ifndef prgprofH +#define prgprofH +//--------------------------------------------------------------------------- + +#ifdef DEFINE_PFS +#define DEF_PFS(name, str) extern const char PFS_##name[]; const char PFS_##name[] = str +#else +#define DEF_PFS(name, str) extern const char PFS_##name[] +#endif + +DEF_PFS(MAIN, "Main"); +DEF_PFS(CONFIG, "Config"); +DEF_PFS(PDIC, "PDIC"); +DEF_PFS(COMMON, "Common"); +DEF_PFS(GRPSEL, "grpsel"); +DEF_PFS(GROUP, "Group"); +DEF_PFS(GROUPOPEN, "GroupOpen"); +DEF_PFS(GROUPNAME, "GroupName"); +DEF_PFS(POPUPKEY, "PopupKey"); +DEF_PFS(TOGGLEKEY, "ToggleKey"); +DEF_PFS(CTRLCLOSE, "CtrlClose"); +DEF_PFS(IGNOREJ, "IgnoreJ"); +DEF_PFS(PATH, "Path"); +DEF_PFS(BANNER, "Banner"); +DEF_PFS(INCSRCH, "IncSrch"); +DEF_PFS(CAPTURE_MODE, "CaptureMode2"); +DEF_PFS(AMODIPATH, "AMODIPath"); +DEF_PFS(DPI_DETECT, "DPIDetect"); +DEF_PFS(SCALE, "Scale"); +DEF_PFS(USE64, "Use64"); + +extern class TMyIni *Ini; + +#endif + diff --git a/DCHookTest/stdafx.h b/DCHookTest/stdafx.h new file mode 100644 index 0000000..e69de29 diff --git a/DKPP.TXT b/DKPP.TXT new file mode 100644 index 0000000..0c7714f --- /dev/null +++ b/DKPP.TXT @@ -0,0 +1,213 @@ +========================================================================== + ‚Ç‚±ƒ|ƒbƒvI Ver.1.11 +========================================================================== +Ð‰î --------------------------------------------------------------------- + +@u‚Ç‚±ƒ|ƒbƒvIv‚́ATaNì‚ÌPersonal Dictionary for Win32(ˆÈ‰ºPDIC)‚Æ +@˜AŒg‚µ‚āAƒ}ƒEƒX‚̃NƒŠƒbƒN‚É‚æ‚Á‚ă}ƒEƒXˆÊ’u‚Ì’PŒê‚ðŒŸõA“ú–{Œê–ó‚È +@‚Ç‚ðƒ|ƒbƒvƒAƒbƒvƒEƒBƒ“ƒhƒE‚É‚æ‚Á‚Ä•\Ž¦‚·‚éƒ\ƒtƒgƒEƒFƒA‚Å‚·B + +“®ìŠm”FOS -------------------------------------------------------------- + +@Windows98/Me +@WindowsNT4.0/2000/XP + +–â‘è“_ -------------------------------------------------------------------- + +EAcrobat Readerã‚Å‚Í“®ì‚µ‚È‚¢ +EOperaã‚Å‚Í“®ì‚µ‚È‚¢ +EDOS‘‹ã‚Å‚Í“®ì‚µ‚È‚¢ +E16bitƒAƒvƒŠã‚Å‚Í“®ì‚µ‚È‚¢ +E•¡”s‚É‚Ü‚½‚ª‚énŒê‚̓qƒbƒg‚µ‚È‚¢ + +€”õ -------------------------------------------------------------------- + +@DKPP111.EXE‚ð‚»‚Ì‚Ü‚ÜŽÀs‚µ‚ĉº‚³‚¢B +@Ž©“®“I‚ɃCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ü‚·B +@ƒXƒ^[ƒgƒAƒbƒv‚É“o˜^‚µ‚½•û‚ª•Ö—˜‚Å‚·B(Windows‹N“®Žž‚ÉDokoPop!‚à‹N“®) + +@‚Ç‚±ƒ|ƒbƒvI‚É‚ÍPDIC for Win32(‚Å‚«‚ê‚ÎVer.4.50ˆÈ~)‚ª•K—v‚Å‚·B +@http://homepage3.nifty.com/TaN/pdic-download.html + ‚©‚çƒ_ƒEƒ“ƒ[ƒh‚µ‚ĉº‚³‚¢B + + NT4.0‚ł́APSAPI.DLL ‚ª•K—v‚Å‚·B + http://homepage3.nifty.com/TaN/psapi.exe + ‚©‚çƒ_ƒEƒ“ƒ[ƒhŒãA‰ð“€AƒVƒXƒeƒ€ƒfƒBƒŒƒNƒgƒŠ(C:\WINNT\System32‚È‚Ç) + ‚ÖƒRƒs[‚µ‚Ä‚­‚¾‚³‚¢B + +Žg—p•û–@ ----------------------------------------------------------------- + +@DKPP.EXE‚ð‹N“®‚·‚é‚ƃ^ƒXƒNƒgƒŒƒC‚ɏ풓‚µ‚Ü‚·B(DP‚Ə‘‚¢‚Ä‚ ‚éƒAƒCƒRƒ“) +@CtrlƒL[‚ð‰Ÿ‚µ‚È‚ª‚çƒ}ƒEƒX‚̉Eƒ{ƒ^ƒ“‚ðƒNƒŠƒbƒN‚·‚é‚ƁAƒNƒŠƒbƒN‚µ‚½ˆÊ’u‚Ì +@’PŒê‚Ü‚½‚͏nŒê‚̈Ӗ¡‚ð•\Ž¦‚µ‚Ü‚·B + + y’ˆÓzPDIC–{‘Ì‚Í•K‚¸Ž«‘ƒOƒ‹[ƒv‚ðƒI[ƒvƒ“‚µ‚½ó‘Ô‚É‚µ‚Ä‚¨‚¢‚Ä‚­‚¾‚³‚¢B + ‚‚܂èA’ʏí‚ÌŒŸõ(WORD—““ü—́j‚ª‚Å‚«‚éó‘Ô‚É‚µ‚Ä‚¨‚¢‚Ä‚­‚¾‚³‚¢B + (ƒƒjƒ…[‚Ì File | Ž«‘ƒOƒ‹[ƒvƒI[ƒvƒ“) + Ž«‘•ÏŠ·’†‚ȂǁA’ʏí‚ÌŒŸõ‚ª‚Å‚«‚È‚¢ó‘Ԃł̓|ƒbƒvƒAƒbƒvŒŸõ‚Í + ‚Å‚«‚Ü‚¹‚ñB + + y’ˆÓzMS-Word‚Å‚Í Ctrl+‰EƒNƒŠƒbƒN ‚ªƒJƒbƒg•ƒy[ƒXƒg‚ÉŠ„‚è“–‚Ä‚ç‚ê‚Ä‚¢‚é + ‚½‚߁A‚¤‚Ü‚­“®ì‚µ‚È‚¢‚Æ‚«‚ª‚ ‚è‚Ü‚·B + iu‚Í‚¶‚ß‚É‘I‘ð‚µ‚Ä‚­‚¾‚³‚¢v‚ȂǂƏo‚Ä‚­‚éj + ‚à‚µ‚±‚Ì–â‘è‚ð‰ñ”ð‚µ‚½‚¢ê‡‚́AŽŸ‚́u‚¿‚å‚Á‚Æ•Ö—˜‚ÈŽg—p•û–@v + ‚É‚ ‚é‚悤‚ɁAu‰EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvv‚É‚·‚é‚©A + ŽŸ‚̂悤‚ɐݒè‚ðs‚Á‚Ä‚­‚¾‚³‚¢B + DokoPop!‚̃^ƒXƒNƒgƒŒƒC‚̃ƒjƒ…[‚©‚çA[Ý’è...]‚ð‘I‚сA + uƒ|ƒbƒvƒAƒbƒvŒŸõv‚©‚çAƒ|ƒbƒvƒAƒbƒv‚ð‚³‚¹‚é‚Æ‚«‚Ì‘g‚ݍ‡‚킹‚ð + ‘I‚ñ‚Å‚­‚¾‚³‚¢B + Alt + ‰EƒNƒŠƒbƒN ‚Å‚ ‚ê‚Ζâ‘è‚È‚¢‚悤‚Å‚·B + +‚¿‚å‚Á‚Æ•Ö—˜‚ÈŽg—p•û–@ --------------------------------------------------- + +@uCtrl + ‰EƒNƒŠƒbƒNv‚͂킸‚ç‚킵‚¢II +@‚Æ‚¢‚¤l‚ɂ́A + +@u‰EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvv + +@‚Æ‚¢‚¤•û–@‚à‚ ‚è‚Ü‚·B +@Ctrl + Alt + ‰EƒNƒŠƒbƒN ‚ÅON/OFF‚̐؂è‘Ö‚¦‚ª‚Å‚«‚Ü‚·B +@iØ‚è‘Ö‚¦Žž‚ɃƒbƒZ[ƒW‚ªo‚Ü‚·) + +@ƒqƒ“ƒgFu‰EƒNƒŠƒbƒN‚¾‚¯v‚É‚µ‚½ê‡AuCtrl + ‰EƒNƒŠƒbƒNv‚ð‚·‚é‚ƁA +@@@@@’ʏí‚̉EƒNƒŠƒbƒNƒƒjƒ…[‚ªo‚Ä‚«‚Ü‚·B +@@@@@‚¿‚傤‚ǁuCtrlv‚ª‹t“]‚·‚銴‚¶‚É‚È‚è‚Ü‚·B + +ƒƒjƒ…[ ----------------------------------------------------------------- + +@ƒ^ƒXƒNƒgƒŒƒC‚ÌDokoPop!ƒAƒCƒRƒ“‚ð‰EƒNƒŠƒbƒN‚·‚é‚ƃƒjƒ…[‚ªŒ»‚ê‚Ü‚·B + +@Ž«‘ƒOƒ‹[ƒv - PDIC‚ÌŽ«‘ƒOƒ‹[ƒv‚̕ύX‚ðs‚¢‚Ü‚· +@‰EƒNƒŠƒbƒNŒŸõ - ƒ}ƒEƒX‚̉EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¢‚Ü‚· +@ƒ|ƒbƒvƒAƒbƒvŒŸõ—LŒø - ŒŸõ‚ð—LŒø^–³Œø‚É‚µ‚Ü‚· +@Ý’è - ŠeŽíÝ’è‚ðs‚¢‚Ü‚· +@à–¾‘‚ð•\Ž¦ - ‚±‚̃tƒ@ƒCƒ‹‚ð•\Ž¦‚µ‚Ü‚· +@ƒo[ƒWƒ‡ƒ“ - version•\Ž¦ +@I—¹ - ‚Ç‚±ƒ|ƒbƒvI‚̏I—¹ + +Ý’è ---------------------------------------------------------------------- + + ƒ^ƒXƒNƒgƒŒƒC‚̉EƒNƒŠƒbƒN‚ŏo‚Ä‚«‚½ƒƒjƒ…[‚́uÝ’èv‚Å‚·B + + ¡‹N“®Žž‚ɃXƒvƒ‰ƒbƒVƒ…‚ð•\Ž¦‚·‚é + ‹N“®Žž‚̉æ–Ê’†‰›‚ɏo‚Ä‚­‚éƒEƒBƒ“ƒhƒE‚Ì + •\Ž¦‚ð—LŒø^–³Œø‚É‚µ‚Ü‚·B + + š‹N“®Žž‚̃Xƒvƒ‰ƒbƒVƒ…ƒrƒbƒgƒ}ƒbƒv‚ðƒJƒXƒ^ƒ}ƒCƒYš + DKPP.EXE‚ª‚ ‚éƒtƒHƒ‹ƒ_[‚É DKPP.BMP ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚é‚ƁA + ‚»‚̃rƒbƒgƒ}ƒbƒv‚ð‹N“®Žž‚ƃo[ƒWƒ‡ƒ“...‚Ì‚Æ‚«‚É•\Ž¦‚µ‚Ü‚·B + + ¡Ž«‘ƒOƒ‹[ƒv‚ðŽw’è‚·‚é + ‚±‚±‚ðƒ`ƒFƒbƒN‚·‚é‚ƁAƒ|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤‚Æ‚«‚É + ‚±‚±‚ÅŽw’肵‚½Ž«‘ƒOƒ‹[ƒv‚ðŽg—p‚µ‚Ü‚·B + PDIC–{‘Ì‚Å‚ÌŽ«‘ƒOƒ‹[ƒv‚Ì‘I‘ð‚ª•ÏX‚³‚ê‚Ü‚·B + y’ˆÓz‚±‚Ì‹@”\‚ÍPDIC for Win32 Ver.4.40‚©‚ç‚̑Ήž‚É‚È‚è‚Ü‚· + + ¡ƒ|ƒbƒvƒAƒbƒvŒŸõ - ƒ|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤ƒ}ƒEƒX‚ƃL[‚Ì‘g‚ݍ‡‚킹‚ðŽw’è + ‚µ‚Ü‚·B + + ¡‰EƒNƒŠƒbƒNŒŸõON/OFF + ‰EƒNƒŠƒbƒNŒŸõ‚Ì—LŒøE–³Œø‚ðØ‚è‘Ö‚¦‚éƒ}ƒEƒX‚ƃL[‚Ì‘g‚ݍ‡‚킹‚Å‚·B + + ¡CtrlƒL[‚𗣂µ‚½‚çƒ|ƒbƒvƒAƒbƒv‚ð•Â‚¶‚é + Ctrl+ƒ}ƒEƒXƒNƒŠƒbƒN‚Ń|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤‚悤‚É‚µ‚½ê‡A + ƒ|ƒbƒvƒAƒbƒv•\Ž¦‚³‚ꂽŒãACtrlƒL[‚𗣂µ‚½‚çƒ|ƒbƒvƒAƒbƒv‚µ‚½ + ƒEƒBƒ“ƒhƒE‚ð•Â‚¶‚Ü‚·B + i«—ˆ“I‚É‚±‚̃IƒvƒVƒ‡ƒ“‚Í–³‚­‚µ‚Ü‚· - ¢‚éI‚Æ‚¢‚¤•û‚Í‚¨’m‚点‚­‚¾‚³‚¢j + + ¡‰p”Žš‚Ì‚ÝŒŸõ‚·‚é + “ú–{ŒêE‰p”Žš¬Ý‚Ì•¶Í‚ª‚ ‚Á‚½ê‡A“ú–{Œê‚𖳎‹‚µ‚ÄŒŸõ‚ðs‚¢‚Ü‚·B + ¬Ý•¶Í‚Å‚Í ON ‚É‚µ‚½‚Ù‚¤‚ªƒqƒbƒg‚µ‚â‚·‚­‚È‚è‚Ü‚·B + ‚Ü‚½Aƒtƒ‰ƒ“ƒXŒêAƒhƒCƒcŒê‚̂悤‚ȃEƒ€ƒ‰ƒEƒgEƒAƒNƒTƒ“‚È‚Ç‚ð + ŠÜ‚Þ•¶Í‚Å‚Í‚±‚±‚ð OFF ‚É‚µ‚È‚¢‚Æ‚¤‚Ü‚­“®ì‚µ‚È‚¢ê‡‚ª‚ ‚è‚Ü‚·B + +‚»‚Ì‘¼ -------------------------------------------------------------------- + +@Ä—˜—pEÄ”z•zE‰ü•Ï‚È‚Ç‚ÍŽ©—R‚Å‚·B +@‚±‚̃\ƒtƒgƒEƒFƒA‚É‚æ‚鑹ŠQ‚͈êØ‚»‚̐ӔC‚𕉂¢‚Ü‚¹‚ñB + +@‚±‚Ìprogram‚́Aopen source‚Å‚ ‚éDCHook‚Ìsample program‚Å‚·B +@ƒ\[ƒXƒtƒ@ƒCƒ‹‚́A +@http://homepage3.nifty.com/TaN/prog-tips.html +@‚É‚ ‚è‚Ü‚·B(dchook-x.xx.lzh) + +@‚±‚̃\ƒtƒgƒEƒFƒA‚̃Tƒ|[ƒg‚͍s‚Á‚Ä‚¢‚Ü‚¹‚ñB‚½‚¾‚µA +@http://www4.plala.or.jp/cgi-bin/wforum/wforum.cgi/grape/dkpp +@‚ɂāAî•ñŒðŠ·‚ðs‚Á‚Ä‚¢‚Ü‚·B + +@PDIC for Win32‚Í +@http://homepage3.nifty.com/TaN/pdic-download.html + +@ƒCƒ“ƒXƒg[ƒ‰‚É‚¿‚­‚킳‚ñ(RXQ01346@nifty.ne.jp)‚ÌMakeSet‚ðŽg—p‚µ‚Ä‚¢‚Ü‚·B + +—š—ð ---------------------------------------------------------------------- + +>> Ver.1.12 << +* Ž«‘‚ª‘å‚«‚¢ê‡‚ɁAPDIC‹N“®Œã‚̍ŏ‰‚̃|ƒbƒvƒAƒbƒv‚ª‚Å‚«‚È‚¢‚Æ‚«‚ª‚ ‚Á‚½ + +>> Ver.1.11 << +EUnicode”őΉž‚Ì‚½‚ß‚É“à•”ˆ—‚ð•ÏX + +>> Ver.1.10 << +›DokoPop‚Ń|ƒbƒvƒAƒbƒv‚µ‚½ƒEƒBƒ“ƒhƒEã‚Å‚³‚ç‚Ƀ|ƒbƒvƒAƒbƒv‚·‚é + ‚±‚Æ‚ª‰Â”\‚Ɂi˜A‘±ƒ|ƒbƒvƒAƒbƒvjiPDIC for Win32‚ÍVer.4.50ˆÈã‚ª•K—vj +›“ú–{Œê¬Ý‚Ì•¶Í‚Å‚à³‚µ‚­“®ì‚·‚é‚悤‚É‚µ‚½B +@iÝ’èƒ_ƒCƒAƒƒO‚́h“ú–{Œê‚𖳎‹‚·‚éh‚Ő؂è‘Ö‚¦‰Â”\j + +>> Ver.1.02 << +* DKPP.EXE‚̃o[ƒWƒ‡ƒ“Ý’è‚ðŠÔˆá‚Á‚Ä‚¢‚½ + +>> Ver.1.01 << +* Windows9x‚Ń|ƒbƒvƒAƒbƒv‚µ‚È‚¢ê‡‚ª‚ ‚Á‚½(IE‚È‚Ç) +E‚»‚ê‚ɑΏˆ‚µ‚½‚½‚߁AWindows95‚Í“®ì‘ΏۊO‚É +* ‰EƒNƒŠƒbƒNŒŸõØ‚è‘Ö‚¦‚ŃŠƒ\[ƒXƒŠ[ƒN‚ª”­¶‚µ‚Ä‚¢‚½ +* ƒqƒbƒg‚µ‚È‚¢’PŒê‚ª‚ ‚é‚ƃƒ‚ƒŠƒŠ[ƒN‚ª”­¶‚µ‚Ä‚¢‚½ + +>> Ver.1.00 << +* Windows9x/MeŒn‚ÌOS‚Å‚Ì“®ì‚ðˆÀ’艻‚µ‚½ +* Ž«‘ƒOƒ‹[ƒvŽw’è‚𐳏í‚É“®ì‚·‚é‚悤‚É‚µ‚½ + y’ˆÓz‚±‚Ì‹@”\‚ÍPDIC for Win32 Ver.4.40‚©‚ç‚̑Ήž‚É‚È‚è‚Ü‚· +EŒŸõ‚̃L[‚Ì‘g‚ݍ‡‚킹‚ðƒJƒXƒ^ƒ}ƒCƒY‚Å‚«‚é‚悤‚É‚µ‚½ +Eƒtƒ@ƒCƒ‹\¬‚ð•ÏX +E˜A‘±‚µ‚ă|ƒbƒvƒAƒbƒvŒŸõ‚ª‚Å‚«‚é‚悤‚É‚µ‚½ +E‚Ù‚©•\Ž¦‚̕ύX‚È‚Ç + +>> Ver.0.98 << +›ƒ}ƒEƒX‰EƒNƒŠƒbƒN‚݂̂Ń|ƒbƒvƒAƒbƒv‚ð‰Â”\‚É +@iCtrl+Alt+‰EƒNƒŠƒbƒN‚ÅON/OFF‚Å‚«‚Ü‚·j +* hŽ«‘ƒOƒ‹[ƒv‚ªŠJ‚¯‚Ü‚¹‚ñh‚Əo‚邱‚Æ‚ª‚ ‚Á‚½ +* Å¬‰»‚Å‹N“®‚µ‚½ê‡Aƒ^ƒXƒNƒo[‚ɃAƒCƒRƒ“‚ªŽc‚Á‚Ä‚¢‚½ + +>> Ver.0.97 << +* Ž«‘ƒOƒ‹[ƒv‚̕ύX‚ª‚Å‚«‚È‚­‚È‚Á‚Ä‚¢‚½ +* IE‚Ńqƒbƒg‚µ‚È‚¢‚±‚Æ‚ª‚ ‚Á‚½ + +>> Ver.0.96 << +* PDIC‚ðŽ©“®‹N“®‚Å‚«‚È‚©‚Á‚½(“ǂݍž‚Þregistry‚ðŠÔˆá‚Á‚Ä‚¢‚½) +* ‚Ç‚±ƒ|ƒbƒv‚ðÅ¬‰»‚Å‹N“®‚µ‚½ê‡AƒXƒvƒ‰ƒbƒVƒ…ƒEƒBƒ“ƒhƒE‚ªÁ‚¦‚È‚©‚Á‚½ + +>> Ver.0.95 << +?? + +>> Ver.0.94 << +* ƒXƒvƒ‰ƒbƒVƒ…‚ð”ñ•\Ž¦‚É‚µ‚½ê‡‚Ì•s‹ï‡C³ + +>> Ver.0.94 << +* ‹N“®ŽžDLL‰Šú‰»Ž¸”s(Win98) +* “ú–{Œê¬‚¶‚è‚Ì•¶‚ŃeƒLƒXƒg’ŠoˆÊ’u‚ª‚¸‚ê‚Ä‚¢‚½(Win98) + +>> Ver.0.93 << +E‹N“®ƒXƒvƒ‰ƒbƒVƒ…•ÏX +EƒXƒvƒ‰ƒbƒVƒ…•\Ž¦E”ñ•\Ž¦ +EƒXƒvƒ‰ƒbƒVƒ…ƒrƒbƒgƒ}ƒbƒv‚̃JƒXƒ^ƒ}ƒCƒY +EƒCƒ“ƒXƒg[ƒ‰’ljÁ +* ƒƒ‚’ ‚ňُíI—¹(NT) +* “ú–{Œê¬‚¶‚è‚Ì•¶‚ŃeƒLƒXƒg’ŠoˆÊ’u‚ª‚¸‚ê‚Ä‚¢‚½ + +>> Ver.0.92 << +EˆÀ’萫Œüã + +>> Ver.0.90 << +EÅ‰‚ÌŒöŠJ + +--------------------------------------------------------------------------- diff --git a/DKPPu.TXT b/DKPPu.TXT new file mode 100644 index 0000000..e049f86 --- /dev/null +++ b/DKPPu.TXT @@ -0,0 +1,41 @@ +======================================================================== +yƒ\ ƒt ƒg–¼z ‚Ç‚±ƒ|ƒbƒvI Ver.1.11 +y“o ˜^ –¼z@DKPP111.EXE +yƒoƒCƒg ”z Bytes +yŒŸõ ƒL[z@1:DOKOPOP 2:PDIC 3:$WIN32 4:#APP 5:#EDU +y’˜ìŒ  ŽÒz@‚È‚µ +yŒf Ú ŽÒz@TaN(SGM00353) +y‘Ήž ‹@Žíz@MS-Windows 98/Me/NT4.0/2000/XP +y“®ì Šm”Fz@IBM PC/ATŒÝŠ·‹@,NT4,0,Win98,2000 +yŒf Ú “úz@2002.12.09 +yì¬ •û–@z@DKPP111.EXE ‚ðŽÀs‚·‚é +y¿Ìijª±Ží•Êz@ƒtƒŠ[ƒEƒFƒA +y“]Ú ðŒz “]ÚŽ©—R +======================================================================== +yƒ\ƒtƒgÐ‰îz + +@DokoPop! - ‚Ç‚±ƒ|ƒbƒvI ‚́ACtrl+ƒ}ƒEƒX‰EƒNƒŠƒbƒN‚ŁA +@ƒ}ƒEƒXƒJ[ƒ\ƒ‹ˆÊ’u‚̉p’PŒêE‰pnŒê‚ðŒŸõ‚µAƒ|ƒbƒvƒAƒbƒv•\Ž¦‚µ‚Ü‚·B + +@‚Ç‚±ƒ|ƒbƒvI ‚Í PDIC for Win32‚ÌDDE‹@”\‚ð—˜—p‚µ‚Ä‚¢‚Ü‚·B +@•Ê“rPDIC for Win32‚ð“üŽè‚µ‚ĉº‚³‚¢B + +@PDIC for Win32‚Ì“üŽèæ(•K{)F + http://homepage3.nifty.com/TaN/pdic-download.html + +@ƒ\[ƒXƒtƒ@ƒCƒ‹F + http://homepage3.nifty.com/TaN/prog-tips.html dchook-1.11.lzh + +>> Ver.1.12 << +* Ž«‘‚ª‘å‚«‚¢ê‡‚ɁAPDIC‹N“®Œã‚̍ŏ‰‚̃|ƒbƒvƒAƒbƒv‚ª‚Å‚«‚È‚¢‚Æ‚«‚ª‚ ‚Á‚½ + +Œ»Ý‚Ì–â‘è“_ + +EAcrobat Readerã‚Å‚Í“®ì‚µ‚È‚¢ +EOperaã‚Å‚Í“®ì‚µ‚È‚¢ +EDOS‘‹ã‚Å‚Í“®ì‚µ‚È‚¢ +E16bitƒAƒvƒŠã‚Å‚Í“®ì‚µ‚È‚¢ +E•¡”s‚É‚Ü‚½‚ª‚énŒê‚̓qƒbƒg‚µ‚È‚¢ + +======================================================================== +ƒ_ƒEƒ“ƒ[ƒhƒtƒ@ƒCƒ‹–¼‚́yDKPP111.EXEz‚Å‚·B diff --git a/DKPU.TXT b/DKPU.TXT new file mode 100644 index 0000000..ca2c1bf --- /dev/null +++ b/DKPU.TXT @@ -0,0 +1,190 @@ +============================================= + ‚Ç‚±ƒ|ƒbƒvI/Unicode Ver.2.023 +============================================= +Ð‰î --------------------------------------------------------- + +@u‚Ç‚±ƒ|ƒbƒvI/Unicodev‚́APersonal Dictionary/Unicode”Å(ˆÈ‰ºPDIC) +@‚ƘAŒg‚µ‚āAƒ}ƒEƒXƒNƒŠƒbƒN‚É‚æ‚Á‚ă}ƒEƒXˆÊ’u‚Ì’PŒê‚ðŒŸõA“ú–{Œê–ó‚È +@‚Ç‚ðƒ|ƒbƒvƒAƒbƒvƒEƒBƒ“ƒhƒE‚É‚æ‚Á‚Ä•\Ž¦‚·‚éƒ\ƒtƒgƒEƒFƒA‚Å‚·B +@Unicode‚ɑΉž‚µ‚Ä‚¢‚Ü‚·B + +“®ìŠm”FOS --------------------------------------------------- + +@Windows7/8/8.1/10 + + ¦Windows2000/XP‚ÅŽg—p‚·‚邱‚Æ‚à‰Â”\‚Å‚·‚ªA•¶Žš”FŽ¯‚ð—˜—p‚µ‚½‚¢ê‡AÝ’肪•K—v‚Å‚·Bi¨•¶Žš”FŽ¯‚̏ꏊ) + +€”õ --------------------------------------------------------- + +@DKPU2023.exe‚ð‚»‚Ì‚Ü‚ÜŽÀs‚µ‚ĉº‚³‚¢B +@Ž©“®“I‚ɃCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ü‚·B +@ƒXƒ^[ƒgƒAƒbƒv‚É“o˜^‚µ‚½•û‚ª•Ö—˜‚Å‚·B(Windows‹N“®Žž‚ÉDokoPop!‚à‹N“®) + +@‚Ç‚±ƒ|ƒbƒvI‚É‚ÍPDIC/Unicode Ver.5.7.21ˆÈ~ ‚ª•K—v‚Å‚·B + http://pdic.la.coocan.jp/ + ‚©‚çƒ_ƒEƒ“ƒ[ƒh‚µ‚ĉº‚³‚¢B + +Žg—p•û–@ ----------------------------------------------------- + +@DKPU.EXE‚ð‹N“®‚·‚é‚ƃ^ƒXƒNƒgƒŒƒC‚ɏ풓‚µ‚Ü‚·B(DP‚Ə‘‚¢‚Ä‚ ‚éƒAƒCƒRƒ“) +@CtrlƒL[‚ð‰Ÿ‚µ‚È‚ª‚çƒ}ƒEƒX‚̉Eƒ{ƒ^ƒ“‚ðƒNƒŠƒbƒN‚·‚é‚ƁAƒNƒŠƒbƒN‚µ‚½ˆÊ’u‚Ì +@’PŒê‚Ü‚½‚͏nŒê‚̈Ӗ¡‚ð•\Ž¦‚µ‚Ü‚·B + + y’ˆÓzPDIC–{‘Ì‚Í•K‚¸Ž«‘ƒOƒ‹[ƒv‚ðƒI[ƒvƒ“‚µ‚½ó‘Ô‚É‚µ‚Ä‚¨‚¢‚Ä‚­‚¾‚³‚¢B + ‚‚܂èA’ʏí‚ÌŒŸõ(WORD—““ü—́j‚ª‚Å‚«‚éó‘Ô‚É‚µ‚Ä‚¨‚¢‚Ä‚­‚¾‚³‚¢B + (ƒƒjƒ…[‚Ì File | Ž«‘ƒOƒ‹[ƒvƒI[ƒvƒ“) + Ž«‘•ÏŠ·’†‚ȂǁA’ʏí‚ÌŒŸõ‚ª‚Å‚«‚È‚¢ó‘Ԃł̓|ƒbƒvƒAƒbƒvŒŸõ‚Í + ‚Å‚«‚Ü‚¹‚ñB + + y’ˆÓzMS-Word‚Å‚Í Ctrl+‰EƒNƒŠƒbƒN ‚ªƒJƒbƒg•ƒy[ƒXƒg‚ÉŠ„‚è“–‚Ä‚ç‚ê‚Ä‚¢‚é + ‚½‚߁A‚¤‚Ü‚­“®ì‚µ‚È‚¢‚Æ‚«‚ª‚ ‚è‚Ü‚·B + iu‚Í‚¶‚ß‚É‘I‘ð‚µ‚Ä‚­‚¾‚³‚¢v‚ȂǂƏo‚Ä‚­‚éj + ‚à‚µ‚±‚Ì–â‘è‚ð‰ñ”ð‚µ‚½‚¢ê‡‚́AŽŸ‚́u‚¿‚å‚Á‚Æ•Ö—˜‚ÈŽg—p•û–@v + ‚É‚ ‚é‚悤‚ɁAu‰EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvv‚É‚·‚é‚©A + ŽŸ‚̂悤‚ɐݒè‚ðs‚Á‚Ä‚­‚¾‚³‚¢B + DokoPop!‚̃^ƒXƒNƒgƒŒƒC‚̃ƒjƒ…[‚©‚çA[Ý’è...]‚ð‘I‚сA + uƒ|ƒbƒvƒAƒbƒvŒŸõv‚©‚çAƒ|ƒbƒvƒAƒbƒv‚ð‚³‚¹‚é‚Æ‚«‚Ì‘g‚ݍ‡‚킹‚ð + ‘I‚ñ‚Å‚­‚¾‚³‚¢B + Alt + ‰EƒNƒŠƒbƒN ‚Å‚ ‚ê‚Ζâ‘è‚È‚¢‚悤‚Å‚·B + +‚¿‚å‚Á‚Æ•Ö—˜‚ÈŽg—p•û–@ --------------------------------------- + +@uCtrl + ‰EƒNƒŠƒbƒNv‚͂킸‚ç‚킵‚¢II +@‚Æ‚¢‚¤l‚ɂ́A + +@u‰EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvv + +@‚Æ‚¢‚¤•û–@‚à‚ ‚è‚Ü‚·B +@Ctrl + Alt + ‰EƒNƒŠƒbƒN ‚ÅON/OFF‚̐؂è‘Ö‚¦‚ª‚Å‚«‚Ü‚·B +@iØ‚è‘Ö‚¦Žž‚ɃƒbƒZ[ƒW‚ªo‚Ü‚·) + +@ƒqƒ“ƒgFu‰EƒNƒŠƒbƒN‚¾‚¯v‚É‚µ‚½ê‡AuCtrl + ‰EƒNƒŠƒbƒNv‚ð‚·‚é‚ƁA +@@@@@’ʏí‚̉EƒNƒŠƒbƒNƒƒjƒ…[‚ªo‚Ä‚«‚Ü‚·B +@@@@@‚¿‚傤‚ǁuCtrlv‚ª‹t“]‚·‚銴‚¶‚É‚È‚è‚Ü‚·B + +ƒƒjƒ…[ ----------------------------------------------------- + +@ƒ^ƒXƒNƒgƒŒƒC‚ÌDokoPop!ƒAƒCƒRƒ“‚ð‰EƒNƒŠƒbƒN‚·‚é‚ƃƒjƒ…[‚ªŒ»‚ê‚Ü‚·B + +@Ž«‘ƒOƒ‹[ƒv - PDIC‚ÌŽ«‘ƒOƒ‹[ƒv‚̕ύX‚ðs‚¢‚Ü‚· +@‰EƒNƒŠƒbƒNŒŸõ - ƒ}ƒEƒX‚̉EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¢‚Ü‚· +@ƒ|ƒbƒvƒAƒbƒvŒŸõ—LŒø - ŒŸõ‚ð—LŒø^–³Œø‚É‚µ‚Ü‚· +@Ý’è - ŠeŽíÝ’è‚ðs‚¢‚Ü‚· +@à–¾‘‚ð•\Ž¦ - ‚±‚̃tƒ@ƒCƒ‹‚ð•\Ž¦‚µ‚Ü‚· +@ƒo[ƒWƒ‡ƒ“ - version•\Ž¦ +@I—¹ - ‚Ç‚±ƒ|ƒbƒvI‚̏I—¹ + +Ý’è --------------------------------------------------------- + + ƒ^ƒXƒNƒgƒŒƒC‚̉EƒNƒŠƒbƒN‚ŏo‚Ä‚«‚½ƒƒjƒ…[‚́uÝ’èv‚Å‚·B + + ¡‹N“®Žž‚ɃXƒvƒ‰ƒbƒVƒ…‚ð•\Ž¦‚·‚é + ‹N“®Žž‚̉æ–Ê’†‰›‚ɏo‚Ä‚­‚éƒEƒBƒ“ƒhƒE‚Ì + •\Ž¦‚ð—LŒø^–³Œø‚É‚µ‚Ü‚·B + + š‹N“®Žž‚̃Xƒvƒ‰ƒbƒVƒ…ƒrƒbƒgƒ}ƒbƒv‚ðƒJƒXƒ^ƒ}ƒCƒYš + DKPU.EXE‚ª‚ ‚éƒtƒHƒ‹ƒ_[‚É DKPU.BMP ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚é‚ƁA + ‚»‚̃rƒbƒgƒ}ƒbƒv‚ð‹N“®Žž‚ƃo[ƒWƒ‡ƒ“...‚Ì‚Æ‚«‚É•\Ž¦‚µ‚Ü‚·B + + ¡Ž«‘ƒOƒ‹[ƒv‚ðŽw’è‚·‚é + ‚±‚±‚ðƒ`ƒFƒbƒN‚·‚é‚ƁAƒ|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤‚Æ‚«‚É + ‚±‚±‚ÅŽw’肵‚½Ž«‘ƒOƒ‹[ƒv‚ðŽg—p‚µ‚Ü‚·B + PDIC–{‘Ì‚Å‚ÌŽ«‘ƒOƒ‹[ƒv‚Ì‘I‘ð‚ª•ÏX‚³‚ê‚Ü‚·B + + ¡ƒ|ƒbƒvƒAƒbƒvŒŸõ - ƒ|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤ƒ}ƒEƒX‚ƃL[‚Ì‘g‚ݍ‡‚킹‚ðŽw’肵‚Ü‚·B + + ¡‰EƒNƒŠƒbƒNŒŸõON/OFF + ‰EƒNƒŠƒbƒNŒŸõ‚Ì—LŒøE–³Œø‚ðØ‚è‘Ö‚¦‚éƒ}ƒEƒX‚ƃL[‚Ì‘g‚ݍ‡‚킹‚Å‚·B + + ¡‰p”Žš‚Ì‚ÝŒŸõ‚·‚é + “ú–{ŒêE‰p”Žš¬Ý‚Ì•¶Í‚ª‚ ‚Á‚½ê‡A“ú–{Œê‚𖳎‹‚µ‚ÄŒŸõ‚ðs‚¢‚Ü‚·B + ¬Ý•¶Í‚Å‚Í ON ‚É‚µ‚½‚Ù‚¤‚ªƒqƒbƒg‚µ‚â‚·‚­‚È‚è‚Ü‚·B + ‚Ü‚½Aƒtƒ‰ƒ“ƒXŒêAƒhƒCƒcŒê‚̂悤‚ȃEƒ€ƒ‰ƒEƒgEƒAƒNƒTƒ“‚È‚Ç‚ð + ŠÜ‚Þ•¶Í‚Å‚Í‚±‚±‚ð OFF ‚É‚µ‚È‚¢‚Æ‚¤‚Ü‚­“®ì‚µ‚È‚¢ê‡‚ª‚ ‚è‚Ü‚·B + + ¡”FŽ¯ƒ‚[ƒh‚̐ݒè + E•¶Žš”FŽ¯{•¶Žš’Šo + E•¶Žš”FŽ¯‚Ì‚Ý + E•¶Žš’Šo‚Ì‚Ý + ’ʏíˆê”ԏã‚̐ݒ肪‚¢‚¢‚ÆŽv‚¢‚Ü‚·‚ªAƒ|ƒbƒvƒAƒbƒv‚µ‚È‚¢AƒAƒvƒŠ‚ª—Ž‚¿‚éA‚Ȃǂ̏ꍇ‚Í + Ý’è‚ð•ÏX‚·‚é‚Æ‚¤‚Ü‚­‚¢‚­‚悤‚É‚È‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñB + ¦DokoPop! Ver.1‚́u•¶Žš’Šo‚̂݁v‚Æ“¯‚¶“®ì‚ð‚µ‚Ü‚· + + ¡•¶Žš”FŽ¯‚̏ꏊ - ã‹‰ŽÒŒü‚¯ + MODI‚ðƒCƒ“ƒXƒg[ƒ‹‚Å‚«‚È‚¢ê‡‚ɁA‘¼‚ÌPC‚É‚ ‚éAMODI‚ð—˜—p‚·‚邱‚Æ‚ÅMODI‚ð—˜—p‰Â”\‚É‚µ‚Ü‚·B + êŠ‚Æ‚µ‚āA + \amodi + ‚ðŽw’肵‚Ü‚·B + —áF + \\server\temp\amodi + ¦ƒtƒ@ƒCƒ‹‹¤—LŒo—R‚Å—˜—p‚µ‚Ü‚·B + + ¡64ƒrƒbƒgƒtƒbƒN‚ðŽg—p‚·‚é + 64bitWindows‚Å‚¤‚Ü‚­ƒqƒbƒg‚µ‚È‚¢ê‡‚É‚±‚±‚ðƒ`ƒFƒbƒN‚·‚é‚Æ“®ì‚·‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñB + +Œ¾Œê”»’èDLL -------------------------------------------------- + +@DokoPop!/Unicode‚ł́AŒŸõ‘Ώۂ̒PŒê‚ðØ‚èo‚·Û‚ɁA‘Ώی¾Œê‚ª +@‰¢•ÄŒn‚ÌŒ¾Œê - ‚±‚±‚Å‚Í’PŒê‚Ì‹æØ‚è‚É”¼ŠpƒXƒy[ƒX‚ðŽg‚¤Œ¾Œê‚Æ‚¢‚¤ˆÓ–¡‚Å +@’è‹` - ‚ð‘O’ñ‚Æ‚µ‚Ĉµ‚Á‚Ä‚¢‚Ü‚·B +@‚µ‚©‚µA‰¢•ÄŒnˆÈŠO‚ÌŒ¾ŒêA—Ⴆ‚Γú–{Œê‚̂悤‚É’PŒê‚Ì‹æØ‚è‚Í“ú–{Œê‚ð +@—‰ð‚Å‚«‚él‚É‚µ‚©‚í‚©‚è‚Ü‚¹‚ñB“–‘RAƒRƒ“ƒsƒ…[ƒ^[‚É‚à’PŒê‚Ì‹æØ‚è‚ð +@ŠÈ’P‚É—‰ð‚³‚¹‚邱‚Æ‚Í‚Å‚«‚Ü‚¹‚ñB +@i“ú–{Œê“ü—Í‚Å•¶ß‚Ì‹æØ‚è‚ð‚Æ‚«‚Ç‚«ŠÔˆá‚¦‚é‚悤‚Ɂj +@‚³‚ç‚ɁAUnicode‚ňµ‚¦‚錾Œê‚É‚Í“ú–{Œê‚̂悤‚ÈŒ¾Œê‚ª”‘½‚­‚ ‚èA +@ŠeŒ¾Œê‚Ì•¶–@‚ð•×‹­‚µA‘g‚ݍž‚Þ•K—v‚ª‚ ‚è‚Ü‚·B + +@‚±‚Ì‚½‚ß‚ÌŠJ”­î•ñ‚ð‚±‚¿‚ç‚ÅŒöŠJ‚µ‚Ä‚¢‚Ü‚·B +@http://pdic.la.coocan.jp/unicode/langproc.html + +‚»‚Ì‘¼ ------------------------------------------------------- + +@Ä—˜—pEÄ”z•zE‰ü•Ï‚È‚Ç‚ÍŽ©—R‚Å‚·B +@‚±‚̃\ƒtƒgƒEƒFƒA‚É‚æ‚鑹ŠQ‚͈êØ‚»‚̐ӔC‚𕉂¢‚Ü‚¹‚ñB + +@‚±‚Ìprogram‚́Aopen source‚Å‚ ‚éDCHook‚Ìsample program‚Å‚·B +@ƒ\[ƒXƒtƒ@ƒCƒ‹‚́A +@http://dokopop.sourceforge.jp/ +@‚É‚ ‚è‚Ü‚·B + +@PDIC/Unicode‚Í +@http://pdic.la.coocan.jp/unicode/ + +—š—ð --------------------------------------------------------- + + +>> Ver.2.00 << + E•¶Žš”FŽ¯‚É‚æ‚èAƒ|ƒbƒvƒAƒbƒvŒŸõ‚ª‚Å‚«‚é‚Æ‚±‚낪‘‚¦‚½ + Eƒ}ƒEƒX‚Ì’†‰›ƒ{ƒ^ƒ“‚ւ̑Ήž + +>> Ver.1.23 << + EDDE‚Å‘—M‚·‚éƒf[ƒ^‚ÌŒ`Ž®‚ª³‚µ‚­Žw’肳‚ê‚Ä‚¢‚È‚©‚Á‚½(CF_TEXT->CF_UNICODETEXT) + +>> Ver.1.22 << + EƒNƒŠƒbƒN‚·‚é‘Ώۂ̃EƒBƒ“ƒhƒE‚ª”ñUnicode‚Å‚ ‚éê‡“®ì‚µ‚È‚©‚Á‚½ + +>> Ver.1.21 << + EŽ«‘ƒOƒ‹[ƒv‚Ì‘I‘ð‚ª³‚µ‚­“®ì‚µ‚È‚¢–â‘è‚ðC³ + +>> Ver.1.20 << + EPDIC/Unicode Ver.5.0.x‚ɑΉž + +>> Ver.1.15 << + EPDIC/Unicode Ver.0.83‚ɑΉž + Edialog‚̏o‚éêŠ‚ðDesktopCenter¨ScreenCenter (ƒ}ƒ‹ƒ`ƒ‚ƒjƒ^‘Ήž) + +>> Ver.1.14 << + EDokoPop!‚ÉŠÖ‚µ‚Ă͒ʏí‚̃o[ƒWƒ‡ƒ“”ԍ†‚ð•t‚¯‚邱‚Æ‚É‚µ‚½ + - DokoPop!‚̓À”łƐ³Ž®”Å‚ÌŽÀÛ“I‚ȈႢ‚ª–³‚¢‚½‚ß + - DokoPop!‚̓I[ƒvƒ“ƒ\[ƒX‚Å‚ ‚èAPDIC–{‘Ì‚Æ‚Í•Ê”z•z‚Å‚ ‚邽‚߁A + PDIC–{‘Ì‚Æ“¯Šú‚·‚éƒÀ”Å‚ÆŒ¾‚¤“K“–‚È‹æØ‚肪–³‚¢‚½‚ß + Eƒo[ƒWƒ‡ƒ“”ԍ†‚Ífor Win32”Å‚Æ‹¤’ʉ»iƒ\[ƒXƒR[ƒh‚ª“¯‚¶‚½‚߁j + * •¶‚̍Ōã‚Ì’PŒê‚ªƒqƒbƒg‚µ‚È‚©‚Á‚½iDokoPop!‚̍ŐV”Å‚ª•K—vj + yŒ´ˆöz + @Žæ“¾‚µ‚½•¶Žš—ñ‚̍Ōã‚ɃSƒ~‚ª•t‘®‚µ‚½‚±‚Æ‚É‚æ‚èA‚»‚ê‚ðPDIC‚ª’ʏí‚̃eƒLƒXƒg + @‚Æ”FŽ¯‚µ‚Ä‚µ‚Ü‚¢A•¶‚̍Ōã‚̃sƒŠƒIƒh‚ª’PŒê’†‚Ì•¶Žš—ñ‚Æ‚µ‚ďˆ—‚³‚ꂽ‚½‚߁B + +>> Ver.0.10 << +EÅ‰‚ÌŒöŠJ + +-------------------------------------------------------------- diff --git a/DKPUu.TXT b/DKPUu.TXT new file mode 100644 index 0000000..e73d9a0 --- /dev/null +++ b/DKPUu.TXT @@ -0,0 +1,34 @@ +======================================================================== +yƒ\ ƒt ƒg–¼z ‚Ç‚±ƒ|ƒbƒvI Ver.2.023 +y“o ˜^ –¼z@DKPU2023.exe +yƒoƒCƒg ”z Bytes +yŒŸõ ƒL[z@1:DOKOPOP 2:PDIC 3:$WIN32 4:#APP 5:#EDU +y’˜ìŒ  ŽÒz@‚È‚µ +yŒf Ú ŽÒz@DokoPop Project +y‘Ήž ‹@Žíz@MS-Windows Vista/7/8/8.1/10 +y“®ì Šm”Fz@IBM PC/ATŒÝŠ·‹@,7/8/8.1/10 +yŒf Ú “úz@2016.10.06 +yì¬ •û–@z@DKPU2023.exe ‚ðŽÀs‚·‚é +y¿Ìijª±Ží•Êz@ƒtƒŠ[ƒEƒFƒA +y“]Ú ðŒz “]ÚŽ©—R +======================================================================== +yƒ\ƒtƒgÐ‰îz + +@DokoPop! - ‚Ç‚±ƒ|ƒbƒvI ‚́ACtrl+ƒ}ƒEƒX‰EƒNƒŠƒbƒN‚ŁA +@ƒ}ƒEƒXƒJ[ƒ\ƒ‹ˆÊ’u‚̉p’PŒêE‰pnŒê‚ðŒŸõ‚µAƒ|ƒbƒvƒAƒbƒv•\Ž¦‚µ‚Ü‚·B + +@‚Ç‚±ƒ|ƒbƒvI ‚Í PDIC/Unicode‚ÌDDE‹@”\‚ð—˜—p‚µ‚Ä‚¢‚Ü‚·B +@•Ê“rPDIC/Unicode‚ð“üŽè‚µ‚ĉº‚³‚¢B + +@PDIC/Unicode ‚Ì“üŽèæ(•K{)F + http://pdic.la.coocan.jp/ + +@ƒ\[ƒXƒtƒ@ƒCƒ‹F + http://dokopop.sourceforge.jp/ + + +Œ»Ý‚Ì–â‘è“_ + + +======================================================================== +ƒ_ƒEƒ“ƒ[ƒhƒtƒ@ƒCƒ‹–¼‚́yDKPU2023.exez‚Å‚·B diff --git a/Diary.txt b/Diary.txt new file mode 100644 index 0000000..ab974c3 --- /dev/null +++ b/Diary.txt @@ -0,0 +1,280 @@ + http://grabacr.net/archives/1132 +¡BUG +Eamodi‚Ì.NET Framework version‚́H +ESetWindowsHookEx–â‘è + - 32bit/64bit—¼•ûload¨32bit‚ÍOKA64bit‚Írun on load context + - 32bit‚Ì‚Ýload¨32bit‚ÍOKA64bit‚Í–³”½‰ž + - 64bit‚Ì‚Ýload¨64bit‚ÍOKA32bit‚Írun on load context + - 64bit‚ðæ‚ÉlaunchA32bit‚ð‚ ‚Æ‚©‚çload¨32bit‚ÍOKA64bit‚Írun on load context + - 64bit/32bit‚ðloadA‚»‚ÌŒã64bit‚Ì‚Ýinit/configA‚»‚Ì‚ ‚Æ32bit‚Ì‚ÝInit‚̂݁¨32bit Init‚ðŽÀs‚·‚é‚Ü‚Å‚Í64bit‚ÍOKA32bit‚ÌInit‚ðs‚¤‚Æ64bit‚Írun on load context + - 64bit‚ðˆÙ‚È‚éƒfƒBƒŒƒNƒgƒŠ‚ÅŽÀs¨•Ï‚í‚炸 +[ˆê”Ê“®ì] +E[B] Edge@Win10@VMware@PWS300‚Å•¶Žš”FŽ¯‚Å‚«‚Ä‚¢‚é‚̂Ƀ|ƒbƒvƒAƒbƒv‚µ‚È‚¢Žž‚ª‚ ‚遨FAQ + ¨ˆÊ’u‚ðŒÅ’èAƒtƒH[ƒJƒXˆÚ“® +E[B] ƒƒOƒCƒ“‚Ìstartup‚Åamodi‚ª—áŠO‚Å—Ž‚¿‚éBFileNotFound‚ÅŠÄŽ‹—pƒtƒHƒ‹ƒ_[‚ªŒ©‚‚©‚ç‚È‚¢H +E[C] Windows shutdown‚ÅExMODI‚ª—áŠOH +E[B] .NET‚ð4.0‚©‚ç3.5‚É‚Å‚«‚È‚¢‚©H +E[B?] main prg‚Ìmain thread‚ªblockingó‘Ô‚É‚È‚é‚Æ‚È‚ºUI‘S‘Ì‚ªŽ~‚Ü‚éH + ¨Ž~‚Ü‚Á‚Ä‚¢‚é‚Æ‚±‚ë‚͏­‚È‚­‚Æ‚àHookŠÖ”“à‚Å‚Í‚È‚¢‚炵‚¢(return‚Ü‚Å‚ÌŽžŠÔ‚ª‚P•bˆÈ“à‚¾‚Á‚½j +E[B] ‚Ü‚¾”{—¦ˆ—‚ª‚¤‚Ü‚­“­‚©‚È‚¢ + - Firefox¨Šg‘å‚È‚µ‚ÅOK + - IE¨Šg‘又—•K—v +E[C] click‚É‚æ‚éCaptureImage‚Ímain‚©‚ç‚̌Ăяo‚µ‚É‚µ‚½‚Ù‚¤‚ª‚¢‚¢‚̂ł́H + ¨‚Ç‚Ì‚Ý‚¿wait‚·‚é‚Ì‚¾‚©‚çA–â‘è‚È‚¯‚ê‚΂±‚Ì‚Ü‚Ü‚Å‚¢‚¢‚©‚àH +E[C] Capture API‚ª64/32bit—¼•û‚ŌĂ΂ê‚Ä‚µ‚Ü‚¤‚Ì‚Í‚Ü‚¸‚¢‚̂ł́H’P‚È‚é–³‘ʁH + ¨‚¹‚ß‚Äbit”‚ð”»’f‚µ‚Ä‚©‚ç‚Å‚ ‚ê‚΁EEE +E[B?] MODI‚ªƒCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ä‚¢‚È‚¢ó‹µ‚ÅDokoPop!‚ð‹N“®A‚»‚ÌŒãMODI‚ðƒCƒ“ƒXƒg[ƒ‹‚·‚邪amodi‚ª•¡”‹N“®‚µ‚ÄOCR‚ª“®ì‚µ‚È‚¢ó‘Ô‚ª‚ ‚Á‚½ + ¨amodi.exe‚ªI—¹‚µ‚È‚¢ðŒ‚ª‚ ‚éH + ¨MODI uninstall/install‚ð‚â‚Á‚Ä‚Ý‚½‚ªÄŒ»‚¹‚¸BOS installŒã‰‰ñ‚¾‚¯H +E[C][Win10] SharePoint Designer‚ðWindows10‚ɃCƒ“ƒXƒg[ƒ‹‚·‚é‚Æ‚«A.NET‚̃Cƒ“ƒXƒg[ƒ‹‚𑣂·‚ªAƒGƒ‰[‚Æ‚È‚è‚Å‚«‚È‚¢B¨‚»‚à‚»‚à.NET‚Í“ü‚Á‚Ä‚¢‚é‚̂ŃCƒ“ƒXƒg[ƒ‹•s—vBinstaller‚̃oƒOH +E[B] ]—ˆ•ûŽ®‚Ì•¶Žš—ñ’Šo‚ª“®ì‚µ‚È‚­‚È‚Á‚½H + ¨DKPUHK64.dll‚ðload‚µ‚½‚½‚߁BDKPUHK64‚ðhook‚³‚¹‚é‚Æ32bitƒAƒvƒŠã‚Åhook‚ª³‚µ‚­“®ì‚µ‚È‚¢iÚ×‚Ì“®ì‚Í•s–¾j + ¨‚È‚º32bitƒAƒvƒŠ‚Å64bit DLL‚ªhook‚³‚ê‚é‚Ì‚©H + ‚Ü‚Æ‚ß‚é‚ƁA + - 64bitDLL‚ðŽg—p‚·‚é‚ƁEEE32bitƒAƒvƒŠã‚Å“®ì‚µ‚È‚­‚È‚éi64bitƒAƒvƒŠ‚ÍOK) + - 64bitDLL‚ðŠO‚·‚ƁEEEEE32bitƒAƒvƒŠ‚Í“®ìA64bitƒAƒvƒŠ‚ÍNG +@ - 64bit DLL‚ðload‚·‚é‚ƁA32bitƒAƒvƒŠã‚Ƀ}ƒEƒX‚ðˆÚ“®‚µ‚Ä‚àDLL attach‚³‚ê‚È‚¢B(32/64bit—¼•û) + - 64bit DLL‚ðload‚µA32bitƒAƒvƒŠã‚Åmouse‘€ì‚·‚é‚ƁA64bit/32bit—¼•û‚ÌDLL‚̏ˆ—‚ª‘–‚éB‚ ‚肦‚È‚¢‚¾‚낤HH + ªattach‚³‚ê‚Ä‚¢‚È‚¢‚Ì‚É‚È‚º”½‰ž‚Å‚«‚éHH + ¨64bit DLL‚ÍDKPUHK64.exe‚Å‘–‚èA32bit DLL‚ÍDCHookTest.exe‚Å‘–‚Á‚Ä‚¢‚éII‚È‚ºH + ¨DKPUHK64.exe‚ð•ÊƒvƒƒZƒX‚©‚ç‹N“®‚µ‚Ä‚àÄŒ»‚·‚éBDLL‚ÌInit()ŒÄ‚яo‚µ‚ð‚µ‚È‚¯‚ê‚΍Č»‚µ‚È‚¢B + SetWindowsHookEx()‚ÌŽg—p‚É–â‘肪‚ ‚é‚炵‚¢B + ¨•ÊƒAƒvƒŠ‚È‚Ì‚É‚È‚º‰e‹¿‚·‚é‚Ì‚©HDLL‚̉½‚©‚ª‚Ԃ‚©‚Á‚Ä‚¢‚éH + http://resources.infosecinstitute.com/using-setwindowshookex-for-dll-injection-on-windows/ + ‚ðn“Ç‚·‚é‚Ɖ½‚©ƒqƒ“ƒg‚ª‚ ‚éH + ¨64bit‚Ì‚ÝInit‚ðs‚¤‚Æ64bitƒAƒvƒŠã‚Ő³í“®ì‚µA32bitƒAƒvƒŠã‚Å‚ÍDKPUHK64.exe‚̃vƒƒZƒXã‚Å“®‚­ + - ProcessExplorer‚ÅŠm”F‚·‚é‚ƁA64bitƒAƒvƒŠ(ƒƒ‚’ )‚Ìload‚³‚ê‚Ä‚¢‚éDLL‚ÉDKPUHK64.DLL‚ª‚¢‚È‚¢ + ¨dchk64.exe‚݂̂𒼐ڎÀs‚µ‚½ê‡‚Í–â‘è‚È‚¢HH(DKPUHK64.DLL‚ªƒƒ‚’ ‚Éhook‚µ‚Ä‚¢‚½) + ¨32bit‘¤‚ÌInit()‚ð‚µ‚È‚¢‚Æ‚Ç‚¤‚È‚éH + ¨bingo!! DKPUHK64.DLL‚ªload‚³‚ꂽ + - [Ï] 64bit DLL‚ÌUninit()‚ªŒÄ‚΂ê‚È‚¢ + ¨32bit DLL‚ªUninit()‚³‚ꂽ‚Æ‚«‚ÉDKPUHK64.exe‚ªI—¹‚µ‚Ä‚¢‚éHH + ¨Unload‚Ì‚ ‚Æ‚ÉUninit‚ªŒÄ‚΂ê‚Ä‚¢‚½¨Uninit->Unload‚É‚µ‚½ +E[B] ƒƒ‚’ ‚Å•¶Žš‰»‚¯ + ¨meta file‚̍ж‚Å EMR_EXTTEXTOUTW‚̃eƒLƒXƒg‚ª‰»‚¯‰»‚¯ + ¨64bit DLL‚𖳌ø‚É‚µ‚½‚ç‚»‚Ì–â‘è‚Í”­¶‚µ‚È‚­‚È‚Á‚½‚ªA•Ê–â‘肪”­¶ +E[C] ƒCƒ“ƒNƒŠƒƒ“ƒ^ƒ‹ƒT[ƒ`‚ð—LŒø‚É‚µ‚½’¼ŒãAOCR Error‚ª”­¶‚·‚é + ¨Reboot()‚µ‚È‚¢‚悤‚É‚·‚é‚ƁA‚»‚ÌŒã‚͐³í‚É“®ì‚·‚éB + ¨‚Æ‚è‚ ‚¦‚¸Reboot()‚ð‚Í‚¸‚µ‚½i•K—v«‚ª¡‚Ì‚Æ‚±‚ë–³‚­‚È‚Á‚½‚̂Łj +E[C] Chrome‚ōÀ•W‚ª‚¸‚ê‚é@VAIO Pro11 + ¨Ø‚蔲‚«‚͑ΏÛwindow‚Ì‚Ý‚ÉŒÀ’肵Aclick point‚à100,100ŒÅ’è‚É‚¹‚¸A‘ΏÛwindow‚Åclip‚µ‚½‚Ù‚¤‚ª‚¢‚¢‚̂ł́H + ¨‚»‚ê‚͑ΉžÏ‚݁B‚µ‚©‚µ–â‘è‚Íwindow8‚ÌŠg‘å‹@”\‚¾‚Á‚½B + http://grabacr.net/archives/1132 + GetDpiForMonitor, CDPI class‚ ‚½‚肪ŠÌ‚©H + ¨GetDeviceCaps(LOGPIXELSx)‚ðŽg—p‚·‚ê‚΂¢‚¢‚¾‚¯H + ¨Žæ“¾•û–@‚ªŒ©‚‚©‚炸Bƒ†[ƒU[“ü—Í‚Å‚Æ‚è‚ ‚¦‚¸‘Ώˆ + ¨ResolutionScale‚¾‚Á‚½‚ª‚¤‚Ü‚­“®‚©‚È‚¢H +E[C] AMODI‚Ìtemporary folder‚ðlock‚µ‚Ä‚¢‚é‚ÆAMODI‚ª‹N“®‚Å‚«‚È‚¢i‹N“®‚µ‚Ä‚à‰½‚àŒ¾‚킸‚ɏI—¹j +E[?] XP‚Ìdpi scaling‚Í–â‘è‚È‚©‚Á‚½H +[ˆÀ’萫] +E[B] inc.srch‚ð—LŒø‚É‚µ‚Ä‚¢‚é‚ÆDKPUHK64.exe‚Å—Ž‚¿‚½B¨MouseMove‚Ì‚Æ‚±‚ë‚ðcomment out +E[B] inc.srch{Ctrl+‰EƒNƒŠƒbƒN‚ÅŒƒ‚µ‚­‚â‚Á‚Ä‚¢‚é‚ÆAMODI‚Å—Ž‚¿‚é + - inc.srch‚ð—LŒø‚É‚µ‚āAƒ^ƒXƒNƒgƒŒƒC‚Ìdp‚ʼnEƒNƒŠƒbƒNƒƒjƒ…[‚ðo‚µAà–¾‘‚ð•\Ž¦‚ɃJ[ƒ\ƒ‹‚ð‡‚í‚¹‚é‚ÆAMODI‚Å—Ž‚¿‚é@win7 +E[B] FileSync‚ÅŒŸõ‚·‚é‚ÆFileSync‚ªassertion failure‚ð‹N‚±‚µAPDHKU64.exe‚ª—Ž‚¿‚é + - SyncExecFrm.cpp TSyncExecFrame::lbLogDrawItem 627 + - XP(xw8400)‚Å‚Í–â‘è‚È‚µ +E[A?] ŒŸõ“®ì‚µ‚È‚­‚È‚é‚Æ‚«‚ª‚ ‚éH@win7 + ¨OSÄ‹N“®‚ȂǂōČ»‚µ‚È‚­‚È‚Á‚½H +E[B?] amodi‚ðŽg—p‚·‚é‚Æoffice‚Ìinstall‚ªŽn‚Ü‚éH@win7 + ¨OSÄ‹N“®‚ȂǂōČ»‚µ‚È‚­‚È‚Á‚½H +E[Q] DokoPop!‚ªPDIC‚ð‹N“®‚·‚é‚Æ‘O‰ñ‚ƈقȂépath‚É‚ ‚éPDIC‚ª‹N“®‚µ‚Ä‚µ‚Ü‚¤@vaio¨portable”Å‚¾‚©‚çBFAQ‚É‚ ‚Á‚½‚Ù‚¤‚ª‚¢‚¢ +E[C] ƒ]ƒ“ƒrDKPUHK64.exe‚̏ˆ— +E[C] pdhk64.exe‚ªŽ€‚ñ‚¾Žž‚̑΍ô +E[?] win8‚Ålog offŽž‚Épdhk64.exe‚ª—Ž‚¿‚éH +E[?] stand-by•œ‹AŒãAMODI‚ª—Ž‚¿‚éH@XP +yÏz +E[B][amodi] ƒtƒ@ƒCƒ‹íœŽž‚Ì—áŠOˆ—’ljÁ +E[B] WinXP‚Åinc.srch‚ª‚Ü‚Á‚½‚­“®‚©‚È‚¢H + ¨WinXP‚ł́Aevent/thread‚ÍDLL’PˆÊ‚Å‚Í‚È‚­ADLL instance’PˆÊ‚Ő¶¬‚·‚é•K—v‚ª‚ ‚Á‚½ +E[B] ƒCƒ“ƒNƒŠƒƒ“ƒ^ƒ‹ƒT[ƒ`‚ª•p”É‚É”­¶‚·‚邽‚ߏd‚­‚Ȃ遨ŒŸõ‚Ì•p“x‚ð‰º‚°‚é•K—v‚ª‚ ‚é + ¨ƒJ[ƒ\ƒ‹‚ª’âŽ~‚µ‚Ä‚©‚ç0.3•bŒãA‚È‚Ç + ¨0.1•bŒã‚É‚È‚é‚悤‚É‚µ‚Ä‚ ‚é‚̂ɏd‚¢B64bitƒAƒvƒŠ(IE‚È‚Ç)ã‚ŏd‚­‚È‚é‚悤‚¾B + ¨OCR Error‚ª”­¶‚·‚é‚ƃtƒ@ƒCƒ‹‘‚«ž‚Ý‘Ò‚¿‚Ì‚R•b‚Åwait‚³‚ê‚Ä‚¢‚½B + ¨–{—ˆ‚»‚±‚Åwait‚µ‚Ä‚àƒXƒgƒbƒv‚·‚é‚Ì‚Í‚¨‚©‚µ‚¢Bwait‚Í•Êthread‚ōs‚¤‚悤‚É‚·‚é + ¨•Êthread‚ÅŽÀs‚·‚é‚悤‚É‚µ‚½¨OK +E[B] ƒƒ‚’ ‚ÅOCR‚ª“®ì‚µ‚È‚¢ + ¨GetDIBits()‚сƒ‚ƒŠ•s‘«ƒGƒ‰[‚ª”­¶‚µ‚Ä‚¢‚é + ¨MODI‚Ìinstall‚ªuƒ}ƒCƒRƒ“ƒsƒ…[ƒ^‚©‚çŽÀsv‚É‚È‚Á‚Ä‚¢‚½i–{“–‚́uƒ}ƒCƒRƒ“ƒsƒ…[ƒ^‚©‚ç‚·‚ׂĎÀsvj + +¡DPI awareness +http://ascii.jp/elem/000/000/905/905248/ - ‚í‚©‚è‚â‚·‚¢à–¾(“ú–{Œê) +http://www.telerik.com/blogs/winforms-scaling-at-large-dpi-settings-is-it-even-possible- - ŠÈ’P‚ÈŠT—và–¾ +http://kynosarges.org/WindowsDpi.html - ‚±‚¿‚ç‚Ì‚Ù‚¤‚ª‚¢‚¢à–¾H +https://msdn.microsoft.com/ja-jp/library/windows/desktop/dn469266%28v=vs.85%29.aspx - HighDPI ‘Ήžˆê——‚È‚Ç—lX‚ȏî•ñ +https://msdn.microsoft.com/ja-jp/library/windows/desktop/dd464659%28v=vs.85%29.aspx - High DPI‘ΉžƒvƒƒOƒ‰ƒ~ƒ“ƒO(8.1—p‚µ‚©‘‚¢‚Ä‚¢‚È‚¢H) +Windows8.1‚Å‚Í 96dpi(100%), 120dpi(125%), 144dpi(150%), 192dpi(200%)‚ÌŽl‚‚ ‚é +EŠm”FŽ–€ + - WinXP‚Å‚àDPI‚ð•ÏX‚·‚é‚ÆDokoPop!‚͐³‚µ‚­“®ì‚µ‚È‚©‚Á‚½‚̂ł́H +EŽŽ‚µ‚É‚â‚Á‚Ă݂邱‚Æ - manifest‚ðDPI aware‚É•Ï‚¦‚Ä‚Ý‚é + + + + true + + + +E‚â‚邱‚Æ + - manifest‚ÅDPI awareness‚ðŽw’è(or SetProcessDpiAwareness API) - DokoPop!‚Ímonitor‚²‚Æ‚É‚·‚é•K—v‚ª‚ ‚é(‚½‚¾‚µ8.1ˆÈ~) + - GetDpiForMonitor() ‚ÅDPIŽæ“¾ (8.1ˆÈ~‚Ì‚Ý) + - WM_DPICHANGED‚ðhandling‚·‚é + ª‚±‚Ì•û–@‚¾‚Æ8.1ˆÈ~‚µ‚©‘Ήž‚Å‚«‚È‚¢‚̂ł́H +E‚â‚邱‚ƁE‚»‚Ì‚Q +https://msdn.microsoft.com/ja-jp/library/windows/desktop/dn469266%28v=vs.85%29.aspx#appendix_a_setting_high_DPI_in_windows +‚±‚ê‚æ‚èA +ScaleFactor = (LogicalMonitorWidth/LogicalDesktopWidth) / (PhysicalMonitorWidth/PhysicalDesktopWidth) + +MONITORINFOEX LogicalMonitorInfo; +LogicalMonitorInfo.cbSize = sizeof(MONITORINFOEX); +GetMonitorInfo(hMonitor, &LogicalMonitorInfo); +LogicalMonitorWidth = LogicalMonitorInfo.rcMonitor.right - LogicalMonitorInfo.rcMonitor.left; + +LogicalDesktopWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); + +(PhysicalDesktopWidth, PhisicalMonitorWidth) = QueryDisplayConfig()‚ÌDISPLAYCONFIG_MODE_INFO‚ÌpModeInfoArray[i].sourceMode.width + +(ŽQl)Windows8‚ɂ́A +PhysicalToLogicalPoint/LogicalToPhysicalPoint‚Æ‚¢‚¤‚à‚Ì‚ª‚ ‚é‚»‚¤‚ȁB +https://msdn.microsoft.com/ja-jp/library/windows/desktop/dn384112%28v=vs.85%29.aspx + +PhysicalToLogicalPointForPerMonitorDPI function/LogicalToPhysicalPointForPerMonitorDPI - ‚±‚ê‚ÍDPI-awareness levelo‚̉e‹¿‚ðŽó‚¯‚È‚¢ (Win8.1ˆÈ~) +GetDpiForMonitor - (Win8.1ˆÈ~) + +HPhysical Desktop Width/Physical Monitor Width +> To get the physical desktop width and physical monitor width, call QueryDisplayConfig. For each DISPLAYCONFIG_MODE_INFO in the returned pModeInfoArray, check the pModeInfoArray[i].sourceMode.width (and height and position) to reconstruct the bounding rect of all the monitors. +‚Æ‚ ‚邪A‚ǂ̂悤‚Ɏ擾‚·‚ê‚΂¢‚¢‚Ì‚¾H +source‚ªdesktop‚Åtarget‚ªmonittorH + +ˆÈã‚ª³‚µ‚¢‚Æ‚·‚é‚ƁAScaleFactor‚́A +ScaleFactor = (1280/1280) / (1920/1920) = 1 ‚Æ‚È‚Á‚Ä‚µ‚Ü‚¤HH—VAIO + +¡TODO +E[B] x64‚͕ʃfƒBƒŒƒNƒgƒŠ‚É‚·‚é‚Ə]—ˆƒtƒbƒN‚ª“®‚­‚悤‚É‚È‚é‚̂ł́H + ¨‚È‚³‚»‚¤ +E[B-] MODIƒCƒ“ƒXƒg[ƒ‹‚͐ê—p‰æ–Ê‚É‚·‚é(URLƒWƒƒƒ“ƒv) + - Å‰‚̉æ–ʂ͐ê—pDLG‚É‚·‚é + ¨ˆê’UŽ©•ª‚ÌHP(source forge?)‚É”ò‚ñ‚Å‚©‚çredirect? +E[B] í‚É”FŽ¯‚ðs‚¤AMODI‚ð‚à‚¤ˆê‚—pˆÓ‚µ‚āAƒ|ƒbƒvƒAƒbƒv‚·‚é‚Ü‚Å‚ÌŽžŠÔ‚ð’Zk‚µ‚Ä‚Ý‚Ä‚Í‚Ç‚¤‚©H + - ­‚µ‚µ‚©ˆÚ“®‚µ‚Ä‚¢‚È‚¢ê‡A”FŽ¯‚µ‚½À•W‚̃IƒtƒZƒbƒg‚ðŒvŽZ‚·‚é‚Æ‚©H +E[B] MODIƒCƒ“ƒXƒg[ƒ‹ŒãADokoPop!Ä‹N“®–³‚µ‚É‚Å‚«‚È‚¢‚©H + ¨AMODI.exe‚ðŽÀs‚·‚é•K—v‚ª‚ ‚邽‚߁Aˆ—‚Æ‚µ‚Ä‚ÍŒ‹\d‚¢ + ¨WizardŒ`Ž®‚É‚·‚é•K—v‚ª‚ ‚é‚̂ł́H +EWizardŒ`Ž®‚ÌŒŸ“¢ + - AMODI.exeŽÀsƒGƒ‰[¨MODI‚ªƒCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ä‚¢‚È‚¢‚Ɖ¼’è‚·‚é + - ƒCƒ“ƒXƒg[ƒ‹‰Â”Û‚Ì–â‚¢‡‚킹 + - Webƒy[ƒW‚ð•\Ž¦‚µ‚ăCƒ“ƒXƒg[ƒ‹‚ðs‚¤©Ž©‘O‚ÌHP‚ð—pˆÓ‚·‚é + - ƒCƒ“ƒXƒg[ƒ‹‚̈ê”ԍŌã‚ÉDokoPop!‚Ì‘€ì(Ä‹N“®Hj‚𑣂· +E[B] CtrlƒL[‚𗣂µ‚½‚ç•Â‚¶‚é‚ðŠO‚·‚ª“®‚©‚È‚¢ +E[B] aero/metro—LŒøŽž‚Ì“®ìƒeƒXƒg +E[B] PDIC–{‘Ì‚Ì‹N“®Šm”F‚Í‚Ç‚¤‚·‚éH +E[B] VUP‹@”\ +E[B] Q&A‚Ì—pˆÓ +E[C] VUP’Ê’m‹@”\ +E[C] amodi OCR“®ì’†‚ð‚Ç‚±‚©‚ŏo‚µ‚½‚Ù‚¤‚ª‚¢‚¢‚̂ł́H +E[C] ‚à‚¤­‚µclickable area‚ðL‚­‚Å‚«‚È‚¢‚©Hpdf‚ł̓qƒbƒg‚³‚¹‚é‚Ì‚ª“‚¢¨MARGIN_UNDER_CLICK‚Å’²® +E[C] metroãAWin8/PDF Viewerã‚È‚Çwin8“ÆŽ©ƒAƒvƒŠ‚Å‚Ì“®ìƒeƒXƒg +E[B] biggest‚ªƒqƒbƒg‚µ‚È‚¢ +E[C] “ñd‹N“®“®ìƒeƒXƒg +E[C] installer + - versionŽ©“®•t‚¯‘Ö‚¦‹@”\ +E[B?] popupŒŸõŽž‚àmulti thread‚É‚·‚é + - ‚»‚ê‚æ‚èA—Dæ‡ˆÊ‚̍‚‚¢‚à‚Ì‚©‚ç—Dæ“I‚É•\Ž¦‚µ‚½‚Ù‚¤‚ª‚¢‚¢‚©‚à‚µ‚ê‚È‚¢ + - ‚Ç‚±‚ÅŽžŠÔ‚ª‚©‚©‚Á‚Ä‚¢‚é‚Ì‚©‚à‚¤­‚µÚ‚µ‚­’²‚ׂé +E[C] AMODIˆÙíI—¹‘΍ô + - DLL‚àˆê‚ÉŽ€–S‚·‚邽‚߁AÄ‹N“®‚µ‚©‚È‚¢H¨Ý’肪Œ³‚É–ß‚é‚à‚Ì‚ª‚ ‚邽‚ß‚æ‚낵‚­‚È‚¢ +E[C?] PDICã‚Å‚Íinc.srch‚ª“®ì‚µ‚È‚¢‚悤‚É‚·‚遨–â‘è‚È‚¢H +E[C] button down‚ðtrigger‚É‚µ‚Ä‚¢‚邪Abutton up‚ðtrigger‚É‚µ‚Äup cancel‚·‚é‚Ì‚ðŽ~‚߂Ă݂ẮH + [•¶Œ¾] + MODI‚ðƒCƒ“ƒXƒg[ƒ‹‚·‚é‚ÆDokoPop!‚ÅŒŸõ‚Å‚«‚éƒAƒvƒŠ‚𑝂₷‚±‚Æ‚ª‚Å‚«‚Ü‚·B + (URL)‚ðŽQl‚ɃCƒ“ƒXƒg[ƒ‹‚ðs‚Á‚Ä‚­‚¾‚³‚¢B + ¦ƒŠƒ“ƒNæ‚̃y[ƒW‚ª³‚µ‚­•\Ž¦‚³‚ê‚È‚¢ê‡‚́A"MODI OCR ƒCƒ“ƒXƒg[ƒ‹"‚ŃlƒbƒgŒŸõ‚µ‚Ä’²‚ׂĂ݂Ă­‚¾‚³‚¢B + ¦Win2K‚Å‚Í‚»‚Ì‚Ü‚Ü‚Å‚ÍŽg—p‚Å‚«‚Ü‚¹‚ñB +E[C] AMODI‚̏I—¹‘΍ô + - DokoPop!Ä‹N“®‚Å‚¢‚¢‚©H + - Å’á‚Å‚àŒx‚ðo‚µ‚½•û‚ªH +E[C] ƒlƒbƒgƒ[ƒNƒ‚[ƒh - AMODI‚ðserverã‚É’u‚­ + - Windows‹¤—L‚Å‚¢‚¢H - ‚±‚̍ہAƒtƒ@ƒCƒ‹Žw’肪•K—v + - TCP/IP‚͍‚‘¬‚¾‚¯‚ǁA–Ê“|‚¾‚µ‚ȁBB + reponse‚ªˆ«‚¯‚ê‚ÎTCP/IP‚ðl‚¦‚é + +¡BUGŠ®—¹ +E[B] MODI install - ƒ^ƒCƒ~ƒ“ƒO‚ªˆ«‚¢‚ƁA + MODIƒCƒ“ƒXƒg[ƒ‹’†‚ÉMODI”FŽ¯¨Ä‹N“®¨MODIŒë”Fiinstall‚³‚ê‚Ä‚¢‚È‚¢j¨Ä‚уCƒ“ƒXƒg[ƒ‹‚µ‚ëDialog + ¨interval‚ð’u‚¢‚Ächeck‚·‚é‚悤‚É‚µ‚½ +E[B] MODIƒCƒ“ƒXƒg[ƒ‹DIALOG‚ð•Â‚¶‚é‚ƃ^ƒXƒNƒo[‚ɃAƒCƒRƒ“‚ªŽc‚é + ¨FormCreate’†‚Édialog‚ð•\Ž¦‚³‚¹‚½‚½‚߁¨IdleProc‚Ö +E[A] ]—ˆ‚Ìdokopop‚ª“®‚©‚È‚­‚È‚Á‚½@vaio + ¨USE_VXD‘Ήž‚É‚æ‚èWindowsNT flag‚ªfalse‚É‚È‚Á‚Ä‚µ‚Ü‚Á‚½‚½‚߁AGetTextFromPoint()‚ªŽÀŽ¿‰½‚àŽÀs‚¹‚¸-1‚ð•Ô‚µ‚Ä‚¢‚½‚½‚߁B +E[B?] ‰Šú‰»Žž‚É64‘¤‚ÌConfig2‚ªŒÄ‚΂ê‚È‚¢H + ¨pdhk64‚ª‰Šú‰»Š®—¹‚·‚é‘O‚ÉConfig‚µ‚Ä‚¢‚½ +EPDF‚Å”÷–­‚ɏ㉺ˆÊ’u‚ª‚¸‚ê‚é‚Æ‚«‚ª‚ ‚遨”FŽ¯‘Ώە¶Žš—ñ‚̐擪‚É—]Œv‚È‹ós‚ª“ü‚éê‡‚ª‚ ‚Á‚½‚½‚ß +E[C] ƒCƒ“ƒNƒŠƒƒ“ƒ^ƒ‹ƒT[ƒ`ON‚Å—Ž‚¿‚é + - Config2()‚ðŒÄ‚яo‚µ‚Ä‚¢‚邾‚¯‚Ì‚Í‚¸‚¾‚ªAhook/unhook‚ªŒÄ‚΂ê‚Ä‚¢‚é + ¨Config2()‚©‚çTHookLoader::Capture‚܂ł̊ԂɌĂ΂ê‚Ä‚¢‚é + ¨config’¼Œã‚Émouse move message‚ªcallback‚³‚êA‚·‚®‚Écapture‚·‚é‚©‚ç‚¢‚¯‚È‚¢‚Ì‚©H + ¨‚¢‚âAhDll->Capture()Ž©‘Ì‚ª•sˆÀ’肾‚Á‚½B‚Æ‚¢‚¤‚±‚Ƃ͐öÝ“I‚É‚ ‚Á‚½–â‘èH(AMODI=OFF) + ¨DBW‚ðOFF‚É‚µ‚½‚ç‰ðŒˆi‚ł͉½‚ª–{“–‚ÌŒ´ˆöHj +E[B] VS2010‚̃GƒfƒBƒ^[‚Ő³í‚É“®‚©‚È‚¢ + ¨click point‚ª100pixel‚­‚ç‚¢‰E‚É‚¸‚ê‚Ä‚¢‚éHã‰º•ûŒü‚à + ¨amodi‘¤‚Í–â‘è‚È‚µBcaptured image‚ÆcursorÀ•W‚ª‚¸‚ê‚Ä‚¢‚éH + - capture page‚ð‚µ‚Ä‚à‚¸‚ê‚Ä‚¢‚éB + ¨‚í‚©‚Á‚½Bmouse cursor‚ÍGetWindowRect()‚É‚æ‚éwindow‘S‘̂Ȃ̂ɑ΂µA + ‰æ‘œ‚ÍGetWindowDC()+BitBlt(hdc)‚Å‚â‚Á‚Ä‚¢‚邽‚߁Ahdc‚ª‘ΏۂɂȂÁ‚Ä‚µ‚Ü‚¤B + ¨screenÀ•WŒn‚Åpoint‚ðˆµ‚¢A‰æ‘œ‚ÍGetWindowRect()‚̗̈æ‚ðBitBlt‚·‚邱‚ƂőΉž +E[B][inc.srch] ƒ}ƒEƒX‰º‚̃AƒvƒŠ‚ª—Ž‚¿‚é(task manager@7 task manager,explorer@XP) + ¨SendMessage( hwnd, WM_PAINT, (WPARAM)hdcMeta, 0 ); + ‚Å—Ž‚¿‚Ä‚¢‚½‚̂ŁARETRYMETA‚ð0‚É‚µ‚½¨‚Ü‚¾—Ž‚¿‚é + ¨MouseProc‚ÆDoCapture‚𕪗£‚·‚ê‚ΈÀ’è‚·‚é‚ñ‚¶‚á‚È‚©‚낤‚©H + ¨Œ‹˜_F•ª—£‚µ‚āADBW‚Í•sˆÀ’è‚É‚µADCHookTest.exe‚Ìbreakpoint‚à•sˆÀ’è—vˆö +E[A] Chrome‚ÅCtrl+‰EƒNƒŠƒbƒN‚·‚é‚Æhit window‚ªo‚é’¼‘O‚ÉChrome‚ª—Ž‚¿‚é + ¨CaptureText‚ªˆ«‚¢‚悤‚¾ + ¨ExtTextOutX()‚̏‘‚«Š·‚¦(METAEXTTEXTOUT)Ž©‘Ì‚ªŒ´ˆö(‘ã‘֊֐”‚Ì–â‘è‚Å‚Í‚È‚¢j + ¨¡‚Ü‚Å‚È‚º“®‚¢‚Ä‚¢‚½H + - SetWriteProtect()‚Åprotect‰ðœ‚µ‚½‚Ì‚ªˆ«‚¢‚悤‚¾ + - ‚»‚ê‚æ‚èAhProcess‚ªerror‚ð‹N‚±‚µNULL‚¾‚Á‚½ + ¨‚±‚ê‚Å—Ž‚¿‚邱‚Ƃ͉ðÁ‚Å‚«‚½‚ªAhProcess‚ªNULL‚Ì–â‘肪‚ ‚é +E[CB] OpenProcess‚Åerror + ¨EnablePrivilege()‚ð’ljÁ‚·‚邱‚Æ‚ÅOK +E[B] inc.srch‚Ì“®ì‚ªd‚¢ + - ExecOCR-2‚̌オ‚Ù‚Ú’âŽ~ó‘Ô + ¨MODI OCR Error‚ª”­¶‚µ‚½‚Æ‚«‚É1.4sec‚Ù‚ÇŽ~‚Ü‚é + ¨”’‚̉摜‚ª‚Å‚«‚Ä‚¢‚é + ¨ŽžXGetDIBits()‚ÅŽ¸”s(error code•s–¾)B + ¨‰æ‘œƒRƒs[‚̃Gƒ‰[ƒ`ƒFƒbƒN‚ð‚µ‚Á‚©‚è‚â‚Á‚½‚çMODI OCR Error‚Í‹N‚«‚Ä‚¢‚È‚¢ + +¡FAQ +EŠÇ—ŽÒŒ ŒÀ‚̃AƒvƒŠã‚Å‚Í“®ì‚µ‚È‚¢ +@¨ŠÇ—ŽÒŒ ŒÀ‚ÅDoioPop!‚ð‹N“®‚·‚ê‚Ή”\ + ¨MODI‚ðŽg—p‚·‚ê‚Ή”\H + +¡Note +EDCHook.dll‚ðVisualC++ 2010‚Ńrƒ‹ƒh‚·‚é‚ƁAWindows2000‚Å“®ì‚µ‚È‚­‚È‚Á‚Ä‚µ‚Ü‚¤II + iLoadLibrary‚ŃGƒ‰[j + ¨DCHook/DCHook.6.0.sln‚ðVisualStudio2008‚ÅŠJ‚«Aƒrƒ‹ƒh‚·‚é +E64bitƒAƒvƒŠã¨32bitDLL‚Ì‚Ý‚ª”½‰ž + 32bitƒAƒvƒŠã¨32bit/64bit—¼•û‚ÌDLL‚ª”½‰ž + +¡MODI +WindowsXPˆÈ~‘Ήž(?) +- MDI to TIFF File Converter + ¨ƒCƒ“ƒXƒg[ƒ‹‚µ‚Ä‚Ý‚½‚ªbuild‚Å‚«‚¸(C:\Program Files (x86)\modiconv‚Émdivwctl.dll‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ÍŒ©‚‚©‚ç‚È‚©‚Á‚½j +- SharePoint Designer 2007‚ðƒCƒ“ƒXƒg[ƒ‹ + http://www.microsoft.com/ja-jp/download/details.aspx?id=21581 + "C:\Program Files (x86)\Common Files\Microsoft Shared\MODI\12.0" + ‚É + MDIVWCTL.DLL + ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚Å‚«‚é‚̂ŁA‚±‚ê‚ðC#‚̃vƒƒWƒFƒNƒg‚ÌŽQÆƒpƒX‚ÉŽw’è‚·‚é + ¦MODI/11.0‚Å‚Íamodi‚ªbuild‚Å‚«‚È‚¢(MODI‚ªŒ©‚‚©‚ç‚È‚¢error)@XP/VS2010 +- SharePoint Designer‚È‚ñ‚ÄŽg‚í‚È‚¢A‚Ù‚©‚Ì•û–@‚Í‚È‚¢‚©H + http://support.microsoft.com/kb/982760/ja-jp + ‚½‚¾‚µA“®ì–¢Šm”F¨ƒŠƒ“ƒNØ‚ê2014.11.11 + +¡BUILD +EDCHook64 - VisualC++ 2010‚ō쐬 +E2016.9.22 + DCHook.vcproj‚Éx64—p‚ÌConfiguration‚ð’ljÁAVS3008‚Åx64‚ðƒrƒ‹ƒh‚Å‚«‚é‚悤‚É‚µ‚½B + DCHook\VS2003, DCHook\VS2008, DCHook\VS2015‚Æ‚¢‚¤ƒfƒBƒŒƒNƒgƒŠ‚ðì¬‚µ‚½‚ª‚¢‚¸‚ê‚à³í‚É‚¢‚©‚È‚¢B + VS2008‚ɂ‚¢‚Ä‚Í.vcprojƒtƒ@ƒCƒ‹‚ðDCHook\DCHook.vcprojƒtƒ@ƒCƒ‹‚Æ”äŠr‚µ‚Đݒ肷‚ê‚΂¤‚Ü‚­“®‚­‚悤‚É‚È‚é‚ÆŽv‚¤ + Œ»Žž“_‚̃vƒƒWƒFƒNƒg + DCHook.6.0.sln, DCHook.vcproj‚ðVS2008‚Ńrƒ‹ƒh‚·‚é + ¦DCHook.sln‚ÍVS2010—p + diff --git a/ExMODIst/ExMODIst.bpf b/ExMODIst/ExMODIst.bpf new file mode 100644 index 0000000..d2eea08 --- /dev/null +++ b/ExMODIst/ExMODIst.bpf @@ -0,0 +1,5 @@ +USEUNIT("main.cpp"); +//--------------------------------------------------------------------------- +This file is used by the project manager only and should be treated like the project file + + main \ No newline at end of file diff --git a/ExMODIst/ExMODIst.bpr b/ExMODIst/ExMODIst.bpr new file mode 100644 index 0000000..8b81150 --- /dev/null +++ b/ExMODIst/ExMODIst.bpr @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1041 +CodePage=932 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=1 +Item0=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=1 +Item0=_DEBUG + +[HistoryLists\hlFinalOutputDir] +Count=2 +Item0=.\obj\ +Item1=.\obj + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication= +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + +[Language] +ActiveLang= +ProjectLang= +RootDir= + + \ No newline at end of file diff --git a/ExMODIst/ExMODIst.cpp b/ExMODIst/ExMODIst.cpp new file mode 100644 index 0000000..8de0dce --- /dev/null +++ b/ExMODIst/ExMODIst.cpp @@ -0,0 +1,46 @@ +// ExMODIst.cpp : ƒRƒ“ƒ\[ƒ‹ ƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚̃Gƒ“ƒgƒŠ ƒ|ƒCƒ“ƒg‚ð’è‹`‚µ‚Ü‚·B +// + +#include "stdafx.h" +#include "ExMODIst.h" +#include "MDIVWCTL.tlh" + +using namespace modi; + +bool IsMODIAvailable(); + +using namespace std; + +int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) +{ + if (IsMODIAvailable()){ + return 1; + } + return 0; +} + +bool IsMODIAvailable() +{ + bool bRet= true; + + HRESULT hr; + modi::IDocument *IDobj = NULL; + + hr = CoInitialize(0); + if ( SUCCEEDED(hr)) + { + hr = CoCreateInstance(CLSID_Document,NULL,CLSCTX_ALL,IID_IDocument,(void**) &IDobj); + + if ( SUCCEEDED(hr) ) + { + IDobj->Release(); + } else { + bRet= false; + } + + } else { + bRet= false; + } + + return bRet; +} diff --git a/ExMODIst/ExMODIst.h b/ExMODIst/ExMODIst.h new file mode 100644 index 0000000..d00d47e --- /dev/null +++ b/ExMODIst/ExMODIst.h @@ -0,0 +1,3 @@ +#pragma once + +#include "resource.h" diff --git a/ExMODIst/ExMODIst.rc b/ExMODIst/ExMODIst.rc new file mode 100644 index 0000000..d7f2b88 --- /dev/null +++ b/ExMODIst/ExMODIst.rc @@ -0,0 +1,69 @@ +//Microsoft Visual C++ ‚Ő¶¬‚³‚ꂽƒŠƒ\[ƒX ƒXƒNƒŠƒvƒg‚Å‚·B +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE 2 ƒŠƒ\[ƒX‚©‚琶¬‚³‚ê‚Ü‚µ‚½B +// +#include "afxres.h" +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN) +LANGUAGE 17, 1 +#pragma code_page(932) + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +// +// ƒXƒgƒŠƒ“ƒO ƒe[ƒuƒ‹ +// + +STRINGTABLE +BEGIN + IDS_APP_TITLE "ExMODIst" +END + +#endif +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE 3 ƒŠƒ\[ƒX‚©‚琶¬‚³‚ê‚Ü‚µ‚½B +// +#ifndef _AFXDLL +#include "l.JPN\\afxres.rc" +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // APSTUDIO_INVOKED ‚Å‚È‚¢ê‡ diff --git a/ExMODIst/ExMODIst.sln b/ExMODIst/ExMODIst.sln new file mode 100644 index 0000000..843ca03 --- /dev/null +++ b/ExMODIst/ExMODIst.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ExMODIst", "ExMODIst.vcxproj", "{1061424B-BA88-4553-AFB9-5A89717E44D7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {1061424B-BA88-4553-AFB9-5A89717E44D7}.Debug|Win32.ActiveCfg = Debug|Win32 + {1061424B-BA88-4553-AFB9-5A89717E44D7}.Debug|Win32.Build.0 = Debug|Win32 + {1061424B-BA88-4553-AFB9-5A89717E44D7}.Release|Win32.ActiveCfg = Release|Win32 + {1061424B-BA88-4553-AFB9-5A89717E44D7}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ExMODIst/ExMODIst.vcproj b/ExMODIst/ExMODIst.vcproj new file mode 100644 index 0000000..e7d6118 --- /dev/null +++ b/ExMODIst/ExMODIst.vcproj @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ExMODIst/ExMODIst.vcxproj b/ExMODIst/ExMODIst.vcxproj new file mode 100644 index 0000000..9598af8 --- /dev/null +++ b/ExMODIst/ExMODIst.vcxproj @@ -0,0 +1,107 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {1061424B-BA88-4553-AFB9-5A89717E44D7} + ExMODIst + Win32Proj + + + + Application + false + Unicode + true + + + Application + false + Unicode + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + true + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + false + + + + Disabled + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + Use + Level3 + EditAndContinue + + + true + Console + MachineX86 + + + + + MaxSpeed + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + MultiThreadedDLL + true + Use + Level3 + ProgramDatabase + + + true + Console + true + true + MachineX86 + + + + + + Create + Create + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ExMODIst/ExMODIst.vcxproj.filters b/ExMODIst/ExMODIst.vcxproj.filters new file mode 100644 index 0000000..9c6aaca --- /dev/null +++ b/ExMODIst/ExMODIst.vcxproj.filters @@ -0,0 +1,47 @@ + + + + + {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 + + + + + ソース ファイル + + + ソース ファイル + + + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + ヘッダー ファイル + + + + + リソース ファイル + + + + + + \ No newline at end of file diff --git a/ExMODIst/ReadMe.txt b/ExMODIst/ReadMe.txt new file mode 100644 index 0000000..52922bf --- /dev/null +++ b/ExMODIst/ReadMe.txt @@ -0,0 +1,2 @@ +Visual Studio 2008でビルドする必要あり。(だったと思う) +でないと、アプリ起動時にMODIが入っていないとエラーになる(だったと思う) diff --git a/ExMODIst/Resource.h b/ExMODIst/Resource.h new file mode 100644 index 0000000..dcd0136 --- /dev/null +++ b/ExMODIst/Resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by ExMODIst.rc +// + +#define IDS_APP_TITLE 103 + +// V‚µ‚¢ƒIƒuƒWƒFƒNƒg‚ÌŽŸ‚ÌŠù’è’l +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/ExMODIst/main.cpp b/ExMODIst/main.cpp new file mode 100644 index 0000000..d6305e9 --- /dev/null +++ b/ExMODIst/main.cpp @@ -0,0 +1,123 @@ +//--------------------------------------------------------------------------- +#include +#include +#pragma hdrstop + +//--------------------------------------------------------------------------- + +const GUID CLSID_Document = + {0x40942a6c,0x1520,0x4132,{0xbd,0xf8,0xbd,0xc1,0xf7,0x1f,0x54,0x7b}}; + +#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ + const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} + +MIDL_DEFINE_GUID(IID, IID_IDocument,0xD4073843,0xA58A,0x469A,0xA8,0xE2,0xCF,0xF3,0xFF,0x77,0xEE,0x4E); + +#define _Inout_ +#define _In_ +#define _Out_ +#define _Deref_out_opt_ + +struct __POSITION {}; +typedef __POSITION* POSITION; + +typedef /* [v1_enum] */ +enum WTS_ALPHATYPE + { WTSAT_UNKNOWN = 0, + WTSAT_RGB = 1, + WTSAT_ARGB = 2 + } WTS_ALPHATYPE; + +class IFilterChunkValue; + +interface IDocument +{ +protected: + IDocument() : m_refCount(0) + { + } + +public: + virtual ~IDocument() + { + } + + virtual LONG AddRef() + { + return InterlockedIncrement((long*)&m_refCount); + } + + virtual LONG Release() + { + //__assert__(m_refCount > 0); + if (InterlockedDecrement((long*)&m_refCount) == 0) + { + delete this; + return 0; + } + + return m_refCount; + } + + virtual HRESULT LoadFromStream( + _Inout_ IStream* pStream, + _In_ DWORD grfMode) = 0; + virtual void InitializeSearchContent() = 0; + virtual void BeginReadChunks() = 0; + + virtual BOOL GetThumbnail( + _In_ UINT cx, + _Out_ HBITMAP* phbmp, + _Out_ WTS_ALPHATYPE* pdwAlpha) = 0; + + virtual void ClearChunkList() = 0; + virtual BOOL SetChunkValue( + _In_ IFilterChunkValue* value) = 0; + virtual BOOL ReadNextChunkValue( + _Deref_out_opt_ IFilterChunkValue** value) = 0; + virtual void RemoveChunk( + _In_ REFCLSID guid, + _In_ DWORD pid) = 0; + virtual POSITION FindChunk( + _In_ REFCLSID guid, + _In_ DWORD pid) = 0; + + virtual LPVOID GetContainer() const = 0; + +protected: + volatile LONG m_refCount; +}; + +#pragma argsused +bool MODIAvail(); +int main(int argc, char* argv[]) +{ + if (MODIAvail()) + return 1; + return 0; +} + +bool MODIAvail() +{ + bool exist = false; + HRESULT hr = CoInitialize(0); + if (SUCCEEDED(hr)){ + IDocument *IDobj = NULL; + hr = ::CoCreateInstance(CLSID_Document, NULL, CLSCTX_ALL, IID_IDocument, (void**)&IDobj); + if (SUCCEEDED(hr)){ +#if 0 + hr = IDobj->Create(AsciiToBSTR("H:\\temp\\nishikawat\\amodi\\2014-12-02-151156.bmp")); + if (SUCCEEDED(hr){ + + } +#endif + exist = true; + IDobj->Release(); //TODO: stack‚ð‰ó‚µ‚Ä‚µ‚Ü‚¤ + } + } + CoUninitialize(); + + return exist; +} + + diff --git a/ExMODIst/stdafx.cpp b/ExMODIst/stdafx.cpp new file mode 100644 index 0000000..35d78ac --- /dev/null +++ b/ExMODIst/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : •W€ƒCƒ“ƒNƒ‹[ƒh ExMODIst.pch ‚Ì‚Ý‚ð +// ŠÜ‚Þƒ\[ƒX ƒtƒ@ƒCƒ‹‚́AƒvƒŠƒRƒ“ƒpƒCƒ‹Ï‚݃wƒbƒ_[‚É‚È‚è‚Ü‚·B +// stdafx.obj ‚ɂ̓vƒŠƒRƒ“ƒpƒCƒ‹Ï‚ÝŒ^î•ñ‚ªŠÜ‚Ü‚ê‚Ü‚·B + +#include "stdafx.h" + +// TODO: ‚±‚̃tƒ@ƒCƒ‹‚Å‚Í‚È‚­ASTDAFX.H ‚Å•K—v‚È +// ’ljÁƒwƒbƒ_[‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢B diff --git a/ExMODIst/stdafx.h b/ExMODIst/stdafx.h new file mode 100644 index 0000000..53d8bf7 --- /dev/null +++ b/ExMODIst/stdafx.h @@ -0,0 +1,14 @@ +// stdafx.h : •W€‚̃VƒXƒeƒ€ ƒCƒ“ƒNƒ‹[ƒh ƒtƒ@ƒCƒ‹‚̃Cƒ“ƒNƒ‹[ƒh ƒtƒ@ƒCƒ‹A‚Ü‚½‚Í +// ŽQÆ‰ñ”‚ª‘½‚­A‚©‚‚ ‚Ü‚è•ÏX‚³‚ê‚È‚¢AƒvƒƒWƒFƒNƒgê—p‚̃Cƒ“ƒNƒ‹[ƒh ƒtƒ@ƒCƒ‹ +// ‚ð‹Lq‚µ‚Ü‚·B +// + +#pragma once + +#include "targetver.h" + +#include +#include + + +// TODO: ƒvƒƒOƒ‰ƒ€‚É•K—v‚ȒljÁƒwƒbƒ_[‚ð‚±‚±‚ÅŽQÆ‚µ‚Ä‚­‚¾‚³‚¢B diff --git a/ExMODIst/targetver.h b/ExMODIst/targetver.h new file mode 100644 index 0000000..a983fa0 --- /dev/null +++ b/ExMODIst/targetver.h @@ -0,0 +1,24 @@ +#pragma once + +// ˆÈ‰º‚̃}ƒNƒ‚́AÅ’áŒÀ•K—v‚ȃvƒ‰ƒbƒgƒtƒH[ƒ€‚ð’è‹`‚µ‚Ü‚·BÅ’áŒÀ•K—v‚ȃvƒ‰ƒbƒgƒtƒH[ƒ€‚Ƃ́A +// ƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚ðŽÀs‚·‚邽‚ß‚É•K—v‚È‹@”\‚ð”õ‚¦‚½Å‚àŒÃ‚¢ƒo[ƒWƒ‡ƒ“‚Ì Windows ‚â Internet Explorer ‚È‚Ç +// ‚ð‚¢‚¢‚Ü‚·B‚±‚ê‚ç‚̃}ƒNƒ‚́AŽw’肵‚½ƒo[ƒWƒ‡ƒ“‚ƁA‚»‚êˆÈ‘O‚̃o[ƒWƒ‡ƒ“‚̃vƒ‰ƒbƒgƒtƒH[ƒ€ã‚Å—˜—p‚Å‚«‚é‚·‚ׂĂ̋@”\‚ð—LŒø‚É‚·‚邱‚Æ‚É‚æ‚Á‚Ä +// “®ì‚µ‚Ü‚·B + +// ‰º‚ÅŽw’肳‚ꂽ’è‹`‚Ì‘O‚ɑΏۃvƒ‰ƒbƒgƒtƒH[ƒ€‚ðŽw’肵‚È‚¯‚ê‚΂Ȃç‚È‚¢ê‡AˆÈ‰º‚Ì’è‹`‚ð•ÏX‚µ‚Ä‚­‚¾‚³‚¢B +// ˆÙ‚È‚éƒvƒ‰ƒbƒgƒtƒH[ƒ€‚ɑΉž‚·‚é’l‚ÉŠÖ‚·‚éÅVî•ñ‚ɂ‚¢‚ẮAMSDN ‚ðŽQÆ‚µ‚Ä‚­‚¾‚³‚¢B +#ifndef WINVER // Å’áŒÀ•K—v‚ȃvƒ‰ƒbƒgƒtƒH[ƒ€‚ª Windows Vista ‚Å‚ ‚邱‚Æ‚ðŽw’肵‚Ü‚·B +#define WINVER 0x0600 // ‚±‚ê‚ð Windows ‚Ì‘¼‚̃o[ƒWƒ‡ƒ“Œü‚¯‚É“KØ‚È’l‚ɕύX‚µ‚Ä‚­‚¾‚³‚¢B +#endif + +#ifndef _WIN32_WINNT // Å’áŒÀ•K—v‚ȃvƒ‰ƒbƒgƒtƒH[ƒ€‚ª Windows Vista ‚Å‚ ‚邱‚Æ‚ðŽw’肵‚Ü‚·B +#define _WIN32_WINNT 0x0600 // ‚±‚ê‚ð Windows ‚Ì‘¼‚̃o[ƒWƒ‡ƒ“Œü‚¯‚É“KØ‚È’l‚ɕύX‚µ‚Ä‚­‚¾‚³‚¢B +#endif + +#ifndef _WIN32_WINDOWS // Å’áŒÀ•K—v‚ȃvƒ‰ƒbƒgƒtƒH[ƒ€‚ª Windows 98 ‚Å‚ ‚邱‚Æ‚ðŽw’肵‚Ü‚·B +#define _WIN32_WINDOWS 0x0410 // ‚±‚ê‚ð Windows Me ‚Ü‚½‚Í‚»‚êˆÈ~‚̃o[ƒWƒ‡ƒ“Œü‚¯‚É“KØ‚È’l‚ɕύX‚µ‚Ä‚­‚¾‚³‚¢B +#endif + +#ifndef _WIN32_IE // Å’áŒÀ•K—v‚ȃvƒ‰ƒbƒgƒtƒH[ƒ€‚ª Internet Explorer 7.0 ‚Å‚ ‚邱‚Æ‚ðŽw’肵‚Ü‚·B +#define _WIN32_IE 0x0700 // ‚±‚ê‚ð IE ‚Ì‘¼‚̃o[ƒWƒ‡ƒ“Œü‚¯‚É“KØ‚È’l‚ɕύX‚µ‚Ä‚­‚¾‚³‚¢B +#endif diff --git a/ExMODIstBCC/ExMODIst.bpf b/ExMODIstBCC/ExMODIst.bpf new file mode 100644 index 0000000..d2eea08 --- /dev/null +++ b/ExMODIstBCC/ExMODIst.bpf @@ -0,0 +1,5 @@ +USEUNIT("main.cpp"); +//--------------------------------------------------------------------------- +This file is used by the project manager only and should be treated like the project file + + main \ No newline at end of file diff --git a/ExMODIstBCC/ExMODIst.bpr b/ExMODIstBCC/ExMODIst.bpr new file mode 100644 index 0000000..8b81150 --- /dev/null +++ b/ExMODIstBCC/ExMODIst.bpr @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1041 +CodePage=932 + +[Version Info Keys] +CompanyName= +FileDescription= +FileVersion=1.0.0.0 +InternalName= +LegalCopyright= +LegalTrademarks= +OriginalFilename= +ProductName= +ProductVersion=1.0.0.0 +Comments= + +[HistoryLists\hlIncludePath] +Count=1 +Item0=$(BCB)\include;$(BCB)\include\vcl + +[HistoryLists\hlLibraryPath] +Count=1 +Item0=$(BCB)\Projects\Lib;$(BCB)\lib\obj;$(BCB)\lib + +[HistoryLists\hlDebugSourcePath] +Count=1 +Item0=$(BCB)\source\vcl + +[HistoryLists\hlConditionals] +Count=1 +Item0=_DEBUG + +[HistoryLists\hlFinalOutputDir] +Count=2 +Item0=.\obj\ +Item1=.\obj + +[Debugging] +DebugSourceDirs=$(BCB)\source\vcl + +[Parameters] +RunParams= +HostApplication= +RemoteHost= +RemotePath= +RemoteDebug=0 + +[Compiler] +ShowInfoMsgs=0 +LinkDebugVcl=0 +LinkCGLIB=0 + +[Language] +ActiveLang= +ProjectLang= +RootDir= + + \ No newline at end of file diff --git a/ExMODIstBCC/main.cpp b/ExMODIstBCC/main.cpp new file mode 100644 index 0000000..6818e87 --- /dev/null +++ b/ExMODIstBCC/main.cpp @@ -0,0 +1,39 @@ +//--------------------------------------------------------------------------- +#include +#pragma hdrstop +#include "MDIVWCTL.tlh" + +//--------------------------------------------------------------------------- +#pragma argsused +bool MODIAvail(); +int main(int argc, char* argv[]) +{ + if (MODIAvail()) + return 1; + return 0; +} + +bool MODIAvail() +{ + bool exist = false; + HRESULT hr = CoInitialize(0); + if (SUCCEEDED(hr)){ + IDocument *IDobj = NULL; + hr = ::CoCreateInstance(CLSID_Document, NULL, CLSCTX_ALL, IID_IDocument, (void**)&IDobj); + if (SUCCEEDED(hr)){ +#if 0 + hr = IDobj->Create(AsciiToBSTR("H:\\temp\\nishikawat\\amodi\\2014-12-02-151156.bmp")); + if (SUCCEEDED(hr){ + + } +#endif + exist = true; + IDobj->Release(); + } + } + CoUninitialize(); + + return exist; +} + + diff --git a/MK.BAT b/MK.BAT new file mode 100644 index 0000000..12bcf3e --- /dev/null +++ b/MK.BAT @@ -0,0 +1,80 @@ +@echo off +echo/ +echo Š®‘S”ŃpƒbƒP[ƒW‚ðì¬‚µ‚Ü‚· +echo/ +echo ./dchook/dchook.dll‚ð€”õ +echo ./dchooktest/dchooktest.exe‚ð€”õ +echo ./vxd/hk95d.vxd‚ð€”õ +pause +set TZ=JST-9 + +copy .\dchook\dchook.dll .\DKPPHK.DLL /y +copy .\VxD\hk95d.vxd .\HK95D.VXD /y +copy .\dchooktest\dchooktest.exe .\DKPP.EXE /y + +touch -d12/09/02 -t01:11:00 -c DKPP.EXE DKPPHK.DLL HK95D.VXD README.TXT + +del dchook-1.11.lzh > nul + +lha32 a dchook-1.11.lzh /x README.TXT +lha32 a dchook-1.11.lzh /x ./dchook/dchook.mak ./dchook/dchook.cpp ./dchook/dchook.h ./dchook/dchook.rc ./dchook/dchook.def +lha32 a dchook-1.11.lzh /x ./dchooktest/dchooktest.bpr ./dchooktest/dchooktest.mak +lha32 a dchook-1.11.lzh /x ./dchooktest/*.h ./dchooktest/*.cpp ./dchooktest/dchooktest.rc ./dchooktest/*.dfm ./dchooktest/dkpp.bmp ./dchooktest/popenable.bmp ./dchooktest/popdisable.bmp ./dchooktest/popenable.h ./dchooktest/popdisable.h ./dchooktest/icon.rc +lha32 a dchook-1.11.lzh /x ./vxd/makefile ./vxd/hk95d.def ./vxd/*.h ./vxd/*.asm ./vxd/*.c + +perl -S chgini.pl dchook.ind Exe Name DKPP111.EXE +perl -S chgini.pl dchook.ind Date Year 2002 +perl -S chgini.pl dchook.ind Date Month 12 +perl -S chgini.pl dchook.ind Date Day 09 +perl -S chgini.pl dchook.ind Date Hour 01 +perl -S chgini.pl dchook.ind Date Minute 11 +perl -S chgini.pl dchook.ind Date Second 00 +perl -S chgini.pl dchook.ind Back 8 "|Doko Pop! Ver.1.11" +perl -S chgini.pl dchook.ind Back 12 "|Doko Pop! Ver.1.11" + +rem IND‚ÌŽÀs +k:\wbin\makeset\makeset .\dchook.ind + +rem lha32 a DKPP111.EXE DKPP.TXT DKPP.EXE DKPPHK.DLL HK95D.VXD +ren DKPP111.EXE DKPP111.EXE +touch -d12/09/02 -t01:11:00 -c DKPP111.EXE + +echo/ +echo •Û‘¶—pˆ³kƒtƒ@ƒCƒ‹‚ðì¬‚µ‚Ü‚· +echo/ +rem pause + +dir dchook-1.11.lzh + +echo/ +echo ŒöŠJ—pƒtƒ@ƒCƒ‹‚ðXV‚µ‚Ü‚· +echo/ +rem pause + +perl -S -i.bak filestamp.pl DKPPu.TXT +del DKPPu.TXT.bak + +echo/ +echo Web—p‚̃tƒ@ƒCƒ‹‚ðXV‚µ‚Ü‚· +echo/ +pause + +copy dchook-1.11.lzh S:\Web\NIFTY\ +copy dchook-1.11.lzh S:\down\MySoft +del S:\Web\NIFTY\dchook-1.10.lzh +copy DKPP111.EXE S:\Web\NIFTY\ +copy DKPP111.EXE S:\down\MySoft +del S:\Web\NIFTY\DKPP110.EXE + +copy S:\Web\NIFTY\pdic-download.var vars.dat +perl -S repvars.pl S:\Web\NIFTY\pdic-download0.html > S:\Web\NIFTY\pdic-download.html +copy vars.dat S:\Web\NIFTY\pdic-download.var + +rem echo [del] >> S:\Web\NIFTY\ftp.ctl +rem echo dchook-1.10.lzh >> S:\Web\NIFTY\ftp.ctl +rem echo DKPP110.EXE >> S:\Web\NIFTY\ftp.ctl +rem echo [include] >> S:\Web\NIFTY\ftp.ctl +rem echo DKPP111.EXE >> S:\Web\NIFTY\ftp.ctl +rem echo dchook-1.11.lzh >> S:\Web\NIFTY\ftp.ctl + + diff --git a/MKU.BAT b/MKU.BAT new file mode 100644 index 0000000..f013dfc --- /dev/null +++ b/MKU.BAT @@ -0,0 +1,74 @@ +@echo off +echo/ +echo Š®‘S”ŃpƒbƒP[ƒW‚ðì¬‚µ‚Ü‚· +echo/ +echo ¡Šm”FŽ–€ +echo E./dchooktest/dchooktest.exe‚ð€”õ(USE_UNICODE defined) +echo Eƒo[ƒWƒ‡ƒ“”ԍ†F.bpr‚ÆUtil.cpp(StrVersion, VersionValue)‚Ì—¼•û‚ª•K—v +echo ERelease Build? +echo EVisualStudio2008‚Åbuild‚µ‚½‚©H for W2K +pause +set TZ=JST-9 + +echo/ +echo Copy the binary to the ind directory. +echo/ +pause + +make copy_bin + +rem touch -d10/06/16 -t02:00:00 -c ind\DKPU.EXE ind\DKPUHK.DLL + +rem dkpu.iss‚̍XV +perl change_iss.pl ind\dkpu.iss Setup AppVerName "DokoPop! 2.023" > ind\dkpu.iss.new +del ind\dkpu.iss.old +ren ind\dkpu.iss dkpu.iss.old +ren ind\dkpu.iss.new dkpu.iss + +rem Installer ‚ÌŽÀs +make buildis + +echo/ +echo Press Enter key after installer made. +echo/ +pause + +copy ind\Output\setup.EXE DKPU2023.exe +dir DKPU2023.exe + +rem lha32 a DKPU2023.exe DKPU.TXT DKPU.EXE DKPUHK.DLL +ren DKPU2023.exe DKPU2023.exe +rem touch -d10/06/16 -t02:00:00 -c DKPU2023.exe + +echo/ +echo ƒ\[ƒXƒtƒ@ƒCƒ‹‚ðzip‚µ‚Ü‚· +echo/ +pause + +make zip_src +copy src.zip src-2.023.zip +rem copy src-2.023.zip zip + +echo/ +echo ŒöŠJ—pƒtƒ@ƒCƒ‹‚ðXV‚µ‚Ü‚· +echo/ +rem pause + +perl -S -i.bak filestamp.pl DKPUu.TXT +del DKPUu.TXT.bak + +echo/ +echo Web—p‚̃tƒ@ƒCƒ‹‚ðXV‚µ‚Ü‚· +echo/ +pause + +rem copy DKPU2023.exe S:\Web\NIFTY\ +rem del S:\Web\NIFTY\DKPU2022.EXE +copy DKPU2023.exe S:\web\sakura-pdic\cgi-bin\download\files\ +del S:\web\sakura-pdic\cgi-bin\download\files\DKPU2022.EXE + +rem echo [del] >> S:\Web\NIFTY\ftp.ctl +rem echo DKPU2022.EXE >> S:\Web\NIFTY\ftp.ctl +rem echo [include] >> S:\Web\NIFTY\ftp.ctl +rem echo DKPU2023.exe >> S:\Web\NIFTY\ftp.ctl + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d0afde4 --- /dev/null +++ b/Makefile @@ -0,0 +1,39 @@ +#!make + +CPI=cp -i -p -u + +all: + +copy_release: + copy DCHook\Release\DCHook.dll DCHookTest\DKPUHK.DLL +# copy DCHook\Win32\Release\DCHook.dll DCHookTest\DKPUHK.DLL +# copy DCHook\x64\Release\DCHook.dll DCHookTest\DKPUHK64.DLL +# copy DCHook64\dchk64\x64\Release\dchk64.exe DCHooktest\DKPUHK64.exe + +copy_bin: + echo DKPUHK.DLL(DCHOOK.DLL)‚ÍVS2008‚ō쐬‚µ‚½‚©H + pause +# $(CPI) DCHook\Win32\Release\DCHook.dll ind\DKPUHK.dll +# $(CPI) DCHook\x64\Release\DCHook.dll ind\DKPUHK64.dll +# $(CPI) bin\DKPUHK.DLL ind\DKPUHK.dll +# $(CPI) DCHook64\dchk64\x64\Release\dchk64.exe ind\DKPUHK64.exe + $(CPI) DCHookTest\DKPUHK.dll ind\DKPUHK.dll + $(CPI) DCHookTest\DKPUHK64.DLL ind\DKPUHK64.dll + $(CPI) DCHookTest\DKPUHK64.exe ind\DKPUHK64.exe + $(CPI) bin\amodi.exe ind\amodi.exe + $(CPI) bin\Interop.MODI.dll ind\Interop.MODI.dll + $(CPI) bin\ExMODIst.exe ind\ExMODIst.exe + $(CPI) DCHookTest\DCHookTest.exe ind\DKPu.exe + $(CPI) DKPU.TXT ind\DKPu.txt + +buildis: + cd ind + start dkpu.iss + +zip_src: + zip -r src . -i *.h *.c *.cpp *.cs *.dfm *.bpr *.bpf *.bpg *.rc *.ico *.bmp *.png *.txr *.ctt *.bat *.ind *.iss *.tpl *.manifest *.txt *.sln *.vcproj *.vcxproj *.user + zip -r src-amodi \src\amodi -i *.h *.c *.cpp *.cs *.dfm *.bpr *.bpf *.bpg *.rc *.ico *.bmp *.png *.txr *.ctt *.bat *.ind *.iss *.tpl *.manifest *.txt *.sln *.vcproj *.vcxproj *.user + +deploy: + mktplu + mku diff --git a/README.TXT b/README.TXT new file mode 100644 index 0000000..8db0ac2 --- /dev/null +++ b/README.TXT @@ -0,0 +1,334 @@ +========================================================================== + DCHook sample program +========================================================================== +Introduction ------------------------------------------------------------- + +DCHook‚́AWindows‚É‚¨‚¢‚Ä”CˆÓ‚ÌWindow‚Ì”CˆÓ‚̍À•WˆÊ’u‚©‚ç +‚»‚±‚É•`‰æ‚³‚ê‚Ä‚¢‚éƒeƒLƒXƒg‚ðE‚Á‚Ä‚­‚éƒvƒƒOƒ‰ƒ€‚Å‚·B +‚¿‚å‚Á‚Æ‚â‚Á‚Ä‚Ý‚½‚çŠÈ’P‚É“®‚¢‚½‚̂ŁAŒöŠJ‚·‚邱‚Æ‚É‚µ‚Ü‚µ‚½B + +‚±‚̃vƒƒOƒ‰ƒ€‚̉ž—p‚Æ‚µ‚ẮA +E”CˆÓ‚̃EƒBƒ“ƒhƒE‚̃eƒLƒXƒg‚ðE‚¤ +E‘SƒEƒBƒ“ƒhƒE‚̃eƒLƒXƒg‚ðgrep‚·‚é +EƒJ[ƒ\ƒ‹ˆÊ’u‚̃eƒLƒXƒg‚ðE‚¤ +‚Æ‚¢‚Á‚½ˆê•—•Ï‚í‚Á‚½‚±‚Æ‚ª‚Å‚«‚Ü‚·B +‚±‚̃vƒƒOƒ‰ƒ€‚É‚ÍŽQl‚Æ‚µ‚āADokoPop‚Æ‚¢‚¤ƒTƒ“ƒvƒ‹ƒvƒƒOƒ‰ƒ€‚ð +“Y•t‚µ‚Ä‚ ‚è‚Ü‚·B + +install ------------------------------------------------------------------ + +ˆ³kƒtƒ@ƒCƒ‹‚ð“K“–‚È‚Æ‚±‚ë‚ɉ𓀂µ‚Ä‚­‚¾‚³‚¢B +ƒfƒBƒŒƒNƒgƒŠ•t‚«‚ʼn𓀂·‚é•K—v‚ª‚ ‚è‚Ü‚·B + +“Y•tƒtƒ@ƒCƒ‹ ------------------------------------------------------------- + +target‚É‚È‚é‚à‚́F + +dchook.dll (NT/2K”Å or 9x”Å) +hk95d.vxd (9xê—p) +dchooktest.exe (NT/2K‚Æ9x8‹¤—p) + +•K—v‚ÈŠJ”­ŠÂ‹« ----------------------------------------------------------- +C++ Builder 5 +Visual C++ 6.0 +Windows Device Driver Kit (DDK) for Windows 98 + +ì¬•û–@ ----------------------------------------------------------------- + +-------------------------------- +dchook.dll +-------------------------------- +•K—v‚Ȋ‹«F +Visual C++ + +ì¬•û–@F +nmake -fdchook.mak + +-------------------------------- +hk95d.vxd +-------------------------------- +•K—v‚Ȋ‹« +Visual C++, DDK for Win98 + +•ÏX‰ÓŠF +makefile +INC32‚ðDDK‚Ìroot path‚É(e:\98ddk‚È‚Ç) + +ì¬•û–@F +nmake +¦‚±‚ÌŽÀs‘O‚ÉVisual-C++‚¨‚æ‚ÑDDK‚̊‹«‚ªÝ’肳‚ê‚Ä‚¢‚é•K—v‚ª‚ ‚è‚Ü‚·B +@ƒoƒbƒ`ƒtƒ@ƒCƒ‹‚Ŋ‹«Ý’è‚·‚é‚悤‚É‚È‚Á‚Ä‚¢‚éê‡‚́A +@ì¬‘O‚Ƀoƒbƒ`ƒtƒ@ƒCƒ‹‚ðŽÀs‚µ‚Ä‚­‚¾‚³‚¢B +@ivcvars32.batAsetenv.bat e:\98ddk ‚Æ‚¢‚Á‚½Š´‚¶‚Å +@¨Ú‚µ‚­‚ÍVisual-C++ADDK‚É•t‘®‚Ìà–¾‘‚ðŽQÆj + +-------------------------------- +dchooktest.exe +-------------------------------- +•K—v‚Ȋ‹«F +C++ Builder 5 + +•ÏX‰ÓŠF +“Á‚É‚È‚µ +¦DEBUG‚ðdefine‚·‚é‚ƁADEBUG—p‚Ì“®ì‚É‚È‚è‚Ü‚·B + +ì¬•û–@F +dchooktest.bpr‚ðC++Builder‚ÅŠJ‚¢‚Ä‚­‚¾‚³‚¢B +C++Builder4‚Å‚à‚Å‚«‚é‚©‚àA‚ÆŽv‚Á‚Ä C++Builder4ˆÈ‘O—p‚É +dchooktest.mak‚à“Y•t‚µ‚Ä‚ ‚è‚Ü‚·B‘½­‚̕ύX‚ÅŽg‚¦‚é‚©‚à‚µ‚ê‚Ü‚¹‚ñB + +‚ ‚Ƃ́Aƒƒjƒ…[‚©‚ç Project | Ä\’z ‚ō쐬‚µ‚Ü‚·B + +ŽÀsF +dchooktest.exe‚ðŽÀs‚µ‚Ü‚·B + +š’ˆÓ“_F +DCHookTest.exe‚ªLoad‚·‚éDLL‚́A +DKPPHK.DLL -> DCHOOK.DLL +‚̏‡”ԂŐæ‚ÉŒ©‚‚©‚Á‚½•û‚ðload‚·‚éŽd—l‚É‚È‚Á‚Ä‚¢‚Ü‚·B +DEBUG‚ðdefine‚µ‚½‚Æ‚«‚́ADCHOOK.DLL‚Ì‚Ý‚ðload‚µ‚悤‚Æ‚µ‚Ü‚·B + +ƒvƒƒOƒ‰ƒ€à–¾ ----------------------------------------------------------- + +ˆê”Ô–ï‰î‚È‚à‚̂́Adchook.cpp‚Å‚µ‚傤B +ŽŽsöŒë‚µ‚È‚ª‚ç‚à’ZŽžŠÔ‚ňê‹C‚ɏ‘‚«ã‚°‚½‚à‚Ì‚Å‚·‚̂ŁA +‚©‚Ȃ艘‚­‚È‚Á‚Ä‚¢‚Ü‚·B +#define‚É‚æ‚éswitch‚ɂ́AF‚ñ‚È‘g‚ݍ‡‚킹‚ª‚ ‚è‚Ü‚·‚ªA +Œ»óˆÈŠO‚̐ݒè‚É‚·‚é‚Ɛ³í‚É“®ì‚µ‚È‚©‚Á‚½‚èA +compile‚³‚¦‚à‚Å‚«‚È‚¢‚Í‚¸‚Å‚·B‚¾‚Á‚½‚çA®—‚µ‚È‚³‚¢I +‚ÆŒ¾‚í‚ê‚»‚¤‚Å‚·‚ªA¡Œã•K—v‚Æ‚È‚é‚Æ‚±‚낪‚ ‚é‚©‚à‚µ‚ê‚È‚¢‚̂ŁA +‚»‚Ì‚Ü‚Ü‚É‚µ‚Ä‚ ‚è‚Ü‚·B + +“®ìŒ´—‚Æ‚µ‚ẮAƒeƒLƒXƒg‚ðŽæ“¾‚µ‚½‚¢window‚ɑ΂µ‚Ä +Ä•`‰æ–½—ß‚ð‘—‚èAÄ•`‰æ’†‚̃eƒLƒXƒg•`‰æŠÖ”‚Ì“à—e‚ð +‰¡Žæ‚è‚·‚邱‚ƂŏE‚Á‚Ä‚«‚Ü‚·B + +Å‰ì‚èŽn‚ß‚½ ‚́AWindows‚©‚çDC‚ð“n‚µ‚Ä‚¢‚éŠÖ”‚ðhook‚µA +DC‚ðmetafile‚ōж‚·‚ê‚ΊȒP‚¶‚á‚È‚¢‚©H‚ÆŽv‚Á‚Ä‚â‚Á‚Ä‚Ý‚Ü‚µ‚½B +‚»‚¤‚µ‚½‚ç‚ ‚Á‚¯‚È‚­“®‚¢‚½‚Ì‚Å‚·‚ªA•Ê‚Ìapplication‚Å‚â‚Á‚Ä‚Ý‚é‚Æ +‚¤‚Ü‚­“®‚©‚È‚¢‚±‚Æ‚ª‚ ‚è‚Ü‚µ‚½B +Œ´ˆö‚́ACreateCompatibleBitmap‚Åbitmap‚ðì¬‚µA‚»‚±‚Öˆê’U•`‰æ +‚µ‚Ä‚©‚çABitBlt‚Åwindow‚É“\‚è•t‚¯‚éapplication‚ª‚ ‚Á‚½‚©‚ç‚Å‚·B +‚»‚¤‚È‚é‚ƁADC‚¾‚¯‚ł̓eƒLƒXƒg•`‰æî•ñ‚ª“¾‚ç‚ê‚Ü‚¹‚ñ‚̂ŁA +•K—v‚Ètext•`‰æŠÖ”‚ðhook‚µ‚Ä‚â‚é•K—v‚ª‚ ‚è‚Ü‚·B +(‚Ù‚©‚É‚àBeginPaint()‚Å“n‚³‚ê‚éDC‚Å‚Í‚È‚­AGetDC()‚Å +“¾‚½DC‚ɑ΂µ‚Ä•`‰æ‚µ‚Ä‚¢‚éapplicaton‚ɑ΂µ‚Ä‚à‚¤‚Ü‚­‚¢‚«‚Ü‚¹‚ñ‚Å‚µ‚½) + +‚±‚Ì‘O‚É‚±‚Ìhook‚Ì•û–@‚Å‚·‚ªANT‚Æ9x‚ł͈قȂè‚Ü‚·B +NT‚ÍŠeapplication‚ª“Æ—§‚Ìmemory‹óŠÔ‚Å‚ ‚èAuser32.dll,gdi32.dll‚à +application–ˆ‚Ìmemory‹óŠÔ‚É‘¶Ý‚µ‚Ä‚¢‚é‚Ì‚Å‚·‚ªA9x‚ł́A +‚¢‚«‚Ȃ苤—Lmemory‚֍s‚Á‚Ä‚µ‚Ü‚Á‚Ä‚¢‚é‚̂ŁAŠÈ’P‚É‚Íhook‚Å‚«‚Ü‚¹‚ñB + +API‚Ìhook•û–@‚́AƒAƒXƒL[‚©‚ço”Å‚³‚ê‚Ä‚¢‚éuAdvanced Windowsv +‚ðŽQl‚É‚µ‚Ü‚µ‚½B +http://www.amazon.co.jp/exec/obidos/ASIN/4756138055/pdichomepage-22 +‚±‚±‚ÉAPIƒtƒbƒN‚Ìà–¾‚ªÚ×‚É‹Lq‚³‚ê‚Ä‚¢‚Ü‚·B +‚µ‚©‚µA‚±‚Ì•û–@‚ð’m‚é‚Ü‚Å‚Í Hookæ‚̃AƒhƒŒƒX‚𒼐ڏ‘‚«Š·‚¦‚é‚Æ‚¢‚¤ +ŠëŒ¯‚È•û–@‚ð‚â‚Á‚Ä‚¢‚Ü‚µ‚½B‚‚܂è Advanced Windows‚É‹Lq‚³‚ê‚Ä‚¢‚é +‚P”Ô–Ú‚Ì•û–@‚Å‚·‚ˁBNTŒn‚ÌOS‚È‚ç‚Ù‚Ú–â‘è‚È‚­“®ì‚·‚é‚Ì‚Å‚·‚ªA +9xŒn‚Í—áŠO‚ª‚Ç‚¤‚µ‚Ä‚à”­¶‚µ‚Ä‚µ‚Ü‚¢‚Ü‚·B +‚Æ‚¢‚¤‚±‚ƂŁA‚±‚Ì–{‚Ì‚Q”Ô–Ú‚Ì•û–@‚ňÀ’肵‚Ä“®ì‚·‚é‚悤‚É +‚È‚è‚Ü‚µ‚½B‚µ‚©‚µA‚±‚Ì–{‚Ì‚Ü‚Ü‚Å‚ÍDokoPop!‚ÅŒø—¦‚æ‚­ +“®ì‚µ‚Ä‚­‚ê‚È‚¢‚̂ŁA‚©‚Ȃ菑‚«Š·‚¦‚Ä‚ ‚è‚Ü‚·B +i‚Æ‚¢‚¤‚±‚Æ‚Å’˜ìŒ •\Ž¦‚àÈ—ª‚µ‚½‚肵‚āEEEj +‘‚«Š·‚¦‚½A‚Æ‚¢‚¤‚æ‚èA¡‚Ü‚ÅŽ©•ª‚ª‘‚¢‚½APIHOOK\‘¢‘Ì‚ð +•ÏX‚µ‚½A‚Æ‚¢‚¤‚Ù‚¤‚ª³‚µ‚¢‚©‚à‚µ‚ê‚Ü‚¹‚ñB +APIƒtƒbƒN‚̉ðà‚Í‚±‚Ì–{‚ɏ÷‚è‚Ü‚·B + +‚Å‚·‚ªA‚¹‚Á‚©‚­‚P”Ԗڂ̊댯‚È•û–@‚Å‚¢‚­‚‚©“¾‚½î•ñ‚ª‚ ‚é‚̂ŁA +‹Œƒo[ƒWƒ‡ƒ“‚ÅŽg—p‚µ‚Ä‚¢‚½ƒtƒbƒN•û–@‚̏î•ñ‚ð‘‚¢‚Ä‚¨‚«‚Ü‚·B +---------- ŒÃ‚¢˜b ---------- +‚¿‚Ȃ݂ɁANT‚Å‚ÍUSER32.DLL,GDI32.DLL‚ÌGetProcAddress()‚Í +application‚É‚æ‚Á‚ĈقȂè‚Ü‚·B‚µ‚©‚µA9x‚Å‚Í“¯‚¶‚Å‚·B +æ‚Ù‚Ç‚à‚¿‚ç‚Á‚Ə‘‚¢‚½‚悤‚ɁANT‚Ìapplication‚͌•ʂÌmemory‹óŠÔ‚Å +USER32.DLL,GDI32.DLL‚àˆÙ‚È‚é‹óŠÔ‚É‘¶Ý‚µ‚Ä‚¢‚é‚©‚ç‚Å‚·B +‚Æ‚±‚낪9x‚Í‹¤—L‚µ‚Ä‚¢‚āA‚µ‚©‚àjump‚µ‚½‚ç‚·‚®‚Ékernel mode‚É +“ü‚Á‚Ä‚¢‚é‚悤‚Å‚·B(NT‚Í‚ ‚é’ö“xuser mode‚Å‚â‚Á‚Ä‚¢‚銴‚¶j + +‚³‚ç‚É‚»‚̐æ‚Í‚Ç‚¤‚È‚Á‚Ä‚¢‚é‚©‚Æ‚¢‚¤‚ƁEEE‚Æ‚¢‚¤˜b‚Í +‚±‚̃vƒƒOƒ‰ƒ€‚ÌscopeŠO‚È‚Ì‚Å‚Ü‚½‚Ì‹@‰ï‚ɏ÷‚é‚Æ‚µ‚āA +‚±‚±‚Å9x‚ɑ΂µ‚Ä‚¿‚å‚Á‚ÆŒ™‚È—\Š´‚ª‚悬‚è‚Ü‚·B +NT‚̏ꍇAentry point‚ð‘‚«Š·‚¦‚Ä‚à‚»‚ÌapplicationŒÅ—L‚Ì +entry point‚Å‚ ‚邽‚߁A‚»‚ÌŠÔ‚Étask switching‚ª”­¶‚µ‚Ä‚à +–â‘è‚È‚¢‚Ì‚Å‚·‚ªA9x‚ł́Aentry point‚ð‘‚«Š·‚¦‚½’¼Œã‚É +task switching‚ª”­¶‚µ‚½‚çA(—ˆ‚Ä—~‚µ‚­‚È‚¢)‚Ù‚©‚Ìapplication‚ª +‚»‚Ìhook‚ð“`‚Á‚Ä‚â‚Á‚Ä‚­‚éEEEÅˆ«entry point‘‚«Š·‚¦’†‚É +switching‚ª”­¶‚·‚é‚ƁEEE‚¿‚å‚Á‚Æ•|‚¢‚Å‚·B +‚Å‚àAŽÀÛ‚Í‚»‚̂悤‚ȃP[ƒX‚Í‹N‚±‚è‚É‚­‚­AŽÀÛ‚»‚¤‚¢‚¤ +–â‘è‚Í”­¶‚µ‚Ä‚¢‚Ü‚¹‚ñB‚Å‚·‚ªAˆê‰žƒvƒƒOƒ‰ƒ€‚Å‚Í +‚»‚Ì‚½‚߂̑΍ô‚ð‚µ‚Ä‚ ‚è‚Ü‚·B +(‚±‚Ì‚Ö‚ñ‚Ì—‹ü‚à‘‚¢‚½•û‚ª‚¢‚¢‚Ì‚Å‚·‚ªEEEÈ—ªj + +entry point‚̏‘‚«Š·‚¦‚Å‚·‚ªANT‚̏ꍇ‚Í +’ʏí‚Ìapplication‚Æ“¯‚¶‚Å‚·‚̂ŁAWriteProcessMemoryŠÖ”‚Å +code—̈æ‚ð‘‚«ž‚Ý‚ª‚Å‚«‚Ü‚·B‚µ‚©‚µA9x‚Í +‹¤—Lmemory‚Å‚ ‚èA‚»‚±‚Íwrite protect‚³‚ê‚Ä‚¢‚Ü‚·B +‚±‚Ìprotection‚ð‰ðœ‚·‚é‚ɂ͒ʏí‚ÌWindows API‚É‚Í +–³‚¢‚悤‚Ȃ̂Łi‚ ‚Á‚½‚狳‚¦‚Ä—~‚µ‚¢jA‚í‚´‚í‚´ +memory‚ð‘‚«Š·‚¦‚邾‚¯‚Ì‚½‚ß‚ÌVxD‚ðì‚è‚Ü‚µ‚½B +VxD‚È‚çkernel mode‚È‚Ì‚Å‚È‚ñ‚Å‚à‚Å‚«‚Ä‚µ‚Ü‚¢‚Ü‚·B +(‚±‚Ì‚Ö‚ñ‚ªæ‚Ù‚Ç‚Ìtask switching‚̘b‚Æ—‚ñ‚Å‚¢‚Ü‚·‚ª) + +VxD‚Ídynamic loading‚ōì‚Á‚Ä‚ ‚è‚Ü‚·B +‚±‚ÌVxD‚Å’ˆÓ‚µ‚È‚¯‚ê‚΂Ȃç‚È‚¢‚̂́ACreateFile()ŠÖ”‚Å +VxD‚ðload‚µ‚Ä‚¢‚Ü‚·‚ªA“ñ“xCreateFile()‚Í‚Å‚«‚È‚¢‚Æ‚±‚ë‚Å‚·B +]‚Á‚āAˆê”ԍŏ‰‚̏‰Šú‰»‚Ì‚Æ‚«‚¾‚¯ACreateFile()‚ðs‚¢A +‚ ‚Æ‚Í‚¸‚Á‚ÆVxD‚ðí’“‚³‚¹‚½‚Ü‚Ü‚É‚µ‚Ä‚¨‚­•K—v‚ª‚ ‚è‚Ü‚·B + +ˆê‰žAPI Hook‚̘b‚Í‚±‚Ì‚­‚ç‚¢‚É‚µ‚Ä‚¨‚«‚Ü‚·B +API Hook‚ð‚·‚éapplication‚Í‚Ù‚©‚É‚à‚ ‚è‚Ü‚·‚ªA +‚»‚¤‚¢‚¤application‚Í‚±‚ê‚Æ“¯‚¶•û–@‚ðŽg—p‚µ‚Ä‚¢‚é‚Ì‚Å‚µ‚傤‚©H +MSDN‚É‚àapimon(‚¾‚Á‚½‚©‚ȁH)‚Æ‚¢‚¤tool‚ª•t‘®‚µ‚Ä‚¢‚Ü‚·‚ªA +‚Ç‚¤‚È‚ñ‚Å‚µ‚傤H +---------- ˆÈãAŒÃ‚¢˜b ---------- + +˜b‚Í‚¸‚Á‚Æ‘O‚É–ß‚Á‚āABitBlt‘΍ô‚̘b‚Å‚·B +‚±‚ÌBitBlt‚Å•`‰æ‚·‚é•û–@‚𒲂ׂĂ݂é‚ƁAwindow‘S‘Ì‚Å‚Í‚È‚­A +banding‚É‚æ‚Á‚āAwindow‚𕡐”‚Ìbitmap‚É•ªŠ„‚µ‚ÄBitBlt‚µ‚Ä‚¢‚é +‚悤‚Å‚·B]‚Á‚āABitBlt API‚àhook‚µ‚Ä‚â‚èAbitmap‚Ötext‚ð +•`‰æ‚µ‚½‚Æ‚«‚̍À•W‚ƁABitBlt‚µ‚½‚Æ‚«‚Ìdestination point‚Ì +offset‚ðl—¶‚µ‚ÄtextÀ•W‚ðŒvŽZ‚µ‚Ä‚â‚é•K—v‚ª‚ ‚è‚Ü‚·B + +ˆÈãAtext‚ðget‚Å‚«‚½‚çAŽw’èÀ•W(sample‚Å‚Ímouse‚ÌcursorˆÊ’u)‚É +text‚ª‚ ‚é‚©‚Ç‚¤‚©A‚Æ‚¢‚¤”»’è‚ðs‚¢‚Ü‚·B +hit‚µ‚½ê‡‚́A‚»‚Ìtext‘S‘̂ƁAtextã‚Ìbyte offset‚ð +WM_COPYDATA message‚ŏ‰Šú‰»‚ÌŽž‚É“o˜^‚µ‚Ä‚ ‚é window‚ÖSendMessage() +‚µ‚Ü‚·B(WM_COPYDATA‚ÍSendMessage‚Å‚È‚¢‚Æ‚¢‚¯‚È‚¢) + +‚»‚µ‚āADCHookTest.exe‚ª‚»‚Ìmessage‚ðŽó‚¯Žæ‚èADCHookTest.exe‚ª +text‚ð‚Ù‚©‚Ìapplication(PDIC)‚ÖDDE‚Å“n‚µ‚Ä‚¢‚Ü‚·B + +DCHookTest.exe‚ª‚â‚Á‚Ä‚¢‚邱‚Æ‚Í‚»‚ꂪ‚Ù‚Æ‚ñ‚ǂŁA +dchook.dll‚É‚­‚ç‚ׂê‚Îꡂ©‚ÉŠy‚ÈŽdŽ–‚È‚Ì‚Å‚·B + +DLL‚ł͏펯‚Å‚·‚ªAdata‚ÍŠî–{“I‚ÉprocessŒÅ—L‚Ì’l‚ðŽ‚¿‚Ü‚·B +‚±‚±‚Å’ˆÓ‚µ‚È‚¯‚ê‚΂Ȃç‚È‚¢‚Ì‚ªAWindowsHook‚Ìhook dll‚́A +WindowsHook‚ŃZƒbƒg‚µ‚½ŒãAforeground application‚É +Ø‚è‘Ö‚í‚Á‚½‚Æ‚«‚ɏ‰‚ß‚Äattach‚³‚ê‚Ü‚·B +(‚‚܂èAWindowsHook‚µ‚½Žž“_‚Å‚ÍHook‚µ‚½process‚É‚µ‚© +attach‚³‚ê‚Ä‚¢‚È‚¢) +‚µ‚©‚àAattach‚µ‚½‚Æ‚«‚ɂ́A•Ê‚Ìapplication‚Ìprocess‹óŠÔ‚É +‹‚Ü‚·‚̂ŁAWM_COPYDATA‚Ì‘—‚èæ‚̏î•ñ‚ª‚Ç‚±‚É‚à‚ ‚è‚Ü‚¹‚ñB +ƒtƒ@ƒCƒ‹/registry‚É•Û‘¶‚µ‚ēǂݍž‚ށA‚È‚ñ‚Ä‚¢‚¤•û–@‚à‚ ‚è +‚Ü‚·‚ªAdchook.def‚Åshared‚É‚æ‚Á‚āAdllŠÔ‚Å‹¤—L‚·‚é +data segment‚ðì¬‚·‚é•û–@‚ª‚ ‚è‚Ü‚·B +‚±‚±‚ÉWM_COPYDATA‘—‚èæ‚Ìhandle‚ð•Û‘¶‚µ‚Ä‚¨‚¯‚΁A‚±‚̂悤‚È +–â‘è‚Í‰ðŒˆ‚Å‚«‚Ü‚·B + +‚»‚ê‚Æ‚à‚¤ˆê‚‚â‚Á‚Ä‚Ý‚Ä‚í‚©‚Á‚½‚Ì‚Å‚·‚ªA9x‚Å‚Í +Unhook‚ð‚·‚é‚ƁA‚·‚®‚É‚·‚ׂÄdetach‚³‚ê‚é‚Ì‚Å‚·‚ªA +NT‚ł́A‚±‚ê‚Ü‚½foreground‚ɐ؂è‘Ö‚í‚Á‚½‚Æ‚«‚É‚µ‚© +detach‚µ‚Ä‚­‚ê‚Ü‚¹‚ñB‚»‚±‚ŁAdchook‚Å‚Í‹­§“I‚É +detach‚³‚¹‚邽‚ß‚Émessage‚ðbroadcast‚³‚¹‚Ä‚¢‚Ü‚·B +ŽÀÛ‚Í‚»‚±‚Ü‚Å‚â‚é•K—v«‚Í‚È‚¢‚Ì‚Å‚·‚ªAŠJ”­Žž‚É +memory‚ð‰ð•ú‚³‚¹‚邽‚߂ɐF‚ñ‚Èapplication‚ɐ؂è‘Ö‚¦‚é‚Ì‚ª +Œ™‚¾‚Á‚½‚̂ŁEEEBroadcastMessageˆÈŠO‚É—Ç‚¢•û–@‚ª‚ ‚é‚Ì‚©‚ȁH + +ƒvƒƒOƒ‰ƒ€‰ðà ----------------------------------------------------------- + +DBW() + +ƒfƒoƒbƒO—p‚̊֐”‚Å‚·BÙì‚Ìdbgmsg.exe‚Ö•¶Žš—ñ‚ðo—Í‚µ‚Ü‚·‚ªA +‚Ù‚©‚Ìdebug string‚ð•â‘«‚·‚édebug string monitor‚ÅŽg‚¦‚é‚悤‚É +DBW()‚ð‘‚«Š·‚¦‚½‚Ù‚¤‚ª—Ç‚¢‚Å‚µ‚傤B(OutputDebugString()‚È‚Ç) + +popenable.h, popdisable.h +‚±‚ê‚ç‚́u‰EƒNƒŠƒbƒNŒŸõ‚ð—LŒø‚É‚µ‚Ü‚µ‚½v‚Æ‚¢‚¤ƒƒbƒZ[ƒWƒEƒBƒ“ƒhƒE‚Ì +ƒŠ[ƒWƒ‡ƒ“î•ñ‚Å‚·BiŠÛ‚Ý‚Ì‚ ‚éƒEƒBƒ“ƒhƒEj +‚±‚̃Š[ƒWƒ‡ƒ“î•ñ‚́Abmp2rgn‚Æ‚¢‚¤ƒc[ƒ‹‚Åpopenable.bmp, popdisable.bmp +‚ð•ÏŠ·‚µ‚½‚à‚Ì‚Å‚·Bbmp2rgn‚̓tƒŠ[ƒEƒFƒA‚Å‚·B + +ƒTƒ“ƒvƒ‹ƒvƒƒOƒ‰ƒ€ ------------------------------------------------------- + +sample program‚Æ‚µ‚āAmouse cursorˆÊ’u‚Ìtext‚𒊏o‚µA +ÙŽÒì‚̉p˜aŽ«‘ŒŸõƒvƒƒOƒ‰ƒ€ Personal Dictionary for Win32(PDIC)‚Ö +DDE‚ðŒo—R‚µ‚āAŒŸõŒ‹‰Ê‚ðpopup‚³‚¹‚é u‚Ç‚±ƒ|ƒbƒvIv‚Æ‚¢‚¤‚à‚Ì‚ª‚ ‚è‚Ü‚·B + +http://homepage3.nifty.com/TaN/pdic-download.html +‚ÉDokoPop!‚Æ‚¢‚¤–¼‘O‚Å“o˜^‚³‚ê‚Ä‚¢‚Ü‚·B + +¡Œã‚̉ۑè --------------------------------------------------------------- + +E•¡”sŒŸo +@‚±‚̃vƒƒOƒ‰ƒ€‚Å‚Í‚Ps•ª‚µ‚©Žæ“¾‚Å‚«‚Ü‚¹‚ñ‚ªA +@•`‰æŠJŽnˆÊ’u‚ð’ǐՂ·‚邱‚Æ‚É‚æ‚èA‘OŒã‚̍s‚à’Šo‰Â”\‚É‚È‚é‚Æ +@Žv‚¢‚Ü‚·B + +’˜ìŒ  ------------------------------------------------------------------ + +Ä”z•zA“]ÚA•¡»A‰ü•ÏA”Ì”„“™‚Í‚·‚ׂĎ©—R‚Å‚·BˆêØ‚̐§ŒÀ‚ðÝ‚¯‚Ü‚¹‚ñB +‚½‚¾‚µAˆÈ‰º‚Ì‚±‚Æ‚Í‚²—¯ˆÓ‚­‚¾‚³‚¢B +E‚±‚̃\ƒtƒgƒEƒFƒA‚É‚æ‚Á‚悶‚éˆêØ‚Ì‘¹ŠQÓ”C‚𕉂¢‚Ü‚¹‚ñB +E‚±‚̃\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚Ä•MŽÒ‚Í‚¢‚©‚È‚é‹`–±‚à•‰‚¢‚Ü‚¹‚ñB +EÄ”z•z‚³‚ꂽ‚à‚Ì‚ÉŠÖ‚µ‚Ă͈êØŠÖ’m‚µ‚Ü‚¹‚ñB + +—š—ð -------------------------------------------------------------------- + +>> Ver.1.12 << +* Ž«‘‚ª‘å‚«‚¢ê‡‚ɁAPDIC‹N“®Œã‚̍ŏ‰‚̃|ƒbƒvƒAƒbƒv‚ª‚Å‚«‚È‚¢‚Æ‚«‚ª‚ ‚Á‚½ + +>> Ver.1.11 << +EUnicode”őΉž‚Ì‚½‚ß‚É“à•”ˆ—‚ð•ÏX + +>> Ver.1.10 << +›DokoPop‚Ń|ƒbƒvƒAƒbƒv‚µ‚½ƒEƒBƒ“ƒhƒEã‚Å‚³‚ç‚Ƀ|ƒbƒvƒAƒbƒv‚·‚é + ‚±‚Æ‚ª‰Â”\‚Ɂi˜A‘±ƒ|ƒbƒvƒAƒbƒvjiPDIC for Win32‚ÍVer.4.50ˆÈã‚ª•K—vj +›“ú–{Œê¬Ý‚Ì•¶Í‚Å‚à³‚µ‚­“®ì‚·‚é‚悤‚É‚µ‚½B +@iÝ’èƒ_ƒCƒAƒƒO‚́h“ú–{Œê‚𖳎‹‚·‚éh‚Ő؂è‘Ö‚¦‰Â”\j + +>> Ver.1.02 << +* DKPP.EXE‚̃o[ƒWƒ‡ƒ“Ý’è‚ðŠÔˆá‚Á‚Ä‚¢‚½ + +>> Ver.1.01 << +* Windows9x‚Ń|ƒbƒvƒAƒbƒv‚µ‚È‚¢ê‡‚ª‚ ‚Á‚½(IE‚È‚Ç) +E‚»‚ê‚ɑΏˆ‚µ‚½‚½‚߁AWindows95‚Í“®ì‘ΏۊO‚É +* ‰EƒNƒŠƒbƒNŒŸõØ‚è‘Ö‚¦‚ŃŠƒ\[ƒXƒŠ[ƒN‚ª”­¶‚µ‚Ä‚¢‚½ +* ƒqƒbƒg‚µ‚È‚¢’PŒê‚ª‚ ‚é‚ƃƒ‚ƒŠƒŠ[ƒN‚ª”­¶‚µ‚Ä‚¢‚½ + +>> Ver.1.00 << +* Windows9x/MeŒn‚ÌOS‚Å‚Ì“®ì‚ðˆÀ’艻‚µ‚½ +* Ž«‘ƒOƒ‹[ƒvŽw’è‚𐳏í‚É“®ì‚·‚é‚悤‚É‚µ‚½ + y’ˆÓz‚±‚Ì‹@”\‚ÍPDIC for Win32 Ver.4.40‚©‚ç‚̑Ήž‚É‚È‚è‚Ü‚· +EŒŸõ‚̃L[‚Ì‘g‚ݍ‡‚킹‚ðƒJƒXƒ^ƒ}ƒCƒY‚Å‚«‚é‚悤‚É‚µ‚½ +Eƒtƒ@ƒCƒ‹\¬‚ð•ÏX +E˜A‘±‚µ‚ă|ƒbƒvƒAƒbƒvŒŸõ‚ª‚Å‚«‚é‚悤‚É‚µ‚½ +E‚Ù‚©•\Ž¦‚̕ύX‚È‚Ç + +>> Ver.0.98 << +›ƒ}ƒEƒX‰EƒNƒŠƒbƒN‚݂̂Ń|ƒbƒvƒAƒbƒv‚ð‰Â”\‚É +@iCtrl+Alt+‰EƒNƒŠƒbƒN‚ÅON/OFF‚Å‚«‚Ü‚·j +* hŽ«‘ƒOƒ‹[ƒv‚ªŠJ‚¯‚Ü‚¹‚ñh‚Əo‚邱‚Æ‚ª‚ ‚Á‚½ +* Å¬‰»‚Å‹N“®‚µ‚½ê‡Aƒ^ƒXƒNƒo[‚ɃAƒCƒRƒ“‚ªŽc‚Á‚Ä‚¢‚½ + +>> Ver.0.97 << +* Ž«‘ƒOƒ‹[ƒv‚̕ύX‚ª‚Å‚«‚È‚­‚È‚Á‚Ä‚¢‚½ +* IE‚Ńqƒbƒg‚µ‚È‚¢‚±‚Æ‚ª‚ ‚Á‚½ + +>> Ver.0.96 << +* PDIC‚ðŽ©“®‹N“®‚Å‚«‚È‚©‚Á‚½(“ǂݍž‚Þregistry‚ðŠÔˆá‚Á‚Ä‚¢‚½) +* ‚Ç‚±ƒ|ƒbƒv‚ðÅ¬‰»‚Å‹N“®‚µ‚½ê‡AƒXƒvƒ‰ƒbƒVƒ…ƒEƒBƒ“ƒhƒE‚ªÁ‚¦‚È‚©‚Á‚½ + +>> Ver.0.95 << +?? + +>> Ver.0.94 << +* ƒXƒvƒ‰ƒbƒVƒ…‚ð”ñ•\Ž¦‚É‚µ‚½ê‡‚Ì•s‹ï‡C³ + +>> Ver.0.94 << +* ‹N“®ŽžDLL‰Šú‰»Ž¸”s(Win98) +* “ú–{Œê¬‚¶‚è‚Ì•¶‚ŃeƒLƒXƒg’ŠoˆÊ’u‚ª‚¸‚ê‚Ä‚¢‚½(Win98) + +>> Ver.0.93 << +E‹N“®ƒXƒvƒ‰ƒbƒVƒ…•ÏX +EƒXƒvƒ‰ƒbƒVƒ…•\Ž¦E”ñ•\Ž¦ +EƒXƒvƒ‰ƒbƒVƒ…ƒrƒbƒgƒ}ƒbƒv‚̃JƒXƒ^ƒ}ƒCƒY +EƒCƒ“ƒXƒg[ƒ‰’ljÁ +* ƒƒ‚’ ‚ňُíI—¹(NT) +* “ú–{Œê¬‚¶‚è‚Ì•¶‚ŃeƒLƒXƒg’ŠoˆÊ’u‚ª‚¸‚ê‚Ä‚¢‚½ + +>> Ver.0.92 << +EˆÀ’萫Œüã + +>> Ver.0.90 << +EÅ‰‚ÌŒöŠJ + diff --git a/VxD/hk95c.c b/VxD/hk95c.c new file mode 100644 index 0000000..16093b2 --- /dev/null +++ b/VxD/hk95c.c @@ -0,0 +1,164 @@ +//// HK95c.c +// -------------------------------------------- +// Dynamically loadable VxD for DCHOOK +// -------------------------------------------- +#define WIN32_LEAN_AND_MEAN // Excludes un-needed parts of windows.h +#include +#include +#include +#include +#include "hk95d.h" + +// ------------------------------------- +// Externs defined in assembly module +// ------------------------------------- +// These defined in assembly for the VMM.INC or VPICD.INC file inclusion +// ------------------------ +// PRAGMA for this DATA +// ------------------------ +// Establish segment +#pragma data_seg ( "_LDATA","_LCODE") + +// ------------------------------------ +// Data structures MUST be INITIALIZED +// ------------------------------------ +// ------------------------ +// PRAGMAS for this CODE +// ------------------------ +// Establish segment +#pragma code_seg ( "_LTEXT", "_LCODE" ) +//No stack checking for routines in this module +#pragma check_stack(off) + +// --------------------------------------- +// Set Good Return code for DIOC requests +// --------------------------------------- +void _declspec(naked)GoodReturnDIOC(void) +{ + // Clear eax and carry flag for GOOD return + _asm xor eax,eax + _asm clc + _asm ret; +} + +// --------------------------------------- +// Set Bad Return code for DIOC requests +// --------------------------------------- +void _declspec(naked) BadReturnDIOC(void) +{ + // NOTE: 50 is a FCN NOT SUPPORTED code -- ok to use + // SET carry flag for BAD return + _asm mov eax,50 + _asm stc + _asm ret; +} + + +// ------------------------------ +// Routine for DCHOOK Device UNINIT +// ------------------------------ +void CHK95_Device_UNInit() +{ + // Set GOOD return code + GoodReturnDIOC(); + return; +} +// ------------------------------ +// Routine for DCHOOK Device INIT +// ------------------------------ + +void CHK95_Device_Init() +{ + GoodReturnDIOC(); +} +DWORD VXDINLINE +PageModPerm( DWORD Page, DWORD nPages, DWORD Flags1, DWORD Flags2 ) +{ + DWORD dw; + + _asm push [Flags2] + _asm push [Flags1] + _asm push [nPages] + _asm push [Page] + VMMCall( _PageModifyPermissions ); + _asm add esp, 10h + _asm mov [dw], eax + + return(dw); +} + +// -------------------------------- +// Routine for DCHOOK Device IO ctrl +// -------------------------------- +void CHK95_Device_IOctrl(PDIOCPARAMETERS ptr) +{ + int i; + unsigned int addr; + unsigned int page; + int npage; + unsigned char *p; + unsigned char *q; + DWORD oldpermission; + // Field the DEV IO requests from VMM + switch(ptr->dwIoControlCode) + { + case DIOC_WRITEABLE_MEMORY: // The address to be changed must be already committed. + if ( ptr->lpvInBuffer ){ + // Does it need a PC_STATIC? + + long r = 0; + + // I don't know exact parameters. But it works well, so I don't care about it.... + + r = PageModPerm( *((DWORD*)ptr->lpvInBuffer), 1, 0xFFFFFFFF, PC_WRITEABLE | PC_USER | PC_STATIC ); + if ( ptr->lpvOutBuffer ){ + *((DWORD*)ptr->lpvOutBuffer) = r; + } + } + break; + case DIOC_NONWRITEABLE_MEMORY: // The address to be changed must be already committed. + { + long r = 0; + + r = PageModPerm( *((DWORD*)ptr->lpvInBuffer), 1, ~PC_WRITEABLE, PC_USER | PC_STATIC ); + if ( ptr->lpvOutBuffer ){ + *((DWORD*)ptr->lpvOutBuffer) = r; + } + } + break; + case DIOC_CHANGE_MEMORY: + addr = (DWORD)ptr->lpvOutBuffer; + page = addr >> 12; // 4KB + npage = ((addr + ptr->cbInBuffer) >> 12) - page + 1; + oldpermission = PageModPerm( page, npage, 0xFFFFFFFF, PC_WRITEABLE | PC_USER | PC_STATIC ); + _asm pushfd + _asm cli + if ( oldpermission == (DWORD)-1 ){ + _asm popfd + BadReturnDIOC(); + return; + } + p = (unsigned char*)addr; + q = (unsigned char*)ptr->lpvInBuffer; + for ( i=0;icbInBuffer;i++ ){ + *p++ = *q++; + } + PageModPerm( page, npage, oldpermission, oldpermission ); + _asm popfd + break; +#if 0 + case DIOC_DEBUG: + *(DWORD*)ptr->lpvOutBuffer = (DWORD)CHK95_Device_IOctrl; + break; +#endif + //The below DIOC_GETVERSION is a part of the dynamic load protocol + //It MUST return a GOOD code (all codes here use GoodReturnDIOC() +// case(DIOC_GETVERSION): +// case(DIOC_CLOSEHANDLE): +// default: +// break; + } + GoodReturnDIOC(); + return; +} + diff --git a/VxD/hk95d.asm b/VxD/hk95d.asm new file mode 100644 index 0000000..91017cc --- /dev/null +++ b/VxD/hk95d.asm @@ -0,0 +1,120 @@ +;;HK95d.asm +name HK95D +.386p +;; ------------------------------------------------ +;; ------------------------------------------------ +;; HK95d.asm -- Assembly module, MAIN module for +;; Dynamically loadable VxD for DCHOOK +;; ------------------------------------------------ +;; ------------------------------------------------ + +;; ----------------------------------- +;; INCLUDE files needed by this module +;; ----------------------------------- + +include +include +include + +;; ------------------------------------ +;; C routines/data used by this module +;; ------------------------------------ +extrn _CHK95_Device_Init:near +extrn _CHK95_Device_UNInit:near +extrn _CHK95_Device_IOctrl:near + +;; ------------------------------------- +;; Routines/data called from this module +;; ------------------------------------- +; public + + ; ================================================================================== +;; Misc HK95-specific Equates +;; ---------------------------------------------------------------------------------- +HK95_MajoREV equ 1 ;MAJOR revision level +HK95_MinoREV equ 0 ;decimal number of revision +HK95_DeviceID equ Undefined_Device_ID ;no need for MS device number assignment +; ================================================================================== + +;; --------------------------------------------- +;; Virtual Device Declaration (Required) +;; (Declares this code as virtual device driver) +;; Also creates the Device Data Block +;; --------------------------------------------- + +Declare_Virtual_Device HK95D,HK95_MajoREV,HK95_MinoREV,HK95_Control,HK95_DeviceID,Undefined_Init_Order + +VxD_LOCKED_CODE_SEG +;; -------------------------------------------- +;; Control Dispatch Table & Proc (Required) +;; Used to dispatch supported messages sent by +;; VMM -- clears carry for unsupported mssgs. +;; -------------------------------------------- +;; Only 3 VMM messages are recognized and processed +;; by this routine -- all DIOC interface messages +;; translate to W32_DeviceIoControl mssgs from the VMM. +;; "Control_Dispatch" precedes MSSG NUMBER, PROCEDURE + +BeginProc HK95_Control + Control_Dispatch Sys_Dynamic_Device_Exit, HK95_Device_UNInit + Control_Dispatch Sys_Dynamic_Device_Init, HK95_Device_Init + Control_Dispatch W32_DeviceIoControl, HK95_Device_IOctrl + xor eax,eax ;;return 0 (required in some instances) + clc ;;clear carry flg for GOOD indicator + ret +EndProc HK95_Control + +;; ------------------------------------------------------------- +;; NOTE: "BeginProc & EndProc" are needed in conjunction with +;; the above dispatch table -- below routines facilitate C fcns +;; ------------------------------------------------------------- + +;; ======================================================================= +;; Routines below are VXD interface (load, unload, process) ROUTINES +;; ======================================================================= + +;; -------------------------------------------- +;; Routine to jump to C routine for processing +;; SYS_DYNAMIC_DEVICE_INIT message +;; -------------------------------------------- +BeginProc HK95_Device_Init + call _CHK95_Device_Init + ret +EndProc HK95_Device_Init + +;; -------------------------------------------- +;; Routine to jump to C routine for processing +;; SYS_DYNAMIC_DEVICE_EXIT message +;; -------------------------------------------- + +BeginProc HK95_Device_UNInit + call _CHK95_Device_UNInit + ret +EndProc HK95_Device_UNInit + +;; -------------------------------------------- +;; Routine to jump to C routine for processing +;; W32_DEVICEIOCONTROL messages -- These are +;; VxD requests from the application. +;; At entry, esi points to the DIOC interface +;; structure passed by the application +;; -------------------------------------------- + +BeginProc HK95_Device_IOctrl + push esi + call _CHK95_Device_IOctrl + pop esi + ret +EndProc HK95_Device_IOctrl + +;; ====================================================== +;; Routines below are miscellaneous assembly interfaces +;; ====================================================== + +VxD_LOCKED_CODE_ENDS + +VxD_LOCKED_DATA_SEG +VxD_LOCKED_DATA_ENDS + + END + diff --git a/VxD/hk95d.def b/VxD/hk95d.def new file mode 100644 index 0000000..32880d1 --- /dev/null +++ b/VxD/hk95d.def @@ -0,0 +1,24 @@ +VXD HK95D.VXD DYNAMIC +DESCRIPTION 'Hk 95 Vxd' +SEGMENTS + _LDATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _LPTEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TEXT CLASS 'LCODE' PRELOAD NONDISCARDABLE + _DATA CLASS 'LCODE' PRELOAD NONDISCARDABLE + CONST CLASS 'LCODE' PRELOAD NONDISCARDABLE + _TLS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _BSS CLASS 'LCODE' PRELOAD NONDISCARDABLE + _ITEXT CLASS 'ICODE' DISCARDABLE + _IDATA CLASS 'ICODE' DISCARDABLE + _PTEXT CLASS 'PCODE' NONDISCARDABLE + _PDATA CLASS 'PDATA' NONDISCARDABLE SHARED + _STEXT CLASS 'SCODE' RESIDENT + _SDATA CLASS 'SCODE' RESIDENT + _DBOSTART CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBOCODE CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _DBODATA CLASS 'DBOCODE' PRELOAD NONDISCARDABLE CONFORMING + _16ICODE CLASS '16ICODE' PRELOAD DISCARDABLE + _RCODE CLASS 'RCODE' +EXPORTS + HK95D_DDB @1 diff --git a/VxD/hk95d.h b/VxD/hk95d.h new file mode 100644 index 0000000..75f87dc --- /dev/null +++ b/VxD/hk95d.h @@ -0,0 +1,12 @@ +//hk95d.h + +#define DIOC_CHANGE_MEMORY 20 +#define DIOC_QUERY_MEMORY 21 +#define DIOC_WRITEABLE_MEMORY 22 +#define DIOC_NONWRITEABLE_MEMORY 23 +#define DIOC_SET_HOOK 25 +#define DIOC_RESTORE_HOOK 26 +#define DIOC_HOOK_START 30 +#define DIOC_HOOK_END 31 +#define DIOC_LAST_STATUS 32 +#define DIOC_DEBUG 33 diff --git a/VxD/makefile b/VxD/makefile new file mode 100644 index 0000000..d9f3c75 --- /dev/null +++ b/VxD/makefile @@ -0,0 +1,70 @@ +BUILD_TYPE=base +# !INCLUDE $(BASEDIR)\inc\master.mk + +# OUTDIR = obj\i386\\ + +# sample make file for building vxd virtual device for Windows + +NAME = HK95D + +# Definitions for the debug level + +!ifdef DEBUG +DDEBUG =-DDEBLEVEL=1 -DDEBUG +!else +DDEBUG =-DDEBLEVEL=0 +!endif + +# Definitions for MASM 6 Assembler + +INC32 = k:\98ddk +ASM = ml +AFLAGS = -coff -DBLD_COFF -DIS_32 -W2 -c -Cx -Zm -DMASM6 -I$(INC32) $(DDEBUG) +ASMENV = ML +LFLAGS = /VXD /NOD + +CFLAGS = -DWIN32 -Di386 -D_X86_ -I$(BASEDIR)\inc + +# MASM 6 only inference rules + +.asm{$(OUTDIR)}.obj: + set $(ASMENV)=$(AFLAGS) + $(ASM) -Fo$*.obj $< + +.c{$(OUDIR)}.obj: + $(CC) -c $(CFLAGS) -Fo$*.obj $*.c + +all : $(OUTDIR)$(NAME).VXD + +OBJS = $(OUTDIR)hk95d.obj $(OUTDIR)hk95c.obj + +$(OUTDIR)vxdstub.exe: $(OUTDIR)vxdstub.obj +!ifndef PASS0ONLY + @echo link -OUT:$@ + $(LINK16) $(OUTDIR)vxdstub.obj; +!endif + +$(OUTDIR)hk95d.obj: hk95d.asm + +$(OUTDIR)$(NAME).vxd: $(NAME).def $(OBJS) +!ifndef PASS0ONLY + @echo link -OUT:$@ + link @<<$(OUTDIR)$(NAME).lnk +$(LFLAGS) +-ignore:4078 -ignore:4039 +/OUT:$(OUTDIR)$(NAME).vxd +/MAP:$(TOUDIR)$(NAME).map +/DEF:$(NAME).def +$(OBJS) +<< + mapsym -s -o $(OUTDIR)R$(NAME).sym $(OUTDIR)$(NAME).map +!endif + +clean: + -@if exist $(OUTDIR)*.obj del $(OUTDIR)*.obj + -@if exist $(OUTDIR)*.vxd del $(OUTDIR)*.vxd + -@if exist $(OUTDIR)*.exp del $(OUTDIR)*.exp + -@if exist $(OUTDIR)*.lib del $(OUTDIR)*.lib + -@if exist $(OUTDIR)*.map del $(OUTDIR)*.map + -@if exist $(OUTDIR)*.sym del $(OUTDIR)*.sym + -@if exist *.bak del *.bak diff --git a/amodi/amodi.sln b/amodi/amodi.sln new file mode 100644 index 0000000..f2e8599 --- /dev/null +++ b/amodi/amodi.sln @@ -0,0 +1,18 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "amodi", "amodi\amodi.csproj", "{211FD925-C172-418B-A746-83DBCE9D339F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {211FD925-C172-418B-A746-83DBCE9D339F}.Debug|x86.ActiveCfg = Debug|Any CPU + {211FD925-C172-418B-A746-83DBCE9D339F}.Release|x86.ActiveCfg = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/amodi/amodi/MainForm.Designer.cs b/amodi/amodi/MainForm.Designer.cs new file mode 100644 index 0000000..571c106 --- /dev/null +++ b/amodi/amodi/MainForm.Designer.cs @@ -0,0 +1,204 @@ +namespace amodi +{ + partial class AutoMODIMainForm + { + ///

+ /// 必要なデザイナー変数です。 + /// + private System.ComponentModel.IContainer components = null; + + /// + /// 使用中のリソースをすべてクリーンアップします。 + /// + /// マネージ リソースが破棄される場合 true、破棄されない場合は false です。 + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows フォーム デザイナーで生成されたコード + + /// + /// デザイナー サポートに必要なメソッドです。このメソッドの内容を + /// コード エディターで変更しないでください。 + /// + private void InitializeComponent() + { + this.components = new System.ComponentModel.Container(); + this.tbText = new System.Windows.Forms.TextBox(); + this.btnDoOCR = new System.Windows.Forms.Button(); + this.tbFileName = new System.Windows.Forms.TextBox(); + this.lbFileName = new System.Windows.Forms.Label(); + this.lbStatus = new System.Windows.Forms.Label(); + this.tbInfo = new System.Windows.Forms.TextBox(); + this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components); + this.miCapturePage = new System.Windows.Forms.ToolStripMenuItem(); + this.miUseDefLang = new System.Windows.Forms.ToolStripMenuItem(); + this.miDebugMode = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.miExit = new System.Windows.Forms.ToolStripMenuItem(); + this.lbPoint = new System.Windows.Forms.Label(); + this.contextMenuStrip1.SuspendLayout(); + this.SuspendLayout(); + // + // tbText + // + this.tbText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbText.Location = new System.Drawing.Point(15, 117); + this.tbText.Multiline = true; + this.tbText.Name = "tbText"; + this.tbText.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.tbText.Size = new System.Drawing.Size(265, 199); + this.tbText.TabIndex = 7; + // + // btnDoOCR + // + this.btnDoOCR.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.btnDoOCR.Location = new System.Drawing.Point(87, 54); + this.btnDoOCR.Name = "btnDoOCR"; + this.btnDoOCR.Size = new System.Drawing.Size(98, 28); + this.btnDoOCR.TabIndex = 6; + this.btnDoOCR.Text = "Do OCR"; + this.btnDoOCR.UseVisualStyleBackColor = true; + this.btnDoOCR.Click += new System.EventHandler(this.btnDoOCR_Click); + // + // tbFileName + // + this.tbFileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbFileName.Location = new System.Drawing.Point(12, 29); + this.tbFileName.Name = "tbFileName"; + this.tbFileName.Size = new System.Drawing.Size(267, 19); + this.tbFileName.TabIndex = 5; + // + // lbFileName + // + this.lbFileName.AutoSize = true; + this.lbFileName.Location = new System.Drawing.Point(13, 9); + this.lbFileName.Name = "lbFileName"; + this.lbFileName.Size = new System.Drawing.Size(53, 12); + this.lbFileName.TabIndex = 4; + this.lbFileName.Text = "&Filename:"; + // + // lbStatus + // + this.lbStatus.AutoSize = true; + this.lbStatus.Location = new System.Drawing.Point(22, 94); + this.lbStatus.Name = "lbStatus"; + this.lbStatus.Size = new System.Drawing.Size(38, 12); + this.lbStatus.TabIndex = 8; + this.lbStatus.Text = "Status"; + // + // tbInfo + // + this.tbInfo.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbInfo.Location = new System.Drawing.Point(16, 322); + this.tbInfo.Multiline = true; + this.tbInfo.Name = "tbInfo"; + this.tbInfo.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; + this.tbInfo.Size = new System.Drawing.Size(262, 51); + this.tbInfo.TabIndex = 9; + // + // contextMenuStrip1 + // + this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.miCapturePage, + this.miUseDefLang, + this.miDebugMode, + this.toolStripMenuItem1, + this.miExit}); + this.contextMenuStrip1.Name = "contextMenuStrip1"; + this.contextMenuStrip1.Size = new System.Drawing.Size(296, 98); + // + // miCapturePage + // + this.miCapturePage.Name = "miCapturePage"; + this.miCapturePage.Size = new System.Drawing.Size(295, 22); + this.miCapturePage.Text = "Capture &Page"; + this.miCapturePage.Click += new System.EventHandler(this.miCapturePage_Click); + // + // miUseDefLang + // + this.miUseDefLang.Name = "miUseDefLang"; + this.miUseDefLang.Size = new System.Drawing.Size(295, 22); + this.miUseDefLang.Text = "Use Default Language (Experimental)"; + this.miUseDefLang.Click += new System.EventHandler(this.miUseDefLang_Click); + // + // miDebugMode + // + this.miDebugMode.Name = "miDebugMode"; + this.miDebugMode.Size = new System.Drawing.Size(295, 22); + this.miDebugMode.Text = "&Debug Mode"; + this.miDebugMode.Click += new System.EventHandler(this.miDebugMode_Click); + // + // toolStripMenuItem1 + // + this.toolStripMenuItem1.Name = "toolStripMenuItem1"; + this.toolStripMenuItem1.Size = new System.Drawing.Size(292, 6); + // + // miExit + // + this.miExit.Name = "miExit"; + this.miExit.ShortcutKeyDisplayString = "Ctrl+W"; + this.miExit.Size = new System.Drawing.Size(295, 22); + this.miExit.Text = "E&xit"; + this.miExit.Click += new System.EventHandler(this.miExit_Click); + // + // lbPoint + // + this.lbPoint.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.lbPoint.AutoSize = true; + this.lbPoint.Location = new System.Drawing.Point(205, 66); + this.lbPoint.Name = "lbPoint"; + this.lbPoint.Size = new System.Drawing.Size(31, 12); + this.lbPoint.TabIndex = 10; + this.lbPoint.Text = "Point"; + // + // AutoMODIMainForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(292, 384); + this.ContextMenuStrip = this.contextMenuStrip1; + this.Controls.Add(this.lbPoint); + this.Controls.Add(this.tbInfo); + this.Controls.Add(this.lbStatus); + this.Controls.Add(this.tbText); + this.Controls.Add(this.btnDoOCR); + this.Controls.Add(this.tbFileName); + this.Controls.Add(this.lbFileName); + this.Name = "AutoMODIMainForm"; + this.Text = "Auto MODI"; + this.Activated += new System.EventHandler(this.AutoMODIMainForm_Activated); + this.contextMenuStrip1.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.TextBox tbText; + private System.Windows.Forms.Button btnDoOCR; + private System.Windows.Forms.TextBox tbFileName; + private System.Windows.Forms.Label lbFileName; + private System.Windows.Forms.Label lbStatus; + private System.Windows.Forms.TextBox tbInfo; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip1; + private System.Windows.Forms.ToolStripMenuItem miExit; + private System.Windows.Forms.ToolStripMenuItem miCapturePage; + private System.Windows.Forms.ToolStripMenuItem miDebugMode; + private System.Windows.Forms.ToolStripMenuItem miUseDefLang; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1; + private System.Windows.Forms.Label lbPoint; + } +} + diff --git a/amodi/amodi/MainForm.cs b/amodi/amodi/MainForm.cs new file mode 100644 index 0000000..7103cc6 --- /dev/null +++ b/amodi/amodi/MainForm.cs @@ -0,0 +1,403 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Windows.Forms; +using System.IO; +using System.Runtime.InteropServices; + +namespace amodi +{ + public partial class AutoMODIMainForm : Form + { + + const int MARGIN_UNDER_CLICK = 2; // 次の行までの空白 + + const int WM_COPYDATA = 0x4A; + const int WM_APP = 0x8000; + const int WM_AMODI = (WM_APP + 0x400); + const int WM_EXEC_OCR = (WM_APP + 0x410); + + // WM_COPYDATA command + const int WMCD_EXISTCHECK = 0x4000; + const int WMCD_SETPOINT = 0x4001; + const int WMCD_RESTORE_WINDOW = 0x4002; + + + //[StructLayout(LayoutKind.Sequential)] + private struct COPYDATASTRUCT + { + public IntPtr dwData; + public int cbData; + public IntPtr lpData; + } + + public struct COPYDATASTRUCT_send { + public Int32 dwData; //送信する32ビット値 + public Int32 cbData;    //lpDataのバイト数 + public string lpData;   //送信するデータへのポインタ(0も可能) + } + + [DllImport("user32.dll", SetLastError = true)] + private static extern int PostMessage(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + [DllImport("user32.dll", SetLastError = true)] + private static extern int SendMessage(IntPtr hWnd, uint msg, IntPtr wParam, ref COPYDATASTRUCT_send lparam); + [DllImport("User32.dll", EntryPoint = "FindWindow")] + public static extern Int32 FindWindow(String lpClassName, String lpWindowName); + + MODI.Document md; + System.IO.FileSystemWatcher fsw; + Queue FileNameQue; + + // parser output // + int CurLoc; // mouse cursor position in text. + + public AutoMODIMainForm() + { + InitializeComponent(); + md = new MODI.Document(); + FileNameQue = new Queue(); + +#if true + string exepath = System.IO.Path.GetTempPath(); + exepath += "amodi\\"; + + try + { + System.IO.Directory.Delete(exepath); + } catch { } + System.IO.Directory.CreateDirectory(exepath); +#else + string exepath = Application.StartupPath; + lbFileName.Text = "Watching... - " + exepath; +#endif + fsw = new System.IO.FileSystemWatcher(); + fsw.Path = exepath; + fsw.IncludeSubdirectories = false; + fsw.SynchronizingObject = this; + fsw.Changed += new System.IO.FileSystemEventHandler(watcher_Changed); + fsw.EnableRaisingEvents = true; + } + void Cleanup() + { + fsw.EnableRaisingEvents = false; + fsw.Dispose(); + fsw= null; + } + + private void btnDoOCR_Click(object sender, EventArgs e) + { + DoOCR(tbFileName.Text); + } + + private bool DoingOCR = false; + bool DoOCR(string filename) + { + if (DoingOCR) return false; + DoingOCR = true; + + bool capture_page = miCapturePage.Checked; + + ParseFileName(filename); + + lbStatus.Text = "Recognizing... " + filename; + tbText.Text = ""; + tbInfo.Text = ""; + for (int i = 0; i < 10; i++){ + try { + md.Create(filename); + } catch { + tbInfo.AppendText("MODI Create failure: " + filename + "\r\n"); + DBW("MODI Create file failure: " + filename); + System.Threading.Thread.Sleep(30); + continue; + } + break; + } + DBW("DoOCR:OCR"); + try { + if (miUseDefLang.Checked){ + md.OCR(MODI.MiLANGUAGES.miLANG_SYSDEFAULT, true, true); + } else { + md.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, true, true); + } + } catch { + DBW("MODI OCR Error: " + filename); + md.Close(); + DBW("DoOCR:Closed"); + lbStatus.Text = "OCR Error: " + filename; + DoingOCR = false; + return false; + } + DBW("DoOCR:Completed"); + const int UnderGap = MARGIN_UNDER_CLICK; // 単語のある領域より少し下のpointでも検索対象と認識する空白部分(Y方向) + int last_x = 0; + int lineno = 0; + CurLoc = 0; + lbPoint.Text = "" + CursorPoint.X + "," + CursorPoint.Y; + tbInfo.AppendText("Page:" + md.Images.Count + " pt:" + CursorPoint.X + "," + CursorPoint.Y + "\r\n"); + for (int i = 0; i < md.Images.Count; i++) + { + MODI.Image image = (MODI.Image)md.Images[i]; + MODI.Layout layout = image.Layout; + bool outok = capture_page; + string prevWord = ""; + for (int j = 0; j < layout.Words.Count; j++) + { + MODI.Word word = (MODI.Word)layout.Words[j]; + bool cr = false; + bool curLocSet = false; + + for (int k = 0; k < word.Rects.Count; k++) + { + MODI.MiRect rc = (MODI.MiRect)word.Rects[k]; + int h = rc.Bottom - rc.Top; + int w = rc.Right - rc.Left; + + //bool incursor; + //tbText.AppendText(word.Text + " (" + rc.Left + "," + rc.Top+ ")\r\n"); + if (CursorPoint.Y >= rc.Top && CursorPoint.Y <= rc.Bottom+UnderGap){ + //incursor = true; + if (!outok) + { + if (CursorPoint.X < rc.Left) { + // cursorを飛び越えた + outok = true; + curLocSet = true; + if (prevWord.Length != 0) { + tbText.AppendText(prevWord + " "); + CurLoc = prevWord.Length + 1; + } + } else + if (CursorPoint.X >= rc.Left && CursorPoint.X <= rc.Right){ + outok = true; + curLocSet = true; + if (prevWord.Length != 0) { + tbText.AppendText(prevWord + " "); + CurLoc = prevWord.Length + 1; + } + } else { + prevWord = word.Text; + } + } + } else { + //incursor = false; + } + + if (outok){ + tbInfo.AppendText(word.Text + " (" + w + "x" + h + ":" + rc.Left + "," + rc.Top + ")\r\n"); + } + + if (last_x > rc.Left){ + if (tbText.Text!="") + cr = true; + lineno++; + } + last_x = rc.Left; + } + + if (outok){ + if (cr){ + tbText.AppendText("\r\n"); + if (curLocSet) + CurLoc += 2; // CR+LF + } + + tbText.AppendText(word.Text + " "); + } + } + } + md.Close(false); + lbStatus.Text = "Done. " + filename; + DoingOCR = false; + return true; + } + private void ParseFileName(string filename) + { + Regex r = new Regex(@"\((?\d+),(?\d+)\)"); + Match m = r.Match(filename); + if (m.Success) + { + CursorPoint.X = int.Parse(m.Groups["x"].Value); + CursorPoint.Y = int.Parse(m.Groups["y"].Value); + } + } + + //イベントハンドラ + private void watcher_Changed(System.Object source, + System.IO.FileSystemEventArgs e) + { + switch (e.ChangeType) + { + case System.IO.WatcherChangeTypes.Changed: + string ext = System.IO.Path.GetExtension(e.FullPath); + if (ext==".gif" || ext==".jpg" || ext==".png" || ext==".tif" || ext==".bmp" || ext==".dib") + { + PostOCR(e.FullPath); + } + break; +// case System.IO.WatcherChangeTypes.Created: + //break; +// case System.IO.WatcherChangeTypes.Deleted: + // break; + } + } + + private void PostOCR(string filename) + { + FileNameQue.Enqueue(filename); + PostMessage(this.Handle, WM_EXEC_OCR, IntPtr.Zero, IntPtr.Zero); + } + + private void ExecOCR(string filename) + { + if (DoOCR(filename)) { + string textname = filename + ".txt"; + for (int i = 0; i < 10; i++) { + try { + StreamWriter writer = new StreamWriter(textname, false, System.Text.Encoding.GetEncoding("utf-16")); + writer.WriteLine(CurLoc.ToString()); + writer.Write(tbText.Text); + writer.Close(); + } catch { + tbInfo.AppendText("Write Error:" + textname + "\r\n"); + System.Threading.Thread.Sleep(30); + continue; + } + break; + } + } + if (!miDebugMode.Checked) { + try { + System.IO.File.Delete(filename); + } + catch + { + // 連続して.bmpファイルが作られているため + tbInfo.AppendText("Delete Error:" + filename + "\r\n"); + } + } + } + + private void miExit_Click(object sender, EventArgs e) + { + Close(); + } + + enum AMODI_CMD + { + QUERY = 0, + PAGE_CAPTURE = 1, + }; + struct POINT + { + public int x; + public int y; + }; + Point CursorPoint; + unsafe static Point int2point(IntPtr param) + { + POINT pt = (POINT)Marshal.PtrToStructure((IntPtr)param, typeof(POINT)); + Point p = new Point(); + p.X = pt.x; + p.Y = pt.y; + return p; + } + // interface for external app + protected override void WndProc(ref Message m) + { + if (m.Msg == WM_AMODI) + { + switch ((AMODI_CMD)m.WParam) + { + case AMODI_CMD.QUERY: + m.Result = (IntPtr)m.LParam; + return; + case AMODI_CMD.PAGE_CAPTURE: + m.Result = (IntPtr)(miCapturePage.Checked ? 1 : 0); + return; + default: + break; + } + } else + if (m.Msg == WM_EXEC_OCR) { + string filename = ""; + while (FileNameQue.Count()!=0) { + filename = FileNameQue.Dequeue(); + } + if (filename != "") { + ExecOCR(filename); + } + } else + if (m.Msg == WM_COPYDATA) + { + COPYDATASTRUCT cds = new COPYDATASTRUCT(); + cds = (COPYDATASTRUCT)Marshal.PtrToStructure(m.LParam, typeof(COPYDATASTRUCT)); + if (cds.dwData == (IntPtr)WMCD_EXISTCHECK) + { + m.Result = (IntPtr)1; + return; + } else + if (cds.dwData == (IntPtr)WMCD_SETPOINT){ + CursorPoint = int2point(cds.lpData); + Console.WriteLine("Cursor:" + CursorPoint.X + "," + CursorPoint.Y); + return; + } else + if (cds.dwData == (IntPtr)WMCD_RESTORE_WINDOW) + { + this.Show(); + } +#if false // 参考 + if (cds.cbData > 0) + { + byte[] data = new byte[cds.cbData]; + Marshal.Copy(cds.lpData, data, 0, cds.cbData); + //あとは data に COPYDATA の内容が入ってるので適宜処理 + } + m.Result = (IntPtr)1; +#endif + } + base.WndProc(ref m); + } + + private void miCapturePage_Click(object sender, EventArgs e) + { + miCapturePage.Checked = !miCapturePage.Checked; + } + + private void AutoMODIMainForm_Activated(object sender, EventArgs e) + { + //this.Hide(); + } + + private void miDebugMode_Click(object sender, EventArgs e) + { + miDebugMode.Checked = !miDebugMode.Checked; + } + + private void miUseDefLang_Click(object sender, EventArgs e) + { + miUseDefLang.Checked = !miUseDefLang.Checked; + } + + static int hWin = 0; + void DBW( string msg ) + { + if ( hWin==0 ){ + hWin = FindWindow( "TDbgMsgForm", "Debug Messenger" ); + if ( hWin==0 ) return; + } + byte[] bytearray = System.Text.Encoding.Default.GetBytes(msg); + int len = bytearray.Length; + COPYDATASTRUCT_send cds; + cds.dwData = 1; // Indicate String + cds.cbData = len + 1; + cds.lpData = msg; + SendMessage( (IntPtr)hWin, WM_COPYDATA, IntPtr.Zero, ref cds ); + } + } +} diff --git a/amodi/amodi/MainForm.resx b/amodi/amodi/MainForm.resx new file mode 100644 index 0000000..ad53752 --- /dev/null +++ b/amodi/amodi/MainForm.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 17, 17 + + \ No newline at end of file diff --git a/amodi/amodi/Program.cs b/amodi/amodi/Program.cs new file mode 100644 index 0000000..d0a3d05 --- /dev/null +++ b/amodi/amodi/Program.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +//using System.Linq; +using System.Windows.Forms; +using System.Threading; +using System.Reflection; + +namespace amodi +{ + static class Program + { + /// + /// アプリケーションのメイン エントリ ポイントです。 + /// + [STAThread] + static void Main() + { + Assembly asm = Assembly.GetEntryAssembly(); + string path = asm.Location; + path = path.Replace('\\', '_'); + Mutex mutex = new Mutex(false, path); + if (mutex.WaitOne(0, false) == false){ + // すでに起動している + return; + } + + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + Application.Run(new AutoMODIMainForm()); + + mutex.ReleaseMutex(); + } + } +} + diff --git a/amodi/amodi/Properties/AssemblyInfo.cs b/amodi/amodi/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..17350a2 --- /dev/null +++ b/amodi/amodi/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 +// アセンブリに関連付けられている情報を変更するには、 +// これらの属性値を変更してください。 +[assembly: AssemblyTitle("amodi")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("DokoPop Project")] +[assembly: AssemblyProduct("amodi")] +[assembly: AssemblyCopyright("Copyright © DokoPop Project")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから +// 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 +// その型の ComVisible 属性を true に設定してください。 +[assembly: ComVisible(false)] + +// 次の GUID は、このプロジェクトが COM に公開される場合の、typelib の ID です +[assembly: Guid("c033b27f-f82d-417e-b219-5878fc8c0169")] + +// アセンブリのバージョン情報は、以下の 4 つの値で構成されています: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を +// 既定値にすることができます: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/amodi/amodi/Properties/Resources.Designer.cs b/amodi/amodi/Properties/Resources.Designer.cs new file mode 100644 index 0000000..0a1842c --- /dev/null +++ b/amodi/amodi/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// このコードはツールによって生成されました。 +// ランタイム バージョン:4.0.30319.18449 +// +// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 +// コードが再生成されるときに損失したりします。 +// +//------------------------------------------------------------------------------ + +namespace amodi.Properties { + using System; + + + /// + /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 + /// + // このクラスは StronglyTypedResourceBuilder クラスが ResGen + // または Visual Studio のようなツールを使用して自動生成されました。 + // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に + // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("amodi.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 + /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/amodi/amodi/Properties/Resources.resx b/amodi/amodi/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/amodi/amodi/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/amodi/amodi/Properties/Settings.Designer.cs b/amodi/amodi/Properties/Settings.Designer.cs new file mode 100644 index 0000000..38239fa --- /dev/null +++ b/amodi/amodi/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// このコードはツールによって生成されました。 +// ランタイム バージョン:4.0.30319.18449 +// +// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 +// コードが再生成されるときに損失したりします。 +// +//------------------------------------------------------------------------------ + +namespace amodi.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/amodi/amodi/Properties/Settings.settings b/amodi/amodi/Properties/Settings.settings new file mode 100644 index 0000000..3964565 --- /dev/null +++ b/amodi/amodi/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + diff --git a/amodi/amodi/amodi.csproj b/amodi/amodi/amodi.csproj new file mode 100644 index 0000000..549a716 --- /dev/null +++ b/amodi/amodi/amodi.csproj @@ -0,0 +1,106 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {211FD925-C172-418B-A746-83DBCE9D339F} + WinExe + Properties + amodi + amodi + v4.5.1 + + + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + + + + + + + + + + + + + + + + + + + Form + + + MainForm.cs + + + + + MainForm.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + True + Resources.resx + True + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + True + Settings.settings + True + + + + + {A5EDEDF4-2BBC-45F3-822B-E60C278A1A79} + 12 + 0 + 0 + tlbimp + False + True + + + + + \ No newline at end of file diff --git a/amodi/amodi/app.config b/amodi/amodi/app.config new file mode 100644 index 0000000..37fee69 --- /dev/null +++ b/amodi/amodi/app.config @@ -0,0 +1,3 @@ + + + diff --git a/amodi/readme.txt b/amodi/readme.txt new file mode 100644 index 0000000..d323400 --- /dev/null +++ b/amodi/readme.txt @@ -0,0 +1,16 @@ +¡Tips +EMODI‚̃vƒƒWƒFƒNƒg‚ւ̒ljÁ•û–@ + VS2013‚̏ꍇF + - ƒ\ƒŠƒ…[ƒVƒ‡ƒ“ƒGƒNƒXƒvƒ[ƒ‰[‚ɁuŽQÆÝ’èv‚̍€–Ú‚ª‚ ‚é + - ‚»‚±‚ð‘I‘ð¨ŽQÆ‚̒ljÁ + - ¶‘¤‚̃yƒCƒ“‚æ‚èAuCOM - ƒ^ƒCƒvƒ‰ƒCƒuƒ‰ƒŠv‚ð‘I‘ð + - ˆê——‚Ì’†‚ɁuMicrosoft Office Document Imaging 12.0 Type Librayv‚ª‚ ‚é‚Ì‚Å‚»‚ê‚ð‘I‘ð‚µ‚ÄOK + +E(MODI.Image)md.Images[i] ‚Ì‚Æ‚±‚ë‚Åcompile error‚ªo‚é‚Æ‚« + - ª–{“I‚È‰ðŒˆ‚Å‚Í‚È‚¢‚ªAamodi.csproj ‚Ì’†‚ÌŽŸ‚̍€–Ú‚ð•ÏXEíœ‚·‚é + - "x86"‚ð‚·‚×‚Ä"AnyCPU"‚É + - TargetFrameworkVersion‚ðv4.0‚©‚çv4.5‚ɕύX + - false‚ðíœ + - true‚ðíœ + ‚±‚ê‚Åcompile error‚Íthrough‚·‚é‚悤‚¾ + diff --git a/change_iss.pl b/change_iss.pl new file mode 100644 index 0000000..01f6f9a --- /dev/null +++ b/change_iss.pl @@ -0,0 +1,46 @@ +#!perl +# Change the string in the .iss file. + +sub usage +{ +print << "EOT"; +Usage: + change_iss.pl [input filename] [section name] [key name] [substituted value] +EOT +} + +$u_input = $ARGV[0]; +$u_section = $ARGV[1]; +$u_key = $ARGV[2]; +$u_value = $ARGV[3]; + +if (!$u_value){ + usage(); + exit(1); +} + +open F,$u_input or die "open error $u_input"; + +while (){ + if (length>0){ + if (/^\[(.+)\]/){ + # Section start + $section = $1; + $key = ''; + } else { + if (/^(.+?)=/){ + # Found a key. + $key = $1; + if ($u_section =~ /^$section$/i){ + # found the same section + if ($u_key =~ /^$key$/i){ + $_ = "$key=$u_value\n"; + } + } + } + } + } + print $_; +} + + diff --git a/cpr.bat b/cpr.bat new file mode 100644 index 0000000..9b98c4d --- /dev/null +++ b/cpr.bat @@ -0,0 +1,3 @@ +copy DCHook\Win32\Release\DCHook.dll DCHookTest\DKPUHK.DLL +copy DCHook\x64\Release\DCHook.dll DCHookTest\DKPUHK64.DLL +copy DCHook64\dchk64\x64\Release\dchk64.exe DCHookTest\DKPUHK64.exe diff --git a/dchook.ind b/dchook.ind new file mode 100644 index 0000000..5a3041f --- /dev/null +++ b/dchook.ind @@ -0,0 +1,232 @@ +[Finish] +Disp=0 +Comp=1148 +[Jump] +Check=0 +Date=0 +Del=0 +Dir=0 +Div=0 +Exe=0 +Ext=0 +File=0 +Go=0 +Go2=0 +Menu=0 +Pack=0 +Title=0 +Upl=0 +Reg=0 +Ask=0 +News=0 +Error=0 +Back=0 +Uninstall=0 +[Setup] +NoUninstall=0 +OnlyUninstall=0 +[Exe] +Name=DKPP111.exe +IconName=DKPP.EXE +Icon=0 +#No1=#1 +#No2=#3 +[Title] +Setup=DokoPop! +Company=DokoPopProject +Soft=DKPP +[Del] +Auto=0 +Checked=1 +ShowError=1 +0= +Force=1 +Reboot=1 +[Dir] +Root=%programs%\DokoPop +1= +[DirRemove] +1= +[File0] +Name=D:\SRC\DCHook\DKPP.EXE +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File1] +Name=D:\SRC\DCHook\DKPP.TXT +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File2] +Name=D:\SRC\DCHook\DKPPHK.DLL +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File3] +Name=D:\SRC\DCHook\HK95D.VXD +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File4] +Name= +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File5] +Name= +[CopyFile] +DefaultNo=0 +Reboot=1 +Question=0 +[Pack] +Copy=0 +Del=0 +[Menu] +Name=DokoPop! +[Check] +Desktop=0 +Startup=2 +Menu=2 +Ext=0 +Send=0 +[Go] +Readmename=DKPP.TXT +Readmeno=1 +Desktop=0 +Startup=1 +Menu=1 +Auto=0 +Agree=0 +[Go2] +Make0= +Erase0= +[Menu0] +Name=DokoPop! +Path=DKPP.EXE +Arg= +Icon=DKPP.EXE +Work= +Short= +IconNo=0 +Show=0 +Init=0 +[Menu1] +Name=DokoPop! à–¾‘ +Path=DKPP.TXT +Arg=DKPP.TXT +Icon=DKPP.TXT +Work= +Short= +IconNo=0 +Show=0 +Init=1 +[Menu2] +Name= +[Send0] +Name= +[Desktop] +Name= +[Startup] +Name=DokoPop! +Path=DKPP.EXE +Arg= +Icon=DKPP.EXE +Work= +Short= +IconNo=0 +Show=0 +Init=0 +[Ext0] +Ext= +[Date] +Year=2002 +Month=12 +Day=9 +Hour=1 +Minute=11 +Second=0 +Comp=1 +Exe=1 +[Upl] +Check=IBM PC/ATŒÝŠ·‹@,NT4.0,Win98 +Env=MS-Windows 98/NT4.0 +Key=DKPP,PDIC,$WIN32,#APP,#UTL +Kind=ƒtƒŠ[ƒEƒFƒA +Make= +Man=TaN(SGM00353) +Title=DokoPop! +Trans=“]ÚŽ©—R +Gal=0 +Win=0 +[Intr] +Count=0 +[Hist] +Count=0 +[Div] +New=DKPPC +Go=0 +Top=0 +Delete=0 +Num=1457664 +TopNum=1457664 +[Reg] +Make0= +Erase0= +[Back] +Do=0 +0=fill,0,0,0 +1=mode,bottom +2=rect,0,0,%100,%80 +3=gradation,0,0,0,0,0,255 +4=mode,bottom +5=rect,%1,%1 +6=font,0,0,0,-21,0,0,0,700,255,0,0,0,3,2,1,18,Times New Roman +7=height,%10 +8=|Doko Pop! Ver.1.11 +9=rect,%2,%2 +10=font,255,255,0,-21,0,0,0,700,255,0,0,0,3,2,1,18,Times New Roman +11=height,%10 +12=|Doko Pop! Ver.1.11 +13=/----- +14= +[Readme] +0=page,install +1=mode,fill +2=fill,64,192,192 +3=mode,right +4=rect,5,0 +5=font,255,255,255,-36,0,0,0,400,0,0,0,0,3,2,1,34,Arial +6=|Welcome to +7=font,255,255,255,-36,0,0,0,400,0,0,0,128,3,2,1,50,‚l‚r ‚oƒSƒVƒbƒN +8=|Doko Pop! +9=rect,7,2 +10=font,0,0,0,-36,0,0,0,400,0,0,0,128,3,2,1,50,‚l‚r ‚oƒSƒVƒbƒN +11=|Welcome to +12=font,0,0,0,-36,0,0,0,400,0,0,0,128,3,2,1,50,‚l‚r ‚oƒSƒVƒbƒN +13=|DokoPop! +14=font,0,0,0,-12,0,0,0,400,0,0,0,128,3,2,1,50,‚l‚r ‚oƒSƒVƒbƒN +15=mode,bottom +16=rect,7,70 +17=| +18=|ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹‚Í +19=| +20=|ƒRƒ“ƒgƒ[ƒ‹ƒpƒlƒ‹‚́uƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚̒ljÁ‚ƍ폜v‚©‚ç +21=| +22=|uDokoPop!v‚ð‘I‘ð•ŽÀs‚µ‚Ä‚­‚¾‚³‚¢D +23=/----- +No=24 diff --git a/dchook.tpl b/dchook.tpl new file mode 100644 index 0000000..024ef72 --- /dev/null +++ b/dchook.tpl @@ -0,0 +1,678 @@ +#!perl -S mktpl.pl dchook.tpl +------------------------------------------------------------------------ + DCHOOK Document Template +------------------------------------------------------------------------ +%NEWMAJOR=1 +%NEWMINOR=11 +%POST= +%OLDMAJOR=1 +%OLDMINOR=10 +%OLDPOST= + +%DATE_Y=02 ŒöŠJ“ú +%DATE_M=12 +%DATE_D=09 + +%TIME_H=01 +%TIME_M=11 +%TIME_S=00 + +%DATE_YY=20%DATE_Y% +%VERSION = %NEWMAJOR%.%NEWMINOR%%POST% +%VER=%NEWMAJOR%%NEWMINOR% +%OLDVERSION=%OLDMAJOR%.%OLDMINOR%%OLDPOST% +%OLDVER=%OLDMAJOR%%OLDMINOR% +%DATE=%DATE_YY%.%DATE_M%.%DATE_D% + +%ARC=dchook-%VERSION%.lzh +%DKPPARC=DKPP%VER%.EXE + +%HTML=S:\Web\NIFTY\ +%MYSOFT=S:\down\MySoft + +#ˆÈ‰º‚ÍMK.BAT—p +%FDATE=%DATE_M%/%DATE_D%/%DATE_Y% +%FTIME=%TIME_H%:%TIME_M%:%TIME_S% +%PDNEW=%VER% +%PDOLD=%OLDVER% + +%VARFILE=%HTML%pdic-download.var +%IND=dchook.ind +%CHGINI=perl -S chgini.pl + +%KEY1=DOKOPOP +%KEY2=PDIC +%KEY3=$WIN32 +%KEY4=#APP +%KEY5=#EDU + +****************** UPDATE “à—e ************************************** +<*UPDATE.TXT +>> Ver.1.12 << +* Ž«‘‚ª‘å‚«‚¢ê‡‚ɁAPDIC‹N“®Œã‚̍ŏ‰‚̃|ƒbƒvƒAƒbƒv‚ª‚Å‚«‚È‚¢‚Æ‚«‚ª‚ ‚Á‚½ +##EOF +******************** DokoPop! ‚̕ύX—š—ð **************************** +##<*HISTORY.TXT +##>UPDATE.TXT + +>> Ver.1.11 << +EUnicode”őΉž‚Ì‚½‚ß‚É“à•”ˆ—‚ð•ÏX + +>> Ver.1.10 << +›DokoPop‚Ń|ƒbƒvƒAƒbƒv‚µ‚½ƒEƒBƒ“ƒhƒEã‚Å‚³‚ç‚Ƀ|ƒbƒvƒAƒbƒv‚·‚é + ‚±‚Æ‚ª‰Â”\‚Ɂi˜A‘±ƒ|ƒbƒvƒAƒbƒvjiPDIC for Win32‚ÍVer.4.50ˆÈã‚ª•K—vj +›“ú–{Œê¬Ý‚Ì•¶Í‚Å‚à³‚µ‚­“®ì‚·‚é‚悤‚É‚µ‚½B +@iÝ’èƒ_ƒCƒAƒƒO‚́h“ú–{Œê‚𖳎‹‚·‚éh‚Ő؂è‘Ö‚¦‰Â”\j + +>> Ver.1.02 << +* DKPP.EXE‚̃o[ƒWƒ‡ƒ“Ý’è‚ðŠÔˆá‚Á‚Ä‚¢‚½ + +>> Ver.1.01 << +* Windows9x‚Ń|ƒbƒvƒAƒbƒv‚µ‚È‚¢ê‡‚ª‚ ‚Á‚½(IE‚È‚Ç) +E‚»‚ê‚ɑΏˆ‚µ‚½‚½‚߁AWindows95‚Í“®ì‘ΏۊO‚É +* ‰EƒNƒŠƒbƒNŒŸõØ‚è‘Ö‚¦‚ŃŠƒ\[ƒXƒŠ[ƒN‚ª”­¶‚µ‚Ä‚¢‚½ +* ƒqƒbƒg‚µ‚È‚¢’PŒê‚ª‚ ‚é‚ƃƒ‚ƒŠƒŠ[ƒN‚ª”­¶‚µ‚Ä‚¢‚½ + +>> Ver.1.00 << +* Windows9x/MeŒn‚ÌOS‚Å‚Ì“®ì‚ðˆÀ’艻‚µ‚½ +* Ž«‘ƒOƒ‹[ƒvŽw’è‚𐳏í‚É“®ì‚·‚é‚悤‚É‚µ‚½ + y’ˆÓz‚±‚Ì‹@”\‚ÍPDIC for Win32 Ver.4.40‚©‚ç‚̑Ήž‚É‚È‚è‚Ü‚· +EŒŸõ‚̃L[‚Ì‘g‚ݍ‡‚킹‚ðƒJƒXƒ^ƒ}ƒCƒY‚Å‚«‚é‚悤‚É‚µ‚½ +Eƒtƒ@ƒCƒ‹\¬‚ð•ÏX +E˜A‘±‚µ‚ă|ƒbƒvƒAƒbƒvŒŸõ‚ª‚Å‚«‚é‚悤‚É‚µ‚½ +E‚Ù‚©•\Ž¦‚̕ύX‚È‚Ç + +>> Ver.0.98 << +›ƒ}ƒEƒX‰EƒNƒŠƒbƒN‚݂̂Ń|ƒbƒvƒAƒbƒv‚ð‰Â”\‚É +@iCtrl+Alt+‰EƒNƒŠƒbƒN‚ÅON/OFF‚Å‚«‚Ü‚·j +* hŽ«‘ƒOƒ‹[ƒv‚ªŠJ‚¯‚Ü‚¹‚ñh‚Əo‚邱‚Æ‚ª‚ ‚Á‚½ +* Å¬‰»‚Å‹N“®‚µ‚½ê‡Aƒ^ƒXƒNƒo[‚ɃAƒCƒRƒ“‚ªŽc‚Á‚Ä‚¢‚½ + +>> Ver.0.97 << +* Ž«‘ƒOƒ‹[ƒv‚̕ύX‚ª‚Å‚«‚È‚­‚È‚Á‚Ä‚¢‚½ +* IE‚Ńqƒbƒg‚µ‚È‚¢‚±‚Æ‚ª‚ ‚Á‚½ + +>> Ver.0.96 << +* PDIC‚ðŽ©“®‹N“®‚Å‚«‚È‚©‚Á‚½(“ǂݍž‚Þregistry‚ðŠÔˆá‚Á‚Ä‚¢‚½) +* ‚Ç‚±ƒ|ƒbƒv‚ðÅ¬‰»‚Å‹N“®‚µ‚½ê‡AƒXƒvƒ‰ƒbƒVƒ…ƒEƒBƒ“ƒhƒE‚ªÁ‚¦‚È‚©‚Á‚½ + +>> Ver.0.95 << +?? + +>> Ver.0.94 << +* ƒXƒvƒ‰ƒbƒVƒ…‚ð”ñ•\Ž¦‚É‚µ‚½ê‡‚Ì•s‹ï‡C³ + +>> Ver.0.94 << +* ‹N“®ŽžDLL‰Šú‰»Ž¸”s(Win98) +* “ú–{Œê¬‚¶‚è‚Ì•¶‚ŃeƒLƒXƒg’ŠoˆÊ’u‚ª‚¸‚ê‚Ä‚¢‚½(Win98) + +>> Ver.0.93 << +E‹N“®ƒXƒvƒ‰ƒbƒVƒ…•ÏX +EƒXƒvƒ‰ƒbƒVƒ…•\Ž¦E”ñ•\Ž¦ +EƒXƒvƒ‰ƒbƒVƒ…ƒrƒbƒgƒ}ƒbƒv‚̃JƒXƒ^ƒ}ƒCƒY +EƒCƒ“ƒXƒg[ƒ‰’ljÁ +* ƒƒ‚’ ‚ňُíI—¹(NT) +* “ú–{Œê¬‚¶‚è‚Ì•¶‚ŃeƒLƒXƒg’ŠoˆÊ’u‚ª‚¸‚ê‚Ä‚¢‚½ + +>> Ver.0.92 << +EˆÀ’萫Œüã + +>> Ver.0.90 << +EÅ‰‚ÌŒöŠJ +##EOF +****************** Ž©ŒÈÐ‰î ****************************************** +##<*PROB.TXT +EAcrobat Readerã‚Å‚Í“®ì‚µ‚È‚¢ +EOperaã‚Å‚Í“®ì‚µ‚È‚¢ +EDOS‘‹ã‚Å‚Í“®ì‚µ‚È‚¢ +E16bitƒAƒvƒŠã‚Å‚Í“®ì‚µ‚È‚¢ +E•¡”s‚É‚Ü‚½‚ª‚énŒê‚̓qƒbƒg‚µ‚È‚¢ +##EOF + +##<*INTRO.TXT +@DokoPop! - ‚Ç‚±ƒ|ƒbƒvI ‚́ACtrl+ƒ}ƒEƒX‰EƒNƒŠƒbƒN‚ŁA +@ƒ}ƒEƒXƒJ[ƒ\ƒ‹ˆÊ’u‚̉p’PŒêE‰pnŒê‚ðŒŸõ‚µAƒ|ƒbƒvƒAƒbƒv•\Ž¦‚µ‚Ü‚·B + +@‚Ç‚±ƒ|ƒbƒvI ‚Í PDIC for Win32‚ÌDDE‹@”\‚ð—˜—p‚µ‚Ä‚¢‚Ü‚·B +@•Ê“rPDIC for Win32‚ð“üŽè‚µ‚ĉº‚³‚¢B + +@PDIC for Win32‚Ì“üŽèæ(•K{)F + http://homepage3.nifty.com/TaN/pdic-download.html + +@ƒ\[ƒXƒtƒ@ƒCƒ‹F + http://homepage3.nifty.com/TaN/prog-tips.html %ARC% +##EOF + +## Bytes +yŒŸõ ƒL[z@1:%KEY1% 2:%KEY2% 3:%KEY3% 4:%KEY4% 5:%KEY5% +y’˜ìŒ  ŽÒz@‚È‚µ +yŒf Ú ŽÒz@TaN(SGM00353) +y‘Ήž ‹@Žíz@MS-Windows 98/Me/NT4.0/2000/XP +y“®ì Šm”Fz@IBM PC/ATŒÝŠ·‹@,NT4,0,Win98,2000 +yŒf Ú “úz@%DATE% +yì¬ •û–@z@%DKPPARC% ‚ðŽÀs‚·‚é +y¿Ìijª±Ží•Êz@ƒtƒŠ[ƒEƒFƒA +y“]Ú ðŒz “]ÚŽ©—R +======================================================================== +yƒ\ƒtƒgÐ‰îz + +##>INTRO.TXT + +##>UPDATE.TXT + +Œ»Ý‚Ì–â‘è“_ + +##>PROB.TXT + +======================================================================== +ƒ_ƒEƒ“ƒ[ƒhƒtƒ@ƒCƒ‹–¼‚́y%DKPPARC%z‚Å‚·B +##EOF + + DCHOOK.DLL +‚̏‡”ԂŐæ‚ÉŒ©‚‚©‚Á‚½•û‚ðload‚·‚éŽd—l‚É‚È‚Á‚Ä‚¢‚Ü‚·B +DEBUG‚ðdefine‚µ‚½‚Æ‚«‚́ADCHOOK.DLL‚Ì‚Ý‚ðload‚µ‚悤‚Æ‚µ‚Ü‚·B + +ƒvƒƒOƒ‰ƒ€à–¾ ----------------------------------------------------------- + +ˆê”Ô–ï‰î‚È‚à‚̂́Adchook.cpp‚Å‚µ‚傤B +ŽŽsöŒë‚µ‚È‚ª‚ç‚à’ZŽžŠÔ‚ňê‹C‚ɏ‘‚«ã‚°‚½‚à‚Ì‚Å‚·‚̂ŁA +‚©‚Ȃ艘‚­‚È‚Á‚Ä‚¢‚Ü‚·B +#define‚É‚æ‚éswitch‚ɂ́AF‚ñ‚È‘g‚ݍ‡‚킹‚ª‚ ‚è‚Ü‚·‚ªA +Œ»óˆÈŠO‚̐ݒè‚É‚·‚é‚Ɛ³í‚É“®ì‚µ‚È‚©‚Á‚½‚èA +compile‚³‚¦‚à‚Å‚«‚È‚¢‚Í‚¸‚Å‚·B‚¾‚Á‚½‚çA®—‚µ‚È‚³‚¢I +‚ÆŒ¾‚í‚ê‚»‚¤‚Å‚·‚ªA¡Œã•K—v‚Æ‚È‚é‚Æ‚±‚낪‚ ‚é‚©‚à‚µ‚ê‚È‚¢‚̂ŁA +‚»‚Ì‚Ü‚Ü‚É‚µ‚Ä‚ ‚è‚Ü‚·B + +“®ìŒ´—‚Æ‚µ‚ẮAƒeƒLƒXƒg‚ðŽæ“¾‚µ‚½‚¢window‚ɑ΂µ‚Ä +Ä•`‰æ–½—ß‚ð‘—‚èAÄ•`‰æ’†‚̃eƒLƒXƒg•`‰æŠÖ”‚Ì“à—e‚ð +‰¡Žæ‚è‚·‚邱‚ƂŏE‚Á‚Ä‚«‚Ü‚·B + +Å‰ì‚èŽn‚ß‚½ ‚́AWindows‚©‚çDC‚ð“n‚µ‚Ä‚¢‚éŠÖ”‚ðhook‚µA +DC‚ðmetafile‚ōж‚·‚ê‚ΊȒP‚¶‚á‚È‚¢‚©H‚ÆŽv‚Á‚Ä‚â‚Á‚Ä‚Ý‚Ü‚µ‚½B +‚»‚¤‚µ‚½‚ç‚ ‚Á‚¯‚È‚­“®‚¢‚½‚Ì‚Å‚·‚ªA•Ê‚Ìapplication‚Å‚â‚Á‚Ä‚Ý‚é‚Æ +‚¤‚Ü‚­“®‚©‚È‚¢‚±‚Æ‚ª‚ ‚è‚Ü‚µ‚½B +Œ´ˆö‚́ACreateCompatibleBitmap‚Åbitmap‚ðì¬‚µA‚»‚±‚Öˆê’U•`‰æ +‚µ‚Ä‚©‚çABitBlt‚Åwindow‚É“\‚è•t‚¯‚éapplication‚ª‚ ‚Á‚½‚©‚ç‚Å‚·B +‚»‚¤‚È‚é‚ƁADC‚¾‚¯‚ł̓eƒLƒXƒg•`‰æî•ñ‚ª“¾‚ç‚ê‚Ü‚¹‚ñ‚̂ŁA +•K—v‚Ètext•`‰æŠÖ”‚ðhook‚µ‚Ä‚â‚é•K—v‚ª‚ ‚è‚Ü‚·B +(‚Ù‚©‚É‚àBeginPaint()‚Å“n‚³‚ê‚éDC‚Å‚Í‚È‚­AGetDC()‚Å +“¾‚½DC‚ɑ΂µ‚Ä•`‰æ‚µ‚Ä‚¢‚éapplicaton‚ɑ΂µ‚Ä‚à‚¤‚Ü‚­‚¢‚«‚Ü‚¹‚ñ‚Å‚µ‚½) + +‚±‚Ì‘O‚É‚±‚Ìhook‚Ì•û–@‚Å‚·‚ªANT‚Æ9x‚ł͈قȂè‚Ü‚·B +NT‚ÍŠeapplication‚ª“Æ—§‚Ìmemory‹óŠÔ‚Å‚ ‚èAuser32.dll,gdi32.dll‚à +application–ˆ‚Ìmemory‹óŠÔ‚É‘¶Ý‚µ‚Ä‚¢‚é‚Ì‚Å‚·‚ªA9x‚ł́A +‚¢‚«‚Ȃ苤—Lmemory‚֍s‚Á‚Ä‚µ‚Ü‚Á‚Ä‚¢‚é‚̂ŁAŠÈ’P‚É‚Íhook‚Å‚«‚Ü‚¹‚ñB + +API‚Ìhook•û–@‚́AƒAƒXƒL[‚©‚ço”Å‚³‚ê‚Ä‚¢‚éuAdvanced Windowsv +‚ðŽQl‚É‚µ‚Ü‚µ‚½B +http://www.amazon.co.jp/exec/obidos/ASIN/4756138055/pdichomepage-22 +‚±‚±‚ÉAPIƒtƒbƒN‚Ìà–¾‚ªÚ×‚É‹Lq‚³‚ê‚Ä‚¢‚Ü‚·B +‚µ‚©‚µA‚±‚Ì•û–@‚ð’m‚é‚Ü‚Å‚Í Hookæ‚̃AƒhƒŒƒX‚𒼐ڏ‘‚«Š·‚¦‚é‚Æ‚¢‚¤ +ŠëŒ¯‚È•û–@‚ð‚â‚Á‚Ä‚¢‚Ü‚µ‚½B‚‚܂è Advanced Windows‚É‹Lq‚³‚ê‚Ä‚¢‚é +‚P”Ô–Ú‚Ì•û–@‚Å‚·‚ˁBNTŒn‚ÌOS‚È‚ç‚Ù‚Ú–â‘è‚È‚­“®ì‚·‚é‚Ì‚Å‚·‚ªA +9xŒn‚Í—áŠO‚ª‚Ç‚¤‚µ‚Ä‚à”­¶‚µ‚Ä‚µ‚Ü‚¢‚Ü‚·B +‚Æ‚¢‚¤‚±‚ƂŁA‚±‚Ì–{‚Ì‚Q”Ô–Ú‚Ì•û–@‚ňÀ’肵‚Ä“®ì‚·‚é‚悤‚É +‚È‚è‚Ü‚µ‚½B‚µ‚©‚µA‚±‚Ì–{‚Ì‚Ü‚Ü‚Å‚ÍDokoPop!‚ÅŒø—¦‚æ‚­ +“®ì‚µ‚Ä‚­‚ê‚È‚¢‚̂ŁA‚©‚Ȃ菑‚«Š·‚¦‚Ä‚ ‚è‚Ü‚·B +i‚Æ‚¢‚¤‚±‚Æ‚Å’˜ìŒ •\Ž¦‚àÈ—ª‚µ‚½‚肵‚āEEEj +‘‚«Š·‚¦‚½A‚Æ‚¢‚¤‚æ‚èA¡‚Ü‚ÅŽ©•ª‚ª‘‚¢‚½APIHOOK\‘¢‘Ì‚ð +•ÏX‚µ‚½A‚Æ‚¢‚¤‚Ù‚¤‚ª³‚µ‚¢‚©‚à‚µ‚ê‚Ü‚¹‚ñB +APIƒtƒbƒN‚̉ðà‚Í‚±‚Ì–{‚ɏ÷‚è‚Ü‚·B + +‚Å‚·‚ªA‚¹‚Á‚©‚­‚P”Ԗڂ̊댯‚È•û–@‚Å‚¢‚­‚‚©“¾‚½î•ñ‚ª‚ ‚é‚̂ŁA +‹Œƒo[ƒWƒ‡ƒ“‚ÅŽg—p‚µ‚Ä‚¢‚½ƒtƒbƒN•û–@‚̏î•ñ‚ð‘‚¢‚Ä‚¨‚«‚Ü‚·B +---------- ŒÃ‚¢˜b ---------- +‚¿‚Ȃ݂ɁANT‚Å‚ÍUSER32.DLL,GDI32.DLL‚ÌGetProcAddress()‚Í +application‚É‚æ‚Á‚ĈقȂè‚Ü‚·B‚µ‚©‚µA9x‚Å‚Í“¯‚¶‚Å‚·B +æ‚Ù‚Ç‚à‚¿‚ç‚Á‚Ə‘‚¢‚½‚悤‚ɁANT‚Ìapplication‚͌•ʂÌmemory‹óŠÔ‚Å +USER32.DLL,GDI32.DLL‚àˆÙ‚È‚é‹óŠÔ‚É‘¶Ý‚µ‚Ä‚¢‚é‚©‚ç‚Å‚·B +‚Æ‚±‚낪9x‚Í‹¤—L‚µ‚Ä‚¢‚āA‚µ‚©‚àjump‚µ‚½‚ç‚·‚®‚Ékernel mode‚É +“ü‚Á‚Ä‚¢‚é‚悤‚Å‚·B(NT‚Í‚ ‚é’ö“xuser mode‚Å‚â‚Á‚Ä‚¢‚銴‚¶j + +‚³‚ç‚É‚»‚̐æ‚Í‚Ç‚¤‚È‚Á‚Ä‚¢‚é‚©‚Æ‚¢‚¤‚ƁEEE‚Æ‚¢‚¤˜b‚Í +‚±‚̃vƒƒOƒ‰ƒ€‚ÌscopeŠO‚È‚Ì‚Å‚Ü‚½‚Ì‹@‰ï‚ɏ÷‚é‚Æ‚µ‚āA +‚±‚±‚Å9x‚ɑ΂µ‚Ä‚¿‚å‚Á‚ÆŒ™‚È—\Š´‚ª‚悬‚è‚Ü‚·B +NT‚̏ꍇAentry point‚ð‘‚«Š·‚¦‚Ä‚à‚»‚ÌapplicationŒÅ—L‚Ì +entry point‚Å‚ ‚邽‚߁A‚»‚ÌŠÔ‚Étask switching‚ª”­¶‚µ‚Ä‚à +–â‘è‚È‚¢‚Ì‚Å‚·‚ªA9x‚ł́Aentry point‚ð‘‚«Š·‚¦‚½’¼Œã‚É +task switching‚ª”­¶‚µ‚½‚çA(—ˆ‚Ä—~‚µ‚­‚È‚¢)‚Ù‚©‚Ìapplication‚ª +‚»‚Ìhook‚ð“`‚Á‚Ä‚â‚Á‚Ä‚­‚éEEEÅˆ«entry point‘‚«Š·‚¦’†‚É +switching‚ª”­¶‚·‚é‚ƁEEE‚¿‚å‚Á‚Æ•|‚¢‚Å‚·B +‚Å‚àAŽÀÛ‚Í‚»‚̂悤‚ȃP[ƒX‚Í‹N‚±‚è‚É‚­‚­AŽÀÛ‚»‚¤‚¢‚¤ +–â‘è‚Í”­¶‚µ‚Ä‚¢‚Ü‚¹‚ñB‚Å‚·‚ªAˆê‰žƒvƒƒOƒ‰ƒ€‚Å‚Í +‚»‚Ì‚½‚߂̑΍ô‚ð‚µ‚Ä‚ ‚è‚Ü‚·B +(‚±‚Ì‚Ö‚ñ‚Ì—‹ü‚à‘‚¢‚½•û‚ª‚¢‚¢‚Ì‚Å‚·‚ªEEEÈ—ªj + +entry point‚̏‘‚«Š·‚¦‚Å‚·‚ªANT‚̏ꍇ‚Í +’ʏí‚Ìapplication‚Æ“¯‚¶‚Å‚·‚̂ŁAWriteProcessMemoryŠÖ”‚Å +code—̈æ‚ð‘‚«ž‚Ý‚ª‚Å‚«‚Ü‚·B‚µ‚©‚µA9x‚Í +‹¤—Lmemory‚Å‚ ‚èA‚»‚±‚Íwrite protect‚³‚ê‚Ä‚¢‚Ü‚·B +‚±‚Ìprotection‚ð‰ðœ‚·‚é‚ɂ͒ʏí‚ÌWindows API‚É‚Í +–³‚¢‚悤‚Ȃ̂Łi‚ ‚Á‚½‚狳‚¦‚Ä—~‚µ‚¢jA‚í‚´‚í‚´ +memory‚ð‘‚«Š·‚¦‚邾‚¯‚Ì‚½‚ß‚ÌVxD‚ðì‚è‚Ü‚µ‚½B +VxD‚È‚çkernel mode‚È‚Ì‚Å‚È‚ñ‚Å‚à‚Å‚«‚Ä‚µ‚Ü‚¢‚Ü‚·B +(‚±‚Ì‚Ö‚ñ‚ªæ‚Ù‚Ç‚Ìtask switching‚̘b‚Æ—‚ñ‚Å‚¢‚Ü‚·‚ª) + +VxD‚Ídynamic loading‚ōì‚Á‚Ä‚ ‚è‚Ü‚·B +‚±‚ÌVxD‚Å’ˆÓ‚µ‚È‚¯‚ê‚΂Ȃç‚È‚¢‚̂́ACreateFile()ŠÖ”‚Å +VxD‚ðload‚µ‚Ä‚¢‚Ü‚·‚ªA“ñ“xCreateFile()‚Í‚Å‚«‚È‚¢‚Æ‚±‚ë‚Å‚·B +]‚Á‚āAˆê”ԍŏ‰‚̏‰Šú‰»‚Ì‚Æ‚«‚¾‚¯ACreateFile()‚ðs‚¢A +‚ ‚Æ‚Í‚¸‚Á‚ÆVxD‚ðí’“‚³‚¹‚½‚Ü‚Ü‚É‚µ‚Ä‚¨‚­•K—v‚ª‚ ‚è‚Ü‚·B + +ˆê‰žAPI Hook‚̘b‚Í‚±‚Ì‚­‚ç‚¢‚É‚µ‚Ä‚¨‚«‚Ü‚·B +API Hook‚ð‚·‚éapplication‚Í‚Ù‚©‚É‚à‚ ‚è‚Ü‚·‚ªA +‚»‚¤‚¢‚¤application‚Í‚±‚ê‚Æ“¯‚¶•û–@‚ðŽg—p‚µ‚Ä‚¢‚é‚Ì‚Å‚µ‚傤‚©H +MSDN‚É‚àapimon(‚¾‚Á‚½‚©‚ȁH)‚Æ‚¢‚¤tool‚ª•t‘®‚µ‚Ä‚¢‚Ü‚·‚ªA +‚Ç‚¤‚È‚ñ‚Å‚µ‚傤H +---------- ˆÈãAŒÃ‚¢˜b ---------- + +˜b‚Í‚¸‚Á‚Æ‘O‚É–ß‚Á‚āABitBlt‘΍ô‚̘b‚Å‚·B +‚±‚ÌBitBlt‚Å•`‰æ‚·‚é•û–@‚𒲂ׂĂ݂é‚ƁAwindow‘S‘Ì‚Å‚Í‚È‚­A +banding‚É‚æ‚Á‚āAwindow‚𕡐”‚Ìbitmap‚É•ªŠ„‚µ‚ÄBitBlt‚µ‚Ä‚¢‚é +‚悤‚Å‚·B]‚Á‚āABitBlt API‚àhook‚µ‚Ä‚â‚èAbitmap‚Ötext‚ð +•`‰æ‚µ‚½‚Æ‚«‚̍À•W‚ƁABitBlt‚µ‚½‚Æ‚«‚Ìdestination point‚Ì +offset‚ðl—¶‚µ‚ÄtextÀ•W‚ðŒvŽZ‚µ‚Ä‚â‚é•K—v‚ª‚ ‚è‚Ü‚·B + +ˆÈãAtext‚ðget‚Å‚«‚½‚çAŽw’èÀ•W(sample‚Å‚Ímouse‚ÌcursorˆÊ’u)‚É +text‚ª‚ ‚é‚©‚Ç‚¤‚©A‚Æ‚¢‚¤”»’è‚ðs‚¢‚Ü‚·B +hit‚µ‚½ê‡‚́A‚»‚Ìtext‘S‘̂ƁAtextã‚Ìbyte offset‚ð +WM_COPYDATA message‚ŏ‰Šú‰»‚ÌŽž‚É“o˜^‚µ‚Ä‚ ‚é window‚ÖSendMessage() +‚µ‚Ü‚·B(WM_COPYDATA‚ÍSendMessage‚Å‚È‚¢‚Æ‚¢‚¯‚È‚¢) + +‚»‚µ‚āADCHookTest.exe‚ª‚»‚Ìmessage‚ðŽó‚¯Žæ‚èADCHookTest.exe‚ª +text‚ð‚Ù‚©‚Ìapplication(PDIC)‚ÖDDE‚Å“n‚µ‚Ä‚¢‚Ü‚·B + +DCHookTest.exe‚ª‚â‚Á‚Ä‚¢‚邱‚Æ‚Í‚»‚ꂪ‚Ù‚Æ‚ñ‚ǂŁA +dchook.dll‚É‚­‚ç‚ׂê‚Îꡂ©‚ÉŠy‚ÈŽdŽ–‚È‚Ì‚Å‚·B + +DLL‚ł͏펯‚Å‚·‚ªAdata‚ÍŠî–{“I‚ÉprocessŒÅ—L‚Ì’l‚ðŽ‚¿‚Ü‚·B +‚±‚±‚Å’ˆÓ‚µ‚È‚¯‚ê‚΂Ȃç‚È‚¢‚Ì‚ªAWindowsHook‚Ìhook dll‚́A +WindowsHook‚ŃZƒbƒg‚µ‚½ŒãAforeground application‚É +Ø‚è‘Ö‚í‚Á‚½‚Æ‚«‚ɏ‰‚ß‚Äattach‚³‚ê‚Ü‚·B +(‚‚܂èAWindowsHook‚µ‚½Žž“_‚Å‚ÍHook‚µ‚½process‚É‚µ‚© +attach‚³‚ê‚Ä‚¢‚È‚¢) +‚µ‚©‚àAattach‚µ‚½‚Æ‚«‚ɂ́A•Ê‚Ìapplication‚Ìprocess‹óŠÔ‚É +‹‚Ü‚·‚̂ŁAWM_COPYDATA‚Ì‘—‚èæ‚̏î•ñ‚ª‚Ç‚±‚É‚à‚ ‚è‚Ü‚¹‚ñB +ƒtƒ@ƒCƒ‹/registry‚É•Û‘¶‚µ‚ēǂݍž‚ށA‚È‚ñ‚Ä‚¢‚¤•û–@‚à‚ ‚è +‚Ü‚·‚ªAdchook.def‚Åshared‚É‚æ‚Á‚āAdllŠÔ‚Å‹¤—L‚·‚é +data segment‚ðì¬‚·‚é•û–@‚ª‚ ‚è‚Ü‚·B +‚±‚±‚ÉWM_COPYDATA‘—‚èæ‚Ìhandle‚ð•Û‘¶‚µ‚Ä‚¨‚¯‚΁A‚±‚̂悤‚È +–â‘è‚Í‰ðŒˆ‚Å‚«‚Ü‚·B + +‚»‚ê‚Æ‚à‚¤ˆê‚‚â‚Á‚Ä‚Ý‚Ä‚í‚©‚Á‚½‚Ì‚Å‚·‚ªA9x‚Å‚Í +Unhook‚ð‚·‚é‚ƁA‚·‚®‚É‚·‚ׂÄdetach‚³‚ê‚é‚Ì‚Å‚·‚ªA +NT‚ł́A‚±‚ê‚Ü‚½foreground‚ɐ؂è‘Ö‚í‚Á‚½‚Æ‚«‚É‚µ‚© +detach‚µ‚Ä‚­‚ê‚Ü‚¹‚ñB‚»‚±‚ŁAdchook‚Å‚Í‹­§“I‚É +detach‚³‚¹‚邽‚ß‚Émessage‚ðbroadcast‚³‚¹‚Ä‚¢‚Ü‚·B +ŽÀÛ‚Í‚»‚±‚Ü‚Å‚â‚é•K—v«‚Í‚È‚¢‚Ì‚Å‚·‚ªAŠJ”­Žž‚É +memory‚ð‰ð•ú‚³‚¹‚邽‚߂ɐF‚ñ‚Èapplication‚ɐ؂è‘Ö‚¦‚é‚Ì‚ª +Œ™‚¾‚Á‚½‚̂ŁEEEBroadcastMessageˆÈŠO‚É—Ç‚¢•û–@‚ª‚ ‚é‚Ì‚©‚ȁH + +ƒvƒƒOƒ‰ƒ€‰ðà ----------------------------------------------------------- + +DBW() + +ƒfƒoƒbƒO—p‚̊֐”‚Å‚·BÙì‚Ìdbgmsg.exe‚Ö•¶Žš—ñ‚ðo—Í‚µ‚Ü‚·‚ªA +‚Ù‚©‚Ìdebug string‚ð•â‘«‚·‚édebug string monitor‚ÅŽg‚¦‚é‚悤‚É +DBW()‚ð‘‚«Š·‚¦‚½‚Ù‚¤‚ª—Ç‚¢‚Å‚µ‚傤B(OutputDebugString()‚È‚Ç) + +popenable.h, popdisable.h +‚±‚ê‚ç‚́u‰EƒNƒŠƒbƒNŒŸõ‚ð—LŒø‚É‚µ‚Ü‚µ‚½v‚Æ‚¢‚¤ƒƒbƒZ[ƒWƒEƒBƒ“ƒhƒE‚Ì +ƒŠ[ƒWƒ‡ƒ“î•ñ‚Å‚·BiŠÛ‚Ý‚Ì‚ ‚éƒEƒBƒ“ƒhƒEj +‚±‚̃Š[ƒWƒ‡ƒ“î•ñ‚́Abmp2rgn‚Æ‚¢‚¤ƒc[ƒ‹‚Åpopenable.bmp, popdisable.bmp +‚ð•ÏŠ·‚µ‚½‚à‚Ì‚Å‚·Bbmp2rgn‚̓tƒŠ[ƒEƒFƒA‚Å‚·B + +ƒTƒ“ƒvƒ‹ƒvƒƒOƒ‰ƒ€ ------------------------------------------------------- + +sample program‚Æ‚µ‚āAmouse cursorˆÊ’u‚Ìtext‚𒊏o‚µA +ÙŽÒì‚̉p˜aŽ«‘ŒŸõƒvƒƒOƒ‰ƒ€ Personal Dictionary for Win32(PDIC)‚Ö +DDE‚ðŒo—R‚µ‚āAŒŸõŒ‹‰Ê‚ðpopup‚³‚¹‚é u‚Ç‚±ƒ|ƒbƒvIv‚Æ‚¢‚¤‚à‚Ì‚ª‚ ‚è‚Ü‚·B + +http://homepage3.nifty.com/TaN/pdic-download.html +‚ÉDokoPop!‚Æ‚¢‚¤–¼‘O‚Å“o˜^‚³‚ê‚Ä‚¢‚Ü‚·B + +¡Œã‚̉ۑè --------------------------------------------------------------- + +E•¡”sŒŸo +@‚±‚̃vƒƒOƒ‰ƒ€‚Å‚Í‚Ps•ª‚µ‚©Žæ“¾‚Å‚«‚Ü‚¹‚ñ‚ªA +@•`‰æŠJŽnˆÊ’u‚ð’ǐՂ·‚邱‚Æ‚É‚æ‚èA‘OŒã‚̍s‚à’Šo‰Â”\‚É‚È‚é‚Æ +@Žv‚¢‚Ü‚·B + +’˜ìŒ  ------------------------------------------------------------------ + +Ä”z•zA“]ÚA•¡»A‰ü•ÏA”Ì”„“™‚Í‚·‚ׂĎ©—R‚Å‚·BˆêØ‚̐§ŒÀ‚ðÝ‚¯‚Ü‚¹‚ñB +‚½‚¾‚µAˆÈ‰º‚Ì‚±‚Æ‚Í‚²—¯ˆÓ‚­‚¾‚³‚¢B +E‚±‚̃\ƒtƒgƒEƒFƒA‚É‚æ‚Á‚悶‚éˆêØ‚Ì‘¹ŠQÓ”C‚𕉂¢‚Ü‚¹‚ñB +E‚±‚̃\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚Ä•MŽÒ‚Í‚¢‚©‚È‚é‹`–±‚à•‰‚¢‚Ü‚¹‚ñB +EÄ”z•z‚³‚ꂽ‚à‚Ì‚ÉŠÖ‚µ‚Ă͈êØŠÖ’m‚µ‚Ü‚¹‚ñB + +—š—ð -------------------------------------------------------------------- + +##>HISTORY.TXT + +##EOF + +PROB.TXT + +€”õ -------------------------------------------------------------------- + +@%DKPPARC%‚ð‚»‚Ì‚Ü‚ÜŽÀs‚µ‚ĉº‚³‚¢B +@Ž©“®“I‚ɃCƒ“ƒXƒg[ƒ‹‚³‚ê‚Ü‚·B +@ƒXƒ^[ƒgƒAƒbƒv‚É“o˜^‚µ‚½•û‚ª•Ö—˜‚Å‚·B(Windows‹N“®Žž‚ÉDokoPop!‚à‹N“®) + +@‚Ç‚±ƒ|ƒbƒvI‚É‚ÍPDIC for Win32(‚Å‚«‚ê‚ÎVer.4.50ˆÈ~)‚ª•K—v‚Å‚·B +@http://homepage3.nifty.com/TaN/pdic-download.html + ‚©‚çƒ_ƒEƒ“ƒ[ƒh‚µ‚ĉº‚³‚¢B + + NT4.0‚ł́APSAPI.DLL ‚ª•K—v‚Å‚·B + http://homepage3.nifty.com/TaN/psapi.exe + ‚©‚çƒ_ƒEƒ“ƒ[ƒhŒãA‰ð“€AƒVƒXƒeƒ€ƒfƒBƒŒƒNƒgƒŠ(C:\WINNT\System32‚È‚Ç) + ‚ÖƒRƒs[‚µ‚Ä‚­‚¾‚³‚¢B + +Žg—p•û–@ ----------------------------------------------------------------- + +@DKPP.EXE‚ð‹N“®‚·‚é‚ƃ^ƒXƒNƒgƒŒƒC‚ɏ풓‚µ‚Ü‚·B(DP‚Ə‘‚¢‚Ä‚ ‚éƒAƒCƒRƒ“) +@CtrlƒL[‚ð‰Ÿ‚µ‚È‚ª‚çƒ}ƒEƒX‚̉Eƒ{ƒ^ƒ“‚ðƒNƒŠƒbƒN‚·‚é‚ƁAƒNƒŠƒbƒN‚µ‚½ˆÊ’u‚Ì +@’PŒê‚Ü‚½‚͏nŒê‚̈Ӗ¡‚ð•\Ž¦‚µ‚Ü‚·B + + y’ˆÓzPDIC–{‘Ì‚Í•K‚¸Ž«‘ƒOƒ‹[ƒv‚ðƒI[ƒvƒ“‚µ‚½ó‘Ô‚É‚µ‚Ä‚¨‚¢‚Ä‚­‚¾‚³‚¢B + ‚‚܂èA’ʏí‚ÌŒŸõ(WORD—““ü—́j‚ª‚Å‚«‚éó‘Ô‚É‚µ‚Ä‚¨‚¢‚Ä‚­‚¾‚³‚¢B + (ƒƒjƒ…[‚Ì File | Ž«‘ƒOƒ‹[ƒvƒI[ƒvƒ“) + Ž«‘•ÏŠ·’†‚ȂǁA’ʏí‚ÌŒŸõ‚ª‚Å‚«‚È‚¢ó‘Ԃł̓|ƒbƒvƒAƒbƒvŒŸõ‚Í + ‚Å‚«‚Ü‚¹‚ñB + + y’ˆÓzMS-Word‚Å‚Í Ctrl+‰EƒNƒŠƒbƒN ‚ªƒJƒbƒg•ƒy[ƒXƒg‚ÉŠ„‚è“–‚Ä‚ç‚ê‚Ä‚¢‚é + ‚½‚߁A‚¤‚Ü‚­“®ì‚µ‚È‚¢‚Æ‚«‚ª‚ ‚è‚Ü‚·B + iu‚Í‚¶‚ß‚É‘I‘ð‚µ‚Ä‚­‚¾‚³‚¢v‚ȂǂƏo‚Ä‚­‚éj + ‚à‚µ‚±‚Ì–â‘è‚ð‰ñ”ð‚µ‚½‚¢ê‡‚́AŽŸ‚́u‚¿‚å‚Á‚Æ•Ö—˜‚ÈŽg—p•û–@v + ‚É‚ ‚é‚悤‚ɁAu‰EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvv‚É‚·‚é‚©A + ŽŸ‚̂悤‚ɐݒè‚ðs‚Á‚Ä‚­‚¾‚³‚¢B + DokoPop!‚̃^ƒXƒNƒgƒŒƒC‚̃ƒjƒ…[‚©‚çA[Ý’è...]‚ð‘I‚сA + uƒ|ƒbƒvƒAƒbƒvŒŸõv‚©‚çAƒ|ƒbƒvƒAƒbƒv‚ð‚³‚¹‚é‚Æ‚«‚Ì‘g‚ݍ‡‚킹‚ð + ‘I‚ñ‚Å‚­‚¾‚³‚¢B + Alt + ‰EƒNƒŠƒbƒN ‚Å‚ ‚ê‚Ζâ‘è‚È‚¢‚悤‚Å‚·B + +‚¿‚å‚Á‚Æ•Ö—˜‚ÈŽg—p•û–@ --------------------------------------------------- + +@uCtrl + ‰EƒNƒŠƒbƒNv‚͂킸‚ç‚킵‚¢II +@‚Æ‚¢‚¤l‚ɂ́A + +@u‰EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvv + +@‚Æ‚¢‚¤•û–@‚à‚ ‚è‚Ü‚·B +@Ctrl + Alt + ‰EƒNƒŠƒbƒN ‚ÅON/OFF‚̐؂è‘Ö‚¦‚ª‚Å‚«‚Ü‚·B +@iØ‚è‘Ö‚¦Žž‚ɃƒbƒZ[ƒW‚ªo‚Ü‚·) + +@ƒqƒ“ƒgFu‰EƒNƒŠƒbƒN‚¾‚¯v‚É‚µ‚½ê‡AuCtrl + ‰EƒNƒŠƒbƒNv‚ð‚·‚é‚ƁA +@@@@@’ʏí‚̉EƒNƒŠƒbƒNƒƒjƒ…[‚ªo‚Ä‚«‚Ü‚·B +@@@@@‚¿‚傤‚ǁuCtrlv‚ª‹t“]‚·‚銴‚¶‚É‚È‚è‚Ü‚·B + +ƒƒjƒ…[ ----------------------------------------------------------------- + +@ƒ^ƒXƒNƒgƒŒƒC‚ÌDokoPop!ƒAƒCƒRƒ“‚ð‰EƒNƒŠƒbƒN‚·‚é‚ƃƒjƒ…[‚ªŒ»‚ê‚Ü‚·B + +@Ž«‘ƒOƒ‹[ƒv - PDIC‚ÌŽ«‘ƒOƒ‹[ƒv‚̕ύX‚ðs‚¢‚Ü‚· +@‰EƒNƒŠƒbƒNŒŸõ - ƒ}ƒEƒX‚̉EƒNƒŠƒbƒN‚¾‚¯‚Ń|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¢‚Ü‚· +@ƒ|ƒbƒvƒAƒbƒvŒŸõ—LŒø - ŒŸõ‚ð—LŒø^–³Œø‚É‚µ‚Ü‚· +@Ý’è - ŠeŽíÝ’è‚ðs‚¢‚Ü‚· +@à–¾‘‚ð•\Ž¦ - ‚±‚̃tƒ@ƒCƒ‹‚ð•\Ž¦‚µ‚Ü‚· +@ƒo[ƒWƒ‡ƒ“ - version•\Ž¦ +@I—¹ - ‚Ç‚±ƒ|ƒbƒvI‚̏I—¹ + +Ý’è ---------------------------------------------------------------------- + + ƒ^ƒXƒNƒgƒŒƒC‚̉EƒNƒŠƒbƒN‚ŏo‚Ä‚«‚½ƒƒjƒ…[‚́uÝ’èv‚Å‚·B + + ¡‹N“®Žž‚ɃXƒvƒ‰ƒbƒVƒ…‚ð•\Ž¦‚·‚é + ‹N“®Žž‚̉æ–Ê’†‰›‚ɏo‚Ä‚­‚éƒEƒBƒ“ƒhƒE‚Ì + •\Ž¦‚ð—LŒø^–³Œø‚É‚µ‚Ü‚·B + + š‹N“®Žž‚̃Xƒvƒ‰ƒbƒVƒ…ƒrƒbƒgƒ}ƒbƒv‚ðƒJƒXƒ^ƒ}ƒCƒYš + DKPP.EXE‚ª‚ ‚éƒtƒHƒ‹ƒ_[‚É DKPP.BMP ‚Æ‚¢‚¤ƒtƒ@ƒCƒ‹‚ª‚ ‚é‚ƁA + ‚»‚̃rƒbƒgƒ}ƒbƒv‚ð‹N“®Žž‚ƃo[ƒWƒ‡ƒ“...‚Ì‚Æ‚«‚É•\Ž¦‚µ‚Ü‚·B + + ¡Ž«‘ƒOƒ‹[ƒv‚ðŽw’è‚·‚é + ‚±‚±‚ðƒ`ƒFƒbƒN‚·‚é‚ƁAƒ|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤‚Æ‚«‚É + ‚±‚±‚ÅŽw’肵‚½Ž«‘ƒOƒ‹[ƒv‚ðŽg—p‚µ‚Ü‚·B + PDIC–{‘Ì‚Å‚ÌŽ«‘ƒOƒ‹[ƒv‚Ì‘I‘ð‚ª•ÏX‚³‚ê‚Ü‚·B + y’ˆÓz‚±‚Ì‹@”\‚ÍPDIC for Win32 Ver.4.40‚©‚ç‚̑Ήž‚É‚È‚è‚Ü‚· + + ¡ƒ|ƒbƒvƒAƒbƒvŒŸõ - ƒ|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤ƒ}ƒEƒX‚ƃL[‚Ì‘g‚ݍ‡‚킹‚ðŽw’è + ‚µ‚Ü‚·B + + ¡‰EƒNƒŠƒbƒNŒŸõON/OFF + ‰EƒNƒŠƒbƒNŒŸõ‚Ì—LŒøE–³Œø‚ðØ‚è‘Ö‚¦‚éƒ}ƒEƒX‚ƃL[‚Ì‘g‚ݍ‡‚킹‚Å‚·B + + ¡CtrlƒL[‚𗣂µ‚½‚çƒ|ƒbƒvƒAƒbƒv‚ð•Â‚¶‚é + Ctrl+ƒ}ƒEƒXƒNƒŠƒbƒN‚Ń|ƒbƒvƒAƒbƒvŒŸõ‚ðs‚¤‚悤‚É‚µ‚½ê‡A + ƒ|ƒbƒvƒAƒbƒv•\Ž¦‚³‚ꂽŒãACtrlƒL[‚𗣂µ‚½‚çƒ|ƒbƒvƒAƒbƒv‚µ‚½ + ƒEƒBƒ“ƒhƒE‚ð•Â‚¶‚Ü‚·B + i«—ˆ“I‚É‚±‚̃IƒvƒVƒ‡ƒ“‚Í–³‚­‚µ‚Ü‚· - ¢‚éI‚Æ‚¢‚¤•û‚Í‚¨’m‚点‚­‚¾‚³‚¢j + + ¡‰p”Žš‚Ì‚ÝŒŸõ‚·‚é + “ú–{ŒêE‰p”Žš¬Ý‚Ì•¶Í‚ª‚ ‚Á‚½ê‡A“ú–{Œê‚𖳎‹‚µ‚ÄŒŸõ‚ðs‚¢‚Ü‚·B + ¬Ý•¶Í‚Å‚Í ON ‚É‚µ‚½‚Ù‚¤‚ªƒqƒbƒg‚µ‚â‚·‚­‚È‚è‚Ü‚·B + ‚Ü‚½Aƒtƒ‰ƒ“ƒXŒêAƒhƒCƒcŒê‚̂悤‚ȃEƒ€ƒ‰ƒEƒgEƒAƒNƒTƒ“‚È‚Ç‚ð + ŠÜ‚Þ•¶Í‚Å‚Í‚±‚±‚ð OFF ‚É‚µ‚È‚¢‚Æ‚¤‚Ü‚­“®ì‚µ‚È‚¢ê‡‚ª‚ ‚è‚Ü‚·B + +‚»‚Ì‘¼ -------------------------------------------------------------------- + +@Ä—˜—pEÄ”z•zE‰ü•Ï‚È‚Ç‚ÍŽ©—R‚Å‚·B +@‚±‚̃\ƒtƒgƒEƒFƒA‚É‚æ‚鑹ŠQ‚͈êØ‚»‚̐ӔC‚𕉂¢‚Ü‚¹‚ñB + +@‚±‚Ìprogram‚́Aopen source‚Å‚ ‚éDCHook‚Ìsample program‚Å‚·B +@ƒ\[ƒXƒtƒ@ƒCƒ‹‚́A +@http://homepage3.nifty.com/TaN/prog-tips.html +@‚É‚ ‚è‚Ü‚·B(dchook-x.xx.lzh) + +@‚±‚̃\ƒtƒgƒEƒFƒA‚̃Tƒ|[ƒg‚͍s‚Á‚Ä‚¢‚Ü‚¹‚ñB‚½‚¾‚µA +@http://www4.plala.or.jp/cgi-bin/wforum/wforum.cgi/grape/dkpp +@‚ɂāAî•ñŒðŠ·‚ðs‚Á‚Ä‚¢‚Ü‚·B + +@PDIC for Win32‚Í +@http://homepage3.nifty.com/TaN/pdic-download.html + +@ƒCƒ“ƒXƒg[ƒ‰‚É‚¿‚­‚킳‚ñ(RXQ01346@nifty.ne.jp)‚ÌMakeSet‚ðŽg—p‚µ‚Ä‚¢‚Ü‚·B + +—š—ð ---------------------------------------------------------------------- + +##>HISTORY.TXT + +--------------------------------------------------------------------------- +##EOF + +****************** ƒpƒbƒP[ƒWì¬—p.BATƒtƒ@ƒCƒ‹ ******************************* + nul + +lha32 a %ARC% /x README.TXT +lha32 a %ARC% /x ./dchook/dchook.mak ./dchook/dchook.cpp ./dchook/dchook.h ./dchook/dchook.rc ./dchook/dchook.def +lha32 a %ARC% /x ./dchooktest/dchooktest.bpr ./dchooktest/dchooktest.mak +lha32 a %ARC% /x ./dchooktest/*.h ./dchooktest/*.cpp ./dchooktest/dchooktest.rc ./dchooktest/*.dfm ./dchooktest/dkpp.bmp ./dchooktest/popenable.bmp ./dchooktest/popdisable.bmp ./dchooktest/popenable.h ./dchooktest/popdisable.h ./dchooktest/icon.rc +lha32 a %ARC% /x ./vxd/makefile ./vxd/hk95d.def ./vxd/*.h ./vxd/*.asm ./vxd/*.c + +%CHGINI% %IND% Exe Name %DKPPARC% +%CHGINI% %IND% Date Year %DATE_YY% +%CHGINI% %IND% Date Month %DATE_M% +%CHGINI% %IND% Date Day %DATE_D% +%CHGINI% %IND% Date Hour %TIME_H% +%CHGINI% %IND% Date Minute %TIME_M% +%CHGINI% %IND% Date Second %TIME_S% +%CHGINI% %IND% Back 8 "|Doko Pop! Ver.%VERSION%" +%CHGINI% %IND% Back 12 "|Doko Pop! Ver.%VERSION%" + +rem IND‚ÌŽÀs +k:\wbin\makeset\makeset .\%IND% + +rem lha32 a %DKPPARC% DKPP.TXT DKPP.EXE DKPPHK.DLL HK95D.VXD +ren %DKPPARC% %DKPPARC% +touch -d%FDATE% -t%FTIME% -c %DKPPARC% + +echo/ +echo •Û‘¶—pˆ³kƒtƒ@ƒCƒ‹‚ðì¬‚µ‚Ü‚· +echo/ +rem pause + +dir %ARC% + +echo/ +echo ŒöŠJ—pƒtƒ@ƒCƒ‹‚ðXV‚µ‚Ü‚· +echo/ +rem pause + +perl -S -i.bak filestamp.pl DKPPu.TXT +del DKPPu.TXT.bak + +echo/ +echo Web—p‚̃tƒ@ƒCƒ‹‚ðXV‚µ‚Ü‚· +echo/ +pause + +copy %ARC% %HTML% +copy %ARC% %MYSOFT% +del %HTML%dchook-%OLDVERSION%.lzh +copy %DKPPARC% %HTML% +copy %DKPPARC% %MYSOFT% +del %HTML%DKPP%OLDVER%.EXE + +copy %VARFILE% vars.dat +perl -S repvars.pl %HTML%pdic-download0.html > %HTML%pdic-download.html +copy vars.dat %VARFILE% + +rem echo [del] >> %HTML%ftp.ctl +rem echo dchook-%OLDVERSION%.lzh >> %HTML%ftp.ctl +rem echo DKPP%OLDVER%.EXE >> %HTML%ftp.ctl +rem echo [include] >> %HTML%ftp.ctl +rem echo %DKPPARC% >> %HTML%ftp.ctl +rem echo %ARC% >> %HTML%ftp.ctl + + +##EOF + +<<@%VARFILE%,DP_ + + \ No newline at end of file diff --git a/dchooku.ind b/dchooku.ind new file mode 100644 index 0000000..b2f0bed --- /dev/null +++ b/dchooku.ind @@ -0,0 +1,232 @@ +[Finish] +Disp=0 +Comp=1148 +[Jump] +Check=0 +Date=0 +Del=0 +Dir=0 +Div=0 +Exe=0 +Ext=0 +File=0 +Go=0 +Go2=0 +Menu=0 +Pack=0 +Title=0 +Upl=0 +Reg=0 +Ask=0 +News=0 +Error=0 +Back=0 +Uninstall=0 +[Setup] +NoUninstall=0 +OnlyUninstall=0 +[Exe] +Name=DKPU114.exe +IconName=DKPU.EXE +Icon=0 +#No1=#1 +#No2=#3 +[Title] +Setup=DokoPop!/Unicode +Company=DokoPopProject +Soft=DKPU +[Del] +Auto=0 +Checked=1 +ShowError=1 +0= +Force=1 +Reboot=1 +[Dir] +Root=%programs%\DokoPopU +1= +[DirRemove] +1= +[File0] +Name=D:\SRC\DCHook\DKPU.EXE +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File1] +Name=D:\SRC\DCHook\DKPU.TXT +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File2] +Name=D:\SRC\DCHook\DKPUHK.DLL +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File3] +Name= +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File4] +Name= +Dir= +Del=1 +News=0 +NoAsk=1 +NoError=0 +Date=0 +[File5] +Name= +[CopyFile] +DefaultNo=0 +Reboot=1 +Question=0 +[Pack] +Copy=0 +Del=0 +[Menu] +Name=DokoPop!(Unicode) +[Check] +Desktop=0 +Startup=2 +Menu=2 +Ext=0 +Send=0 +[Go] +Readmename=DKPU.TXT +Readmeno=1 +Desktop=0 +Startup=1 +Menu=1 +Auto=0 +Agree=0 +[Go2] +Make0= +Erase0= +[Menu0] +Name=DokoPop!(Unicode) +Path=DKPU.EXE +Arg= +Icon=DKPU.EXE +Work= +Short= +IconNo=0 +Show=0 +Init=0 +[Menu1] +Name=DokoPop!(Unicode) à–¾‘ +Path=DKPU.TXT +Arg=DKPU.TXT +Icon=DKPU.TXT +Work= +Short= +IconNo=0 +Show=0 +Init=1 +[Menu2] +Name= +[Send0] +Name= +[Desktop] +Name= +[Startup] +Name=DokoPop!(Unicode) +Path=DKPU.EXE +Arg= +Icon=DKPU.EXE +Work= +Short= +IconNo=0 +Show=0 +Init=0 +[Ext0] +Ext= +[Date] +Year=2004 +Month=10 +Day=2 +Hour=1 +Minute=14 +Second=0 +Comp=1 +Exe=1 +[Upl] +Check=IBM PC/ATŒÝŠ·‹@,NT4.0,Win98 +Env=MS-Windows 98/NT4.0 +Key=DKPU,PDIC,$WIN32,#APP,#UTL +Kind=ƒtƒŠ[ƒEƒFƒA +Make= +Man=TaN(SGM00353) +Title=DokoPop!/Unicode +Trans=“]ÚŽ©—R +Gal=0 +Win=0 +[Intr] +Count=0 +[Hist] +Count=0 +[Div] +New=DKPPC +Go=0 +Top=0 +Delete=0 +Num=1457664 +TopNum=1457664 +[Reg] +Make0= +Erase0= +[Back] +Do=0 +0=fill,0,0,0 +1=mode,bottom +2=rect,0,0,%100,%80 +3=gradation,0,0,0,0,0,255 +4=mode,bottom +5=rect,%1,%1 +6=font,0,0,0,-21,0,0,0,700,255,0,0,0,3,2,1,18,Times New Roman +7=height,%10 +8=|Doko Pop! Ver.1.14 +9=rect,%2,%2 +10=font,255,255,0,-21,0,0,0,700,255,0,0,0,3,2,1,18,Times New Roman +11=height,%10 +12=|Doko Pop! Ver.1.14 +13=/----- +14= +[Readme] +0=page,install +1=mode,fill +2=fill,64,192,192 +3=mode,right +4=rect,5,0 +5=font,255,255,255,-36,0,0,0,400,0,0,0,0,3,2,1,34,Arial +6=|Welcome to +7=font,255,255,255,-36,0,0,0,400,0,0,0,128,3,2,1,50,‚l‚r ‚oƒSƒVƒbƒN +8=|Doko Pop! +9=rect,7,2 +10=font,0,0,0,-36,0,0,0,400,0,0,0,128,3,2,1,50,‚l‚r ‚oƒSƒVƒbƒN +11=|Welcome to +12=font,0,0,0,-36,0,0,0,400,0,0,0,128,3,2,1,50,‚l‚r ‚oƒSƒVƒbƒN +13=|DokoPop!/Unicode +14=font,0,0,0,-12,0,0,0,400,0,0,0,128,3,2,1,50,‚l‚r ‚oƒSƒVƒbƒN +15=mode,bottom +16=rect,7,70 +17=| +18=|ƒAƒ“ƒCƒ“ƒXƒg[ƒ‹‚Í +19=| +20=|ƒRƒ“ƒgƒ[ƒ‹ƒpƒlƒ‹‚́uƒAƒvƒŠƒP[ƒVƒ‡ƒ“‚̒ljÁ‚ƍ폜v‚©‚ç +21=| +22=|uDokoPop!v‚ð‘I‘ð•ŽÀs‚µ‚Ä‚­‚¾‚³‚¢D +23=/----- +No=24 diff --git a/dchooku.tpl b/dchooku.tpl new file mode 100644 index 0000000..bf9531f --- /dev/null +++ b/dchooku.tpl @@ -0,0 +1,377 @@ +#!perl -S mktpl.pl dchooku.tpl +------------------------------------------------------------------------ + DCHOOK/Unicode Document Template +------------------------------------------------------------------------ +%NEWMAJOR=2 +%NEWMINOR=0 +%NEWRELEASE=23 +%POST= +%OLDMAJOR=2 +%OLDMINOR=0 +%OLDRELEASE=22 +%OLDPOST= + +%DATE_Y=16 ŒöŠJ“ú +%DATE_M=10 +%DATE_D=06 + +%TIME_H=02 +%TIME_M=00 +%TIME_S=00 + +%DATE_YY=20%DATE_Y% +%VERSION = %NEWMAJOR%.%NEWMINOR%%NEWRELEASE%%POST% +%VER=%NEWMAJOR%%NEWMINOR%%NEWRELEASE% +%OLDVERSION=%OLDMAJOR%.%OLDMINOR%%OLDRELEASE%%OLDPOST% +%OLDVER=%OLDMAJOR%%OLDMINOR%%OLDRELEASE% +%DATE=%DATE_YY%.%DATE_M%.%DATE_D% + +%INSTALLER=DKPU%VER%.exe + +%HTML=S:\Web\NIFTY\ +%SAKURA=S:\web\sakura-pdic\cgi-bin\download\files\ + +#ˆÈ‰º‚ÍMKU.BAT—p +%FDATE=%DATE_M%/%DATE_D%/%DATE_Y% +%FTIME=%TIME_H%:%TIME_M%:%TIME_S% +%PDNEW=%VER% +%PDOLD=%OLDVER% + +%VARFILE=%HTML%pdic-unicode.var +%IND=dchooku.ind +%CHGINI=perl -S chgini.pl + +%KEY1=DOKOPOP +%KEY2=PDIC +%KEY3=$WIN32 +%KEY4=#APP +%KEY5=#EDU + +****************** UPDATE “à—e ************************************** +<*UPDATE.TXT +##EOF +******************** DokoPop! ‚̕ύX—š—ð **************************** +##<*HISTORY.TXT +##>UPDATE.TXT + +>> Ver.2.00 << + E•¶Žš”FŽ¯‚É‚æ‚èAƒ|ƒbƒvƒAƒbƒvŒŸõ‚ª‚Å‚«‚é‚Æ‚±‚낪‘‚¦‚½ + Eƒ}ƒEƒX‚Ì’†‰›ƒ{ƒ^ƒ“‚ւ̑Ήž + +>> Ver.1.23 << + EDDE‚Å‘—M‚·‚éƒf[ƒ^‚ÌŒ`Ž®‚ª³‚µ‚­Žw’肳‚ê‚Ä‚¢‚È‚©‚Á‚½(CF_TEXT->CF_UNICODETEXT) + +>> Ver.1.22 << + EƒNƒŠƒbƒN‚·‚é‘Ώۂ̃EƒBƒ“ƒhƒE‚ª”ñUnicode‚Å‚ ‚éê‡“®ì‚µ‚È‚©‚Á‚½ + +>> Ver.1.21 << + EŽ«‘ƒOƒ‹[ƒv‚Ì‘I‘ð‚ª³‚µ‚­“®ì‚µ‚È‚¢–â‘è‚ðC³ + +>> Ver.1.20 << + EPDIC/Unicode Ver.5.0.x‚ɑΉž + +>> Ver.1.15 << + EPDIC/Unicode Ver.0.83‚ɑΉž + Edialog‚̏o‚éêŠ‚ðDesktopCenter¨ScreenCenter (ƒ}ƒ‹ƒ`ƒ‚ƒjƒ^‘Ήž) + +>> Ver.1.14 << + EDokoPop!‚ÉŠÖ‚µ‚Ă͒ʏí‚̃o[ƒWƒ‡ƒ“”ԍ†‚ð•t‚¯‚邱‚Æ‚É‚µ‚½ + - DokoPop!‚̓À”łƐ³Ž®”Å‚ÌŽÀÛ“I‚ȈႢ‚ª–³‚¢‚½‚ß + - DokoPop!‚̓I[ƒvƒ“ƒ\[ƒX‚Å‚ ‚èAPDIC–{‘Ì‚Æ‚Í•Ê”z•z‚Å‚ ‚邽‚߁A + PDIC–{‘Ì‚Æ“¯Šú‚·‚éƒÀ”Å‚ÆŒ¾‚¤“K“–‚È‹æØ‚肪–³‚¢‚½‚ß + Eƒo[ƒWƒ‡ƒ“”ԍ†‚Ífor Win32”Å‚Æ‹¤’ʉ»iƒ\[ƒXƒR[ƒh‚ª“¯‚¶‚½‚߁j + * •¶‚̍Ōã‚Ì’PŒê‚ªƒqƒbƒg‚µ‚È‚©‚Á‚½iDokoPop!‚̍ŐV”Å‚ª•K—vj + yŒ´ˆöz + @Žæ“¾‚µ‚½•¶Žš—ñ‚̍Ōã‚ɃSƒ~‚ª•t‘®‚µ‚½‚±‚Æ‚É‚æ‚èA‚»‚ê‚ðPDIC‚ª’ʏí‚̃eƒLƒXƒg + @‚Æ”FŽ¯‚µ‚Ä‚µ‚Ü‚¢A•¶‚̍Ōã‚̃sƒŠƒIƒh‚ª’PŒê’†‚Ì•¶Žš—ñ‚Æ‚µ‚ďˆ—‚³‚ꂽ‚½‚߁B + +>> Ver.0.10 << +EÅ‰‚ÌŒöŠJ +##EOF +****************** Ž©ŒÈÐ‰î ****************************************** +##<*PROB.TXT +##EOF + +##<*INTRO.TXT +@DokoPop! - ‚Ç‚±ƒ|ƒbƒvI ‚́ACtrl+ƒ}ƒEƒX‰EƒNƒŠƒbƒN‚ŁA +@ƒ}ƒEƒXƒJ[ƒ\ƒ‹ˆÊ’u‚̉p’PŒêE‰pnŒê‚ðŒŸõ‚µAƒ|ƒbƒvƒAƒbƒv•\Ž¦‚µ‚Ü‚·B + +@‚Ç‚±ƒ|ƒbƒvI ‚Í PDIC/Unicode‚ÌDDE‹@”\‚ð—˜—p‚µ‚Ä‚¢‚Ü‚·B +@•Ê“rPDIC/Unicode‚ð“üŽè‚µ‚ĉº‚³‚¢B + +@PDIC/Unicode ‚Ì“üŽèæ(•K{)F + http://pdic.la.coocan.jp/ + +@ƒ\[ƒXƒtƒ@ƒCƒ‹F + http://dokopop.sourceforge.jp/ +##EOF + +## Bytes +yŒŸõ ƒL[z@1:%KEY1% 2:%KEY2% 3:%KEY3% 4:%KEY4% 5:%KEY5% +y’˜ìŒ  ŽÒz@‚È‚µ +yŒf Ú ŽÒz@DokoPop Project +y‘Ήž ‹@Žíz@MS-Windows Vista/7/8/8.1/10 +y“®ì Šm”Fz@IBM PC/ATŒÝŠ·‹@,7/8/8.1/10 +yŒf Ú “úz@%DATE% +yì¬ •û–@z@%INSTALLER% ‚ðŽÀs‚·‚é +y¿Ìijª±Ží•Êz@ƒtƒŠ[ƒEƒFƒA +y“]Ú ðŒz “]ÚŽ©—R +======================================================================== +yƒ\ƒtƒgÐ‰îz + +##>INTRO.TXT + +##>UPDATE.TXT + +Œ»Ý‚Ì–â‘è“_ + +##>PROB.TXT + +======================================================================== +ƒ_ƒEƒ“ƒ[ƒhƒtƒ@ƒCƒ‹–¼‚́y%INSTALLER%z‚Å‚·B +##EOF + +HISTORY.TXT + +-------------------------------------------------------------- +##EOF + +****************** ƒpƒbƒP[ƒWì¬—p.BATƒtƒ@ƒCƒ‹ ******************************* + ind\dkpu.iss.new +del ind\dkpu.iss.old +ren ind\dkpu.iss dkpu.iss.old +ren ind\dkpu.iss.new dkpu.iss + +rem Installer ‚ÌŽÀs +make buildis + +echo/ +echo Press Enter key after installer made. +echo/ +pause + +copy ind\Output\setup.EXE %INSTALLER% +dir %INSTALLER% + +rem lha32 a %INSTALLER% DKPU.TXT DKPU.EXE DKPUHK.DLL +ren %INSTALLER% %INSTALLER% +rem touch -d%FDATE% -t%FTIME% -c %INSTALLER% + +echo/ +echo ƒ\[ƒXƒtƒ@ƒCƒ‹‚ðzip‚µ‚Ü‚· +echo/ +pause + +make zip_src +copy src.zip src-%VERSION%.zip +rem copy src-%VERSION%.zip zip + +echo/ +echo ŒöŠJ—pƒtƒ@ƒCƒ‹‚ðXV‚µ‚Ü‚· +echo/ +rem pause + +perl -S -i.bak filestamp.pl DKPUu.TXT +del DKPUu.TXT.bak + +echo/ +echo Web—p‚̃tƒ@ƒCƒ‹‚ðXV‚µ‚Ü‚· +echo/ +pause + +rem copy %INSTALLER% %HTML% +rem del %HTML%DKPU%OLDVER%.EXE +copy %INSTALLER% %SAKURA% +del %SAKURA%DKPU%OLDVER%.EXE + +rem echo [del] >> %HTML%ftp.ctl +rem echo DKPU%OLDVER%.EXE >> %HTML%ftp.ctl +rem echo [include] >> %HTML%ftp.ctl +rem echo %INSTALLER% >> %HTML%ftp.ctl + +##EOF + +<<@%VARFILE%,DU_ + diff --git a/mktpl.bat b/mktpl.bat new file mode 100644 index 0000000..9167f02 --- /dev/null +++ b/mktpl.bat @@ -0,0 +1,2 @@ +@echo off +Perl -S mktpl.pl dchook.tpl diff --git a/mktplu.bat b/mktplu.bat new file mode 100644 index 0000000..04034c1 --- /dev/null +++ b/mktplu.bat @@ -0,0 +1,2 @@ +@echo off +Perl -S mktpl.pl dchooku.tpl -- 2.11.0