OSDN Git Service

Rename m_nApplicationID m_nAppID and rename m_szCurrentApplication
[xkeymacs/xkeymacs.git] / xkeymacs / mainfrm.cpp
index 866fe53..092c062 100644 (file)
@@ -5,7 +5,6 @@
 #include <Lmcons.h>\r
 #include "xkeymacs.h"\r
 #include "Profile.h"\r
-\r
 #include "MainFrm.h"\r
 \r
 #ifdef _DEBUG\r
@@ -43,7 +42,6 @@ END_MESSAGE_MAP()
 \r
 CMainFrame::CMainFrame()\r
 {\r
-       m_pXkeymacsDll                  = new CXkeymacsDll;\r
        m_pPropertiesDlg                = new CProperties;\r
        m_nResultPropertiesDlg  = -1;\r
        m_bPropertiesDlgExist   = FALSE;\r
@@ -61,6 +59,8 @@ CMainFrame::CMainFrame()
        }\r
        memset(m_nResultKeyboardDlg, -1, sizeof(m_nResultKeyboardDlg));\r
        memset(m_bKeyboardDlgExist, 0, sizeof(m_bKeyboardDlgExist));\r
+       memset(m_stOldNtfyIcon, 0, sizeof(m_stOldNtfyIcon));\r
+       memset(m_dwOldMessage, 0, sizeof(m_dwOldMessage));\r
 \r
        // register window class\r
        WNDCLASS        stWndClass;\r
@@ -87,9 +87,6 @@ CMainFrame::CMainFrame()
 \r
 CMainFrame::~CMainFrame()\r
 {\r
-       delete m_pXkeymacsDll;\r
-       m_pXkeymacsDll = NULL;\r
-\r
        delete m_pPropertiesDlg;\r
        m_pPropertiesDlg = NULL;\r
 \r
@@ -114,8 +111,6 @@ int CMainFrame::OnCreate(const LPCREATESTRUCT lpCreateStruct)
                return -1;\r
        }\r
 \r
-       CXkeymacsData::Set106Keyboard(CProfile::Is106Keyboard());\r
-\r
        // init notify icon data\r
        NOTIFYICONDATA notifyIconData[MAX_ICON_TYPE] = {\r
                { sizeof(NOTIFYICONDATA), m_hWnd, MAIN_ICON, NIF_MESSAGE | NIF_ICON | NIF_TIP, WM_USER_NTFYICON,\r
@@ -149,57 +144,174 @@ int CMainFrame::OnCreate(const LPCREATESTRUCT lpCreateStruct)
                           sizeof(notifyIconData[ALT_ICON].szTip));\r
 \r
        // set notify icon data\r
-       m_pXkeymacsDll->SetNotifyIconData(MAIN_ICON, notifyIconData[MAIN_ICON],\r
-               (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_SHARED),\r
-               (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_TMP), IMAGE_ICON, 16, 16, LR_SHARED),\r
-               (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_WOCQ), IMAGE_ICON, 16, 16, LR_SHARED),              // disable without C-q\r
-               (HICON)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE), IMAGE_ICON, 16, 16, LR_SHARED),\r
-               AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MAIN)), 1));\r
+       m_hIcon[MAIN_ICON][STATUS_ENABLE] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME), IMAGE_ICON, 16, 16, LR_SHARED),\r
+       m_hIcon[MAIN_ICON][STATUS_DISABLE_TMP] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_TMP), IMAGE_ICON, 16, 16, LR_SHARED);\r
+       m_hIcon[MAIN_ICON][STATUS_DISABLE_WOCQ] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE_WOCQ), IMAGE_ICON, 16, 16, LR_SHARED);\r
+       m_hIcon[MAIN_ICON][STATUS_DISABLE] = (HICON)LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAIN_DISABLE), IMAGE_ICON, 16, 16, LR_SHARED);\r
+       m_bIcon[MAIN_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MAIN)), 1);\r
+       m_stNtfyIcon[MAIN_ICON] = notifyIconData[MAIN_ICON];\r
+       AddShell_NotifyIcon(MAIN_ICON);\r
 \r
        // set notify ^X icon data\r
