1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
5 #define APSTUDIO_INVOKED
\r
8 #include "compiler_specific_func.h"
\r
9 #include "dlginvestigate.h"
\r
11 #include "dlgsetting.h"
\r
12 #include "dlgversion.h"
\r
14 #include "errormessage.h"
\r
16 #include "function.h"
\r
19 #include "mayuipc.h"
\r
21 #include "msgstream.h"
\r
22 #include "multithread.h"
\r
23 #include "registry.h"
\r
24 #include "setting.h"
\r
26 #include "windowstool.h"
\r
27 #include "fixscancodemap.h"
\r
28 #include "vk2tchar.h"
\r
29 #include <process.h>
\r
31 #include <commctrl.h>
\r
32 #include <wtsapi32.h>
\r
37 #define ID_MENUITEM_reloadBegin _APS_NEXT_COMMAND_VALUE
\r
40 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
47 HWND m_hwndTaskTray; /// tasktray window
\r
48 HWND m_hwndLog; /// log dialog
\r
49 HWND m_hwndInvestigate; /// investigate dialog
\r
50 HWND m_hwndVersion; /// version dialog
\r
52 UINT m_WM_TaskbarRestart; /** window message sent when
\r
54 UINT m_WM_MayuIPC; /** IPC message sent from
\r
55 other applications */
\r
56 NOTIFYICONDATA m_ni; /// taskbar icon data
\r
57 HICON m_tasktrayIcon[2]; /// taskbar icon
\r
58 bool m_canUseTasktrayBaloon; ///
\r
60 tomsgstream m_log; /** log stream (output to log
\r
63 tofstream m_logFile;
\r
64 #endif // LOG_TO_FILE
\r
66 HMENU m_hMenuTaskTray; /// tasktray menu
\r
68 PROCESS_INFORMATION m_pi;
\r
71 HANDLE m_hNotifyMailslot; /// mailslot to receive notify
\r
72 HANDLE m_hNotifyEvent; /// event on receive notify
\r
73 OVERLAPPED m_olNotify; ///
\r
74 BYTE m_notifyBuf[NOTIFY_MESSAGE_SIZE];
\r
75 #endif // USE_MAILSLOT
\r
76 bool m_isConsoleConnected;
\r
77 int m_escapeNlsKeys;
\r
78 FixScancodeMap m_fixScancodeMap;
\r
80 Setting *m_setting; /// current setting
\r
81 bool m_isSettingDialogOpened; /// is setting dialog opened ?
\r
83 Engine m_engine; /// engine
\r
85 bool m_usingSN; /// using WTSRegisterSessionNotification() ?
\r
86 time_t m_startTime; /// mayu started at ...
\r
89 WM_APP_taskTrayNotify = WM_APP + 101, ///
\r
90 WM_APP_msgStreamNotify = WM_APP + 102, ///
\r
91 ID_TaskTrayIcon = 1, ///
\r
96 static VOID CALLBACK mailslotProc(DWORD i_code, DWORD i_len, LPOVERLAPPED i_ol) {
\r
99 if (i_code == ERROR_SUCCESS) {
\r
100 pThis = reinterpret_cast<Mayu*>(CONTAINING_RECORD(i_ol, Mayu, m_olNotify));
\r
101 pThis->mailslotHandler(i_code, i_len);
\r
106 BOOL mailslotHandler(DWORD i_code, DWORD i_len) {
\r
112 cd.dwData = reinterpret_cast<Notify *>(m_notifyBuf)->m_type;
\r
114 cd.lpData = m_notifyBuf;
\r
115 notifyHandler(&cd);
\r
118 memset(m_notifyBuf, 0, sizeof(m_notifyBuf));
\r
119 result = ReadFileEx(m_hNotifyMailslot, m_notifyBuf, sizeof(m_notifyBuf),
\r
120 &m_olNotify, Mayu::mailslotProc);
\r
123 #endif // USE_MAILSLOT
\r
125 /// register class for tasktray
\r
126 ATOM Register_tasktray() {
\r
129 wc.lpfnWndProc = tasktray_wndProc;
\r
131 wc.cbWndExtra = sizeof(Mayu *);
\r
132 wc.hInstance = g_hInst;
\r
135 wc.hbrBackground = NULL;
\r
136 wc.lpszMenuName = NULL;
\r
137 wc.lpszClassName = _T("mayuTasktray");
\r
138 return RegisterClass(&wc);
\r
142 BOOL notifyHandler(COPYDATASTRUCT *cd) {
\r
143 switch (cd->dwData) {
\r
144 case Notify::Type_setFocus:
\r
145 case Notify::Type_name: {
\r
146 NotifySetFocus *n = (NotifySetFocus *)cd->lpData;
\r
147 n->m_className[NUMBER_OF(n->m_className) - 1] = _T('\0');
\r
148 n->m_titleName[NUMBER_OF(n->m_titleName) - 1] = _T('\0');
\r
150 if (n->m_type == Notify::Type_setFocus)
\r
151 m_engine.setFocus(reinterpret_cast<HWND>(n->m_hwnd), n->m_threadId,
\r
152 n->m_className, n->m_titleName, false);
\r
155 Acquire a(&m_log, 1);
\r
156 m_log << _T("HWND:\t") << std::hex
\r
158 << std::dec << std::endl;
\r
159 m_log << _T("THREADID:") << static_cast<int>(n->m_threadId)
\r
162 Acquire a(&m_log, (n->m_type == Notify::Type_name) ? 0 : 1);
\r
163 m_log << _T("CLASS:\t") << n->m_className << std::endl;
\r
164 m_log << _T("TITLE:\t") << n->m_titleName << std::endl;
\r
167 HWND hwnd = getToplevelWindow(reinterpret_cast<HWND>(n->m_hwnd), &isMDI);
\r
170 getChildWindowRect(hwnd, &rc);
\r
171 m_log << _T("MDI Window Position/Size: (")
\r
172 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
173 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
175 hwnd = getToplevelWindow(reinterpret_cast<HWND>(n->m_hwnd), NULL);
\r
178 GetWindowRect(hwnd, &rc);
\r
179 m_log << _T("Toplevel Window Position/Size: (")
\r
180 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
181 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
184 SystemParametersInfo(SPI_GETWORKAREA, 0, (void *)&rc, FALSE);
\r
185 m_log << _T("Desktop Window Position/Size: (")
\r
186 << rc.left << _T(", ") << rc.top << _T(") / (")
\r
187 << rcWidth(&rc) << _T("x") << rcHeight(&rc) << _T(")")
\r
190 m_log << std::endl;
\r
194 case Notify::Type_lockState: {
\r
195 NotifyLockState *n = (NotifyLockState *)cd->lpData;
\r
196 m_engine.setLockState(n->m_isNumLockToggled,
\r
197 n->m_isCapsLockToggled,
\r
198 n->m_isScrollLockToggled,
\r
199 n->m_isKanaLockToggled,
\r
200 n->m_isImeLockToggled,
\r
201 n->m_isImeCompToggled);
\r
203 Acquire a(&m_log, 0);
\r
204 if (n->m_isKanaLockToggled) {
\r
205 m_log << _T("Notify::Type_lockState Kana on : ");
\r
207 m_log << _T("Notify::Type_lockState Kana off : ");
\r
209 m_log << n->m_debugParam << ", "
\r
210 << g_hookData->m_correctKanaLockHandling << std::endl;
\r
215 case Notify::Type_sync: {
\r
216 m_engine.syncNotify();
\r
220 case Notify::Type_threadDetach: {
\r
221 NotifyThreadDetach *n = (NotifyThreadDetach *)cd->lpData;
\r
222 m_engine.threadDetachNotify(n->m_threadId);
\r
226 case Notify::Type_command: {
\r
227 NotifyCommand *n = (NotifyCommand *)cd->lpData;
\r
228 m_engine.commandNotify(n->m_hwnd, n->m_message,
\r
229 n->m_wParam, n->m_lParam);
\r
233 case Notify::Type_show: {
\r
234 NotifyShow *n = (NotifyShow *)cd->lpData;
\r
235 switch (n->m_show) {
\r
236 case NotifyShow::Show_Maximized:
\r
237 m_engine.setShow(true, false, n->m_isMDI);
\r
239 case NotifyShow::Show_Minimized:
\r
240 m_engine.setShow(false, true, n->m_isMDI);
\r
242 case NotifyShow::Show_Normal:
\r
244 m_engine.setShow(false, false, n->m_isMDI);
\r
250 case Notify::Type_log: {
\r
251 Acquire a(&m_log, 1);
\r
252 NotifyLog *n = (NotifyLog *)cd->lpData;
\r
253 m_log << _T("hook log: ") << n->m_msg << std::endl;
\r
260 /// window procedure for tasktray
\r
261 static LRESULT CALLBACK
\r
262 tasktray_wndProc(HWND i_hwnd, UINT i_message,
\r
263 WPARAM i_wParam, LPARAM i_lParam) {
\r
265 Mayu *This = reinterpret_cast<Mayu *>(GetWindowLongPtr(i_hwnd, 0));
\r
267 Mayu *This = reinterpret_cast<Mayu *>(GetWindowLong(i_hwnd, 0));
\r
271 switch (i_message) {
\r
273 This = reinterpret_cast<Mayu *>(
\r
274 reinterpret_cast<CREATESTRUCT *>(i_lParam)->lpCreateParams);
\r
275 if (This->m_escapeNlsKeys) {
\r
277 err = This->m_fixScancodeMap.fix();
\r
279 This->errorDialogWithCode(IDS_escapeNlsKeysFailed, err);
\r
283 SetWindowLongPtr(i_hwnd, 0, (LONG_PTR)This);
\r
285 SetWindowLong(i_hwnd, 0, (long)This);
\r
290 switch (i_message) {
\r
291 case WM_COPYDATA: {
\r
292 COPYDATASTRUCT *cd;
\r
293 cd = reinterpret_cast<COPYDATASTRUCT *>(i_lParam);
\r
294 return This->notifyHandler(cd);
\r
296 case WM_QUERYENDSESSION:
\r
297 This->m_engine.prepairQuit();
\r
298 PostQuitMessage(0);
\r
301 #ifndef WM_WTSSESSION_CHANGE // WinUser.h
\r
302 # define WM_WTSSESSION_CHANGE 0x02B1
\r
304 case WM_WTSSESSION_CHANGE: {
\r
305 const char *m = "";
\r
306 switch (i_wParam) {
\r
307 #ifndef WTS_CONSOLE_CONNECT // WinUser.h
\r
308 # define WTS_CONSOLE_CONNECT 0x1
\r
309 # define WTS_CONSOLE_DISCONNECT 0x2
\r
310 # define WTS_REMOTE_CONNECT 0x3
\r
311 # define WTS_REMOTE_DISCONNECT 0x4
\r
312 # define WTS_SESSION_LOGON 0x5
\r
313 # define WTS_SESSION_LOGOFF 0x6
\r
314 # define WTS_SESSION_LOCK 0x7
\r
315 # define WTS_SESSION_UNLOCK 0x8
\r
318 order of WTS_* messages:
\r
319 <case1>screen lock -> screen unlock
\r
320 <case2>change of user -> logon by same user
\r
321 (1)WTS_SESSION_LOCK ... restore Scancode Map
\r
322 (2)WTS_SESSION_UNLOCK ... re-fix Scancode Map
\r
324 <case3>change of user -> logon by another user -> change of user -> logon by previous user
\r
325 (1)WTS_SESSION_LOCK ... restore Scancode Map
\r
326 (2)WTS_CONSOLE_CONNECT ... mark disconnection(m_isConsoleConnected=false)
\r
327 (3)WTS_SESSION_UNLOCK ... (re-fix Scancode Map is not effective here!)
\r
328 (4)WTS_CONSOLE_DISCONNECT ... re-fix Scancode Map
\r
330 case WTS_CONSOLE_CONNECT:
\r
331 if (This->m_isConsoleConnected == false) {
\r
332 This->m_isConsoleConnected = true;
\r
333 if (This->m_escapeNlsKeys) {
\r
336 ret = This->m_fixScancodeMap.fix();
\r
338 This->m_log << _T("escape NLS keys failed: ") << ret << std::endl;
\r
342 m = "WTS_CONSOLE_CONNECT";
\r
344 case WTS_CONSOLE_DISCONNECT:
\r
345 This->m_isConsoleConnected = false;
\r
346 m = "WTS_CONSOLE_DISCONNECT";
\r
348 case WTS_REMOTE_CONNECT:
\r
349 m = "WTS_REMOTE_CONNECT";
\r
351 case WTS_REMOTE_DISCONNECT:
\r
352 m = "WTS_REMOTE_DISCONNECT";
\r
354 case WTS_SESSION_LOGON:
\r
355 m = "WTS_SESSION_LOGON";
\r
357 case WTS_SESSION_LOGOFF:
\r
358 m = "WTS_SESSION_LOGOFF";
\r
360 case WTS_SESSION_LOCK: {
\r
361 if (This->m_escapeNlsKeys) {
\r
364 ret = This->m_fixScancodeMap.restore();
\r
366 This->m_log << _T("restore NLS keys failed: ") << ret << std::endl;
\r
369 m = "WTS_SESSION_LOCK";
\r
372 case WTS_SESSION_UNLOCK: {
\r
373 if (This->m_isConsoleConnected == true) {
\r
374 if (This->m_escapeNlsKeys) {
\r
377 ret = This->m_fixScancodeMap.fix();
\r
379 This->m_log << _T("escape NLS keys failed: ") << ret << std::endl;
\r
383 m = "WTS_SESSION_UNLOCK";
\r
386 //case WTS_SESSION_REMOTE_CONTROL: m = "WTS_SESSION_REMOTE_CONTROL"; break;
\r
388 This->m_log << _T("WM_WTSESSION_CHANGE(")
\r
389 << i_wParam << ", " << i_lParam << "): "
\r
393 case WM_APP_msgStreamNotify: {
\r
394 tomsgstream::StreamBuf *log =
\r
395 reinterpret_cast<tomsgstream::StreamBuf *>(i_lParam);
\r
396 const tstring &str = log->acquireString();
\r
398 This->m_logFile << str << std::flush;
\r
399 #endif // LOG_TO_FILE
\r
400 editInsertTextAtLast(GetDlgItem(This->m_hwndLog, IDC_EDIT_log),
\r
402 log->releaseString();
\r
406 case WM_APP_taskTrayNotify: {
\r
407 if (i_wParam == ID_TaskTrayIcon)
\r
408 switch (i_lParam) {
\r
409 case WM_RBUTTONUP: {
\r
411 CHECK_TRUE( GetCursorPos(&p) );
\r
412 SetForegroundWindow(i_hwnd);
\r
413 HMENU hMenuSub = GetSubMenu(This->m_hMenuTaskTray, 0);
\r
414 if (This->m_engine.getIsEnabled())
\r
415 CheckMenuItem(hMenuSub, ID_MENUITEM_disable,
\r
416 MF_UNCHECKED | MF_BYCOMMAND);
\r
418 CheckMenuItem(hMenuSub, ID_MENUITEM_disable,
\r
419 MF_CHECKED | MF_BYCOMMAND);
\r
420 CHECK_TRUE( SetMenuDefaultItem(hMenuSub,
\r
421 ID_MENUITEM_investigate, FALSE) );
\r
423 // create reload menu
\r
424 HMENU hMenuSubSub = GetSubMenu(hMenuSub, 1);
\r
425 Registry reg(MAYU_REGISTRY_ROOT);
\r
427 reg.read(_T(".mayuIndex"), &mayuIndex, 0);
\r
428 while (DeleteMenu(hMenuSubSub, 0, MF_BYPOSITION))
\r
430 tregex getName(_T("^([^;]*);"));
\r
431 for (int index = 0; ; index ++) {
\r
433 _sntprintf(buf, NUMBER_OF(buf), _T(".mayu%d"), index);
\r
435 if (!reg.read(buf, &dot_mayu))
\r
438 if (boost::regex_search(dot_mayu, what, getName)) {
\r
440 std::memset(&mii, 0, sizeof(mii));
\r
441 mii.cbSize = sizeof(mii);
\r
442 mii.fMask = MIIM_ID | MIIM_STATE | MIIM_TYPE;
\r
443 mii.fType = MFT_STRING;
\r
445 MFS_ENABLED | ((mayuIndex == index) ? MFS_CHECKED : 0);
\r
446 mii.wID = ID_MENUITEM_reloadBegin + index;
\r
447 tstringi name(what.str(1));
\r
448 mii.dwTypeData = const_cast<_TCHAR *>(name.c_str());
\r
449 mii.cch = name.size();
\r
451 InsertMenuItem(hMenuSubSub, index, TRUE, &mii);
\r
456 TrackPopupMenu(hMenuSub, TPM_LEFTALIGN,
\r
457 p.x, p.y, 0, i_hwnd, NULL);
\r
458 // TrackPopupMenu may fail (ERROR_POPUP_ALREADY_ACTIVE)
\r
462 case WM_LBUTTONDBLCLK:
\r
463 SendMessage(i_hwnd, WM_COMMAND,
\r
464 MAKELONG(ID_MENUITEM_investigate, 0), 0);
\r
471 int notify_code = HIWORD(i_wParam);
\r
472 int id = LOWORD(i_wParam);
\r
473 if (notify_code == 0) // menu
\r
476 if (ID_MENUITEM_reloadBegin <= id) {
\r
477 Registry reg(MAYU_REGISTRY_ROOT);
\r
478 reg.write(_T(".mayuIndex"), id - ID_MENUITEM_reloadBegin);
\r
482 case ID_MENUITEM_reload:
\r
485 case ID_MENUITEM_investigate: {
\r
486 ShowWindow(This->m_hwndLog, SW_SHOW);
\r
487 ShowWindow(This->m_hwndInvestigate, SW_SHOW);
\r
490 GetWindowRect(This->m_hwndInvestigate, &rc1);
\r
491 GetWindowRect(This->m_hwndLog, &rc2);
\r
493 MoveWindow(This->m_hwndLog, rc1.left, rc1.bottom,
\r
494 rcWidth(&rc1), rcHeight(&rc2), TRUE);
\r
496 SetForegroundWindow(This->m_hwndLog);
\r
497 SetForegroundWindow(This->m_hwndInvestigate);
\r
500 case ID_MENUITEM_setting:
\r
501 if (!This->m_isSettingDialogOpened) {
\r
502 This->m_isSettingDialogOpened = true;
\r
503 if (DialogBox(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_setting),
\r
504 NULL, dlgSetting_dlgProc))
\r
506 This->m_isSettingDialogOpened = false;
\r
509 case ID_MENUITEM_log:
\r
510 ShowWindow(This->m_hwndLog, SW_SHOW);
\r
511 SetForegroundWindow(This->m_hwndLog);
\r
513 case ID_MENUITEM_check: {
\r
516 ret = GetKeyboardState(keys);
\r
518 This->m_log << _T("Check Keystate Failed(%d)")
\r
519 << GetLastError() << std::endl;
\r
521 This->m_log << _T("Check Keystate: ") << std::endl;
\r
522 for (int i = 0; i < 0xff; i++) {
\r
524 asyncKey = GetAsyncKeyState(i);
\r
525 This->m_log << std::hex;
\r
526 if (asyncKey & 0x8000) {
\r
527 This->m_log << _T(" ") << VK2TCHAR[i]
\r
528 << _T("(0x") << i << _T("): pressed!")
\r
531 if (i == 0x14 || // VK_CAPTITAL
\r
532 i == 0x15 || // VK_KANA
\r
533 i == 0x19 || // VK_KANJI
\r
534 i == 0x90 || // VK_NUMLOCK
\r
535 i == 0x91 // VK_SCROLL
\r
538 This->m_log << _T(" ") << VK2TCHAR[i]
\r
539 << _T("(0x") << i << _T("): locked!")
\r
543 This->m_log << std::dec;
\r
545 This->m_log << std::endl;
\r
549 case ID_MENUITEM_version:
\r
550 ShowWindow(This->m_hwndVersion, SW_SHOW);
\r
551 SetForegroundWindow(This->m_hwndVersion);
\r
553 case ID_MENUITEM_help: {
\r
554 _TCHAR buf[GANA_MAX_PATH];
\r
555 CHECK_TRUE( GetModuleFileName(g_hInst, buf, NUMBER_OF(buf)) );
\r
556 tstringi helpFilename = pathRemoveFileSpec(buf);
\r
557 helpFilename += _T("\\");
\r
558 helpFilename += loadString(IDS_helpFilename);
\r
559 ShellExecute(NULL, _T("open"), helpFilename.c_str(),
\r
560 NULL, NULL, SW_SHOWNORMAL);
\r
563 case ID_MENUITEM_disable:
\r
564 This->m_engine.enable(!This->m_engine.getIsEnabled());
\r
565 This->showTasktrayIcon();
\r
567 case ID_MENUITEM_quit:
\r
568 This->m_engine.prepairQuit();
\r
569 PostQuitMessage(0);
\r
575 case WM_APP_engineNotify: {
\r
576 switch (i_wParam) {
\r
577 case EngineNotify_shellExecute:
\r
578 This->m_engine.shellExecute();
\r
580 case EngineNotify_loadSetting:
\r
583 case EngineNotify_helpMessage:
\r
584 This->showHelpMessage(false);
\r
586 This->showHelpMessage(true);
\r
588 case EngineNotify_showDlg: {
\r
589 // show investigate/log window
\r
590 int sw = (i_lParam & ~MayuDialogType_mask);
\r
592 switch (static_cast<MayuDialogType>(
\r
593 i_lParam & MayuDialogType_mask)) {
\r
594 case MayuDialogType_investigate:
\r
595 hwnd = This->m_hwndInvestigate;
\r
597 case MayuDialogType_log:
\r
598 hwnd = This->m_hwndLog;
\r
602 ShowWindow(hwnd, sw);
\r
604 case SW_SHOWNORMAL:
\r
605 case SW_SHOWMAXIMIZED:
\r
608 case SW_SHOWDEFAULT:
\r
609 SetForegroundWindow(hwnd);
\r
615 case EngineNotify_setForegroundWindow:
\r
616 // FIXME: completely useless. why ?
\r
617 setForegroundWindow(reinterpret_cast<HWND>(i_lParam));
\r
619 Acquire a(&This->m_log, 1);
\r
620 This->m_log << _T("setForegroundWindow(0x")
\r
621 << std::hex << i_lParam << std::dec << _T(")")
\r
625 case EngineNotify_clearLog:
\r
626 SendMessage(This->m_hwndLog, WM_COMMAND,
\r
627 MAKELONG(IDC_BUTTON_clearLog, 0), 0);
\r
635 case WM_APP_dlglogNotify: {
\r
636 switch (i_wParam) {
\r
637 case DlgLogNotify_logCleared:
\r
638 This->showBanner(true);
\r
647 if (This->m_usingSN) {
\r
648 wtsUnRegisterSessionNotification(i_hwnd);
\r
649 This->m_usingSN = false;
\r
651 if (This->m_escapeNlsKeys) {
\r
653 err = This->m_fixScancodeMap.restore();
\r
655 This->errorDialogWithCode(IDS_escapeNlsKeysFailed, err);
\r
661 if (i_message == This->m_WM_TaskbarRestart) {
\r
662 if (This->showTasktrayIcon(true)) {
\r
663 Acquire a(&This->m_log, 0);
\r
664 This->m_log << _T("Tasktray icon is updated.") << std::endl;
\r
666 Acquire a(&This->m_log, 1);
\r
667 This->m_log << _T("Tasktray icon already exists.") << std::endl;
\r
670 } else if (i_message == This->m_WM_MayuIPC) {
\r
671 switch (static_cast<MayuIPCCommand>(i_wParam)) {
\r
672 case MayuIPCCommand_Enable:
\r
673 This->m_engine.enable(!!i_lParam);
\r
674 This->showTasktrayIcon();
\r
676 Acquire a(&This->m_log, 1);
\r
677 This->m_log << _T("Enabled by another application.")
\r
680 Acquire a(&This->m_log, 1);
\r
681 This->m_log << _T("Disabled by another application.")
\r
688 return DefWindowProc(i_hwnd, i_message, i_wParam, i_lParam);
\r
693 Setting *newSetting = new Setting;
\r
696 for (int i = 1; i < __argc; ++ i) {
\r
697 if (__targv[i][0] == _T('-') && __targv[i][1] == _T('D'))
\r
698 newSetting->m_symbols.insert(__targv[i] + 2);
\r
701 if (!SettingLoader(&m_log, &m_log).load(newSetting)) {
\r
702 ShowWindow(m_hwndLog, SW_SHOW);
\r
703 SetForegroundWindow(m_hwndLog);
\r
705 Acquire a(&m_log, 0);
\r
706 m_log << _T("error: failed to load.") << std::endl;
\r
709 m_log << _T("successfully loaded.") << std::endl;
\r
710 while (!m_engine.setSetting(newSetting))
\r
713 m_setting = newSetting;
\r
716 // show message (a baloon from the task tray icon)
\r
717 void showHelpMessage(bool i_doesShow = true) {
\r
718 if (m_canUseTasktrayBaloon) {
\r
720 tstring helpMessage, helpTitle;
\r
721 m_engine.getHelpMessages(&helpMessage, &helpTitle);
\r
722 tcslcpy(m_ni.szInfo, helpMessage.c_str(), NUMBER_OF(m_ni.szInfo));
\r
723 tcslcpy(m_ni.szInfoTitle, helpTitle.c_str(),
\r
724 NUMBER_OF(m_ni.szInfoTitle));
\r
725 m_ni.dwInfoFlags = NIIF_INFO;
\r
727 m_ni.szInfo[0] = m_ni.szInfoTitle[0] = _T('\0');
\r
728 CHECK_TRUE( Shell_NotifyIcon(NIM_MODIFY, &m_ni) );
\r
732 // change the task tray icon
\r
733 bool showTasktrayIcon(bool i_doesAdd = false) {
\r
734 m_ni.hIcon = m_tasktrayIcon[m_engine.getIsEnabled() ? 1 : 0];
\r
735 m_ni.szInfo[0] = m_ni.szInfoTitle[0] = _T('\0');
\r
737 // http://support.microsoft.com/kb/418138/JA/
\r
739 for (; !Shell_NotifyIcon(NIM_ADD, &m_ni) && 0 < guard; -- guard) {
\r
740 if (Shell_NotifyIcon(NIM_MODIFY, &m_ni)) {
\r
743 Sleep(1000); // 1sec
\r
747 return !!Shell_NotifyIcon(NIM_MODIFY, &m_ni);
\r
751 void showBanner(bool i_isCleared) {
\r
755 _TCHAR starttimebuf[1024];
\r
756 _TCHAR timebuf[1024];
\r
758 #ifdef __BORLANDC__
\r
759 #pragma message("\t\t****\tAfter std::ostream() is called, ")
\r
760 #pragma message("\t\t****\tstrftime(... \"%%#c\" ...) fails.")
\r
761 #pragma message("\t\t****\tWhy ? Bug of Borland C++ 5.5.1 ? ")
\r
762 #pragma message("\t\t****\t - nayuta")
\r
763 _tcsftime(timebuf, NUMBER_OF(timebuf), _T("%Y/%m/%d %H:%M:%S"),
\r
765 _tcsftime(starttimebuf, NUMBER_OF(starttimebuf), _T("%Y/%m/%d %H:%M:%S"),
\r
766 localtime(&m_startTime));
\r
768 _tcsftime(timebuf, NUMBER_OF(timebuf), _T("%#c"), localtime(&now));
\r
769 _tcsftime(starttimebuf, NUMBER_OF(starttimebuf), _T("%#c"),
\r
770 localtime(&m_startTime));
\r
773 Acquire a(&m_log, 0);
\r
774 m_log << _T("------------------------------------------------------------") << std::endl;
\r
775 m_log << loadString(IDS_mayu) << _T(" ") _T(VERSION);
\r
777 m_log << _T(" (DEBUG)");
\r
780 m_log << _T(" (UNICODE)");
\r
782 m_log << std::endl;
\r
783 m_log << _T(" built by ")
\r
784 << _T(LOGNAME) << _T("@") << toLower(_T(COMPUTERNAME))
\r
785 << _T(" (") << _T(__DATE__) << _T(" ")
\r
786 << _T(__TIME__) << _T(", ")
\r
787 << getCompilerVersionString() << _T(")") << std::endl;
\r
788 _TCHAR modulebuf[1024];
\r
789 CHECK_TRUE( GetModuleFileName(g_hInst, modulebuf,
\r
790 NUMBER_OF(modulebuf)) );
\r
791 m_log << _T("started at ") << starttimebuf << std::endl;
\r
792 m_log << modulebuf << std::endl;
\r
793 m_log << _T("------------------------------------------------------------") << std::endl;
\r
796 m_log << _T("log was cleared at ") << timebuf << std::endl;
\r
798 m_log << _T("log begins at ") << timebuf << std::endl;
\r
802 bool errorDialogWithCode(UINT ids, int code)
\r
804 _TCHAR title[1024];
\r
807 _sntprintf_s(title, NUMBER_OF(title), _TRUNCATE, loadString(IDS_mayu).c_str());
\r
808 _sntprintf_s(text, NUMBER_OF(text), _TRUNCATE, loadString(ids).c_str(), code);
\r
809 MessageBox((HWND)NULL, text, title, MB_OK | MB_ICONSTOP);
\r
813 int enableToWriteByUser(HANDLE hdl)
\r
815 TCHAR userName[GANA_MAX_ATOM_LENGTH];
\r
816 DWORD userNameSize = NUMBER_OF(userName);
\r
818 SID_NAME_USE sidType;
\r
821 TCHAR *pDomain = NULL;
\r
822 DWORD domainSize = 0;
\r
824 PSECURITY_DESCRIPTOR pSd;
\r
826 ACL_SIZE_INFORMATION aclInfo;
\r
832 DWORD newAceIndex = 0;
\r
837 ret = GetUserName(userName, &userNameSize);
\r
838 if (ret == FALSE) {
\r
843 // get buffer size for pSid (and pDomain)
\r
844 ret = LookupAccountName(NULL, userName, pSid, &sidSize, pDomain, &domainSize, &sidType);
\r
845 if (ret != FALSE || GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
\r
846 // above call should fail by ERROR_INSUFFICIENT_BUFFER
\r
851 pSid = reinterpret_cast<PSID>(LocalAlloc(LPTR, sidSize));
\r
852 pDomain = reinterpret_cast<TCHAR*>(LocalAlloc(LPTR, domainSize * sizeof(TCHAR)));
\r
853 if (pSid == NULL || pDomain == NULL) {
\r
858 // get SID (and Domain) for logoned user
\r
859 ret = LookupAccountName(NULL, userName, pSid, &sidSize, pDomain, &domainSize, &sidType);
\r
860 if (ret == FALSE) {
\r
861 // LookupAccountName() should success in this time
\r
866 // get DACL for hdl
\r
867 ret = GetSecurityInfo(hdl, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOrigDacl, NULL, &pSd);
\r
868 if (ret != ERROR_SUCCESS) {
\r
873 // get size for original DACL
\r
874 ret = GetAclInformation(pOrigDacl, &aclInfo, sizeof(aclInfo), AclSizeInformation);
\r
875 if (ret == FALSE) {
\r
880 // compute size for new DACL
\r
881 newDaclSize = aclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pSid) - sizeof(DWORD);
\r
883 // allocate memory for new DACL
\r
884 pNewDacl = reinterpret_cast<PACL>(LocalAlloc(LPTR, newDaclSize));
\r
885 if (pNewDacl == NULL) {
\r
890 // initialize new DACL
\r
891 ret = InitializeAcl(pNewDacl, newDaclSize, ACL_REVISION);
\r
892 if (ret == FALSE) {
\r
897 // copy original DACL to new DACL
\r
898 for (aceIndex = 0; aceIndex < aclInfo.AceCount; aceIndex++) {
\r
901 ret = GetAce(pOrigDacl, aceIndex, &pAce);
\r
902 if (ret == FALSE) {
\r
907 if ((reinterpret_cast<ACCESS_ALLOWED_ACE*>(pAce))->Header.AceFlags & INHERITED_ACE) {
\r
911 if (EqualSid(pSid, &(reinterpret_cast<ACCESS_ALLOWED_ACE*>(pAce))->SidStart) != FALSE) {
\r
915 ret = AddAce(pNewDacl, ACL_REVISION, MAXDWORD, pAce, (reinterpret_cast<PACE_HEADER>(pAce))->AceSize);
\r
916 if (ret == FALSE) {
\r
924 ret = AddAccessAllowedAce(pNewDacl, ACL_REVISION, GENERIC_ALL, pSid);
\r
925 if (ret == FALSE) {
\r
930 // copy the rest of inherited ACEs
\r
931 for (; aceIndex < aclInfo.AceCount; aceIndex++) {
\r
934 ret = GetAce(pOrigDacl, aceIndex, &pAce);
\r
935 if (ret == FALSE) {
\r
940 ret = AddAce(pNewDacl, ACL_REVISION, MAXDWORD, pAce, (reinterpret_cast<PACE_HEADER>(pAce))->AceSize);
\r
941 if (ret == FALSE) {
\r
947 ret = SetSecurityInfo(hdl, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL);
\r
948 if (ret != ERROR_SUCCESS) {
\r
955 LocalFree(pDomain);
\r
956 LocalFree(pNewDacl);
\r
963 Mayu(HANDLE i_mutex)
\r
964 : m_hwndTaskTray(NULL),
\r
967 m_WM_TaskbarRestart(RegisterWindowMessage(_T("TaskbarCreated"))),
\r
968 m_WM_MayuIPC(RegisterWindowMessage(WM_MayuIPC_NAME)),
\r
969 m_canUseTasktrayBaloon(
\r
970 PACKVERSION(5, 0) <= getDllVersion(_T("shlwapi.dll"))),
\r
971 m_log(WM_APP_msgStreamNotify),
\r
973 m_isSettingDialogOpened(false),
\r
974 m_isConsoleConnected(true),
\r
976 Registry reg(MAYU_REGISTRY_ROOT);
\r
977 reg.read(_T("escapeNLSKeys"), &m_escapeNlsKeys, 0);
\r
978 #ifdef USE_MAILSLOT
\r
979 m_hNotifyMailslot = CreateMailslot(NOTIFY_MAILSLOT_NAME, 0, MAILSLOT_WAIT_FOREVER, (SECURITY_ATTRIBUTES *)NULL);
\r
980 ASSERT(m_hNotifyMailslot != INVALID_HANDLE_VALUE);
\r
982 if (checkWindowsVersion(6, 0) != FALSE) { // enableToWriteByUser() is available only Vista or later
\r
983 err = enableToWriteByUser(m_hNotifyMailslot);
\r
985 errorDialogWithCode(IDS_cannotPermitStandardUser, err);
\r
989 m_hNotifyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
\r
990 ASSERT(m_hNotifyEvent);
\r
991 m_olNotify.Offset = 0;
\r
992 m_olNotify.OffsetHigh = 0;
\r
993 m_olNotify.hEvent = m_hNotifyEvent;
\r
994 #endif // USE_MAILSLOT
\r
995 time(&m_startTime);
\r
997 CHECK_TRUE( Register_focus() );
\r
998 CHECK_TRUE( Register_target() );
\r
999 CHECK_TRUE( Register_tasktray() );
\r
1003 HomeDirectories pathes;
\r
1004 getHomeDirectories(&pathes);
\r
1005 for (HomeDirectories::iterator i = pathes.begin(); i != pathes.end(); ++ i)
\r
1006 if (SetCurrentDirectory(i->c_str()))
\r
1010 // create windows, dialogs
\r
1011 tstringi title = loadString(IDS_mayu);
\r
1012 m_hwndTaskTray = CreateWindow(_T("mayuTasktray"), title.c_str(),
\r
1013 WS_OVERLAPPEDWINDOW,
\r
1014 CW_USEDEFAULT, CW_USEDEFAULT,
\r
1015 CW_USEDEFAULT, CW_USEDEFAULT,
\r
1016 NULL, NULL, g_hInst, this);
\r
1017 CHECK_TRUE( m_hwndTaskTray );
\r
1019 // set window handle of tasktray to hooks
\r
1020 #ifndef USE_MAILSLOT
\r
1021 g_hookData->m_hwndTaskTray = reinterpret_cast<DWORD>(m_hwndTaskTray);
\r
1022 #endif // !USE_MAILSLOT
\r
1023 CHECK_FALSE( installMessageHook() );
\r
1024 m_usingSN = wtsRegisterSessionNotification(m_hwndTaskTray,
\r
1025 NOTIFY_FOR_THIS_SESSION);
\r
1028 dld.m_log = &m_log;
\r
1029 dld.m_hwndTaskTray = m_hwndTaskTray;
\r
1031 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_log), NULL,
\r
1032 dlgLog_dlgProc, (LPARAM)&dld);
\r
1033 CHECK_TRUE( m_hwndLog );
\r
1035 DlgInvestigateData did;
\r
1036 did.m_engine = &m_engine;
\r
1037 did.m_hwndLog = m_hwndLog;
\r
1038 m_hwndInvestigate =
\r
1039 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_investigate), NULL,
\r
1040 dlgInvestigate_dlgProc, (LPARAM)&did);
\r
1041 CHECK_TRUE( m_hwndInvestigate );
\r
1044 CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_DIALOG_version),
\r
1045 NULL, dlgVersion_dlgProc,
\r
1046 (LPARAM)m_engine.getMayudVersion().c_str());
\r
1047 CHECK_TRUE( m_hwndVersion );
\r
1050 #ifdef LOG_TO_FILE
\r
1052 _TCHAR exePath[GANA_MAX_PATH];
\r
1053 _TCHAR exeDrive[GANA_MAX_PATH];
\r
1054 _TCHAR exeDir[GANA_MAX_PATH];
\r
1055 GetModuleFileName(NULL, exePath, GANA_MAX_PATH);
\r
1056 _tsplitpath_s(exePath, exeDrive, GANA_MAX_PATH, exeDir, GANA_MAX_PATH, NULL, 0, NULL, 0);
\r
1059 path += _T("mayu.log");
\r
1060 m_logFile.open(path.c_str(), std::ios::app);
\r
1061 m_logFile.imbue(std::locale("japanese"));
\r
1062 #endif // LOG_TO_FILE
\r
1063 SendMessage(GetDlgItem(m_hwndLog, IDC_EDIT_log), EM_SETLIMITTEXT, 0, 0);
\r
1064 m_log.attach(m_hwndTaskTray);
\r
1066 // start keyboard handler thread
\r
1067 m_engine.setAssociatedWndow(m_hwndTaskTray);
\r
1070 // show tasktray icon
\r
1071 m_tasktrayIcon[0] = loadSmallIcon(IDI_ICON_mayu_disabled);
\r
1072 m_tasktrayIcon[1] = loadSmallIcon(IDI_ICON_mayu);
\r
1073 std::memset(&m_ni, 0, sizeof(m_ni));
\r
1074 m_ni.uID = ID_TaskTrayIcon;
\r
1075 m_ni.hWnd = m_hwndTaskTray;
\r
1076 m_ni.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
\r
1077 m_ni.hIcon = m_tasktrayIcon[1];
\r
1078 m_ni.uCallbackMessage = WM_APP_taskTrayNotify;
\r
1079 tstring tip = loadString(IDS_mayu);
\r
1080 tcslcpy(m_ni.szTip, tip.c_str(), NUMBER_OF(m_ni.szTip));
\r
1081 if (m_canUseTasktrayBaloon) {
\r
1082 m_ni.cbSize = sizeof(m_ni);
\r
1083 m_ni.uFlags |= NIF_INFO;
\r
1085 m_ni.cbSize = NOTIFYICONDATA_V1_SIZE;
\r
1086 showTasktrayIcon(true);
\r
1089 m_hMenuTaskTray = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU_tasktray));
\r
1090 ASSERT(m_hMenuTaskTray);
\r
1092 // set initial lock state
\r
1093 notifyLockState();
\r
1097 ZeroMemory(&m_pi,sizeof(m_pi));
\r
1098 ZeroMemory(&m_si,sizeof(m_si));
\r
1099 m_si.cb=sizeof(m_si);
\r
1101 result = CreateProcess(_T("yamyd32"), _T("yamyd32"), NULL, NULL, FALSE,
\r
1102 NORMAL_PRIORITY_CLASS, 0, NULL, &m_si, &m_pi);
\r
1103 if (result == FALSE) {
\r
1106 TCHAR title[1024];
\r
1108 LoadString(GetModuleHandle(NULL), IDS_cannotInvoke,
\r
1109 text, sizeof(text)/sizeof(text[0]));
\r
1110 LoadString(GetModuleHandle(NULL), IDS_mayu,
\r
1111 title, sizeof(title)/sizeof(title[0]));
\r
1112 _stprintf_s(buf, sizeof(buf)/sizeof(buf[0]),
\r
1113 text, _T("yamyd32"), GetLastError());
\r
1114 MessageBox((HWND)NULL, buf, title, MB_OK | MB_ICONSTOP);
\r
1116 CloseHandle(m_pi.hThread);
\r
1117 CloseHandle(m_pi.hProcess);
\r
1124 #ifdef USE_MAILSLOT
\r
1125 CancelIo(m_hNotifyMailslot);
\r
1127 CloseHandle(m_hNotifyMailslot);
\r
1128 CloseHandle(m_hNotifyEvent);
\r
1129 #endif // USE_MAILSLOT
\r
1130 ReleaseMutex(m_mutex);
\r
1131 WaitForSingleObject(m_mutex, INFINITE);
\r
1132 // first, detach log from edit control to avoid deadlock
\r
1134 #ifdef LOG_TO_FILE
\r
1135 m_logFile.close();
\r
1136 #endif // LOG_TO_FILE
\r
1138 // stop notify from mayu.dll
\r
1139 g_hookData->m_hwndTaskTray = NULL;
\r
1140 CHECK_FALSE( uninstallMessageHook() );
\r
1141 PostMessage(HWND_BROADCAST, WM_NULL, 0, 0);
\r
1143 // destroy windows
\r
1144 CHECK_TRUE( DestroyWindow(m_hwndVersion) );
\r
1145 CHECK_TRUE( DestroyWindow(m_hwndInvestigate) );
\r
1146 CHECK_TRUE( DestroyWindow(m_hwndLog) );
\r
1147 CHECK_TRUE( DestroyWindow(m_hwndTaskTray) );
\r
1150 DestroyMenu(m_hMenuTaskTray);
\r
1152 // delete tasktray icon
\r
1153 CHECK_TRUE( Shell_NotifyIcon(NIM_DELETE, &m_ni) );
\r
1154 CHECK_TRUE( DestroyIcon(m_tasktrayIcon[1]) );
\r
1155 CHECK_TRUE( DestroyIcon(m_tasktrayIcon[0]) );
\r
1157 // stop keyboard handler thread
\r
1160 // remove setting;
\r
1165 WPARAM messageLoop() {
\r
1166 showBanner(false);
\r
1169 #ifdef USE_MAILSLOT
\r
1170 mailslotHandler(0, 0);
\r
1172 HANDLE handles[] = { m_hNotifyEvent };
\r
1174 switch (ret = MsgWaitForMultipleObjectsEx(NUMBER_OF(handles), &handles[0],
\r
1175 INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE)) {
\r
1176 case WAIT_OBJECT_0: // m_hNotifyEvent
\r
1179 case WAIT_OBJECT_0 + NUMBER_OF(handles): {
\r
1181 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != 0) {
\r
1182 if (msg.message == WM_QUIT) {
\r
1183 return msg.wParam;
\r
1185 if (IsDialogMessage(m_hwndLog, &msg))
\r
1187 if (IsDialogMessage(m_hwndInvestigate, &msg))
\r
1189 if (IsDialogMessage(m_hwndVersion, &msg))
\r
1191 TranslateMessage(&msg);
\r
1192 DispatchMessage(&msg);
\r
1198 case WAIT_IO_COMPLETION:
\r
1206 #else // !USE_MAILSLOT
\r
1208 while (0 < GetMessage(&msg, NULL, 0, 0)) {
\r
1209 if (IsDialogMessage(m_hwndLog, &msg))
\r
1211 if (IsDialogMessage(m_hwndInvestigate, &msg))
\r
1213 if (IsDialogMessage(m_hwndVersion, &msg))
\r
1215 TranslateMessage(&msg);
\r
1216 DispatchMessage(&msg);
\r
1218 return msg.wParam;
\r
1219 #endif // !USE_MAILSLOT
\r
1224 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
1228 /// convert registry
\r
1229 void convertRegistry()
\r
1231 Registry reg(MAYU_REGISTRY_ROOT);
\r
1232 tstringi dot_mayu;
\r
1233 bool doesAdd = false;
\r
1235 if (reg.read(_T(".mayu"), &dot_mayu)) {
\r
1236 reg.write(_T(".mayu0"), _T(";") + dot_mayu + _T(";"));
\r
1237 reg.remove(_T(".mayu"));
\r
1240 } else if (!reg.read(_T(".mayu0"), &dot_mayu)) {
\r
1241 reg.write(_T(".mayu0"), loadString(IDS_readFromHomeDirectory) + _T(";;"));
\r
1246 Registry commonreg(HKEY_LOCAL_MACHINE, _T("Software\\GANAware\\mayu"));
\r
1247 tstringi dir, layout;
\r
1248 if (commonreg.read(_T("dir"), &dir) &&
\r
1249 commonreg.read(_T("layout"), &layout)) {
\r
1250 tstringi tmp = _T(";") + dir + _T("\\dot.mayu");
\r
1251 if (layout == _T("109")) {
\r
1252 reg.write(_T(".mayu1"), loadString(IDS_109Emacs) + tmp
\r
1253 + _T(";-DUSE109") _T(";-DUSEdefault"));
\r
1254 reg.write(_T(".mayu2"), loadString(IDS_104on109Emacs) + tmp
\r
1255 + _T(";-DUSE109") _T(";-DUSEdefault") _T(";-DUSE104on109"));
\r
1256 reg.write(_T(".mayu3"), loadString(IDS_109) + tmp
\r
1257 + _T(";-DUSE109"));
\r
1258 reg.write(_T(".mayu4"), loadString(IDS_104on109) + tmp
\r
1259 + _T(";-DUSE109") _T(";-DUSE104on109"));
\r
1261 reg.write(_T(".mayu1"), loadString(IDS_104Emacs) + tmp
\r
1262 + _T(";-DUSE104") _T(";-DUSEdefault"));
\r
1263 reg.write(_T(".mayu2"), loadString(IDS_109on104Emacs) + tmp
\r
1264 + _T(";-DUSE104") _T(";-DUSEdefault") _T(";-DUSE109on104"));
\r
1265 reg.write(_T(".mayu3"), loadString(IDS_104) + tmp
\r
1266 + _T(";-DUSE104"));
\r
1267 reg.write(_T(".mayu4"), loadString(IDS_109on104) + tmp
\r
1268 + _T(";-DUSE104") _T(";-DUSE109on104"));
\r
1270 reg.write(_T(".mayuIndex"), index);
\r
1277 int WINAPI _tWinMain(HINSTANCE i_hInstance, HINSTANCE /* i_hPrevInstance */,
\r
1278 LPTSTR /* i_lpszCmdLine */, int /* i_nCmdShow */)
\r
1280 g_hInst = i_hInstance;
\r
1283 CHECK_TRUE( _tsetlocale(LC_ALL, _T("")) );
\r
1285 // common controls
\r
1286 #if defined(_WIN95)
\r
1287 InitCommonControls();
\r
1289 INITCOMMONCONTROLSEX icc;
\r
1290 icc.dwSize = sizeof(icc);
\r
1291 icc.dwICC = ICC_LISTVIEW_CLASSES;
\r
1292 CHECK_TRUE( InitCommonControlsEx(&icc) );
\r
1295 // convert old registry to new registry
\r
1297 convertRegistry();
\r
1298 #endif // !USE_INI
\r
1300 // is another mayu running ?
\r
1301 HANDLE mutex = CreateMutex((SECURITY_ATTRIBUTES *)NULL, TRUE,
\r
1302 MUTEX_MAYU_EXCLUSIVE_RUNNING);
\r
1303 if (GetLastError() == ERROR_ALREADY_EXISTS) {
\r
1304 // another mayu already running
\r
1305 tstring text = loadString(IDS_mayuAlreadyExists);
\r
1306 tstring title = loadString(IDS_mayu);
\r
1308 UINT WM_TaskbarRestart = RegisterWindowMessage(_T("TaskbarCreated"));
\r
1309 PostMessage(reinterpret_cast<HWND>(g_hookData->m_hwndTaskTray),
\r
1310 WM_TaskbarRestart, 0, 0);
\r
1312 MessageBox((HWND)NULL, text.c_str(), title.c_str(), MB_OK | MB_ICONSTOP);
\r
1317 Mayu(mutex).messageLoop();
\r
1318 } catch (ErrorMessage &i_e) {
\r
1319 tstring title = loadString(IDS_mayu);
\r
1320 MessageBox((HWND)NULL, i_e.getMessage().c_str(), title.c_str(),
\r
1321 MB_OK | MB_ICONSTOP);
\r
1324 CHECK_TRUE( CloseHandle(mutex) );
\r