OSDN Git Service

[U] 高DPIモニター対応の強化
[dokopop/dokopop.git] / DCHook64 / dchk64 / dchk64.cpp
1 // dchk64.cpp : \83A\83v\83\8a\83P\81[\83V\83\87\83\93\82Ì\83G\83\93\83g\83\8a \83|\83C\83\93\83g\82ð\92è\8b`\82µ\82Ü\82·\81B
2 //
3
4 #include "stdafx.h"
5 #include "dchk64.h"
6 #include "../../DCHookTest/HookLoader.h"
7 #include "../DCHook64.h"
8
9 #define MAX_LOADSTRING 100
10
11 // \83O\83\8d\81[\83o\83\8b\95Ï\90\94:
12 HINSTANCE hInst;                                                                // \8c»\8dÝ\82Ì\83C\83\93\83^\81[\83t\83F\83C\83X
13 TCHAR szTitle[MAX_LOADSTRING];                                  // \83^\83C\83g\83\8b \83o\81[\82Ì\83e\83L\83X\83g
14 TCHAR szWindowClass[MAX_LOADSTRING];                    // \83\81\83C\83\93 \83E\83B\83\93\83h\83\83N\83\89\83X\96¼
15
16 const char *StrDCHOOKDLL = "DKPUHK64.dll";
17 THookLoader HookDll(StrDCHOOKDLL);
18
19 HWND hWnd = NULL;
20 HWND hwndParent = NULL;
21 HANDLE hMutex = NULL;
22 bool WindowsNT = true;
23
24 #ifdef _DEBUG
25 #define DBW     dbw
26 #else
27 #define DBW
28 #endif
29 void dbw( const char *format, ... );
30
31 // \82±\82Ì\83R\81[\83\83\82\83W\83\85\81[\83\8b\82É\8aÜ\82Ü\82ê\82é\8aÖ\90\94\82Ì\90é\8c¾\82ð\93]\91\97\82µ\82Ü\82·:
32 ATOM MyRegisterClass(HINSTANCE hInstance);
33 BOOL InitInstance(HINSTANCE, LPTSTR lpCmdLine, int);
34 void Cleanup();
35 LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
36
37 int atox( const TCHAR *str, TCHAR **next );
38 void SetDpiAware();
39
40 int APIENTRY _tWinMain(HINSTANCE hInstance,
41                      HINSTANCE hPrevInstance,
42                      LPTSTR    lpCmdLine,
43                      int       nCmdShow)
44 {
45         UNREFERENCED_PARAMETER(hPrevInstance);
46         //UNREFERENCED_PARAMETER(lpCmdLine);
47
48         MSG msg;
49         HACCEL hAccelTable;
50
51         SetDpiAware();
52
53         // \83O\83\8d\81[\83o\83\8b\95\8e\9a\97ñ\82ð\8f\89\8aú\89»\82µ\82Ä\82¢\82Ü\82·\81B
54         LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
55         LoadString(hInstance, IDC_DCHK64, szWindowClass, MAX_LOADSTRING);
56         MyRegisterClass(hInstance);
57
58         // \83A\83v\83\8a\83P\81[\83V\83\87\83\93\82Ì\8f\89\8aú\89»\82ð\8eÀ\8ds\82µ\82Ü\82·:
59         if (!InitInstance (hInstance, lpCmdLine, nCmdShow))
60         {
61                 return FALSE;
62         }
63
64         hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DCHK64));
65
66         // \83\81\83C\83\93 \83\81\83b\83Z\81[\83\83\8b\81[\83v:
67         while (GetMessage(&msg, NULL, 0, 0))
68         {
69                 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
70                 {
71                         TranslateMessage(&msg);
72                         DispatchMessage(&msg);
73                 }
74         }
75
76         Cleanup();
77
78         return (int) msg.wParam;
79 }
80
81
82
83 //
84 //  \8aÖ\90\94: MyRegisterClass()
85 //
86 //  \96Ú\93I: \83E\83B\83\93\83h\83\83N\83\89\83X\82ð\93o\98^\82µ\82Ü\82·\81B
87 //
88 //  \83R\83\81\83\93\83g:
89 //
90 //    \82±\82Ì\8aÖ\90\94\82¨\82æ\82Ñ\8eg\82¢\95û\82Í\81A'RegisterClassEx' \8aÖ\90\94\82ª\92Ç\89Á\82³\82ê\82½
91 //    Windows 95 \82æ\82è\91O\82Ì Win32 \83V\83X\83e\83\80\82Æ\8cÝ\8a·\82³\82¹\82é\8fê\8d\87\82É\82Ì\82Ý\95K\97v\82Å\82·\81B
92 //    \83A\83v\83\8a\83P\81[\83V\83\87\83\93\82ª\81A\8aÖ\98A\95t\82¯\82ç\82ê\82½
93 //    \90³\82µ\82¢\8c`\8e®\82Ì\8f¬\82³\82¢\83A\83C\83R\83\93\82ð\8eæ\93¾\82Å\82«\82é\82æ\82¤\82É\82·\82é\82É\82Í\81A
94 //    \82±\82Ì\8aÖ\90\94\82ð\8cÄ\82Ñ\8fo\82µ\82Ä\82­\82¾\82³\82¢\81B
95 //
96 ATOM MyRegisterClass(HINSTANCE hInstance)
97 {
98         WNDCLASSEX wcex;
99
100         wcex.cbSize = sizeof(WNDCLASSEX);
101
102         wcex.style                      = CS_HREDRAW | CS_VREDRAW;
103         wcex.lpfnWndProc        = WndProc;
104         wcex.cbClsExtra         = 0;
105         wcex.cbWndExtra         = 0;
106         wcex.hInstance          = hInstance;
107         wcex.hIcon                      = NULL; //LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PDHK64));
108 #ifdef _DEBUG
109         wcex.hCursor            = LoadCursor(NULL, IDC_ARROW);
110         wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);
111 #else
112         wcex.hCursor            = NULL; //LoadCursor(NULL, IDC_ARROW);
113         wcex.hbrBackground      = NULL; //(HBRUSH)(COLOR_WINDOW+1);
114 #endif
115         wcex.lpszMenuName       = NULL; //MAKEINTRESOURCE(IDC_PDHK64);
116         wcex.lpszClassName      = szWindowClass;
117         wcex.hIconSm            = NULL; //LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
118
119         return RegisterClassEx(&wcex);
120 }
121
122 //
123 //   \8aÖ\90\94: InitInstance(HINSTANCE, LPTSTR, int)
124 //
125 //   \96Ú\93I: \83C\83\93\83X\83^\83\93\83\83n\83\93\83h\83\8b\82ð\95Û\91\82µ\82Ä\81A\83\81\83C\83\93 \83E\83B\83\93\83h\83E\82ð\8dì\90¬\82µ\82Ü\82·\81B
126 //
127 //   \83R\83\81\83\93\83g:
128 //
129 //        \82±\82Ì\8aÖ\90\94\82Å\81A\83O\83\8d\81[\83o\83\8b\95Ï\90\94\82Å\83C\83\93\83X\83^\83\93\83\83n\83\93\83h\83\8b\82ð\95Û\91\82µ\81A
130 //        \83\81\83C\83\93 \83v\83\8d\83O\83\89\83\80 \83E\83B\83\93\83h\83E\82ð\8dì\90¬\82¨\82æ\82Ñ\95\\8e¦\82µ\82Ü\82·\81B
131 //
132 BOOL InitInstance(HINSTANCE hInstance, LPTSTR lpCmdLine, int nCmdShow)
133 {
134    hInst = hInstance; // \83O\83\8d\81[\83o\83\8b\95Ï\90\94\82É\83C\83\93\83X\83^\83\93\83X\8f\88\97\9d\82ð\8ai\94[\82µ\82Ü\82·\81B
135
136         TCHAR ModuleName[_MAX_PATH];
137         GetModuleFileName(NULL, ModuleName, sizeof(ModuleName)/sizeof(TCHAR));
138         hMutex = CreateMutex(NULL, FALSE, ModuleName);
139         if (GetLastError()==ERROR_ALREADY_EXISTS){
140                 return FALSE;   // dup launched
141         }
142
143 #ifdef _DEBUG
144         const int width = 800;
145         const int height = 400;
146 #else
147         const int width = 0;
148         const int height = 0;
149 #endif
150
151    hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
152       CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL);
153
154    if (!hWnd)
155    {
156       return FALSE;
157    }
158
159         hwndParent = (HWND)(LONG_PTR)atox(lpCmdLine, NULL);
160         //DBW("hwndParent=%d", (int)(LONG_PTR)hwndParent);
161         if (hwndParent){
162                 PostMessage(hwndParent, UM_SHORTCUT, SCINX_NOTIFY64, (LPARAM)hWnd);
163                 //DBW("Posted");
164         }
165
166 #ifdef _DEBUG
167    ShowWindow(hWnd, nCmdShow);
168    UpdateWindow(hWnd);
169 #endif
170
171    return TRUE;
172 }
173
174 void Cleanup()
175 {
176         if (hMutex){
177                 CloseHandle(hMutex);
178                 hMutex = NULL;
179         }
180 }
181
182 //
183 //  \8aÖ\90\94: WndProc(HWND, UINT, WPARAM, LPARAM)
184 //
185 //  \96Ú\93I:  \83\81\83C\83\93 \83E\83B\83\93\83h\83E\82Ì\83\81\83b\83Z\81[\83W\82ð\8f\88\97\9d\82µ\82Ü\82·\81B
186 //
187 //  WM_COMMAND  - \83A\83v\83\8a\83P\81[\83V\83\87\83\93 \83\81\83j\83\85\81[\82Ì\8f\88\97\9d
188 //  WM_PAINT    - \83\81\83C\83\93 \83E\83B\83\93\83h\83E\82Ì\95`\89æ
189 //  WM_DESTROY  - \92\86\8e~\83\81\83b\83Z\81[\83W\82ð\95\\8e¦\82µ\82Ä\96ß\82é
190 //
191 //
192 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
193 {
194         //int wmId, wmEvent;
195         PAINTSTRUCT ps;
196         HDC hdc;
197
198         switch (message)
199         {
200         case WM_CREATE:
201                 HookDll.Load(hWnd);
202 #ifdef _DEBUG
203                 {
204                 if (!HookDll.Init(hWnd)){
205                         DBW("Hook.Init error");
206                 }
207 #if 0
208                 HookDll.Config(-1, KA_POPUP, KF_CONTROL);
209                 TDCHConfig cfg;
210                 memset(&cfg, 0, sizeof(cfg));
211                 cfg.UseAMODI = 0;
212                 cfg.MoveSend = 0;
213                 cfg.ScaleX = 0;
214                 cfg.ScaleY = 0;
215                 HookDll.Config2(&cfg);
216 #endif
217                 }
218 #endif
219                 break;
220 #if 0
221         case WM_COMMAND:
222                 wmId    = LOWORD(wParam);
223                 wmEvent = HIWORD(wParam);
224                 // \91I\91ð\82³\82ê\82½\83\81\83j\83\85\81[\82Ì\89ð\90Í:
225                 switch (wmId)
226                 {
227                 case IDM_ABOUT:
228                         DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
229                         break;
230                 case IDM_EXIT:
231                         DestroyWindow(hWnd);
232                         break;
233                 default:
234                         return DefWindowProc(hWnd, message, wParam, lParam);
235                 }
236                 break;
237 #endif
238         case WM_PAINT:
239                 hdc = BeginPaint(hWnd, &ps);
240                 EndPaint(hWnd, &ps);
241                 break;
242         case WM_DESTROY:
243                 PostQuitMessage(0);
244                 break;
245
246         case WM_COPYDATA:
247                 {
248                 COPYDATASTRUCT *cds = (COPYDATASTRUCT*)lParam;
249                 if ( !cds ) break;
250                 switch (cds->dwData){
251                         case HDC_Init:
252                                 {
253                                 HDCInitParam &p = *(HDCInitParam*)cds->lpData;
254                                 return HookDll.Init(p.hwnd);
255                                 }
256                         case HDC_Uninit:
257                                 HookDll.Uninit();
258                                 break;
259                         case HDC_Config:
260                                 {
261                                 HDCConfigParam &p = *(HDCConfigParam*)cds->lpData;
262                                 return HookDll.Config(p.clickonly, p.keyaction, p.keyflag);
263                                 }
264                         case HDC_Config2:
265                                 return HookDll.Config2((TDCHConfig*)cds->lpData);
266                         case HDC_Capture:
267                                 return HookDll.Capture();
268                         case HDC_CaptureAsync:
269                                 return HookDll.CaptureAsync();
270                         case HDC_CaptureAsyncWait:
271                                 return HookDll.CaptureAsyncWait();
272                         case HDC_Debug:
273                                 return HookDll.Debug();
274                 }
275                 }
276                 break;
277         default:
278                 return DefWindowProc(hWnd, message, wParam, lParam);
279         }
280         return 0;
281 }
282
283 int atox( const TCHAR *str, TCHAR **next )
284 {
285         unsigned val = 0;
286         while ( 1 )
287         {
288                 TCHAR c = *str;
289                 if ( c >= '0' && c <= '9' ){
290                         val = (val<<4) + (c - '0');
291                 } else if ( c >= 'A' && c <= 'F' ){
292                         val = (val<<4) + ( c - 'A' + 10 );
293                 } else if ( c >= 'a' && c <= 'f' ){
294                         val = (val<<4) + ( c - 'a' + 10 );
295                 } else {
296                         break;
297                 }
298                 str++;
299         }
300         if ( next ) *next = (TCHAR*)str;
301         return val;
302 }
303
304 static HWND hWin = NULL;
305 static const TCHAR *clsnameW = _T("TDbgMsgForm");
306 static const TCHAR *winnameW = _T("Debug Messenger");
307
308 void dbw( const char *format, ... )
309 {
310         if ( !hWin ){
311                 hWin = FindWindow( clsnameW, winnameW );
312                 if ( !hWin ) return;
313         }
314         va_list ap;
315         va_start( ap, format );
316         char buf[ 2048 ];
317         wvsprintfA( buf, format, ap );
318         COPYDATASTRUCT cds;
319         cds.dwData = 1; // Indicate String
320         cds.cbData = (DWORD)strlen(buf)+1;
321         cds.lpData = buf;
322         SendMessageA( hWin, WM_COPYDATA, NULL, (LPARAM)&cds );
323         va_end( ap );
324 }
325
326 static const char *MyWinTitle = "<Processing...>";
327 HANDLE WinExecEx( const char *cmd, int show, const char *dir, const char *title )
328 {
329         STARTUPINFO sui;
330         memset( &sui, 0, sizeof(STARTUPINFO) );
331         sui.cb = sizeof(STARTUPINFO);
332         sui.dwFlags = STARTF_USESHOWWINDOW;
333         sui.wShowWindow = (WORD)show;
334         sui.lpTitle = (LPTSTR)(title ? title : MyWinTitle);
335         PROCESS_INFORMATION pi;
336         if ( !CreateProcess( NULL, (LPTSTR)cmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, dir, &sui, &pi ) )
337                 return NULL;
338         return pi.hProcess;
339 }
340
341 typedef WINUSERAPI BOOL (WINAPI *FNSetProcessDpiAwarenessContext)(UINT_PTR vaule);
342 #define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2      ((UINT_PTR)-4)
343 void SetDpiAware()
344 {
345         HINSTANCE hDll = LoadLibrary( _T("user32") );
346         if (!hDll)
347                 return;
348         FNSetProcessDpiAwarenessContext fnSetProcessDpiAwarenessContext = (FNSetProcessDpiAwarenessContext)GetProcAddress(hDll, "SetProcessDpiAwarenessContext");
349         if (fnSetProcessDpiAwarenessContext){
350                 if (fnSetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)){
351                 } else {
352                         DBW("x64-SetDpiAware failed: %d", GetLastError());
353                 }
354         }
355         FreeLibrary(hDll);
356 }
357