-       m_pXkeymacsDll->SetNotifyIconData(CX_ICON, notifyIconData[CX_ICON], AfxGetApp()->LoadIcon(IDI_CX_ON),\r
-                                                                         AfxGetApp()->LoadIcon(IDI_CX_OFF),\r
-                                                                         AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CX)), 0));\r
+       m_hIcon[CX_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_CX_ON);\r
+       m_hIcon[CX_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_CX_OFF);\r
+       m_bIcon[CX_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CX)), 0);\r
+       m_stNtfyIcon[CX_ICON] = notifyIconData[CX_ICON];\r
+       AddShell_NotifyIcon(CX_ICON);\r
 \r
        // set notify M-x icon data\r
-       m_pXkeymacsDll->SetNotifyIconData(MX_ICON, notifyIconData[MX_ICON], AfxGetApp()->LoadIcon(IDI_MX_ON),\r
-                                                                         AfxGetApp()->LoadIcon(IDI_MX_OFF),\r
-                                                                         AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MX)), 0));\r
+       m_hIcon[MX_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_MX_ON);\r
+       m_hIcon[MX_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_MX_OFF);\r
+       m_bIcon[MX_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_MX)), 0);\r
+       m_stNtfyIcon[MX_ICON] = notifyIconData[MX_ICON];\r
+       AddShell_NotifyIcon(MX_ICON);\r
 \r
        // set notify Meta icon data\r
-       m_pXkeymacsDll->SetNotifyIconData(META_ICON, notifyIconData[META_ICON], AfxGetApp()->LoadIcon(IDI_META_ON),\r
-                                                                         AfxGetApp()->LoadIcon(IDI_META_OFF),\r
-                                                                         AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_META)), 0));\r
+       m_hIcon[META_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_META_ON);\r
+       m_hIcon[META_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_META_OFF);\r
+       m_bIcon[META_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_META)), 0);\r
+       m_stNtfyIcon[META_ICON] = notifyIconData[META_ICON];\r
+       AddShell_NotifyIcon(META_ICON);\r
 \r
        // set notify Shift icon data\r
-       m_pXkeymacsDll->SetNotifyIconData(SHIFT_ICON, notifyIconData[SHIFT_ICON], AfxGetApp()->LoadIcon(IDI_SHIFT_ON),\r
-                                                                         AfxGetApp()->LoadIcon(IDI_SHIFT_OFF),\r
-                                                                         AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_SHIFT)), 0));\r
+       m_hIcon[SHIFT_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_SHIFT_ON);\r
+       m_hIcon[SHIFT_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_SHIFT_OFF);\r
+       m_bIcon[SHIFT_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_SHIFT)), 0);\r
+       m_stNtfyIcon[SHIFT_ICON] = notifyIconData[SHIFT_ICON];\r
+       AddShell_NotifyIcon(SHIFT_ICON);\r
 \r
        // set notify Ctrl icon data\r
-       m_pXkeymacsDll->SetNotifyIconData(CTRL_ICON, notifyIconData[CTRL_ICON], AfxGetApp()->LoadIcon(IDI_CTRL_ON),\r
-                                                                         AfxGetApp()->LoadIcon(IDI_CTRL_OFF),\r
-                                                                         AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CTRL)), 0));\r
+       m_hIcon[CTRL_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_CTRL_ON);\r
+       m_hIcon[CTRL_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_CTRL_OFF);\r
+       m_bIcon[CTRL_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CTRL)), 0);\r
+       m_stNtfyIcon[CTRL_ICON] = notifyIconData[CTRL_ICON];\r
+       AddShell_NotifyIcon(CTRL_ICON);\r
 \r
        // set notify Alt icon data\r
