#include <Lmcons.h>\r
#include "xkeymacs.h"\r
#include "Profile.h"\r
-\r
#include "MainFrm.h"\r
\r
#ifdef _DEBUG\r
\r
CMainFrame::CMainFrame()\r
{\r
- m_pXkeymacsDll = new CXkeymacsDll;\r
m_pPropertiesDlg = new CProperties;\r
m_nResultPropertiesDlg = -1;\r
m_bPropertiesDlgExist = FALSE;\r
}\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
\r
CMainFrame::~CMainFrame()\r
{\r
- delete m_pXkeymacsDll;\r
- m_pXkeymacsDll = NULL;\r
-\r
delete m_pPropertiesDlg;\r
m_pPropertiesDlg = NULL;\r
\r
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
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
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
}\r
default:\r
if (message == s_uTaskbarRestart) {\r
- m_pXkeymacsDll->AddAllShell_NotifyIcon();\r
+ AddAllShell_NotifyIcon();\r
}\r
break;\r
}\r
// 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
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
\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