1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
10 #include "stringtool.h"
\r
14 #include <richedit.h>
\r
18 #define HOOK_DATA_NAME _T("{08D6E55C-5103-4e00-8209-A1C4AB13BBEF}") _T(VERSION)
\r
20 #define HOOK_DATA_NAME_ARCH _T("{290C0D51-8AEE-403d-9172-E43D46270996}") _T(VERSION)
\r
22 #define HOOK_DATA_NAME_ARCH _T("{716A5DEB-CB02-4438-ABC8-D00E48673E45}") _T(VERSION)
\r
25 // Some applications use different values for below messages
\r
26 // when double click of title bar.
\r
27 #define SC_MAXIMIZE2 (SC_MAXIMIZE + 2)
\r
28 #define SC_MINIMIZE2 (SC_MINIMIZE + 2)
\r
29 #define SC_RESTORE2 (SC_RESTORE + 2)
\r
33 #define HOOK_RPT0(msg)
\r
34 #define HOOK_RPT1(msg, arg1)
\r
35 #define HOOK_RPT2(msg, arg1, arg2)
\r
36 #define HOOK_RPT3(msg, arg1, arg2, arg3)
\r
37 #define HOOK_RPT4(msg, arg1, arg2, arg3, arg4)
\r
38 #define HOOK_RPT5(msg, arg1, arg2, arg3, arg4, arg5)
\r
40 #define HOOK_RPT0(msg) if (g.m_isLogging) { _RPT0(_CRT_WARN, msg); }
\r
41 #define HOOK_RPT1(msg, arg1) if (g.m_isLogging) { _RPT1(_CRT_WARN, msg, arg1); }
\r
42 #define HOOK_RPT2(msg, arg1, arg2) if (g.m_isLogging) { _RPT2(_CRT_WARN, msg, arg1, arg2); }
\r
43 #define HOOK_RPT3(msg, arg1, arg2, arg3) if (g.m_isLogging) { _RPT3(_CRT_WARN, msg, arg1, arg2, arg3); }
\r
44 #define HOOK_RPT4(msg, arg1, arg2, arg3, arg4) if (g.m_isLogging) { _RPT4(_CRT_WARN, msg, arg1, arg2, arg3, arg4); }
\r
45 #define HOOK_RPT5(msg, arg1, arg2, arg3, arg4, arg5) if (g.m_isLogging) { _RPT5(_CRT_WARN, msg, arg1, arg2, arg3, arg4, arg5); }
\r
48 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
52 DllExport HookData *g_hookData; ///
\r
58 HHOOK m_hHookGetMessage; ///
\r
59 HHOOK m_hHookCallWndProc; ///
\r
62 static HookDataArch *s_hookDataArch;
\r
65 HANDLE m_hHookData; ///
\r
66 HANDLE m_hHookDataArch; ///
\r
67 HWND m_hwndFocus; ///
\r
68 HINSTANCE m_hInstDLL; ///
\r
69 bool m_isInMenu; ///
\r
70 UINT m_WM_MAYU_MESSAGE; ///
\r
71 bool m_isImeLock; ///
\r
72 bool m_isImeCompositioning; ///
\r
73 HHOOK m_hHookMouseProc; ///
\r
74 HHOOK m_hHookKeyboardProc; ///
\r
75 INPUT_DETOUR m_keyboardDetour;
\r
76 INPUT_DETOUR m_mouseDetour;
\r
78 DWORD m_hwndTaskTray; ///
\r
80 bool m_isInitialized;
\r
81 #ifdef HOOK_LOG_TO_FILE
\r
83 #endif // HOOK_LOG_TO_FILE
\r
86 _TCHAR m_moduleName[GANA_MAX_PATH];
\r
93 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
97 static void notifyThreadDetach();
\r
98 static void notifyShow(NotifyShow::Show i_show, bool i_isMDI);
\r
99 static void notifyLog(_TCHAR *i_msg);
\r
100 static bool mapHookData(bool i_isYamy);
\r
101 static void unmapHookData();
\r
102 static bool initialize(bool i_isYamy);
\r
103 static bool notify(void *i_data, size_t i_dataSize);
\r
106 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
110 #ifdef HOOK_LOG_TO_FILE
\r
111 static void WriteToLog(const char *data)
\r
116 WideCharToMultiByte(CP_THREAD_ACP, 0, g.m_moduleName, -1, buf, NUMBER_OF(buf), NULL, NULL);
\r
119 SetFilePointer(g.m_logFile, 0, NULL, FILE_END);
\r
120 WriteFile(g.m_logFile, buf, strlen(buf), &count, NULL);
\r
121 FlushFileBuffers(g.m_logFile);
\r
123 #else // !HOOK_LOG_TO_FILE
\r
124 #define WriteToLog(data)
\r
125 #endif // !HOOK_LOG_TO_FILE
\r
127 bool initialize(bool i_isYamy)
\r
130 _TCHAR path[GANA_MAX_PATH];
\r
131 GetModuleFileName(NULL, path, GANA_MAX_PATH);
\r
132 _tsplitpath_s(path, NULL, 0, NULL, 0, g.m_moduleName, GANA_MAX_PATH, NULL, 0);
\r
133 if (_tcsnicmp(g.m_moduleName, _T("Dbgview"), sizeof(_T("Dbgview"))/sizeof(_TCHAR)) != 0 &&
\r
134 _tcsnicmp(g.m_moduleName, _T("windbg"), sizeof(_T("windbg"))/sizeof(_TCHAR)) != 0) {
\r
135 g.m_isLogging = true;
\r
138 #ifdef HOOK_LOG_TO_FILE
\r
139 _TCHAR logFileName[GANA_MAX_PATH];
\r
140 GetEnvironmentVariable(_T("USERPROFILE"), logFileName, NUMBER_OF(logFileName));
\r
141 _tcsncat(logFileName, _T("\\AppData\\LocalLow\\yamydll.txt"), _tcslen(_T("\\AppData\\LocalLow\\yamydll.log")));
\r
142 g.m_logFile = CreateFile(logFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
\r
143 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
\r
144 #endif // HOOK_LOG_TO_FILE
\r
145 WriteToLog("try to open mailslot\r\n");
\r
147 CreateFile(NOTIFY_MAILSLOT_NAME, GENERIC_WRITE,
\r
148 FILE_SHARE_READ | FILE_SHARE_WRITE,
\r
149 (SECURITY_ATTRIBUTES *)NULL, OPEN_EXISTING,
\r
150 FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
\r
151 if (g.m_hMailslot == INVALID_HANDLE_VALUE) {
\r
152 HOOK_RPT2("MAYU: %S create mailslot failed(0x%08x)\r\n", g.m_moduleName, GetLastError());
\r
153 WriteToLog("open mailslot NG\r\n");
\r
155 HOOK_RPT1("MAYU: %S create mailslot successed\r\n", g.m_moduleName);
\r
156 WriteToLog("open mailslot OK\r\n");
\r
158 if (!mapHookData(i_isYamy))
\r
160 _tsetlocale(LC_ALL, _T(""));
\r
161 g.m_WM_MAYU_MESSAGE =
\r
162 RegisterWindowMessage(addSessionId(WM_MAYU_MESSAGE_NAME).c_str());
\r
163 g.m_hwndTaskTray = g_hookData->m_hwndTaskTray;
\r
165 NotifyThreadAttach ntd;
\r
166 ntd.m_type = Notify::Type_threadAttach;
\r
167 ntd.m_threadId = GetCurrentThreadId();
\r
168 notify(&ntd, sizeof(ntd));
\r
170 g.m_isInitialized = true;
\r
175 BOOL WINAPI DllMain(HINSTANCE i_hInstDLL, DWORD i_fdwReason,
\r
176 LPVOID /* i_lpvReserved */)
\r
178 switch (i_fdwReason) {
\r
179 case DLL_PROCESS_ATTACH: {
\r
181 g.m_isLogging = false;
\r
183 g.m_isInitialized = false;
\r
184 g.m_hInstDLL = i_hInstDLL;
\r
187 case DLL_THREAD_ATTACH:
\r
189 case DLL_PROCESS_DETACH:
\r
190 notifyThreadDetach();
\r
192 if (g.m_hMailslot != INVALID_HANDLE_VALUE) {
\r
193 CloseHandle(g.m_hMailslot);
\r
194 g.m_hMailslot = INVALID_HANDLE_VALUE;
\r
196 #ifdef HOOK_LOG_TO_FILE
\r
197 if (g.m_logFile != INVALID_HANDLE_VALUE) {
\r
198 CloseHandle(g.m_logFile);
\r
199 g.m_logFile = INVALID_HANDLE_VALUE;
\r
201 #endif // HOOK_LOG_TO_FILE
\r
203 case DLL_THREAD_DETACH:
\r
204 notifyThreadDetach();
\r
214 static bool mapHookData(bool i_isYamy)
\r
216 DWORD access = FILE_MAP_READ;
\r
219 access |= FILE_MAP_WRITE;
\r
220 g.m_hHookData = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(HookData), addSessionId(HOOK_DATA_NAME).c_str());
\r
221 g.m_hHookDataArch = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(HookDataArch), addSessionId(HOOK_DATA_NAME_ARCH).c_str());
\r
223 g.m_hHookData = OpenFileMapping(access, FALSE, addSessionId(HOOK_DATA_NAME).c_str());
\r
224 g.m_hHookDataArch = OpenFileMapping(access, FALSE, addSessionId(HOOK_DATA_NAME_ARCH).c_str());
\r
227 if (g.m_hHookData == NULL || g.m_hHookDataArch == NULL) {
\r
232 g_hookData = (HookData *)MapViewOfFile(g.m_hHookData, access, 0, 0, sizeof(HookData));
\r
233 s_hookDataArch = (HookDataArch *)MapViewOfFile(g.m_hHookDataArch, access, 0, 0, sizeof(HookDataArch));
\r
234 if (g_hookData == NULL || s_hookDataArch == NULL) {
\r
243 /// unmap hook data
\r
244 static void unmapHookData()
\r
247 UnmapViewOfFile(g_hookData);
\r
250 CloseHandle(g.m_hHookData);
\r
251 g.m_hHookData = NULL;
\r
252 if (s_hookDataArch)
\r
253 UnmapViewOfFile(s_hookDataArch);
\r
254 s_hookDataArch = NULL;
\r
255 if (g.m_hHookDataArch)
\r
256 CloseHandle(g.m_hHookDataArch);
\r
257 g.m_hHookDataArch = NULL;
\r
262 bool notify(void *i_data, size_t i_dataSize)
\r
272 if (g.m_hMailslot != INVALID_HANDLE_VALUE) {
\r
274 ret = WriteFile(g.m_hMailslot, i_data, i_dataSize, &len, NULL);
\r
277 HOOK_RPT2("MAYU: %S WriteFile to mailslot failed(0x%08x)\r\n", g.m_moduleName, GetLastError());
\r
279 HOOK_RPT1("MAYU: %S WriteFile to mailslot successed\r\n", g.m_moduleName);
\r
283 cd.dwData = reinterpret_cast<Notify *>(i_data)->m_type;
\r
284 cd.cbData = i_dataSize;
\r
285 cd.lpData = i_data;
\r
286 if (g.m_hwndTaskTray == 0 || cd.dwData == Notify::Type_threadDetach)
\r
288 if (!SendMessageTimeout(reinterpret_cast<HWND>(g.m_hwndTaskTray),
\r
289 WM_COPYDATA, NULL, reinterpret_cast<LPARAM>(&cd),
\r
290 SMTO_ABORTIFHUNG | SMTO_NORMAL, 5000, &result)) {
\r
291 _RPT0(_CRT_WARN, "MAYU: SendMessageTimeout() timeouted\r\n");
\r
299 /// get class name and title name
\r
300 static void getClassNameTitleName(HWND i_hwnd, bool i_isInMenu,
\r
301 tstringi *o_className,
\r
302 tstring *o_titleName)
\r
304 tstringi &className = *o_className;
\r
305 tstring &titleName = *o_titleName;
\r
307 bool isTheFirstTime = true;
\r
310 className = titleName = _T("MENU");
\r
311 isTheFirstTime = false;
\r
315 _TCHAR buf[MAX(GANA_MAX_PATH, GANA_MAX_ATOM_LENGTH)];
\r
319 GetClassName(i_hwnd, buf, NUMBER_OF(buf));
\r
321 GetModuleFileName(GetModuleHandle(NULL), buf, NUMBER_OF(buf));
\r
322 buf[NUMBER_OF(buf) - 1] = _T('\0');
\r
323 if (isTheFirstTime)
\r
326 className = tstringi(buf) + _T(":") + className;
\r
330 GetWindowText(i_hwnd, buf, NUMBER_OF(buf));
\r
331 buf[NUMBER_OF(buf) - 1] = _T('\0');
\r
332 for (_TCHAR *b = buf; *b; ++ b)
\r
333 if (_istlead(*b) && b[1])
\r
335 else if (_istcntrl(*b))
\r
338 if (isTheFirstTime)
\r
341 titleName = tstring(buf) + _T(":") + titleName;
\r
343 // next loop or exit
\r
346 i_hwnd = GetParent(i_hwnd);
\r
347 isTheFirstTime = false;
\r
353 static void updateShow(HWND i_hwnd, NotifyShow::Show i_show)
\r
355 bool isMDI = false;
\r
361 LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
\r
363 LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
\r
365 if (!(style & WS_MAXIMIZEBOX) && !(style & WS_MAXIMIZEBOX))
\r
366 return; // ignore window that has neither maximize or minimize button
\r
368 if (style & WS_CHILD) {
\r
370 LONG_PTR exStyle = GetWindowLongPtr(i_hwnd, GWL_EXSTYLE);
\r
372 LONG exStyle = GetWindowLong(i_hwnd, GWL_EXSTYLE);
\r
374 if (exStyle & WS_EX_MDICHILD) {
\r
377 return; // ignore non-MDI child window case
\r
380 notifyShow(i_show, isMDI);
\r
384 /// notify WM_Targetted
\r
385 static void notifyName(HWND i_hwnd, Notify::Type i_type = Notify::Type_name)
\r
387 tstringi className;
\r
389 getClassNameTitleName(i_hwnd, g.m_isInMenu, &className, &titleName);
\r
391 NotifySetFocus *nfc = new NotifySetFocus;
\r
392 nfc->m_type = i_type;
\r
393 nfc->m_threadId = GetCurrentThreadId();
\r
394 nfc->m_hwnd = reinterpret_cast<DWORD>(i_hwnd);
\r
395 tcslcpy(nfc->m_className, className.c_str(), NUMBER_OF(nfc->m_className));
\r
396 tcslcpy(nfc->m_titleName, titleName.c_str(), NUMBER_OF(nfc->m_titleName));
\r
398 notify(nfc, sizeof(*nfc));
\r
403 /// notify WM_SETFOCUS
\r
404 static void notifySetFocus(bool i_doesForce = false)
\r
406 HWND hwnd = GetFocus();
\r
407 if (i_doesForce || hwnd != g.m_hwndFocus) {
\r
408 g.m_hwndFocus = hwnd;
\r
409 notifyName(hwnd, Notify::Type_setFocus);
\r
415 static void notifySync()
\r
418 n.m_type = Notify::Type_sync;
\r
419 notify(&n, sizeof(n));
\r
423 /// notify DLL_THREAD_DETACH
\r
424 static void notifyThreadDetach()
\r
426 NotifyThreadDetach ntd;
\r
427 ntd.m_type = Notify::Type_threadDetach;
\r
428 ntd.m_threadId = GetCurrentThreadId();
\r
429 notify(&ntd, sizeof(ntd));
\r
433 /// notify WM_COMMAND, WM_SYSCOMMAND
\r
434 static void notifyCommand(
\r
435 HWND i_hwnd, UINT i_message, WPARAM i_wParam, LPARAM i_lParam)
\r
437 if (g_hookData->m_doesNotifyCommand) {
\r
439 NotifyCommand64 ntc;
\r
440 ntc.m_type = Notify::Type_command64;
\r
442 NotifyCommand32 ntc;
\r
443 ntc.m_type = Notify::Type_command32;
\r
445 ntc.m_hwnd = i_hwnd;
\r
446 ntc.m_message = i_message;
\r
447 ntc.m_wParam = i_wParam;
\r
448 ntc.m_lParam = i_lParam;
\r
449 notify(&ntc, sizeof(ntc));
\r
454 /// notify show of current window
\r
455 static void notifyShow(NotifyShow::Show i_show, bool i_isMDI)
\r
458 ns.m_type = Notify::Type_show;
\r
459 ns.m_show = i_show;
\r
460 ns.m_isMDI = i_isMDI;
\r
461 notify(&ns, sizeof(ns));
\r
466 static void notifyLog(_TCHAR *i_msg)
\r
469 nl.m_type = Notify::Type_log;
\r
470 tcslcpy(nl.m_msg, i_msg, NUMBER_OF(nl.m_msg));
\r
471 notify(&nl, sizeof(nl));
\r
476 static void funcRecenter(HWND i_hwnd)
\r
478 _TCHAR buf[MAX(GANA_MAX_PATH, GANA_MAX_ATOM_LENGTH)];
\r
479 GetClassName(i_hwnd, buf, NUMBER_OF(buf));
\r
481 if (_tcsicmp(buf, _T("Edit")) == 0)
\r
483 else if (_tcsnicmp(buf, _T("RichEdit"), 8) == 0)
\r
486 return; // this function only works for Edit control
\r
489 LONG_PTR style = GetWindowLongPtr(i_hwnd, GWL_STYLE);
\r
491 LONG style = GetWindowLong(i_hwnd, GWL_STYLE);
\r
493 if (!(style & ES_MULTILINE))
\r
494 return; // this function only works for multi line Edit control
\r
497 GetClientRect(i_hwnd, &rc);
\r
498 POINTL p = { (rc.right + rc.left) / 2, (rc.top + rc.bottom) / 2 };
\r
501 line = SendMessage(i_hwnd, EM_CHARFROMPOS, 0, MAKELPARAM(p.x, p.y));
\r
502 line = HIWORD(line);
\r
504 int ci = SendMessage(i_hwnd, EM_CHARFROMPOS, 0, (LPARAM)&p);
\r
505 line = SendMessage(i_hwnd, EM_EXLINEFROMCHAR, 0, ci);
\r
507 int caretLine = SendMessage(i_hwnd, EM_LINEFROMCHAR, -1, 0);
\r
508 SendMessage(i_hwnd, EM_LINESCROLL, 0, caretLine - line);
\r
513 static void funcSetImeStatus(HWND i_hwnd, int i_status)
\r
517 hIMC = ImmGetContext(i_hwnd);
\r
518 if (hIMC == INVALID_HANDLE_VALUE)
\r
522 i_status = !ImmGetOpenStatus(hIMC);
\r
524 ImmSetOpenStatus(hIMC, i_status);
\r
525 ImmReleaseContext(i_hwnd, hIMC);
\r
530 static void funcSetImeString(HWND i_hwnd, int i_size)
\r
532 _TCHAR *buf = new _TCHAR(i_size);
\r
534 _TCHAR ImeDesc[GANA_MAX_ATOM_LENGTH];
\r
539 = CreateFile(addSessionId(HOOK_PIPE_NAME).c_str(), GENERIC_READ,
\r
540 FILE_SHARE_READ, (SECURITY_ATTRIBUTES *)NULL,
\r
541 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL);
\r
542 error = ReadFile(hPipe, buf, i_size, &len, NULL);
\r
543 CloseHandle(hPipe);
\r
545 ImeDescLen = ImmGetDescription(GetKeyboardLayout(0),
\r
546 ImeDesc, sizeof(ImeDesc));
\r
547 if (_tcsncmp(ImeDesc, _T("SKKIME"), ImeDescLen) > 0)
\r
548 denom = sizeof(_TCHAR);
\r
550 HIMC hIMC = ImmGetContext(i_hwnd);
\r
551 if (hIMC == INVALID_HANDLE_VALUE)
\r
554 int status = ImmGetOpenStatus(hIMC);
\r
555 ImmSetCompositionString(hIMC, SCS_SETSTR, buf, len / denom, NULL, 0);
\r
557 ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_COMPLETE, 0);
\r
559 ImmSetOpenStatus(hIMC, status);
\r
560 ImmReleaseContext(i_hwnd, hIMC);
\r
563 /// notify lock state
\r
565 void notifyLockState(int i_cause)
\r
568 n.m_type = Notify::Type_lockState;
\r
569 n.m_isNumLockToggled = !!(GetKeyState(VK_NUMLOCK) & 1);
\r
570 n.m_isCapsLockToggled = !!(GetKeyState(VK_CAPITAL) & 1);
\r
571 n.m_isScrollLockToggled = !!(GetKeyState(VK_SCROLL) & 1);
\r
572 n.m_isKanaLockToggled = !!(GetKeyState(VK_KANA) & 1);
\r
573 n.m_isImeLockToggled = g.m_isImeLock;
\r
574 n.m_isImeCompToggled = g.m_isImeCompositioning;
\r
575 n.m_debugParam = i_cause;
\r
576 notify(&n, sizeof(n));
\r
579 DllExport void notifyLockState()
\r
581 notifyLockState(9);
\r
585 /// hook of GetMessage
\r
586 LRESULT CALLBACK getMessageProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
\r
588 if (!g.m_isInitialized)
\r
594 MSG &msg = (*(MSG *)i_lParam);
\r
596 if (i_wParam != PM_REMOVE)
\r
599 switch (msg.message) {
\r
601 case WM_SYSCOMMAND:
\r
602 notifyCommand(msg.hwnd, msg.message, msg.wParam, msg.lParam);
\r
606 case WM_SYSKEYDOWN:
\r
607 case WM_SYSKEYUP: {
\r
608 if (HIMC hIMC = ImmGetContext(msg.hwnd)) {
\r
609 bool prev = g.m_isImeLock;
\r
610 g.m_isImeLock = !!ImmGetOpenStatus(hIMC);
\r
611 ImmReleaseContext(msg.hwnd, hIMC);
\r
612 if (prev != g.m_isImeLock) {
\r
613 notifyLockState(1);
\r
616 int nVirtKey = (int)msg.wParam;
\r
617 // int repeatCount = (msg.lParam & 0xffff);
\r
618 BYTE scanCode = (BYTE)((msg.lParam >> 16) & 0xff);
\r
619 bool isExtended = !!(msg.lParam & (1 << 24));
\r
620 // bool isAltDown = !!(msg.lParam & (1 << 29));
\r
621 // bool isKeyup = !!(msg.lParam & (1 << 31));
\r
623 if (nVirtKey == VK_CAPITAL ||
\r
624 nVirtKey == VK_NUMLOCK ||
\r
625 nVirtKey == VK_KANA ||
\r
626 nVirtKey == VK_SCROLL)
\r
627 notifyLockState(2);
\r
628 else if (scanCode == g_hookData->m_syncKey &&
\r
629 isExtended == g_hookData->m_syncKeyIsExtended)
\r
633 case WM_IME_STARTCOMPOSITION:
\r
634 g.m_isImeCompositioning = true;
\r
635 notifyLockState(3);
\r
637 case WM_IME_ENDCOMPOSITION:
\r
638 g.m_isImeCompositioning = false;
\r
639 notifyLockState(4);
\r
642 if (i_wParam == PM_REMOVE && msg.message == g.m_WM_MAYU_MESSAGE) {
\r
643 switch (msg.wParam) {
\r
644 case MayuMessage_notifyName:
\r
645 notifyName(msg.hwnd);
\r
647 case MayuMessage_funcRecenter:
\r
648 funcRecenter(msg.hwnd);
\r
650 case MayuMessage_funcSetImeStatus:
\r
651 funcSetImeStatus(msg.hwnd, msg.lParam);
\r
653 case MayuMessage_funcSetImeString:
\r
654 funcSetImeString(msg.hwnd, msg.lParam);
\r
661 return CallNextHookEx(s_hookDataArch->m_hHookGetMessage,
\r
662 i_nCode, i_wParam, i_lParam);
\r
666 /// hook of SendMessage
\r
667 LRESULT CALLBACK callWndProc(int i_nCode, WPARAM i_wParam, LPARAM i_lParam)
\r
669 if (!g.m_isInitialized)
\r
675 CWPSTRUCT &cwps = *(CWPSTRUCT *)i_lParam;
\r
677 if (0 <= i_nCode) {
\r
678 switch (cwps.message) {
\r
679 case WM_ACTIVATEAPP:
\r
680 case WM_NCACTIVATE:
\r
684 case WM_SYSCOMMAND:
\r
685 switch (cwps.wParam) {
\r
688 updateShow(cwps.hwnd, NotifyShow::Show_Maximized);
\r
692 updateShow(cwps.hwnd, NotifyShow::Show_Minimized);
\r
696 updateShow(cwps.hwnd, NotifyShow::Show_Normal);
\r
701 /* through below */
\r
703 notifyCommand(cwps.hwnd, cwps.message, cwps.wParam, cwps.lParam);
\r
706 switch (cwps.wParam) {
\r
707 case SIZE_MAXIMIZED:
\r
708 updateShow(cwps.hwnd, NotifyShow::Show_Maximized);
\r
710 case SIZE_MINIMIZED:
\r
711 updateShow(cwps.hwnd, NotifyShow::Show_Minimized);
\r
713 case SIZE_RESTORED:
\r
714 updateShow(cwps.hwnd, NotifyShow::Show_Normal);
\r
720 case WM_MOUSEACTIVATE:
\r
724 if (LOWORD(cwps.wParam) != WA_INACTIVE) {
\r
726 if (HIWORD(cwps.wParam)) { // check minimized flag
\r
727 // minimized flag on
\r
728 notifyShow(NotifyShow::Show_Minimized, false);
\r
729 //notifyShow(NotifyShow::Show_Normal, true);
\r
733 case WM_ENTERMENULOOP:
\r
734 g.m_isInMenu = true;
\r
735 notifySetFocus(true);
\r
737 case WM_EXITMENULOOP:
\r
738 g.m_isInMenu = false;
\r
739 notifySetFocus(true);
\r
742 g.m_isInMenu = false;
\r
744 if (g_hookData->m_correctKanaLockHandling) {
\r
745 if (HIMC hIMC = ImmGetContext(cwps.hwnd)) {
\r
746 bool status = !!ImmGetOpenStatus(hIMC);
\r
747 // this code set the VK_KANA state correctly.
\r
748 ImmSetOpenStatus(hIMC, !status);
\r
749 ImmSetOpenStatus(hIMC, status);
\r
750 ImmReleaseContext(cwps.hwnd, hIMC);
\r
754 notifyLockState(5);
\r
756 case WM_IME_STARTCOMPOSITION:
\r
757 g.m_isImeCompositioning = true;
\r
758 notifyLockState(6);
\r
760 case WM_IME_ENDCOMPOSITION:
\r
761 g.m_isImeCompositioning = false;
\r
762 notifyLockState(7);
\r
764 case WM_IME_NOTIFY:
\r
765 if (cwps.wParam == IMN_SETOPENSTATUS)
\r
766 if (HIMC hIMC = ImmGetContext(cwps.hwnd)) {
\r
767 g.m_isImeLock = !!ImmGetOpenStatus(hIMC);
\r
768 ImmReleaseContext(cwps.hwnd, hIMC);
\r
769 notifyLockState(8);
\r
774 return CallNextHookEx(s_hookDataArch->m_hHookCallWndProc, i_nCode,
\r
775 i_wParam, i_lParam);
\r
779 static LRESULT CALLBACK lowLevelMouseProc(int nCode, WPARAM wParam, LPARAM lParam)
\r
781 if (!g.m_isInitialized)
\r
784 if (!g_hookData || nCode < 0)
\r
787 if (g.m_mouseDetour && g.m_engine) {
\r
788 unsigned int result;
\r
789 result = g.m_mouseDetour(g.m_engine, wParam, lParam);
\r
796 return CallNextHookEx(g.m_hHookMouseProc,
\r
797 nCode, wParam, lParam);
\r
801 static LRESULT CALLBACK lowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
\r
803 KBDLLHOOKSTRUCT *pKbll = (KBDLLHOOKSTRUCT*)lParam;
\r
805 if (!g.m_isInitialized)
\r
808 if (!g_hookData || nCode < 0)
\r
811 if (g.m_keyboardDetour && g.m_engine) {
\r
812 unsigned int result;
\r
813 result = g.m_keyboardDetour(g.m_engine, wParam, lParam);
\r
819 return CallNextHookEx(g.m_hHookKeyboardProc,
\r
820 nCode, wParam, lParam);
\r
824 /// install message hook
\r
825 DllExport int installMessageHook(DWORD i_hwndTaskTray)
\r
827 if (!g.m_isInitialized)
\r
830 if (i_hwndTaskTray) {
\r
831 g_hookData->m_hwndTaskTray = i_hwndTaskTray;
\r
833 g.m_hwndTaskTray = g_hookData->m_hwndTaskTray;
\r
834 s_hookDataArch->m_hHookGetMessage =
\r
835 SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)getMessageProc,
\r
837 s_hookDataArch->m_hHookCallWndProc =
\r
838 SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)callWndProc, g.m_hInstDLL, 0);
\r
843 /// uninstall message hook
\r
844 DllExport int uninstallMessageHook()
\r
846 if (s_hookDataArch->m_hHookGetMessage)
\r
847 UnhookWindowsHookEx(s_hookDataArch->m_hHookGetMessage);
\r
848 s_hookDataArch->m_hHookGetMessage = NULL;
\r
849 if (s_hookDataArch->m_hHookCallWndProc)
\r
850 UnhookWindowsHookEx(s_hookDataArch->m_hHookCallWndProc);
\r
851 s_hookDataArch->m_hHookCallWndProc = NULL;
\r
852 g.m_hwndTaskTray = 0;
\r
857 /// install keyboard hook
\r
858 DllExport int installKeyboardHook(INPUT_DETOUR i_keyboardDetour, Engine *i_engine, bool i_install)
\r
861 if (!g.m_isInitialized)
\r
864 g.m_keyboardDetour = i_keyboardDetour;
\r
865 g.m_engine = i_engine;
\r
866 g.m_hHookKeyboardProc =
\r
867 SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)lowLevelKeyboardProc,
\r
870 if (g.m_hHookKeyboardProc)
\r
871 UnhookWindowsHookEx(g.m_hHookKeyboardProc);
\r
872 g.m_hHookKeyboardProc = NULL;
\r
878 /// install mouse hook
\r
879 DllExport int installMouseHook(INPUT_DETOUR i_mouseDetour, Engine *i_engine, bool i_install)
\r
882 if (!g.m_isInitialized)
\r
885 g.m_mouseDetour = i_mouseDetour;
\r
886 g.m_engine = i_engine;
\r
887 g_hookData->m_mouseHookType = MouseHookType_None;
\r
888 g.m_hHookMouseProc =
\r
889 SetWindowsHookEx(WH_MOUSE_LL, (HOOKPROC)lowLevelMouseProc,
\r
892 if (g.m_hHookMouseProc)
\r
893 UnhookWindowsHookEx(g.m_hHookMouseProc);
\r
894 g.m_hHookMouseProc = NULL;
\r