-       m_pXkeymacsDll->SetNotifyIconData(ALT_ICON, notifyIconData[ALT_ICON], AfxGetApp()->LoadIcon(IDI_ALT_ON),\r
-                                                                         AfxGetApp()->LoadIcon(IDI_ALT_OFF),\r
-                                                                         AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ALT)), 0));\r
-\r
-       m_pXkeymacsDll->SetKeyboardSpeed(CProfile::GetKeyboardSpeed());\r
-       m_pXkeymacsDll->SetAccelerate(AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ACCELERATE)), 1));\r
+       m_hIcon[ALT_ICON][ON_ICON] = AfxGetApp()->LoadIcon(IDI_ALT_ON);\r
+       m_hIcon[ALT_ICON][OFF_ICON] = AfxGetApp()->LoadIcon(IDI_ALT_OFF);\r
+       m_bIcon[ALT_ICON] = AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ALT)), 0);\r
+       m_stNtfyIcon[ALT_ICON] = notifyIconData[ALT_ICON];\r
+       AddShell_NotifyIcon(ALT_ICON);\r
+       \r
+       CXkeymacsDll::SetKeyboardSpeed(CProfile::GetKeyboardSpeed());\r
+       CXkeymacsDll::SetAccelerate(AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_ACCELERATE)), 1));\r
 \r
-       m_pXkeymacsDll->SetCursorData((HCURSOR)::LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
+       CXkeymacsDll::SetCursorData((HCURSOR)::LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
                                                                  (HCURSOR)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_DISABLE_TMP_CURSOR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
                                                                  (HCURSOR)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_DISABLE_WOCQ_CURSOR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
                                                                  (HCURSOR)::LoadImage(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_DISABLE_CURSOR), IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED),\r
                                                                  AfxGetApp()->GetProfileInt(CString(), CString(MAKEINTRESOURCE(IDS_REG_ENTRY_CHANGE_CURSOR)), 0));\r
 \r
-       m_pXkeymacsDll->SetHooks();\r
+       CXkeymacsDll::SetHooks();\r
+       StartPollThread();\r
+\r
+       return 0;\r
+}\r
+\r
+void CMainFrame::StartPollThread()\r
+{\r
+       m_bPollIconMessage = TRUE;\r
+       m_hThread = CreateThread(NULL, 0, PollIconMessage, this, 0, NULL);\r
+}\r
+\r
+void CMainFrame::TerminatePollThread()\r
+{\r
+       m_bPollIconMessage = FALSE;\r
+       ICONMSG nul = {MAIN_ICON,};\r
+       if (CXkeymacsDll::SendIconMessage(&nul, 1))\r
+               WaitForSingleObject(m_hThread, 5000);\r
+       CloseHandle(m_hThread);\r
+}\r
 \r
+DWORD WINAPI CMainFrame::PollIconMessage(LPVOID lpParam)\r
+{\r
+       CMainFrame *pThis = reinterpret_cast<CMainFrame *>(lpParam);\r
+       HANDLE hPipe = CreateNamedPipe(ICON_PIPE, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, 1,\r
+                                                                       sizeof(DWORD), sizeof(ICONMSG) * MAX_ICON_TYPE, 0, NULL);\r
+       if (hPipe == INVALID_HANDLE_VALUE)\r
+               return 1;\r
+       for (; ;) {\r
+               if (ConnectNamedPipe(hPipe, NULL) ? FALSE : (GetLastError() != ERROR_PIPE_CONNECTED))\r
+                       break;\r
+               ICONMSG msg[MAX_ICON_TYPE];\r
+               DWORD read;\r
+               if (!ReadFile(hPipe, msg, sizeof(msg), &read, NULL))\r
+                       break;\r
+               DWORD written, ack = 0;\r
+               // return ack ASAP to release hooks from blocking state.\r
+               if (!WriteFile(hPipe, &ack, sizeof(DWORD), &written, NULL) || written != sizeof(DWORD) ||\r
+                               !FlushFileBuffers(hPipe) || !DisconnectNamedPipe(hPipe))\r
+                       break;\r
+               if (!pThis->m_bPollIconMessage)\r
+                       break;\r
+               for (DWORD i = 0; i < read / sizeof(ICONMSG); ++i) {\r
+                       pThis->m_stNtfyIcon[msg[i].nType].hIcon = pThis->m_hIcon[msg[i].nType][msg[i].nState];\r
+                       if (msg[i].nType == MX_ICON && msg[i].szTip[0] != 0)\r
+                               memcpy(pThis->m_stNtfyIcon[MX_ICON].szTip, msg[i].szTip, 128);\r
+                       pThis->DoShell_NotifyIcon(msg[i].nType, NIM_MODIFY);\r
+               }\r
+       }\r
+       CloseHandle(hPipe);\r
        return 0;\r
 }\r
 \r
+BOOL CMainFrame::DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage)\r
+{\r
+       if (m_bIcon[icon]\r
+        &&     (m_dwOldMessage[icon] != dwMessage\r
+         || memcmp(&m_stOldNtfyIcon[icon], &m_stNtfyIcon[icon], sizeof(m_stNtfyIcon[icon])))) {\r
+               m_dwOldMessage[icon] = dwMessage;\r
+               m_stOldNtfyIcon[icon] = m_stNtfyIcon[icon];\r
+\r
+               BOOL rc = FALSE;\r
+               for (int retry_count = 0; retry_count < 20; ++retry_count) { // retry for timeout\r
+                       rc = Shell_NotifyIcon(dwMessage, &m_stNtfyIcon[icon]);\r
+                       if (dwMessage != NIM_ADD || rc || (GetLastError() != ERROR_TIMEOUT && 5 < retry_count)) {\r
+                               break;\r
+                       }\r
+                       Sleep(1000); // 1sec\r
+                       if ((rc = Shell_NotifyIcon(NIM_MODIFY, &m_stNtfyIcon[icon])) != FALSE) {\r
+                               break; // ERROR_TIMEOUT was returned but the icon was also added.\r
+                       }\r
+               }\r
+               return rc;\r
+       } else {\r
+               return TRUE;\r
+       }\r
+}\r
+\r
+void CMainFrame::EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable)\r
+{\r
+       DeleteShell_NotifyIcon(icon);\r
+       m_bIcon[icon] = bEnable;\r
+       AddShell_NotifyIcon(icon);\r
+}\r
+\r
+void CMainFrame::AddShell_NotifyIcon(ICON_TYPE icon)\r
+{\r
+       DoShell_NotifyIcon(icon, NIM_ADD);\r
+}\r
+\r
+void CMainFrame::DeleteShell_NotifyIcon(ICON_TYPE icon)\r
+{\r
+       DoShell_NotifyIcon(icon, NIM_DELETE);\r
+}\r
+\r
+void CMainFrame::DeleteAllShell_NotifyIcon()\r
+{\r
+       for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {\r
+               DeleteShell_NotifyIcon((ICON_TYPE)icon);\r
+       }\r
+}\r
+\r
+void CMainFrame::AddAllShell_NotifyIcon()\r
+{\r
+       for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {\r
+               AddShell_NotifyIcon((ICON_TYPE)icon);\r
+       }\r
+}\r
+\r
 /////////////////////////////////////////////////////////////////////////////\r
 // CMainFrame diagnostics\r
 \r
@@ -290,7 +402,7 @@ void CMainFrame::ShowRightMenu(const ICON_TYPE icon)
                popUp->SetDefaultItem(IDC_PROPERTIES);\r
 \r
                CString szDisable(MAKEINTRESOURCE(IDS_ENABLE));\r
-               if (m_pXkeymacsDll->IsKeyboardHook()) {\r
+               if (CXkeymacsDll::IsKeyboardHook()) {\r
                        szDisable.LoadString(IDS_DISABLE);\r
                }\r
                szDisable += _T("\tCtrl+Q");\r
@@ -359,7 +471,7 @@ LRESULT CMainFrame::WindowProc(const UINT message, const WPARAM wParam, const LP
                }\r
        default:\r
                if (message == s_uTaskbarRestart) {\r
-                       m_pXkeymacsDll->AddAllShell_NotifyIcon();\r
+                       AddAllShell_NotifyIcon();\r
                }\r
                break;\r
        }\r
@@ -385,11 +497,7 @@ void CMainFrame::OnOptions()
 // stop/start keyboard hook\r
 void CMainFrame::OnDisable() \r
 {\r
-       if (m_pXkeymacsDll->IsKeyboardHook()) {\r
-               m_pXkeymacsDll->SetKeyboardHookFlag(FALSE);\r
-       } else {\r
-               m_pXkeymacsDll->SetKeyboardHookFlag(TRUE);\r
-       }\r
+       CXkeymacsDll::ToggleKeyboardHookState();\r
 }\r
 \r
 // Close the Dialog if it is opened.\r
@@ -411,8 +519,10 @@ void CMainFrame::OnQuit()
                CloseDialog(m_p109KeyboardDlg[i], &m_nResultKeyboardDlg[JAPANESE_KEYBOARD][i]);\r
        }\r
 \r
-       m_pXkeymacsDll->ReleaseHooks();\r
-       m_pXkeymacsDll->DeleteAllShell_NotifyIcon();\r
+       CXkeymacsDll::ReleaseHooks();\r
+       TerminatePollThread();\r
+       static_cast<CXkeymacsApp *>(AfxGetApp())->SendIPCMessage(XKEYMACS_EXIT);\r
+       DeleteAllShell_NotifyIcon();\r
 \r
        PostQuitMessage(0);\r
 }\r
@@ -459,22 +569,26 @@ void CMainFrame::OnExport()
 \r
 void CMainFrame::OnReset() \r
 {\r
-       m_pXkeymacsDll->ReleaseHooks();\r
-       m_pXkeymacsDll->SetHooks();\r
+       TerminatePollThread();\r
+       CXkeymacsDll::ResetHooks();\r
+       StartPollThread();\r
+       CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());\r
+       if (!pApp->SendIPCMessage(XKEYMACS_RESET))\r
+               pApp->Create64bitProcess(); // try to restart 64bit app\r
 }\r
 \r
 void CMainFrame::OnHelpFinder() \r
 {\r
        TCHAR szPath[MAX_PATH] = {'\0'};\r
        const TCHAR szExt[] = _T("txt");\r
-       _tmakepath(szPath, NULL, NULL, CString(MAKEINTRESOURCE(IDS_README)), szExt);\r
+       _tmakepath_s(szPath, NULL, NULL, CString(MAKEINTRESOURCE(IDS_README)), szExt);\r
 \r
        TCHAR szModuleFileName[MAX_PATH] = {'\0'};\r
        if (GetModuleFileName(NULL, szModuleFileName, sizeof(szModuleFileName))) {\r
                TCHAR szDrive[_MAX_DRIVE] = {'\0'};\r
                TCHAR szDir[_MAX_DIR] = {'\0'};\r
-               _tsplitpath(szModuleFileName, szDrive, szDir, NULL, NULL);\r
-               _tmakepath(szPath, szDrive, szDir, CString(MAKEINTRESOURCE(IDS_README)), szExt);\r
+               _tsplitpath_s(szModuleFileName, szDrive, _MAX_DRIVE, szDir, _MAX_DIR, NULL, 0, NULL, 0);\r
+               _tmakepath_s(szPath, szDrive, szDir, CString(MAKEINTRESOURCE(IDS_README)), szExt);\r
        }\r
 \r
        ShellExecute(NULL, NULL, szPath, NULL, NULL, SW_SHOWNORMAL);\r