#include <afxdllx.h>\r
#include <math.h>\r
#include <Imm.h>\r
+#include <vector>\r
\r
#ifdef _DEBUG\r
#define new DEBUG_NEW\r
static char THIS_FILE[] = __FILE__;\r
#endif\r
\r
+struct Modifier {\r
+ LPCTSTR name;\r
+ int id;\r
+};\r
+\r
+static const Modifier Modifiers[] = {\r
+// { _T("A-"), ALT },\r
+ { _T("C-"), CONTROL},\r
+// { _T("H-"), HYPER },\r
+ { _T("M-"), META },\r
+ { _T("S-"), SHIFT },\r
+// { _T("s-"), SUPER },\r
+ { _T("Ctrl+"), WIN_CTRL },\r
+ { _T("Alt+"), WIN_ALT },\r
+ { _T("Win+"), WIN_WIN },\r
+};\r
+static const int MAX_MODIFIER = _countof(Modifiers);\r
+\r
+static const KeyName KeyNames[] = {\r
+// { VK_LBUTTON, _T("mouse-1") }, // does not work well\r
+// { VK_RBUTTON, _T("mouse-3") }, // does not work well\r
+ { VK_CANCEL, _T("break") },\r
+// { VK_MBUTTON, _T("mouse-2") }, // does not work well\r
+ { VK_BACK, _T("backspace") },\r
+ { VK_TAB, _T("tab") },\r
+ { VK_RETURN, _T("return") },\r
+ { VK_CAPITAL, _T("capslock") },\r
+ { VK_KANA, _T("kana") },\r
+ { VK_KANJI, _T("kanji") },\r
+ { VK_ESCAPE, _T("escape") },\r
+ { VK_CONVERT, _T("convert") },\r
+ { VK_NONCONVERT, _T("nonconvert") },\r
+// { VK_SPACE, _T("SPC") }, // [? ]\r
+ { VK_PRIOR, _T("prior") },\r
+ { VK_NEXT, _T("next") },\r
+ { VK_END, _T("end") },\r
+ { VK_HOME, _T("home") },\r
+ { VK_LEFT, _T("left") },\r
+ { VK_UP, _T("up") },\r
+ { VK_RIGHT, _T("right") },\r
+ { VK_DOWN, _T("down") },\r
+ { VK_SELECT, _T("select") },\r
+ { VK_PRINT, _T("print") },\r
+ { VK_EXECUTE, _T("execute") },\r
+ { VK_SNAPSHOT, _T("printscreen") }, // work as print\r
+ { VK_INSERT, _T("insert") },\r
+ { VK_DELETE, _T("delete") },\r
+ { VK_LWIN, _T("lwindow") },\r
+ { VK_RWIN, _T("rwindow") },\r
+ { VK_APPS, _T("apps") },\r
+ { VK_SLEEP, _T("sleep") },\r
+ { VK_NUMPAD0, _T("kp-0") },\r
+ { VK_NUMPAD1, _T("kp-1") },\r
+ { VK_NUMPAD2, _T("kp-2") },\r
+ { VK_NUMPAD3, _T("kp-3") },\r
+ { VK_NUMPAD4, _T("kp-4") },\r
+ { VK_NUMPAD5, _T("kp-5") },\r
+ { VK_NUMPAD6, _T("kp-6") },\r
+ { VK_NUMPAD7, _T("kp-7") },\r
+ { VK_NUMPAD8, _T("kp-8") },\r
+ { VK_NUMPAD9, _T("kp-9") },\r
+ { VK_MULTIPLY, _T("kp-multiply") },\r
+ { VK_ADD, _T("kp-add") },\r
+ { VK_SUBTRACT, _T("kp-subtract") },\r
+ { VK_DECIMAL, _T("kp-decimal") },\r
+ { VK_DIVIDE, _T("kp-divide") },\r
+// { VK_F1, _T("f1") }, // FIXME\r
+// { VK_F2, _T("f2") }, // Move at the end of definition of function keys to keep away confliction f1/f2 and f1?/f2? by _tcsncmp() i.e. strncmp()\r
+ { VK_F3, _T("f3") },\r
+ { VK_F4, _T("f4") },\r
+ { VK_F5, _T("f5") },\r
+ { VK_F6, _T("f6") },\r
+ { VK_F7, _T("f7") },\r
+ { VK_F8, _T("f8") },\r
+ { VK_F9, _T("f9") },\r
+ { VK_F10, _T("f10") },\r
+ { VK_F11, _T("f11") },\r
+ { VK_F12, _T("f12") },\r
+ { VK_F13, _T("f13") },\r
+ { VK_F14, _T("f14") },\r
+ { VK_F15, _T("f15") },\r
+ { VK_F16, _T("f16") },\r
+ { VK_F17, _T("f17") },\r
+ { VK_F18, _T("f18") },\r
+ { VK_F19, _T("f19") },\r
+ { VK_F20, _T("f20") },\r
+ { VK_F21, _T("f21") },\r
+ { VK_F22, _T("f22") },\r
+ { VK_F23, _T("f23") },\r
+ { VK_F24, _T("f24") },\r
+ { VK_F1, _T("f1") },\r
+ { VK_F2, _T("f2") },\r
+ { VK_NUMLOCK, _T("kp-numlock") },\r
+ { VK_SCROLL, _T("scroll") },\r
+ { 0xa6, _T("browser-back") }, // VK_BROWSER_BACK\r
+ { 0xa7, _T("browser-forward") }, // VK_BROWSER_FORWARD\r
+ { 0xa8, _T("browser-refresh") }, // VK_BROWSER_REFRESH\r
+ { 0xa9, _T("browser-stop") }, // VK_BROWSER_STOP\r
+ { 0xaa, _T("browser-search") }, // VK_BROWSER_SEARCH\r
+ { 0xab, _T("browser-favorites") }, // VK_BROWSER_FAVORITES\r
+ { 0xac, _T("browser-home") }, // VK_BROWSER_HOME\r
+ { 0xad, _T("volume-mute") }, // VK_VOLUME_MUTE\r
+ { 0xae, _T("volume-down") }, // VK_VOLUME_DOWN\r
+ { 0xaf, _T("volume-up") }, // VK_VOLUME_UP\r
+ { 0xb0, _T("media-next-track") }, // VK_MEDIA_NEXT_TRACK\r
+ { 0xb1, _T("media-prev-track") }, // VK_MEDIA_PREV_TRACK\r
+ { 0xb2, _T("media-stop") }, // VK_MEDIA_STOP\r
+ { 0xb3, _T("media-play-pause") }, // VK_MEDIA_PLAY_PAUSE\r
+ { 0xb4, _T("launch-mail") }, // VK_LAUNCH_MAIL\r
+ { 0xb5, _T("launch-media-select") }, // VK_LAUNCH_MEDIA_SELECT\r
+ { 0xb6, _T("launch-1") }, // VK_LAUNCH_APP1\r
+ { 0xb7, _T("launch-2") }, // VK_LAUNCH_APP2\r
+};\r
+static const int MAX_KEYNAME = _countof(KeyNames);\r
\r
static AFX_EXTENSION_MODULE XkeymacsdllDLL = { NULL, NULL };\r
\r
-static __declspec(thread) HINSTANCE g_hDllInst = NULL;\r
-static __declspec(thread) HHOOK g_hHookKeyboard = NULL;\r
+static HINSTANCE g_hDllInst = NULL;\r
+static DWORD g_TlsIndex = NULL;\r
\r
extern "C" int APIENTRY\r
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)\r
{\r
g_hDllInst = hInstance;\r
+ LPVOID lpData;\r
\r
// Remove this if you use lpReserved\r
UNREFERENCED_PARAMETER(lpReserved);\r
switch (dwReason) {\r
case DLL_PROCESS_ATTACH:\r
TRACE0("XKEYMACSDLL.DLL Initializing!\n");\r
- \r
+\r
// Extension DLL one-time initialization\r
if (!AfxInitExtensionModule(XkeymacsdllDLL, hInstance)) {\r
return 0;\r
e->Delete();\r
// CUtils::Log("DllMain: 'new' threw an exception");\r
}\r
+\r
+ if ((g_TlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)\r
+ return FALSE;\r
+ // fall through\r
case DLL_THREAD_ATTACH:\r
- CXkeymacsDll::SetKeyboardHook();\r
+ if ((lpData = LocalAlloc(LPTR, sizeof(HHOOK))) != NULL)\r
+ TlsSetValue(g_TlsIndex, lpData);\r
break;\r
case DLL_PROCESS_DETACH:\r
TRACE0("XKEYMACSDLL.DLL Terminating!\n");\r
// Terminate the library before destructors are called\r
AfxTermExtensionModule(XkeymacsdllDLL);\r
+ CXkeymacsDll::ReleaseKeyboardHook();\r
+ if ((lpData = TlsGetValue(g_TlsIndex)) != NULL)\r
+ LocalFree(lpData);\r
+ TlsFree(g_TlsIndex);\r
+ break;\r
case DLL_THREAD_DETACH:\r
CXkeymacsDll::ReleaseKeyboardHook();\r
+ if ((lpData = TlsGetValue(g_TlsIndex)) != NULL)\r
+ LocalFree(lpData);\r
+ break;\r
}\r
return 1; // ok\r
}\r
\r
#include "xkeymacsDll.h"\r
#pragma data_seg(".xkmcs")\r
- BOOL CXkeymacsDll::m_bEnableKeyboardHook = FALSE;\r
- HHOOK CXkeymacsDll::m_hHookCallWnd = NULL;\r
- HHOOK CXkeymacsDll::m_hHookCallWndRet = NULL;\r
- HHOOK CXkeymacsDll::m_hHookGetMessage = NULL;\r
- HHOOK CXkeymacsDll::m_hHookShell = NULL;\r
- int CXkeymacsDll::m_nCommandID[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};\r
- BOOL CXkeymacsDll::m_bAtIbeamCursorOnly[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};\r
- int CXkeymacsDll::m_nFunctionID[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};\r
- TCHAR CXkeymacsDll::m_szSpecialApp[MAX_APP][CLASS_NAME_LENGTH] = {'\0'};\r
- TCHAR CXkeymacsDll::m_szWindowText[MAX_APP][WINDOW_TEXT_LENGTH] = {'\0'};\r
+ bool CXkeymacsDll::m_bEnableKeyboardHook = false;\r
+ DWORD CXkeymacsDll::m_nHookAltRelease = 0;\r
BOOL CXkeymacsDll::m_bRightControl = FALSE;\r
BOOL CXkeymacsDll::m_bRightAlt = FALSE;\r
BOOL CXkeymacsDll::m_bRightShift = FALSE;\r
BOOL CXkeymacsDll::m_bHook = TRUE;\r
- BOOL CXkeymacsDll::m_bDefiningMacro = FALSE;\r
- DWORD CXkeymacsDll::m_dwOldMessage[MAX_ICON_TYPE] = {'\0'};\r
- NOTIFYICONDATA CXkeymacsDll::m_stNtfyIcon[MAX_ICON_TYPE] = {'\0'};\r
- NOTIFYICONDATA CXkeymacsDll::m_stOldNtfyIcon[MAX_ICON_TYPE] = {'\0'};\r
- HICON CXkeymacsDll::m_hIcon[MAX_ICON_TYPE][MAX_STATUS] = {'\0'};\r
- BOOL CXkeymacsDll::m_bIcon[MAX_ICON_TYPE] = {'\0'};\r
- int CXkeymacsDll::m_nKillRingMax[MAX_APP] = {'\0'};\r
- BOOL CXkeymacsDll::m_bUseDialogSetting[MAX_APP] = {'\0'};\r
CList<CClipboardSnap *, CClipboardSnap *> CXkeymacsDll::m_oKillRing;\r
- CObList CXkeymacsDll::m_Macro;\r
int CXkeymacsDll::m_nKillRing = 0;\r
- int CXkeymacsDll::m_nOriginal[MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};\r
- int CXkeymacsDll::m_nApplicationID = 0;\r
- int CXkeymacsDll::m_nSettingStyle[MAX_APP] = {'\0'};\r
- BOOL CXkeymacsDll::m_bIgnoreUndefinedMetaCtrl[MAX_APP] = {'\0'};\r
- BOOL CXkeymacsDll::m_bIgnoreUndefinedC_x[MAX_APP] = {'\0'};\r
-// int CXkeymacsDll::m_nPassThrough = 0;\r
- TCHAR CXkeymacsDll::m_szApplicationName[MAX_PATH] = {'\0'};\r
- TCHAR CXkeymacsDll::m_szOldApplicationName[MAX_PATH] = {'\0'};\r
- BOOL CXkeymacsDll::m_bEnableCUA[MAX_APP] = {'\0'};\r
- TCHAR CXkeymacsDll::m_szFunctionDefinition[MAX_FUNCTION][MAX_DEFINITION] = {'\0'};\r
+ BYTE CXkeymacsDll::m_nOriginal[MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};\r
+ int CXkeymacsDll::m_nAppID = 0;\r
int CXkeymacsDll::m_nAccelerate = 0;\r
int CXkeymacsDll::m_nKeyboardSpeed = 31;\r
HCURSOR CXkeymacsDll::m_hCursor[MAX_STATUS] = {'\0'};\r
HCURSOR CXkeymacsDll::m_hCurrentCursor = NULL;\r
BOOL CXkeymacsDll::m_bCursor = FALSE;\r
- BOOL CXkeymacsDll::m_b326Compatible[MAX_APP] = {'\0'};\r
-\r
- BOOL CXkeymacsData::m_b106Keyboard = FALSE;\r
+ TCHAR CXkeymacsDll::m_M_xTip[128] = "";\r
+ CONFIG CXkeymacsDll::m_Config = {0};\r
#pragma data_seg()\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Construction/Destruction\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-CXkeymacsDll::CXkeymacsDll()\r
-{\r
- CUtils::InitCUtils();\r
-}\r
-\r
-CXkeymacsDll::~CXkeymacsDll()\r
-{\r
-\r
-}\r
-\r
-int CXkeymacsDll::ModifyShell_NotifyIcon(ICON_TYPE icon, BOOL bNewStatus, BOOL bForce)\r
-{\r
- if (m_stNtfyIcon[icon].hIcon == (bNewStatus ? m_hIcon[icon][ON_ICON] : m_hIcon[icon][OFF_ICON])) {\r
- if (!bForce) {\r
- return TRUE;\r
- }\r
- } else {\r
- m_stNtfyIcon[icon].hIcon = (bNewStatus ? m_hIcon[icon][ON_ICON] : m_hIcon[icon][OFF_ICON]);\r
- }\r
- return DoShell_NotifyIcon(icon, NIM_MODIFY);\r
+HHOOK CXkeymacsDll::m_hHookCallWnd = NULL;\r
+HHOOK CXkeymacsDll::m_hHookCallWndRet = NULL;\r
+HHOOK CXkeymacsDll::m_hHookGetMessage = NULL;\r
+HHOOK CXkeymacsDll::m_hHookShell = NULL;\r
+BOOL CXkeymacsDll::m_bRecordingMacro = FALSE;\r
+BOOL CXkeymacsDll::m_bDown[MAX_KEY] = {0};\r
+std::list<KbdMacro> CXkeymacsDll::m_Macro;\r
+\r
+BOOL CXkeymacsDll::SaveConfig()\r
+{\r
+ TCHAR szTmp[MAX_PATH];\r
+ if (!GetTempPath(MAX_PATH, szTmp))\r
+ return FALSE;\r
+ if (_tmakepath_s(szTmp, NULL, szTmp, _T("xkeymacs"), _T("tmp")))\r
+ return FALSE;\r
+ HANDLE hFile = CreateFile(szTmp, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);\r
+ if (hFile == INVALID_HANDLE_VALUE)\r
+ return FALSE;\r
+ DWORD written;\r
+ BOOL res = WriteFile(hFile, &m_Config, sizeof(m_Config), &written, NULL) || written != sizeof(m_Config);\r
+ CloseHandle(hFile);\r
+ return res;\r
}\r
\r
-void CXkeymacsDll::SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hEnable, HICON hDisableTMP, HICON hDisableWOCQ, HICON hDisable, BOOL bEnable)\r
+BOOL CXkeymacsDll::LoadConfig()\r
{\r
- m_hIcon[icon][STATUS_ENABLE] = hEnable;\r
- m_hIcon[icon][STATUS_DISABLE_TMP] = hDisableTMP;\r
- m_hIcon[icon][STATUS_DISABLE_WOCQ] = hDisableWOCQ;\r
- m_hIcon[icon][STATUS_DISABLE] = hDisable;\r
- m_bIcon[icon] = bEnable;\r
- m_stNtfyIcon[icon] = stNtfyIcon;\r
- AddShell_NotifyIcon(icon);\r
+ TCHAR szTmp[MAX_PATH];\r
+ if (!GetTempPath(MAX_PATH, szTmp))\r
+ return FALSE;\r
+ if (_tmakepath_s(szTmp, NULL, szTmp, _T("xkeymacs"), _T("tmp")))\r
+ return FALSE;\r
+ HANDLE hFile = CreateFile(szTmp, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);\r
+ if (hFile == INVALID_HANDLE_VALUE)\r
+ return FALSE;\r
+ DWORD read;\r
+ BOOL res = ReadFile(hFile, &m_Config, sizeof(m_Config), &read, NULL) && read == sizeof(m_Config);\r
+ CloseHandle(hFile);\r
+ return res;\r
}\r
\r
-void CXkeymacsDll::SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hOn, HICON hOff, BOOL bEnable)\r
+void CXkeymacsDll::SetConfig(const CONFIG& config)\r
{\r
- m_hIcon[icon][ON_ICON] = hOn;\r
- m_hIcon[icon][OFF_ICON] = hOff;\r
- m_bIcon[icon] = bEnable;\r
- m_stNtfyIcon[icon] = stNtfyIcon;\r
- AddShell_NotifyIcon(icon);\r
+ m_Config = config;\r
}\r
\r
-void CXkeymacsDll::EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable)\r
+void CXkeymacsDll::SetHooks()\r
{\r
- DeleteShell_NotifyIcon(icon);\r
- m_bIcon[icon] = bEnable;\r
- AddShell_NotifyIcon(icon);\r
+ m_hHookCallWnd = SetWindowsHookEx(WH_CALLWNDPROC, CallWndProc, g_hDllInst, 0);\r
+ m_hHookCallWndRet = SetWindowsHookEx(WH_CALLWNDPROCRET, CallWndRetProc, g_hDllInst, 0);\r
+ m_hHookGetMessage = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hDllInst, 0);\r
+ m_hHookShell = SetWindowsHookEx(WH_SHELL, ShellProc, g_hDllInst, 0);\r
+ m_bEnableKeyboardHook = true;\r
}\r
\r
-\r
-BOOL CXkeymacsDll::DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage)\r
+void CXkeymacsDll::SetKeyboardHook()\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
+ LPVOID lpData = TlsGetValue(g_TlsIndex);\r
+ if (!lpData) {\r
+ lpData = LocalAlloc(LPTR, sizeof(HHOOK));\r
+ if (!lpData)\r
+ return;\r
+ if (!TlsSetValue(g_TlsIndex, lpData))\r
+ return;\r
}\r
+ HHOOK *phHook = reinterpret_cast<HHOOK *>(lpData);\r
+ if (!*phHook)\r
+ *phHook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hDllInst, GetCurrentThreadId());\r
}\r
\r
-void CXkeymacsDll::AddShell_NotifyIcon(ICON_TYPE icon)\r
-{\r
- DoShell_NotifyIcon(icon, NIM_ADD);\r
-}\r
-\r
-void CXkeymacsDll::DeleteShell_NotifyIcon(ICON_TYPE icon)\r
+inline void unhook(HHOOK &hh)\r
{\r
- DoShell_NotifyIcon(icon, NIM_DELETE);\r
+ if (hh)\r
+ UnhookWindowsHookEx(hh);\r
+ hh = NULL;\r
}\r
\r
-// set hooks\r
-void CXkeymacsDll::SetHooks()\r
-{\r
- m_bEnableKeyboardHook = TRUE;\r
- m_hHookCallWnd = SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProc, g_hDllInst, 0);\r
- m_hHookCallWndRet = SetWindowsHookEx(WH_CALLWNDPROCRET, (HOOKPROC)CallWndRetProc, g_hDllInst, 0);\r
- m_hHookGetMessage = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hDllInst, 0);\r
- m_hHookShell = SetWindowsHookEx(WH_SHELL, (HOOKPROC)ShellProc, g_hDllInst, 0);\r
-}\r
-\r
-void CXkeymacsDll::SetKeyboardHook()\r
+void CXkeymacsDll::ResetHooks() \r
{\r
- if (!g_hHookKeyboard)\r
- SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, g_hDllInst, GetCurrentThreadId());\r
+ ReleaseHooks();\r
+ SetHooks();\r
}\r
\r
-// release hooks\r
void CXkeymacsDll::ReleaseHooks()\r
{\r
- m_bEnableKeyboardHook = FALSE;\r
- if (m_hHookCallWnd)\r
- UnhookWindowsHookEx(m_hHookCallWnd);\r
- m_hHookCallWnd = NULL;\r
- if (m_hHookCallWndRet)\r
- UnhookWindowsHookEx(m_hHookCallWndRet);\r
- m_hHookCallWndRet = NULL;\r
- if (m_hHookGetMessage)\r
- UnhookWindowsHookEx(m_hHookGetMessage);\r
- m_hHookGetMessage = NULL;\r
- if (m_hHookShell)\r
- UnhookWindowsHookEx(m_hHookShell);\r
- m_hHookShell = NULL;\r
+ unhook(m_hHookCallWnd);\r
+ unhook(m_hHookCallWndRet);\r
+ unhook(m_hHookGetMessage);\r
+ unhook(m_hHookShell);\r
+ m_bEnableKeyboardHook = false;\r
}\r
\r
void CXkeymacsDll::ReleaseKeyboardHook()\r
{\r
- if (g_hHookKeyboard)\r
- UnhookWindowsHookEx(g_hHookKeyboard);\r
- g_hHookKeyboard = NULL;\r
+ HHOOK *phHook = reinterpret_cast<HHOOK *>(TlsGetValue(g_TlsIndex));\r
+ if (phHook)\r
+ unhook(*phHook);\r
}\r
\r
-void CXkeymacsDll::SetKeyboardHookFlag(BOOL bFlag)\r
+void CXkeymacsDll::ToggleKeyboardHookState()\r
{\r
- m_bHook = bFlag;\r
+ m_bHook = !m_bHook;\r
+ ShowKeyboardHookState();\r
+}\r
\r
+void CXkeymacsDll::ShowKeyboardHookState()\r
+{\r
+ ICONMSG msg = {MAIN_ICON,};\r
if (m_bHook) {\r
if (CCommands::IsTemporarilyDisableXKeymacs()) {\r
- m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE_TMP];\r
+ msg.nState = STATUS_DISABLE_TMP;\r
m_hCurrentCursor = m_hCursor[STATUS_DISABLE_TMP];\r
} else {\r
- m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_ENABLE];\r
+ msg.nState = STATUS_ENABLE;\r
m_hCurrentCursor = m_hCursor[STATUS_ENABLE];\r
}\r
} else {\r
- m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE_WOCQ];\r
- m_hCurrentCursor = m_hCursor[STATUS_DISABLE_WOCQ];\r
+ msg.nState = STATUS_DISABLE_WOCQ;\r
}\r
- if (m_nSettingStyle[m_nApplicationID] == SETTING_DISABLE\r
- || (!_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Default"))\r
+ if (m_Config.nSettingStyle[m_nAppID] == SETTING_DISABLE\r
+ || (!_tcsicmp(m_Config.szSpecialApp[m_nAppID], _T("Default"))\r
&& CUtils::IsDefaultIgnoreApplication())) {\r
- m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE];\r
+ msg.nState = STATUS_DISABLE;\r
m_hCurrentCursor = m_hCursor[STATUS_DISABLE];\r
}\r
- DoShell_NotifyIcon(MAIN_ICON, NIM_MODIFY);\r
+ SendIconMessage(&msg, 1);\r
DoSetCursor();\r
}\r
\r
-// if be keyboard hook, return TRUE\r
BOOL CXkeymacsDll::IsKeyboardHook()\r
{\r
- if (m_bHook) {\r
- return TRUE;\r
- }\r
-\r
- return FALSE;\r
-}\r
-\r
-void CXkeymacsDll::LogCallWndProcMessage(WPARAM wParam, LPARAM lParam)\r
-{\r
- CWPSTRUCT &cwps = *(CWPSTRUCT *)lParam;\r
-\r
- switch (cwps.message) {\r
- case WM_PAINT: // 0x000F\r
- case WM_MDIGETACTIVE: // 0x0229\r
- case 0x0403:\r
- case 0x0407:\r
- case 0x0418:\r
- case 0x043F:\r
- case 0x0440:\r
- break;\r
- case WM_CREATE: // 0x0001\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_CREATE"));\r
- break;\r
- case WM_DESTROY: // 0x0002\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_DESTROY"));\r
- break;\r
- case WM_MOVE: // 0x0003\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_MOVE");)\r
- break;\r
- case WM_SIZE: // 0x0005\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_SIZE"));\r
- break;\r
- case WM_GETTEXT: // 0x000D\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_GETTEXT"));\r
- break;\r
- case WM_ERASEBKGND: // 0x0014\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_ERASEBKGND"));\r
- break;\r
- case WM_WINDOWPOSCHANGING: // 0x0046\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_WINDOWPOSCHANGING"));\r
- break;\r
- case WM_WINDOWPOSCHANGED: // 0x0047\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_WINDOWPOSCHANGED"));\r
- break;\r
- case WM_COPYDATA: // 0x004A\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_COPYDATA"));\r
- break;\r
- case WM_NCCREATE: // 0x0081\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_NCCREATE"));\r
- break;\r
- case WM_NCDESTROY: // 0x0082\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_NCDESTROY"));\r
- break;\r
- case WM_NCCALCSIZE: // 0x0083\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_NCCALCSIZE"));\r
- break;\r
- case WM_NCPAINT: // 0x0085\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_NCPAINT"));\r
- break;\r
- case WM_IME_STARTCOMPOSITION: // 0x010D\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_IME_STARTCOMPOSITION"));\r
- break;\r
- case WM_IME_ENDCOMPOSITION: // 0x010E\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_IME_ENDCOMPOSITION"));\r
- break;\r
- case WM_IME_KEYLAST: // 0x010F\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_IME_KEYLAST"));\r
- break;\r
- case WM_COMMAND: // 0x0111\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_COMMAND"));\r
- break;\r
- case WM_CTLCOLOREDIT: // 0x0133\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_CTLCOLOREDIT"));\r
- break;\r
- case WM_POWERBROADCAST: // 0x0218\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_POWERBROADCAST"));\r
- switch (wParam) {\r
- case PBT_APMQUERYSUSPEND: // 0x0000\r
-// CUtils::Log(_T("PBT_APMQUERYSUSPEND"));\r
- break;\r
- case PBT_APMQUERYSTANDBY: // 0x0001\r
-// CUtils::Log(_T("PBT_APMQUERYSTANDBY"));\r
- break;\r
- case PBT_APMQUERYSUSPENDFAILED: // 0x0002\r
-// CUtils::Log(_T("PBT_APMQUERYSUSPENDFAILED"));\r
- break;\r
- case PBT_APMQUERYSTANDBYFAILED: // 0x0003\r
-// CUtils::Log(_T("PBT_APMQUERYSTANDBYFAILED"));\r
- break;\r
- case PBT_APMSUSPEND: // 0x0004\r
-// CUtils::Log(_T("PBT_APMSUSPEND"));\r
- break;\r
- case PBT_APMSTANDBY: // 0x0005\r
-// CUtils::Log(_T("PBT_APMSTANDBY"));\r
- break;\r
- case PBT_APMRESUMECRITICAL: // 0x0006\r
-// CUtils::Log(_T("PBT_APMRESUMECRITICAL"));\r
- break;\r
- case PBT_APMRESUMESUSPEND: // 0x0007\r
-// CUtils::Log(_T("PBT_APMRESUMESUSPEND"));\r
- break;\r
- case PBT_APMRESUMESTANDBY: // 0x0008\r
-// CUtils::Log(_T("PBT_APMRESUMESTANDBY"));\r
- break;\r
- case PBT_APMBATTERYLOW: // 0x0009\r
-// CUtils::Log(_T("PBT_APMBATTERYLOW"));\r
- break;\r
- case PBT_APMPOWERSTATUSCHANGE: // 0x000A\r
-// CUtils::Log(_T("PBT_APMPOWERSTATUSCHANGE"));\r
- break;\r
- case PBT_APMOEMEVENT: // 0x000B\r
-// CUtils::Log(_T("PBT_APMOEMEVENT"));\r
- break;\r
- case PBT_APMRESUMEAUTOMATIC: // 0x0012\r
-// CUtils::Log(_T("PBT_APMRESUMEAUTOMATIC"));\r
- break;\r
- default:\r
-// CUtils::Log(_T("PBT_OTHERS: %d"), wParam);\r
- break;\r
- }\r
- break;\r
- case WM_IME_NOTIFY: // 0x0282\r
-// CUtils::Log(_T("CallWndProc: cwps.message = WM_IME_NOTIFY"));\r
- break;\r
- default:\r
-// CUtils::Log(_T("CallWndProc: cwps.message = 0x%04X"), cwps.message);\r
- break;\r
- }\r
+ return m_bHook;\r
}\r
\r
LRESULT CALLBACK CXkeymacsDll::CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)\r
{\r
-// LogCallWndProcMessage(wParam, lParam);\r
-\r
- if (0 <= nCode) {\r
- CWPSTRUCT &cwps = *(CWPSTRUCT *)lParam;\r
- switch (cwps.message) {\r
+ SetKeyboardHook();\r
+ if (nCode >= 0) {\r
+ const CWPSTRUCT *cwps = reinterpret_cast<CWPSTRUCT *>(lParam);\r
+ switch (cwps->message) {\r
case WM_IME_STARTCOMPOSITION:\r
InitKeyboardProc(TRUE);\r
break;\r
InitKeyboardProc(FALSE);\r
break;\r
case WM_SETFOCUS:\r
- if (cwps.hwnd == GetForegroundWindow()) {\r
+ if (cwps->hwnd == GetForegroundWindow()) {\r
InitKeyboardProc(FALSE);\r
- SetKeyboardHookFlag(m_bHook);\r
+ ShowKeyboardHookState();\r
}\r
break;\r
case WM_NCACTIVATE:\r
- if (cwps.wParam) {\r
- if (cwps.hwnd == GetForegroundWindow()) {\r
- InitKeyboardProc(FALSE);\r
- SetKeyboardHookFlag(m_bHook);\r
- }\r
- }\r
- break;\r
- case WM_POWERBROADCAST:\r
- switch (wParam) {\r
- case PBT_APMRESUMECRITICAL: // 0x0006\r
- case PBT_APMRESUMESUSPEND: // 0x0007\r
- case PBT_APMRESUMESTANDBY: // 0x0008\r
- ReleaseHooks();\r
- SetHooks();\r
- break;\r
- default:\r
- break;\r
+ if (cwps->wParam && cwps->hwnd == GetForegroundWindow()) {\r
+ InitKeyboardProc(FALSE);\r
+ ShowKeyboardHookState();\r
}\r
break;\r
- default:\r
- break;\r
}\r
}\r
- return CallNextHookEx(m_hHookCallWnd, nCode, wParam, lParam);\r
+ return CallNextHookEx(NULL, nCode, wParam, lParam);\r
}\r
\r
LRESULT CALLBACK CXkeymacsDll::CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)\r
{\r
- if (0 <= nCode) {\r
- CWPRETSTRUCT &cwprets = *(CWPRETSTRUCT *)lParam;\r
- switch (cwprets.message) {\r
+ SetKeyboardHook();\r
+ if (nCode >= 0) {\r
+ const CWPRETSTRUCT *cwprets = reinterpret_cast<CWPRETSTRUCT *>(lParam);\r
+ switch (cwprets->message) {\r
case WM_SETTEXT:\r
- if (cwprets.hwnd == GetForegroundWindow()) {\r
+ if (cwprets->hwnd == GetForegroundWindow())\r
InitKeyboardProc(FALSE);\r
- }\r
break;\r
case WM_SETCURSOR:\r
DoSetCursor();\r
break;\r
- default:\r
- break;\r
}\r
}\r
- return CallNextHookEx(m_hHookCallWndRet, nCode, wParam, lParam);\r
+ return CallNextHookEx(NULL, nCode, wParam, lParam);\r
}\r
\r
LRESULT CALLBACK CXkeymacsDll::GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)\r
{\r
- MSG &msg = (*(MSG *)lParam);\r
-\r
- switch (msg.message) {\r
- case WM_IME_STARTCOMPOSITION:\r
- InitKeyboardProc(TRUE);\r
- break;\r
- case WM_IME_ENDCOMPOSITION:\r
- InitKeyboardProc(FALSE);\r
- break;\r
+ SetKeyboardHook();\r
+ if (nCode >= 0) {\r
+ const MSG *msg = reinterpret_cast<MSG *>(lParam);\r
+ switch (msg->message) {\r
+ case WM_IME_STARTCOMPOSITION:\r
+ InitKeyboardProc(TRUE);\r
+ break;\r
+ case WM_IME_ENDCOMPOSITION:\r
+ InitKeyboardProc(FALSE);\r
+ break;\r
+ }\r
}\r
- return CallNextHookEx(m_hHookGetMessage, nCode, wParam, lParam);\r
+ return CallNextHookEx(NULL, nCode, wParam, lParam);\r
}\r
\r
LRESULT CALLBACK CXkeymacsDll::ShellProc(int nCode, WPARAM wParam, LPARAM lParam)\r
{\r
- switch (nCode) {\r
- case HSHELL_WINDOWACTIVATED:\r
- {\r
+ if (nCode == HSHELL_WINDOWACTIVATED) {\r
TCHAR className[256];\r
- ::GetClassName((HWND)wParam, className, 255);\r
+ GetClassName((HWND)wParam, className, 255);\r
if (!_tcsicmp(className, _T("ConsoleWindowClass"))) {\r
InitKeyboardProc(FALSE);\r
- SetKeyboardHookFlag(m_bHook);\r
+ ShowKeyboardHookState();\r
}\r
- break;\r
}\r
- default:\r
- break;\r
+ return CallNextHookEx(NULL, nCode, wParam, lParam);\r
+}\r
+\r
+UINT CXkeymacsDll::GetModifierState(BOOL bPhysicalKey)\r
+{\r
+ UINT result = 0;\r
+ if (IsDown(VK_SHIFT, bPhysicalKey))\r
+ result |= SHIFT;\r
+ if (IsDown(VK_CONTROL, bPhysicalKey))\r
+ result |= CONTROL;\r
+ if (IsDown(VK_MENU, bPhysicalKey))\r
+ result |= META;\r
+ return result;\r
+}\r
+\r
+void CXkeymacsDll::SetModifierState(const UINT after, const UINT before)\r
+{\r
+ if (after & SHIFT && !(before & SHIFT))\r
+ DepressKey(VK_SHIFT);\r
+ else if (!(after & SHIFT) && before & SHIFT)\r
+ ReleaseKey(VK_SHIFT);\r
+\r
+ if (after & CONTROL && !(before & CONTROL)) {\r
+ UpdateKeyboardState(VK_CONTROL, 1);\r
+ DepressKey(VK_CONTROL);\r
+ } else if (!(after & CONTROL) && before & CONTROL) {\r
+ ReleaseKey(VK_CONTROL);\r
+ UpdateKeyboardState(VK_CONTROL, 0);\r
+ }\r
+\r
+ const BOOL bHookApp =\r
+ CUtils::IsVisualCpp() || CUtils::IsVisualStudio() ||\r
+ CUtils::IsInternetExplorer() || CUtils::IsFirefox() || CUtils::IsChrome();\r
+ if (after & META && !(before & META)) {\r
+ if (bHookApp)\r
+ m_nHookAltRelease |= HOOK_ALT_LATER;\r
+ DepressKey(VK_MENU);\r
+ } else if (!(after & META) && before & META) {\r
+ if (bHookApp)\r
+ ++m_nHookAltRelease;\r
+ ReleaseKey(VK_MENU);\r
}\r
- return CallNextHookEx( m_hHookShell, nCode, wParam, lParam );\r
}\r
\r
-// return true if the key is down\r
+BOOL CXkeymacsDll::UpdateKeyboardState(BYTE bVk, BYTE bState)\r
+{\r
+ BYTE ks[256] = {'\0'};\r
+ if (!GetKeyboardState(ks))\r
+ return FALSE;\r
+ ks[bVk] = bState;\r
+ return SetKeyboardState(ks);\r
+}\r
+\r
BOOL CXkeymacsDll::IsDown(BYTE bVk, BOOL bPhysicalKey)\r
{\r
- if (bPhysicalKey) {\r
- return GetKeyState(bVk) < 0;\r
- } else {\r
- return GetAsyncKeyState(bVk) < 0;\r
- }\r
+ return bPhysicalKey ? GetAsyncKeyState(bVk) < 0 : GetKeyState(bVk) < 0;\r
}\r
\r
// Do keybd_event\r
// Set KEYEVENTF_EXTENDEDKEY if needed\r
switch (bVk) {\r
case VK_CONTROL:\r
- if (m_bRightControl) { // Right Ctrl\r
+ if (m_bRightControl)\r
dwFlags |= KEYEVENTF_EXTENDEDKEY;\r
- }\r
break;\r
\r
case VK_MENU:\r
- if (m_bRightAlt) { // Right Alt\r
+ if (m_bRightAlt)\r
dwFlags |= KEYEVENTF_EXTENDEDKEY;\r
-// CUtils::Log("Right Alt %d", dwFlags);\r
-// } else {\r
-// CUtils::Log("Left Alt %d", dwFlags);\r
- }\r
break;\r
\r
case VK_SHIFT:\r
- if (m_bRightShift) { // Right Shift\r
- dwFlags |= KEYEVENTF_EXTENDEDKEY;\r
+ if (m_bRightShift) {\r
+ if (CUtils::IsXPorLater())\r
+ bVk = VK_RSHIFT;\r
+ else\r
+ dwFlags |= KEYEVENTF_EXTENDEDKEY;\r
}\r
break;\r
-\r
case VK_PAUSE:\r
- if (IsDown(VK_CONTROL)) { // Break\r
+ if (IsDown(VK_CONTROL, FALSE)) // Break\r
dwFlags |= KEYEVENTF_EXTENDEDKEY;\r
- }\r
break;\r
-\r
case VK_INSERT:\r
case VK_DELETE:\r
case VK_HOME:\r
case VK_PRINT:\r
dwFlags |= KEYEVENTF_EXTENDEDKEY;\r
break;\r
-\r
- default:\r
- break;\r
}\r
-\r
-// CUtils::Log(_T("b: %x, %x, %x, %#x, %#x"), bVk, dwFlags, GetMessageExtraInfo(), GetKeyState(bVk), GetAsyncKeyState(bVk));\r
+// CUtils::Log(_T("b: %x, %x, %x, %#hx, %#hx"), bVk, dwFlags, GetMessageExtraInfo(), GetKeyState(bVk), GetAsyncKeyState(bVk));\r
keybd_event(bVk, 0, dwFlags, GetMessageExtraInfo());\r
-// CUtils::Log(_T("a: %x, %x, %x, %#x, %#x"), bVk, dwFlags, GetMessageExtraInfo(), GetKeyState(bVk), GetAsyncKeyState(bVk));\r
+// CUtils::Log(_T("a: %x, %x, %x, %#hx, %#hx"), bVk, dwFlags, GetMessageExtraInfo(), GetKeyState(bVk), GetAsyncKeyState(bVk));\r
}\r
\r
// the key is being depressed\r
// CUtils::Log(_T("i: %x, %d, %d, %d, %d, %d, %d, %d, %d"), bVk,\r
// IsDown(VK_CONTROL), IsDown(VK_CONTROL, FALSE), IsDepressedModifier(CCommands::C_), IsDepressedModifier(CCommands::C_, FALSE),\r
// IsDown(VK_MENU), IsDown(VK_MENU, FALSE), IsDepressedModifier(CCommands::MetaAlt), IsDepressedModifier(CCommands::MetaAlt, FALSE));\r
-\r
- int nCommandType = NONE;\r
- if (IsDown(VK_CONTROL, FALSE)) {\r
- nCommandType |= CONTROL;\r
- }\r
- if (IsDown(VK_MENU, FALSE)) {\r
- nCommandType |= META;\r
- }\r
- Original(nCommandType, bVk, 1);\r
+ SetOriginal(GetModifierState(), bVk);\r
}\r
-\r
DoKeybd_event(bVk, 0);\r
}\r
\r
\r
void CXkeymacsDll::InitKeyboardProc(BOOL bImeComposition)\r
{\r
- if (CUtils::IsFindDialog()) {\r
- static BOOL bImeCompositionOld = FALSE;\r
- if (!bImeComposition\r
- && bImeCompositionOld) {\r
- DepressKey(VK_END);\r
- ReleaseKey(VK_END);\r
- }\r
- bImeCompositionOld = bImeComposition;\r
- }\r
-\r
CUtils::SetApplicationName(bImeComposition);\r
-\r
- if (_tcsnicmp(m_szSpecialApp[m_nApplicationID], CUtils::GetApplicationName(), 0xF) || !IsMatchWindowText(m_szWindowText[m_nApplicationID])) { // PROCESSENTRY32 has only 0xF bytes of Name\r
- m_nApplicationID = -1;\r
-\r
- for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
- if (!_tcsnicmp(m_szSpecialApp[nApplicationID], CUtils::GetApplicationName(), 0xF) && IsMatchWindowText(m_szWindowText[nApplicationID])) {\r
-\r
- if (m_nApplicationID < 0\r
- || CUtils::GetWindowTextType(m_szWindowText[m_nApplicationID]) < CUtils::GetWindowTextType(m_szWindowText[nApplicationID])\r
- || CUtils::GetWindowTextType(m_szWindowText[m_nApplicationID]) == CUtils::GetWindowTextType(m_szWindowText[nApplicationID])\r
- && _tcscmp(m_szWindowText[m_nApplicationID], m_szWindowText[nApplicationID]) <= 0) {\r
- m_nApplicationID = nApplicationID;\r
- }\r
- }\r
- }\r
-\r
- if (m_nApplicationID < 0) {\r
- for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
- if (!_tcsicmp(m_szSpecialApp[nApplicationID], _T("Default"))) {\r
- m_nApplicationID = nApplicationID;\r
- break;\r
- }\r
- }\r
-\r
- if (m_nApplicationID < 0) {\r
- m_nApplicationID = 0;\r
+ if (_tcsnicmp(m_Config.szSpecialApp[m_nAppID], CUtils::GetApplicationName(), 0xF) || !IsMatchWindowText(m_Config.szWindowText[m_nAppID])) { // PROCESSENTRY32 has only 0xF bytes of Name\r
+ m_nAppID = -1;\r
+ for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
+ if (_tcsnicmp(m_Config.szSpecialApp[nAppID], CUtils::GetApplicationName(), 0xF) || !IsMatchWindowText(m_Config.szWindowText[nAppID]))\r
+ continue;\r
+ if (m_nAppID < 0)\r
+ m_nAppID = nAppID;\r
+ else {\r
+ const LPCSTR curText = m_Config.szWindowText[m_nAppID];\r
+ const LPCSTR newText = m_Config.szWindowText[nAppID];\r
+ const int curType = CUtils::GetWindowTextType(curText);\r
+ const int newType = CUtils::GetWindowTextType(newText);\r
+ if (curType < newType || curType == newType && _tcscmp(curText, newText) <= 0)\r
+ m_nAppID = nAppID;\r
}\r
}\r
+ if (m_nAppID < 0)\r
+ m_nAppID = GetAppID(_T("Default"), 0);\r
}\r
-\r
- if (m_nSettingStyle[m_nApplicationID] != SETTING_DISABLE\r
- && (_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Default")) || !CUtils::IsDefaultIgnoreApplication())\r
- && !bImeComposition\r
- && CUtils::IsDialog()) {\r
+ if (m_Config.nSettingStyle[m_nAppID] != SETTING_DISABLE &&\r
+ (_tcsicmp(m_Config.szSpecialApp[m_nAppID], _T("Default")) || !CUtils::IsDefaultIgnoreApplication()) &&\r
+ !bImeComposition && CUtils::IsDialog() && m_Config.bUseDialogSetting[m_nAppID])\r
// Use Dialog Setting\r
- if (m_bUseDialogSetting[m_nApplicationID]) {\r
- int nOriginalApplicationID = m_nApplicationID;\r
- for (m_nApplicationID = 0; m_nApplicationID < MAX_APP; ++m_nApplicationID) {\r
- if (!_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Dialog"))) {\r
- break;\r
- }\r
- }\r
- if (m_nApplicationID == MAX_APP) {\r
- m_nApplicationID = nOriginalApplicationID;\r
- }\r
- }\r
- }\r
-\r
- ModifyShell_NotifyIcon(CX_ICON, FALSE);\r
- ModifyShell_NotifyIcon(MX_ICON, FALSE);\r
- ModifyShell_NotifyIcon(META_ICON, FALSE);\r
+ m_nAppID = GetAppID(_T("Dialog"), m_nAppID);\r
+\r
+ ICONMSG msg[3] = {\r
+ {CX_ICON, OFF_ICON, ""},\r
+ {MX_ICON, OFF_ICON, ""},\r
+ {META_ICON, OFF_ICON, ""}\r
+ };\r
+ SendIconMessage(msg, 3);\r
CCommands::SetMark(FALSE);\r
CCommands::SetTemporarilyDisableXKeymacs(FALSE);\r
CCommands::Reset();\r
}\r
\r
-// emulate emacs // cf virtual-key code\r
-LRESULT CALLBACK CXkeymacsDll::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)\r
+int CXkeymacsDll::GetAppID(const LPCSTR szName, const int fallback)\r
{\r
- ASSERT(0 <= wParam && wParam <= UCHAR_MAX);\r
+ for (int i = 0; i < MAX_APP; ++i)\r
+ if (!_tcsicmp(m_Config.szSpecialApp[i], szName))\r
+ return i;\r
+ return fallback;\r
+}\r
\r
- int nCommandType = NONE;\r
- BYTE nKey = (BYTE)wParam;\r
+LRESULT CALLBACK CXkeymacsDll::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)\r
+{\r
+ const BYTE nOrigKey = static_cast<BYTE>(wParam);\r
+ const bool bRelease = (HIWORD(lParam) & KF_UP) != 0;\r
+ const bool bExtended = (HIWORD(lParam) & KF_EXTENDED) != 0;\r
\r
static BOOL bLocked = FALSE;\r
static const BYTE RECURSIVE_KEY = 0x07;\r
- static int (*fCommand)() = NULL;\r
+ static int (*fLastCommand)() = NULL;\r
static BYTE nOneShotModifier[MAX_KEY] = {'\0'};\r
static BOOL bCherryOneShotModifier = FALSE;\r
\r
-// CUtils::Log(_T("nCode = %#x, nKey = %#x, lParam = %#x"), nCode, nKey, lParam);\r
+// CUtils::Log(_T("nCode = %#x, nKey = %#x, lParam = %#x"), nCode, nOrigKey, lParam);\r
\r
- if (!m_bEnableKeyboardHook)\r
- return CallNextHookEx(g_hHookKeyboard, nCode, wParam, lParam);\r
+ if (!m_bEnableKeyboardHook || CUtils::IsXkeymacs() ||\r
+ nCode < 0 || nCode == HC_NOREMOVE)\r
+ return CallNextHookEx(NULL, nCode, wParam, lParam);\r
\r
- if (nCode < 0 || nCode == HC_NOREMOVE) {\r
- goto DO_NOTHING;\r
- }\r
+// CUtils::Log(_T("nKey = %#x, ext = %d, rel = %d, pre = %d, %#hx, %#hx"), nOrigKey,\r
+// (HIWORD(lParam) & KF_EXTENDED) ? 1 : 0, (HIWORD(lParam) & KF_UP) ? 1 : 0, (HIWORD(lParam) & KF_REPEAT) ? 1 : 0,\r
+// GetKeyState(nOrigKey), GetAsyncKeyState(nOrigKey));\r
\r
- if (nKey == RECURSIVE_KEY) {\r
- if (lParam & BEING_RELEASED) {\r
+ if (nOrigKey == RECURSIVE_KEY) {\r
+ if (bRelease)\r
goto HOOK_RECURSIVE_KEY;\r
- } else {\r
+ else\r
goto RECURSIVE_COMMAND;\r
- }\r
}\r
\r
- {\r
- static BOOL bShift = FALSE;\r
- if (IsDepressedShiftKeyOnly(nKey)) {\r
- if (lParam & BEING_RELEASED) {\r
- if (bShift) {\r
- CCommands::SetMark(FALSE);\r
- }\r
- } else {\r
- bShift = TRUE;\r
- }\r
- } else {\r
- bShift = FALSE;\r
- }\r
+ CancelMarkWithShift(nOrigKey, bRelease);\r
+\r
+ BYTE nKey = nOrigKey;\r
+ switch (nKey) {\r
+ case VK_CONTROL:\r
+ nKey = bExtended ? VK_RCONTROL : VK_LCONTROL;\r
+ break;\r
+ case VK_MENU:\r
+ nKey = bExtended ? VK_RMENU : VK_LMENU;\r
+ break;\r
+ case VK_SHIFT:\r
+ nKey = bExtended ? VK_RSHIFT : VK_LSHIFT;\r
+ break;\r
}\r
\r
- if (CUtils::IsNT()) {\r
- switch (nKey) {\r
- case VK_CONTROL:\r
- if (lParam & EXTENDED_KEY) {\r
- nKey = VK_RCONTROL;\r
- } else {\r
- nKey = VK_LCONTROL;\r
- }\r
- break;\r
+#define fCommand(type) (Commands[m_Config.nCommandID[m_nAppID][(type)][nKey]].fCommand)\r
+#define nFunctionID (m_Config.nFunctionID[m_nAppID][nType][nKey])\r
+\r
+ if (bRelease) {\r
+ switch (nOrigKey) {\r
case VK_MENU:\r
- if (lParam & EXTENDED_KEY) {\r
- nKey = VK_RMENU;\r
- } else {\r
- nKey = VK_LMENU;\r
- }\r
- break;\r
- case VK_SHIFT:\r
- if (lParam & EXTENDED_KEY) {\r
- nKey = VK_RSHIFT;\r
- } else {\r
- nKey = VK_LSHIFT;\r
+ if (m_nHookAltRelease) {\r
+ if (m_nHookAltRelease & ~HOOK_ALT_LATER)\r
+ m_nHookAltRelease--;\r
+ else if (m_nHookAltRelease & HOOK_ALT_LATER)\r
+ m_nHookAltRelease = 0;\r
+ goto HOOK;\r
}\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- if (lParam & BEING_RELEASED) {\r
- if (nKey == VK_MENU\r
- || nKey == VK_LWIN\r
- || nKey == VK_RWIN\r
- || nKey == VK_APPS\r
- || nKey == VK_LMENU\r
- || nKey == VK_RMENU) {\r
+ // pass through\r
+ case VK_LWIN:\r
+ case VK_RWIN:\r
+ case VK_APPS:\r
for (int i = 0; i < MAX_COMMAND_TYPE; ++i) {\r
- if (Commands[m_nCommandID[m_nApplicationID][i][nKey]].fCommand\r
- && (Commands[m_nCommandID[m_nApplicationID][i][nKey]].fCommand != CCommands::MetaAlt\r
- || nKey != VK_MENU && nKey != VK_LMENU && nKey != VK_RMENU)) {\r
+ int (*const fCommand)() = fCommand(i);\r
+ if (fCommand && !(nOrigKey == VK_MENU && fCommand == CCommands::MetaAlt))\r
goto HOOK;\r
- }\r
}\r
}\r
-\r
if (nOneShotModifier[nKey]) {\r
ReleaseKey(nOneShotModifier[nKey]);\r
nOneShotModifier[nKey] = 0;\r
-\r
if (bCherryOneShotModifier) {\r
bCherryOneShotModifier = FALSE;\r
Kdu(nKey);\r
}\r
}\r
-\r
goto DO_NOTHING;\r
}\r
\r
- if (m_nSettingStyle[m_nApplicationID] == SETTING_DISABLE) {\r
+ if (m_Config.nSettingStyle[m_nAppID] == SETTING_DISABLE)\r
goto DO_NOTHING;\r
- }\r
\r
// Do Nothing for Meadow, Mule for Win32, ... if those use default setting.\r
- if (!_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Default"))\r
- && CUtils::IsDefaultIgnoreApplication()) {\r
+ if (!_tcsicmp(m_Config.szSpecialApp[m_nAppID], _T("Default")) && CUtils::IsDefaultIgnoreApplication())\r
goto DO_NOTHING;\r
- }\r
\r
switch (IsPassThrough(nKey)) {\r
case GOTO_DO_NOTHING:\r
goto HOOK;\r
case CONTINUE:\r
break;\r
- default:\r
- ASSERT(0);\r
- break;\r
}\r
\r
// set command type\r
- {\r
- nCommandType = NONE;\r
- if (IsDown(VK_SHIFT, FALSE)) {\r
- nCommandType |= SHIFT;\r
- }\r
- if (IsControl()) {\r
- nCommandType |= CONTROL;\r
- }\r
- if (IsMeta()) {\r
- nCommandType |= META;\r
- }\r
- if (CCommands::bC_x()) {\r
- nCommandType |= CONTROLX;\r
- }\r
-\r
- // Ignore undefined C-x ?\r
- if (nCommandType & CONTROLX) {\r
- if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == NULL\r
- && m_nFunctionID[m_nApplicationID][nCommandType][nKey] < 0) {\r
- if (m_bIgnoreUndefinedC_x[m_nApplicationID]) {\r
- CCommands::Reset(GOTO_HOOK);\r
- goto HOOK;\r
- }\r
- nCommandType &= ~CONTROLX;\r
- }\r
+ int nType = IsDown(VK_SHIFT) * SHIFT | IsControl() * CONTROL | IsMeta() * META | CCommands::bC_x() * CONTROLX;\r
+ // Ignore undefined C-x ?\r
+ if (nType & CONTROLX && fCommand(nType) == NULL && nFunctionID < 0) {\r
+ if (m_Config.bIgnoreUndefinedC_x[m_nAppID]) {\r
+ CCommands::Reset(GOTO_HOOK);\r
+ goto HOOK;\r
}\r
-\r
- // Ignore undefined Meta Ctrl+?\r
- if (CCommands::bM_() && (nCommandType & CONTROL)) {\r
- if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == NULL\r
- && m_nFunctionID[m_nApplicationID][nCommandType][nKey] < 0) {\r
- if (m_bIgnoreUndefinedMetaCtrl[m_nApplicationID]) {\r
- if (Original(CONTROL, nKey)) {\r
- Original(CONTROL, nKey, -1);\r
- goto DO_NOTHING;\r
- }\r
- CCommands::Reset(GOTO_HOOK);\r
- goto HOOK;\r
- }\r
- nCommandType &= ~META;\r
- }\r
+ nType &= ~CONTROLX;\r
+ }\r
+ // Ignore undefined Meta Ctrl+?\r
+ if (CCommands::bM_() && nType & CONTROL && fCommand(nType) == NULL && nFunctionID < 0) {\r
+ if (m_Config.bIgnoreUndefinedMetaCtrl[m_nAppID]) {\r
+ if (CheckOriginal(CONTROL, nKey))\r
+ goto DO_NOTHING;\r
+ CCommands::Reset(GOTO_HOOK);\r
+ goto HOOK;\r
+ nType &= ~META;\r
}\r
}\r
\r
- {\r
-// CUtils::Log(_T("o: %x, %d, %d, %d, %d, %d, %d, %d, %d"), (BYTE)wParam,\r
-// IsDown(VK_CONTROL), IsDown(VK_CONTROL, FALSE), IsDepressedModifier(CCommands::C_), IsDepressedModifier(CCommands::C_, FALSE),\r
-// IsDown(VK_MENU), IsDown(VK_MENU, FALSE), IsDepressedModifier(CCommands::MetaAlt), IsDepressedModifier(CCommands::MetaAlt, FALSE));\r
-\r
- BYTE nKey = (BYTE)wParam; // VK_CONTROL is needed instead of VK_RCONTROL and VK_LCONTROL in this block just for Original()\r
- int nVirtualCommandType = NONE;\r
- if (IsDown(VK_CONTROL) && nKey != VK_CONTROL) {\r
- nVirtualCommandType |= CONTROL;\r
- }\r
- if (IsDown(VK_MENU) && nKey != VK_MENU) {\r
- nVirtualCommandType |= META;\r
- }\r
- if (Original(nVirtualCommandType, nKey)) {\r
- Original(nVirtualCommandType, nKey, -1);\r
- goto DO_NOTHING;\r
- }\r
+ int nVirtualType = GetModifierState(FALSE);\r
+ if (nOrigKey == VK_CONTROL)\r
+ nVirtualType &= ~CONTROL;\r
+ if (nOrigKey == VK_MENU)\r
+ nVirtualType &= ~META;\r
+ if (CheckOriginal(nVirtualType, nOrigKey)) {\r
+ goto DO_NOTHING;\r
}\r
\r
- if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::EnableOrDisableXKeymacs) {\r
- SetKeyboardHookFlag(!m_bHook);\r
+ int (*const fCommand)() = fCommand(nType);\r
+ if (fCommand == CCommands::EnableOrDisableXKeymacs) {\r
+ ToggleKeyboardHookState();\r
goto HOOK;\r
}\r
- if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::EnableXKeymacs) {\r
- if (!m_bHook) {\r
- SetKeyboardHookFlag(!m_bHook);\r
- }\r
+ if (fCommand == CCommands::EnableXKeymacs) {\r
+ if (!m_bHook)\r
+ ToggleKeyboardHookState();\r
goto HOOK;\r
}\r
- if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::DisableXKeymacs) {\r
- if (m_bHook) {\r
- SetKeyboardHookFlag(!m_bHook);\r
- }\r
+ if (fCommand == CCommands::DisableXKeymacs) {\r
+ if (m_bHook)\r
+ ToggleKeyboardHookState();\r
goto HOOK;\r
}\r
- if (!m_bHook) {\r
+ if (!m_bHook)\r
goto DO_NOTHING;\r
- }\r
\r
- if (CCommands::bM_x()) {\r
- static unsigned int index = 0;\r
+ if (CCommands::bM_x() && !bRelease) {\r
+ static size_t index = 0;\r
static TCHAR szPath[MAX_PATH] = {'\0'};\r
-\r
- if (lParam & BEING_RELEASED) {\r
- // ignore\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::BackwardChar) {\r
- if (index) {\r
+ if (fCommand == CCommands::BackwardChar) {\r
+ if (index)\r
--index;\r
- }\r
goto HOOKX;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::BeginningOfLine) {\r
+ } else if (fCommand == CCommands::BeginningOfLine) {\r
index = 0;\r
goto HOOKX;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::DeleteBackwardChar) {\r
+ } else if (fCommand == CCommands::DeleteBackwardChar) {\r
if (index) {\r
--index;\r
- memmove(&szPath[index], &szPath[index + 1], _tcslen(szPath) - index);\r
- ModifyM_xTip(szPath);\r
+ memmove(szPath + index, szPath + index + 1, MAX_PATH - index);\r
+ SetM_xTip(szPath);\r
}\r
goto HOOKX;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::DeleteChar) {\r
+ } else if (fCommand == CCommands::DeleteChar) {\r
if (index < _tcslen(szPath)) {\r
- memmove(&szPath[index], &szPath[index + 1], _tcslen(szPath) - index);\r
- ModifyM_xTip(szPath);\r
+ memmove(szPath + index, szPath + index + 1, MAX_PATH - index);\r
+ SetM_xTip(szPath);\r
}\r
goto HOOKX;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::EndOfLine) {\r
+ } else if (fCommand == CCommands::EndOfLine) {\r
index = _tcslen(szPath);\r
goto HOOKX;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::ForwardChar) {\r
- if (index < _tcslen(szPath)) {\r
+ } else if (fCommand == CCommands::ForwardChar) {\r
+ if (index < _tcslen(szPath))\r
++index;\r
- }\r
goto HOOKX;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::KeyboardQuit) {\r
+ } else if (fCommand == CCommands::KeyboardQuit) {\r
CCommands::bM_x(FALSE);\r
index = 0;\r
memset(szPath, 0, sizeof(szPath));\r
goto HOOK;\r
- } else if (nKey == VK_RETURN\r
- || Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::Newline) {\r
+ } else if (nKey == VK_RETURN || fCommand == CCommands::Newline) {\r
InvokeM_x(szPath);\r
-\r
CCommands::bM_x(FALSE);\r
index = 0;\r
memset(szPath, 0, sizeof(szPath));\r
goto HOOK;\r
- } else if (index < MAX_PATH - 1) {\r
- const BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);\r
- for (TCHAR nAscii = 1; nAscii != 0; ++nAscii) { // repeat until overflow\r
- if (nKey != 0 && a2v(nAscii) == nKey && bIsShiftDown == IsShift(nAscii)) {\r
+ } else if (nKey && index < MAX_PATH - 1) {\r
+ const BOOL bIsShiftDown = IsDown(VK_SHIFT, FALSE);\r
+ TCHAR nAscii = 0;\r
+ do { // 1-127\r
+ if (a2v(++nAscii) == nKey && bIsShiftDown == IsShift(nAscii)) {\r
// CUtils::Log("M-x: %#X (%c), %#X (%c)", nKey, nKey, nAscii, nAscii);\r
- if (index < _tcslen(szPath)) {\r
- memmove(&szPath[index + 1], &szPath[index], __min(_tcslen(szPath) - index, MAX_PATH - (index + 1) - 1));\r
- }\r
+ if (index < _tcslen(szPath))\r
+ memmove(szPath + index + 1, szPath + index, MAX_PATH - index - 1);\r
szPath[index++] = nAscii;\r
// CUtils::Log("M-x: %c(%#04x)", nAscii, nAscii);\r
- ModifyM_xTip(szPath);\r
+ SetM_xTip(szPath);\r
goto HOOKX;\r
}\r
- }\r
+ } while (nAscii != 127);\r
}\r
}\r
\r
- if (CCommands::bC_u()) {\r
- if ((nCommandType == NONE) && ('0' <= nKey) && (nKey <= '9')) {\r
+ if (CCommands::bC_u() && nType == NONE) {\r
+ if ('0' <= nKey && nKey <= '9') {\r
CCommands::NumericArgument(nKey - '0');\r
goto HOOK0_9;\r
}\r
- if ((nCommandType == NONE) && (nKey == 0xBD)) {\r
+ if (nKey == VK_OEM_MINUS) {\r
CCommands::NumericArgumentMinus();\r
goto HOOK0_9;\r
}\r
}\r
\r
- if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~CONTROL][nKey]].fCommand == CCommands::OneShotModifierCtrl) {\r
- nOneShotModifier[nKey] = VK_LCONTROL;\r
- DepressKey(nOneShotModifier[nKey]);\r
- bCherryOneShotModifier = TRUE;\r
- goto HOOK;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::OneShotModifierCtrlRepeat) {\r
- nOneShotModifier[nKey] = VK_LCONTROL;\r
- DepressKey(nOneShotModifier[nKey]);\r
- bCherryOneShotModifier = TRUE;\r
- goto HOOK;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~CONTROL][nKey]].fCommand == CCommands::OneShotModifierCtrlRepeat) {\r
- ReleaseKey(nOneShotModifier[nKey]);\r
+#define OneShotModifier(type, vk, mod) \\r
+ if (fCommand(nType & ~type) == CCommands::OneShotModifier ## mod || \\r
+ fCommand(nType) == CCommands::OneShotModifier ## mod ## Repeat) { \\r
+ nOneShotModifier[nKey] = vk; \\r
+ DepressKey(vk); \\r
+ bCherryOneShotModifier = TRUE; \\r
+ goto HOOK; \\r
+ } else if (fCommand(nType & ~CONTROL) == CCommands::OneShotModifier ## mod ## Repeat) { \\r
+ ReleaseKey(vk); \\r
+ bCherryOneShotModifier = FALSE; \\r
+ Kdu(nKey); \\r
+ goto HOOK; \\r
+ }\r
+\r
+ OneShotModifier(CONTROL, VK_CONTROL, Ctrl);\r
+ OneShotModifier(META, VK_MENU, Alt);\r
+ OneShotModifier(SHIFT, VK_SHIFT, Shift);\r
+ int i;\r
+ for (i = 0; i < MAX_KEY; ++i)\r
+ if (nOneShotModifier[i] == nOrigKey)\r
+ break;\r
+ if (i == MAX_KEY)\r
bCherryOneShotModifier = FALSE;\r
- Kdu(nKey);\r
- goto HOOK;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~META][nKey]].fCommand == CCommands::OneShotModifierAlt) {\r
- nOneShotModifier[nKey] = VK_LMENU;\r
- DepressKey(nOneShotModifier[nKey]);\r
- bCherryOneShotModifier = TRUE;\r
- goto HOOK;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::OneShotModifierAltRepeat) {\r
- nOneShotModifier[nKey] = VK_LMENU;\r
- DepressKey(nOneShotModifier[nKey]);\r
- bCherryOneShotModifier = TRUE;\r
- goto HOOK;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~META][nKey]].fCommand == CCommands::OneShotModifierAltRepeat) {\r
- ReleaseKey(nOneShotModifier[nKey]);\r
- bCherryOneShotModifier = FALSE;\r
- Kdu(nKey);\r
- goto HOOK;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~SHIFT][nKey]].fCommand == CCommands::OneShotModifierShift) {\r
- nOneShotModifier[nKey] = VK_SHIFT;\r
- DepressKey(nOneShotModifier[nKey]);\r
- bCherryOneShotModifier = TRUE;\r
- goto HOOK;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::OneShotModifierShiftRepeat) {\r
- nOneShotModifier[nKey] = VK_SHIFT;\r
- DepressKey(nOneShotModifier[nKey]);\r
- bCherryOneShotModifier = TRUE;\r
- goto HOOK;\r
- } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~SHIFT][nKey]].fCommand == CCommands::OneShotModifierShiftRepeat) {\r
- ReleaseKey(nOneShotModifier[nKey]);\r
- bCherryOneShotModifier = FALSE;\r
- Kdu(nKey);\r
- goto HOOK;\r
- } else {\r
- for (int i = 0; i < MAX_KEY; ++i) {\r
- if (nOneShotModifier[i] == nKey) {\r
- break;\r
- }\r
- }\r
- if (i == MAX_KEY) {\r
- bCherryOneShotModifier = FALSE;\r
- }\r
- }\r
-\r
- if (0 <= m_nFunctionID[m_nApplicationID][nCommandType][nKey]\r
- && m_nFunctionID[m_nApplicationID][nCommandType][nKey] < MAX_FUNCTION\r
- && _tcslen(m_szFunctionDefinition[m_nFunctionID[m_nApplicationID][nCommandType][nKey]])) {\r
- CallFunction(m_nFunctionID[m_nApplicationID][nCommandType][nKey]);\r
- CCommands::Reset(GOTO_HOOK);\r
+\r
+ if (0 <= nFunctionID && nFunctionID < MAX_FUNCTION && m_Config.szFunctionDefinition[nFunctionID][0]) {\r
+ CallFunction(nFunctionID);\r
+ CCommands::Reset(GOTO_HOOK);\r
goto HOOK;\r
}\r
+#undef fCommand\r
+#undef nFunctionID\r
\r
- if (!Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand) {\r
- if (nKey == VK_CONTROL\r
- || nKey == VK_LCONTROL\r
- || nKey == VK_RCONTROL\r
- || nKey == VK_MENU\r
- || nKey == VK_LMENU\r
- || nKey == VK_RMENU\r
- || nKey == VK_SHIFT\r
- || nKey == VK_LSHIFT\r
- || nKey == VK_RSHIFT) {\r
+ if (!fCommand) {\r
+ if (nOrigKey == VK_CONTROL || nOrigKey == VK_MENU || nOrigKey == VK_SHIFT)\r
goto DO_NOTHING;\r
- }\r
-\r
- if (!(nCommandType & SHIFT)) {\r
+ if (!(nType & SHIFT)) {\r
if (CCommands::IsSetMark()) {\r
- if (CCommands::MoveCaret(nKey, nCommandType & CONTROL) != CONTINUE) {\r
+ if (CCommands::MoveCaret(nKey, nType & CONTROL) != CONTINUE) {\r
CCommands::ClearNumericArgument();\r
goto HOOK;\r
}\r
CCommands::SetMark(FALSE);\r
}\r
}\r
-\r
if (1 < CCommands::GetNumericArgument()) {\r
Kdu(nKey, CCommands::GetNumericArgument());\r
CCommands::ClearNumericArgument();\r
goto HOOK;\r
}\r
-\r
goto DO_NOTHING;\r
}\r
\r
- if (CCommands::IsTemporarilyDisableXKeymacs()\r
- && Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand != CCommands::KeyboardQuit) {\r
+ if (CCommands::IsTemporarilyDisableXKeymacs() && fCommand != CCommands::KeyboardQuit) {\r
CCommands::SetTemporarilyDisableXKeymacs(FALSE);\r
goto DO_NOTHING;\r
}\r
\r
- if (m_bAtIbeamCursorOnly[m_nApplicationID][nCommandType][nKey]) {\r
- CURSORINFO cursorinfo = { sizeof(cursorinfo) };\r
- if (GetCursorInfo(&cursorinfo) && cursorinfo.flags && cursorinfo.hCursor != LoadCursor(NULL, IDC_IBEAM)) {\r
- goto DO_NOTHING;\r
- }\r
- }\r
-\r
- m_bRightControl = IsDown(VK_RCONTROL);\r
- m_bRightAlt = IsDown(VK_RMENU);\r
- m_bRightShift = IsDown(VK_RSHIFT);\r
+ m_bRightControl = IsDown(VK_RCONTROL, FALSE);\r
+ m_bRightAlt = IsDown(VK_RMENU, FALSE);\r
+ m_bRightShift = IsDown(VK_RSHIFT, FALSE);\r
\r
- if (!bLocked) {\r
- bLocked = TRUE;\r
- fCommand = Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand;\r
+ if (bLocked)\r
+ goto HOOK_RECURSIVE_KEY;\r
+ bLocked = TRUE;\r
+ fLastCommand = fCommand;\r
RECURSIVE_COMMAND:\r
- switch (fCommand()) {\r
- case GOTO_DO_NOTHING:\r
- bLocked = FALSE;\r
- goto DO_NOTHING;\r
- case GOTO_HOOK:\r
- bLocked = FALSE;\r
- goto HOOK;\r
- case GOTO_RECURSIVE:\r
- goto RECURSIVE;\r
- case GOTO_HOOKX:\r
- bLocked = FALSE;\r
- goto HOOKX;\r
+ switch (fLastCommand()) {\r
+ case GOTO_DO_NOTHING:\r
+ bLocked = FALSE;\r
+ goto DO_NOTHING;\r
+ case GOTO_HOOK:\r
+ bLocked = FALSE;\r
+ goto HOOK;\r
+ case GOTO_RECURSIVE:\r
+ goto RECURSIVE;\r
+ case GOTO_HOOKX:\r
+ bLocked = FALSE;\r
+ goto HOOKX;\r
case GOTO_HOOK0_9:\r
- bLocked = FALSE;\r
- goto HOOK0_9;\r
- default:\r
- ASSERT(0);\r
- bLocked = FALSE;\r
- goto DO_NOTHING;\r
- }\r
- } else {\r
- goto HOOK_RECURSIVE_KEY;\r
+ bLocked = FALSE;\r
+ goto HOOK0_9;\r
}\r
\r
DO_NOTHING:\r
- ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));\r
- ModifyShell_NotifyIcon(CTRL_ICON, IsControl());\r
- ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));\r
-\r
- {\r
- static BOOL bDefiningMacro = FALSE;\r
- if (m_bDefiningMacro) {\r
- static BOOL bDown[MAX_KEY] = {'\0'};\r
-\r
- if (!bDefiningMacro) {\r
- while (m_Macro.GetHeadPosition()) {\r
- void *p = m_Macro.GetAt(m_Macro.GetHeadPosition());\r
- m_Macro.RemoveHead();\r
- delete p;\r
- p = NULL;\r
- }\r
- memset(bDown, 0, sizeof(bDown));\r
- }\r
-\r
- if ((!(lParam & BEING_RELEASED)) || bDown[wParam]) {\r
- try {\r
- KbdMacro *pKbdMacro = new KbdMacro;\r
- if (pKbdMacro) {\r
- pKbdMacro->nCode = nCode;\r
- pKbdMacro->wParam = wParam;\r
- pKbdMacro->lParam = lParam;\r
- pKbdMacro->bOriginal = TRUE;\r
- m_Macro.AddTail((CObject *)pKbdMacro);\r
- }\r
- }\r
- catch (CMemoryException* e) {\r
- e->Delete();\r
-// CUtils::Log("KeyboardProc: 'new' threw an exception");\r
- }\r
- if (!(lParam & BEING_RELEASED)) {\r
- bDown[wParam] = TRUE;\r
- }\r
- }\r
- }\r
- bDefiningMacro = m_bDefiningMacro;\r
+ SetModifierIcons();\r
+ if (m_bRecordingMacro && (!bRelease || m_bDown[wParam])) {\r
+ KbdMacro m = { nCode, wParam, lParam, TRUE };\r
+ m_Macro.push_back(m);\r
+ m_bDown[wParam] |= !bRelease;\r
}\r
-\r
- return CallNextHookEx(g_hHookKeyboard, nCode, wParam, lParam);\r
+ return CallNextHookEx(NULL, nCode, wParam, lParam);\r
\r
RECURSIVE:\r
Kdu(RECURSIVE_KEY, 1, FALSE);\r
- ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));\r
- ModifyShell_NotifyIcon(CTRL_ICON, IsControl());\r
- ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));\r
- return TRUE;\r
-\r
+ goto HOOKX;\r
HOOK:\r
- CCommands::SetLastCommand(fCommand);\r
+ CCommands::SetLastCommand(fLastCommand);\r
HOOK0_9:\r
HOOKX:\r
- ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));\r
- ModifyShell_NotifyIcon(CTRL_ICON, IsControl());\r
- ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));\r
+ SetModifierIcons();\r
HOOK_RECURSIVE_KEY:\r
- return TRUE;\r
-}\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// CXkeymacsData Class\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-//////////////////////////////////////////////////////////////////////\r
-// Construction/Destruction\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-CXkeymacsData::CXkeymacsData()\r
-{\r
- ClearAll();\r
-}\r
-\r
-CXkeymacsData::~CXkeymacsData()\r
-{\r
-\r
-}\r
-\r
-// set application name\r
-void CXkeymacsData::SetApplicationName(LPCTSTR lpszApplicationName)\r
-{\r
- m_strApplicationName.Format(lpszApplicationName);\r
-}\r
-\r
-// return application name\r
-CString CXkeymacsData::GetApplicationName()\r
-{\r
- return m_strApplicationName;\r
-}\r
-\r
-// set hook or not\r
-void CXkeymacsData::SetCommandID(int nCommandType, int nKey, int nCommandID)\r
-{\r
- ASSERT(0 <= nCommandType || nCommandType < MAX_COMMAND_TYPE);\r
- ASSERT(0 <= nKey || nKey < MAX_KEY);\r
-\r
- m_nCommandID[nCommandType][nKey] = nCommandID;\r
-}\r
-\r
-// return hook or not\r
-int CXkeymacsData::GetCommandID(int nCommandType, int nKey)\r
-{\r
- ASSERT(0 <= nCommandType || nCommandType < MAX_COMMAND_TYPE);\r
- ASSERT(0 <= nKey || nKey < MAX_KEY);\r
-\r
- return m_nCommandID[nCommandType][nKey];\r
-}\r
-\r
-// set hook at ibeam cursor only or not\r
-void CXkeymacsData::SetAtIbeamCursorOnly(int nCommandType, int nKey, BOOL bAtIbeamCursorOnly)\r
-{\r
- ASSERT(0 <= nCommandType || nCommandType < MAX_COMMAND_TYPE);\r
- ASSERT(0 <= nKey || nKey < MAX_KEY);\r
-\r
- m_bAtIbeamCursorOnly[nCommandType][nKey] = bAtIbeamCursorOnly;\r
-}\r
-\r
-// get hook at ibeam cursor only or not\r
-BOOL CXkeymacsData::GetAtIbeamCursorOnly(int nCommandType, int nKey)\r
-{\r
- ASSERT(0 <= nCommandType || nCommandType < MAX_COMMAND_TYPE);\r
- ASSERT(0 <= nKey || nKey < MAX_KEY);\r
-\r
- return m_bAtIbeamCursorOnly[nCommandType][nKey];\r
-}\r
-\r
-// clear all data\r
-void CXkeymacsData::ClearAll()\r
-{\r
- ZeroMemory(m_nCommandID, sizeof(m_nCommandID));\r
- ZeroMemory(m_bAtIbeamCursorOnly, sizeof(m_bAtIbeamCursorOnly));\r
- m_strApplicationName.Empty();\r
-}\r
-\r
-void CXkeymacsDll::SetApplicationName(int nApplicationID, CString szApplicationName)\r
-{\r
- ZeroMemory(m_szSpecialApp[nApplicationID], sizeof(m_szSpecialApp[nApplicationID]));\r
- _tcsncpy(m_szSpecialApp[nApplicationID], szApplicationName, sizeof(m_szSpecialApp[nApplicationID]));\r
-}\r
-\r
-void CXkeymacsDll::SetWindowText(int nApplicationID, CString szWindowText)\r
-{\r
- ZeroMemory(m_szWindowText[nApplicationID], sizeof(m_szWindowText[nApplicationID]));\r
- _tcsncpy(m_szWindowText[nApplicationID], szWindowText, sizeof(m_szWindowText[nApplicationID]));\r
-}\r
-\r
-void CXkeymacsDll::SetCommandID(int nApplicationID, int nCommandType, int nKey, int nCommandID)\r
-{\r
- m_nCommandID[nApplicationID][nCommandType][nKey] = nCommandID;\r
-}\r
-\r
-void CXkeymacsDll::SetAtIbeamCursorOnly(int nApplicationID, int nCommandType, int nKey, BOOL bAtIbeamCursorOnly)\r
-{\r
- m_bAtIbeamCursorOnly[nApplicationID][nCommandType][nKey] = bAtIbeamCursorOnly;\r
-}\r
-\r
-void CXkeymacsDll::SetKillRingMax(int nApplicationID, int nKillRingMax)\r
-{\r
- m_nKillRingMax[nApplicationID] = nKillRingMax;\r
-}\r
-\r
-void CXkeymacsDll::SetUseDialogSetting(int nApplicationID, BOOL bUseDialogSetting)\r
-{\r
- m_bUseDialogSetting[nApplicationID] = bUseDialogSetting;\r
-}\r
-\r
-// Clear data of nApplicationID\r
-void CXkeymacsDll::Clear(int nApplicationID)\r
-{\r
- if (0 <= nApplicationID && nApplicationID < MAX_APP) {\r
- ZeroMemory(m_szSpecialApp[nApplicationID], sizeof(m_szSpecialApp[nApplicationID]));\r
- ZeroMemory(m_nCommandID[nApplicationID], sizeof(m_nCommandID[nApplicationID]));\r
- ZeroMemory(m_bAtIbeamCursorOnly[nApplicationID], sizeof(m_bAtIbeamCursorOnly[nApplicationID]));\r
- m_nKillRingMax[nApplicationID] = 0;\r
- m_bUseDialogSetting[nApplicationID] = FALSE;\r
- m_nSettingStyle[nApplicationID] = 0;\r
- } else {\r
- ASSERT(0);\r
- }\r
-}\r
-\r
-void CXkeymacsData::SetApplicationTitle(LPCTSTR lpszApplicationTitle)\r
-{\r
- m_strApplicationTitle.Format(lpszApplicationTitle);\r
-\r
- // delete white space at the end of the application title.\r
- while (!m_strApplicationTitle.IsEmpty()\r
- && _istspace(m_strApplicationTitle.GetAt(m_strApplicationTitle.GetLength() - 1))) {\r
- m_strApplicationTitle.Delete(m_strApplicationTitle.GetLength() - 1);\r
- }\r
-}\r
-\r
-CString CXkeymacsData::GetApplicationTitle()\r
-{\r
- return m_strApplicationTitle;\r
-}\r
-\r
-void CXkeymacsData::SetKillRingMax(int nKillRingMax)\r
-{\r
- m_nKillRingMax = nKillRingMax;\r
-}\r
-\r
-int CXkeymacsData::GetKillRingMax()\r
-{\r
- return m_nKillRingMax;\r
-}\r
-\r
-BOOL CXkeymacsDll::IsValidKey(BYTE bVk)\r
-{\r
- if (bVk == 0xf0) { // 0xf0: Eisu key. GetAsyncKeyState returns the wrong state of Eisu key.\r
- return FALSE;\r
- }\r
-\r
- if (CUtils::IsNT()) {\r
- switch (bVk) {\r
- case VK_CONTROL:\r
- case VK_MENU:\r
- case VK_SHIFT:\r
- return FALSE;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-BOOL CXkeymacsDll::IsDepressedModifier(int (__cdecl *Modifier)(void), BOOL bPhysicalKey)\r
-{\r
- BYTE bVk = 0;\r
- do {\r
- if (IsValidKey(bVk)\r
- && IsDown(bVk, bPhysicalKey)\r
- && Commands[m_nCommandID[m_nApplicationID][NONE][bVk]].fCommand == Modifier) {\r
- return TRUE;\r
- }\r
- } while (++bVk);\r
- return FALSE;\r
-}\r
-\r
-BOOL CXkeymacsDll::IsDepressedShiftKeyOnly(BYTE nKey)\r
-{\r
- if (nKey != VK_SHIFT\r
- && nKey != VK_LSHIFT\r
- && nKey != VK_RSHIFT) {\r
- return FALSE;\r
- }\r
-\r
- BYTE bVk = 0;\r
- do {\r
- if (bVk == VK_SHIFT\r
- || bVk == VK_LSHIFT\r
- || bVk == VK_RSHIFT) {\r
- continue;\r
- }\r
-\r
- if (IsDown(bVk)) {\r
- return FALSE;\r
- }\r
- } while (++bVk);\r
- return TRUE;\r
-}\r
-\r
-BOOL CXkeymacsDll::IsControl()\r
-{\r
- return CCommands::bC_() || IsDepressedModifier(CCommands::C_, FALSE);\r
-}\r
-\r
-BOOL CXkeymacsDll::IsMeta()\r
-{\r
- return CCommands::bM_() || IsDepressedModifier(CCommands::MetaAlt, FALSE);\r
-}\r
-\r
-void CXkeymacsDll::AddKillRing(BOOL bNewData)\r
-{\r
- if (m_nKillRingMax[m_nApplicationID] == 0) {\r
- return;\r
- }\r
-\r
- CClipboardSnap *pSnap = new CClipboardSnap;\r
- if( !pSnap ) return;\r
-\r
- BOOL bCapture = pSnap->Capture();\r
- bCapture = pSnap->Capture(); // for "office drawing shape format". Can CClipboardSnap care this problem?\r
-\r
- if( bCapture ) {\r
- if (bNewData) {\r
- m_oKillRing.AddHead(pSnap);\r
- } else {\r
- if (m_oKillRing.IsEmpty()) {\r
- m_oKillRing.AddHead(pSnap);\r
- } else {\r
- for (CClipboardSnap *pParent = m_oKillRing.GetHead(); pParent->GetNext(); pParent = pParent->GetNext()) {\r
- ;\r
- }\r
- pParent->SetNext(pSnap);\r
- }\r
- }\r
- } else {\r
- delete pSnap;\r
- pSnap = NULL;\r
- }\r
-\r
- m_nKillRing = 0;\r
-\r
- if (m_nKillRingMax[m_nApplicationID] < m_oKillRing.GetCount()) {\r
- CClipboardSnap *pSnap = m_oKillRing.GetTail();\r
- delete pSnap;\r
- pSnap = NULL;\r
- m_oKillRing.RemoveTail();\r
- }\r
-}\r
-\r
-// Return TRUE if there is another data\r
-// Return FALSE if there is no more data\r
-CClipboardSnap* CXkeymacsDll::GetKillRing(CClipboardSnap* pSnap, BOOL bForce)\r
-{\r
- if (m_nKillRingMax[m_nApplicationID] == 0) {\r
- return NULL;\r
- }\r
-\r
- if (m_oKillRing.IsEmpty()) {\r
- return NULL;\r
- }\r
-\r
- m_nKillRing %= m_oKillRing.GetCount();\r
-\r
- if (!bForce) {\r
- CClipboardSnap oCurrentSnap;\r
- oCurrentSnap.Capture();\r
-\r
- CClipboardSnap *pKillRing = m_oKillRing.GetAt(m_oKillRing.FindIndex(m_nKillRing));\r
- if (!pKillRing) {\r
- return NULL;\r
- }\r
- for (; pKillRing->GetNext(); pKillRing = pKillRing->GetNext()) {\r
- ;\r
- }\r
- if (*pKillRing != oCurrentSnap) {\r
- return NULL;\r
- }\r
- }\r
-\r
- if (!pSnap) {\r
- pSnap = m_oKillRing.GetAt(m_oKillRing.FindIndex(m_nKillRing));\r
- }\r
- pSnap->Restore();\r
-\r
- return pSnap->GetNext();\r
-}\r
-\r
-void CXkeymacsDll::Original(int nCommandType, BYTE bVk, int nOriginal)\r
-{\r
- nCommandType &= ~SHIFT;\r
-\r
- if (CUtils::IsNT()) {\r
- switch (bVk) {\r
- case VK_CONTROL:\r
- bVk = VK_LCONTROL;\r
- break;\r
- case VK_MENU:\r
- bVk = VK_LMENU;\r
- break;\r
- case VK_SHIFT:\r
- bVk = VK_LSHIFT;\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- m_nOriginal[nCommandType][bVk] += nOriginal;\r
-}\r
-\r
-int CXkeymacsDll::Original(int nCommandType, BYTE bVk)\r
-{\r
- nCommandType &= ~SHIFT;\r
-\r
- if (CUtils::IsNT()) {\r
- switch (bVk) {\r
- case VK_CONTROL:\r
- bVk = VK_LCONTROL;\r
- break;\r
- case VK_MENU:\r
- bVk = VK_LMENU;\r
- break;\r
- case VK_SHIFT:\r
- bVk = VK_LSHIFT;\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
-\r
- return m_nOriginal[nCommandType][bVk];\r
-}\r
-\r
-void CXkeymacsDll::IncreaseKillRingIndex(int nKillRing)\r
-{\r
- m_nKillRing += nKillRing;\r
-}\r
-\r
-// move CCommands\r
-CString CXkeymacsData::GetCommandName(int nCommandID)\r
-{\r
- CString szCommandName(Commands[nCommandID].szCommandName);\r
- return szCommandName;\r
-}\r
-\r
-// move CCommands\r
-int CXkeymacsData::GetDefaultCommandType(int nCommandID, int nIndex)\r
-{\r
- if (nCommandID < 0 || sizeof(Commands) / sizeof(Commands[0]) <= nCommandID\r
- || nIndex < 0 || sizeof(Commands[nCommandID].keybind) / sizeof(Commands[nCommandID].keybind[0]) <= nIndex) {\r
- ASSERT(0);\r
- return NONE;\r
- }\r
-\r
- int nCommandType = Commands[nCommandID].keybind[nIndex].nCommandType;\r
- int bVk = Commands[nCommandID].keybind[nIndex].bVk;\r
-\r
- if (m_b106Keyboard) {\r
- if (nCommandType & SHIFT) { // Shift\r
- switch (bVk) {\r
- case '2':\r
- case '6':\r
- case 0xBA: // VK_OEM_1 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the ';:' key\r
- nCommandType &= ~SHIFT;\r
- break;\r
- default:\r
- break;\r
- }\r
- } else { // Normal\r
- switch (bVk) {\r
- case 0xBB: // VK_OEM_PLUS Windows 2000/XP: For any country/region, the '+' key\r
- case 0xC0: // VK_OEM_3 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the '`~' key\r
- case 0xDE: // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key\r
- nCommandType |= SHIFT;\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
-\r
- return nCommandType;\r
-}\r
-\r
-// move CCommands\r
-int CXkeymacsData::GetDefaultCommandKey(int nCommandID, int nIndex)\r
-{\r
- if (nCommandID < 0 || sizeof(Commands) / sizeof(Commands[0]) <= nCommandID\r
- || nIndex < 0 || sizeof(Commands[nCommandID].keybind) / sizeof(Commands[nCommandID].keybind[0]) <= nIndex) {\r
- ASSERT(0);\r
- return 0;\r
- }\r
-\r
- int nCommandType = Commands[nCommandID].keybind[nIndex].nCommandType;\r
- int bVk = Commands[nCommandID].keybind[nIndex].bVk;\r
-\r
- if (m_b106Keyboard) {\r
- if (nCommandType & SHIFT) { // Shift\r
- switch (bVk) {\r
- case '0':\r
- bVk = '9';\r
- break;\r
- case '2':\r
- bVk = 0xC0; // VK_OEM_3 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the '`~' key\r
- break;\r
- case '6':\r
- bVk = 0xDE; // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key\r
- break;\r
- case '7':\r
- bVk = '6';\r
- break;\r
- case '8':\r
- bVk = 0xBA; // VK_OEM_1 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the ';:' key\r
- break;\r
- case '9':\r
- bVk = '8';\r
- break;\r
- case 0xBD: // VK_OEM_MINUS Windows 2000/XP: For any country/region, the '-' key\r
- bVk = 0xE2; // VK_OEM_102 Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard\r
- break;\r
- case 0xC0:\r
- bVk = 0xDE; // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key\r
- break;\r
- case 0xDE: // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key\r
- bVk = '2';\r
- break;\r
- default:\r
- break;\r
- }\r
- } else { // Normal\r
- switch (bVk) {\r
- case 0xBA: // VK_OEM_1 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the ';:' key\r
- bVk = 0xBB; // VK_OEM_PLUS Windows 2000/XP: For any country/region, the '+' key\r
- break;\r
- case 0xBB: // VK_OEM_PLUS Windows 2000/XP: For any country/region, the '+' key\r
- bVk = 0xBD; // VK_OEM_MINUS Windows 2000/XP: For any country/region, the '-' key\r
- break;\r
- case 0xDE: // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard. \r
- // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key\r
- bVk = '7';\r
- break;\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
-\r
- return bVk;\r
-}\r
-\r
-// move CCommands\r
-int CXkeymacsData::GetDefaultControlID(int nCommandID, int nIndex)\r
-{\r
- if (nCommandID < 0 || sizeof(Commands) / sizeof(Commands[0]) <= nCommandID\r
- || nIndex < 0 || sizeof(Commands[nCommandID].keybind) / sizeof(Commands[nCommandID].keybind[0]) <= nIndex) {\r
- ASSERT(0);\r
- return 0;\r
- }\r
-\r
- return Commands[nCommandID].keybind[nIndex].nControlID;\r
-}\r
-\r
-// nobody use\r
-int CXkeymacsDll::GetMickey(int nDifferential, int nThreshold1, int nThreshold2, int nAcceleration, int nSpeed)\r
-{\r
- nDifferential = nDifferential * 10 / nSpeed;\r
-\r
- switch (nAcceleration) {\r
- case 2:\r
- if (nThreshold2 < fabs((double)(nDifferential / 4))) {\r
- nDifferential /= 4;\r
- break;\r
- }\r
- // Do NOT write break; here.\r
- case 1:\r
- if (nThreshold1 < fabs((double)(nDifferential / 2))) {\r
- nDifferential /= 2;\r
- }\r
- break;\r
- case 0:\r
- break;\r
- default:\r
- ASSERT(0);\r
- break;\r
- }\r
-\r
- return nDifferential;\r
-}\r
-\r
-\r
-int CXkeymacsData::GetSettingStyle()\r
-{\r
- return m_nSettingStyle;\r
-}\r
-\r
-void CXkeymacsData::SetSettingStyle(int nSettingStyle)\r
-{\r
- m_nSettingStyle = nSettingStyle;\r
-}\r
-\r
-void CXkeymacsDll::SetSettingStyle(int nApplicationID, int nSettingStyle)\r
-{\r
- m_nSettingStyle[nApplicationID] = nSettingStyle;\r
-}\r
-\r
-int CXkeymacsData::GetCategoryID(int nCommandID)\r
-{\r
- return Commands[nCommandID].nCategoryID;\r
-}\r
-\r
-void CXkeymacsData::SetIgnoreUndefinedMetaCtrl(BOOL bIgnoreUndefinedMetaCtrl)\r
-{\r
- m_bIgnoreUndefinedMetaCtrl = bIgnoreUndefinedMetaCtrl;\r
-}\r
-\r
-BOOL CXkeymacsData::GetIgnoreUndefinedMetaCtrl()\r
-{\r
- return m_bIgnoreUndefinedMetaCtrl;\r
-}\r
-\r
-void CXkeymacsDll::SetIgnoreUndefinedMetaCtrl(int nApplicationID, BOOL bIgnoreUndefinedMetaCtrl)\r
-{\r
- m_bIgnoreUndefinedMetaCtrl[nApplicationID] = bIgnoreUndefinedMetaCtrl;\r
+ return TRUE;\r
}\r
\r
-void CXkeymacsData::SetIgnoreUndefinedC_x(BOOL bIgnoreUndefinedC_x)\r
+void CXkeymacsDll::SetModifierIcons()\r
{\r
- m_bIgnoreUndefinedC_x = bIgnoreUndefinedC_x;\r
+ ICONMSG msg[6] = {\r
+ {MX_ICON, CCommands::bM_x(), ""},\r
+ {CX_ICON, CCommands::bC_x(), ""},\r
+ {META_ICON, CCommands::bM_(), ""},\r
+ {SHIFT_ICON, IsDown(VK_SHIFT, FALSE), ""},\r
+ {CTRL_ICON, IsControl(), ""},\r
+ {ALT_ICON, IsDown(VK_MENU, FALSE), ""}\r
+ };\r
+ _tcscpy_s(msg[0].szTip, m_M_xTip);\r
+ SendIconMessage(msg, 6);\r
}\r
\r
-BOOL CXkeymacsData::GetIgnoreUndefinedC_x()\r
+// Clear data of nAppID\r
+void CXkeymacsDll::Clear(int nAppID)\r
{\r
- return m_bIgnoreUndefinedC_x;\r
+ if (0 <= nAppID && nAppID < MAX_APP) {\r
+ ZeroMemory(m_Config.szSpecialApp[nAppID], sizeof(m_Config.szSpecialApp[nAppID]));\r
+ ZeroMemory(m_Config.nCommandID[nAppID], sizeof(m_Config.nCommandID[nAppID]));\r
+ m_Config.nKillRingMax[nAppID] = 0;\r
+ m_Config.bUseDialogSetting[nAppID] = FALSE;\r
+ m_Config.nSettingStyle[nAppID] = 0;\r
+ } else {\r
+ ASSERT(0);\r
+ }\r
}\r
\r
-void CXkeymacsDll::SetIgnoreUndefinedC_x(int nApplicationID, BOOL bIgnoreUndefinedC_x)\r
+BOOL CXkeymacsDll::IsValidKey(BYTE bVk)\r
{\r
- m_bIgnoreUndefinedC_x[nApplicationID] = bIgnoreUndefinedC_x;\r
-}\r
+ if (bVk == 0xf0) { // 0xf0: Eisu key. GetAsyncKeyState returns the wrong state of Eisu key.\r
+ return FALSE;\r
+ }\r
\r
-void CXkeymacsData::SetEnableCUA(BOOL bEnableCUA)\r
-{\r
- m_bEnableCUA = bEnableCUA;\r
-}\r
+ switch (bVk) {\r
+ case VK_CONTROL:\r
+ case VK_MENU:\r
+ case VK_SHIFT:\r
+ return FALSE;\r
+ default:\r
+ break;\r
+ }\r
\r
-BOOL CXkeymacsData::GetEnableCUA()\r
-{\r
- return m_bEnableCUA;\r
+ return TRUE;\r
}\r
\r
-void CXkeymacsDll::SetEnableCUA(int nApplicationID, BOOL bEnableCUA)\r
+BOOL CXkeymacsDll::IsDepressedModifier(int (__cdecl *Modifier)(void), BOOL bPhysicalKey)\r
{\r
- m_bEnableCUA[nApplicationID] = bEnableCUA;\r
+ BYTE bVk = 0;\r
+ do {\r
+ if (IsValidKey(bVk) && IsDown(bVk, bPhysicalKey) &&\r
+ Commands[m_Config.nCommandID[m_nAppID][NONE][bVk]].fCommand == Modifier)\r
+ return TRUE;\r
+ } while (++bVk);\r
+ return FALSE;\r
}\r
\r
-BOOL CXkeymacsDll::GetEnableCUA()\r
+void CXkeymacsDll::CancelMarkWithShift(BYTE nKey, bool bRelease)\r
{\r
- return m_bEnableCUA[m_nApplicationID];\r
+ static bool bShift;\r
+ if (nKey != VK_SHIFT)\r
+ goto exit;\r
+ BYTE bVk = 0;\r
+ do {\r
+ if (bVk == VK_SHIFT || VK_LSHIFT || VK_RSHIFT)\r
+ continue;\r
+ if (IsDown(bVk, FALSE))\r
+ goto exit;\r
+ } while (++bVk);\r
+ if (!bRelease) {\r
+ bShift = TRUE;\r
+ return;\r
+ }\r
+ if (bShift)\r
+ CCommands::SetMark(FALSE);\r
+exit:\r
+ bShift = FALSE;\r
+ return;\r
}\r
\r
-void CXkeymacsData::SetUseDialogSetting(BOOL bUseDialogSetting)\r
+BOOL CXkeymacsDll::IsControl()\r
{\r
- m_bUseDialogSetting = bUseDialogSetting;\r
+ return CCommands::bC_() || IsDepressedModifier(CCommands::C_);\r
}\r
\r
-BOOL CXkeymacsData::GetUseDialogSetting()\r
+BOOL CXkeymacsDll::IsMeta()\r
{\r
- return m_bUseDialogSetting;\r
+ return CCommands::bM_() || IsDepressedModifier(CCommands::MetaAlt);\r
}\r
\r
-int CXkeymacsData::GetDescriptionID(int nCommandID)\r
+void CXkeymacsDll::AddKillRing(BOOL bNewData)\r
{\r
- return Commands[nCommandID].nDescriptionID;\r
-}\r
+ if (m_Config.nKillRingMax[m_nAppID] == 0) {\r
+ return;\r
+ }\r
\r
-int CXkeymacsData::GetToolTipID(int nCommandID)\r
-{\r
- return Commands[nCommandID].nToolTipID;\r
-}\r
+ CClipboardSnap *pSnap = new CClipboardSnap;\r
+ if( !pSnap ) return;\r
\r
-void CXkeymacsDll::DefiningMacro(BOOL bDefiningMacro)\r
-{\r
- m_bDefiningMacro = bDefiningMacro;\r
+ BOOL bCapture = pSnap->Capture();\r
+ bCapture = pSnap->Capture(); // for "office drawing shape format". Can CClipboardSnap care this problem?\r
\r
- if (bDefiningMacro) { // start-kbd-macro\r
- if (CCommands::bC_u()) {\r
- ReleaseKey(VK_SHIFT);\r
- CallMacro();\r
- }\r
- } else { // end-kbd-macro\r
- while (!m_Macro.IsEmpty()) {\r
- KbdMacro *pKbdMacro = (KbdMacro *)m_Macro.GetTail();\r
- if (pKbdMacro->lParam & BEING_RELEASED) {\r
- break;\r
+ if( bCapture ) {\r
+ if (bNewData) {\r
+ m_oKillRing.AddHead(pSnap);\r
+ } else {\r
+ if (m_oKillRing.IsEmpty()) {\r
+ m_oKillRing.AddHead(pSnap);\r
} else {\r
- m_Macro.RemoveTail();\r
- delete pKbdMacro;\r
- pKbdMacro = NULL;\r
- }\r
- }\r
-\r
-// CUtils::Log(_T("Macro MemMap: start"));\r
- if (!m_Macro.IsEmpty()) {\r
- static HANDLE hMacro = NULL;\r
- if (!hMacro) {\r
- hMacro = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x3000, _T("macro"));\r
- }\r
- if (hMacro) {\r
-// CUtils::Log(_T("Macro MemMap: 1"));\r
- PVOID pView = MapViewOfFile(hMacro, FILE_MAP_ALL_ACCESS, 0, 0, 0);\r
-// CUtils::Log(_T("Macro MemMap: 2"));\r
- if (pView) {\r
-// CUtils::Log(_T("Macro MemMap: 2.5"));\r
- for (int i = 0; i < m_Macro.GetCount(); ++i) {\r
-// CUtils::Log(_T("Macro MemMap: 3-1 %d"), i);\r
- KbdMacro *pKbdMacro = (KbdMacro *)m_Macro.GetAt(m_Macro.FindIndex(i));\r
-// CUtils::Log(_T("Macro MemMap: 3-2 %d"), i);\r
- memcpy((LPTSTR) pView + i * sizeof(KbdMacro), pKbdMacro, sizeof(KbdMacro));\r
-// CUtils::Log(_T("Macro MemMap: 3-3 %d"), i);\r
- }\r
-// CUtils::Log(_T("Macro MemMap: 4"));\r
- UnmapViewOfFile(pView);\r
-// CUtils::Log(_T("Macro MemMap: 5"));\r
- } else {\r
-// CUtils::Log(_T("Macro MemMpa: error: %d"), GetLastError());\r
+ CClipboardSnap *pParent;\r
+ for (pParent = m_oKillRing.GetHead(); pParent->GetNext(); pParent = pParent->GetNext()) {\r
+ ;\r
}\r
- } else {\r
-// CUtils::Log(_T("Macro MemMap: 6"));\r
- ASSERT(0);\r
+ pParent->SetNext(pSnap);\r
}\r
}\r
+ } else {\r
+ delete pSnap;\r
+ pSnap = NULL;\r
}\r
-}\r
\r
-BOOL CXkeymacsDll::DefiningMacro()\r
-{\r
- return m_bDefiningMacro;\r
+ m_nKillRing = 0;\r
+\r
+ if (m_Config.nKillRingMax[m_nAppID] < m_oKillRing.GetCount()) {\r
+ CClipboardSnap *pSnap = m_oKillRing.GetTail();\r
+ delete pSnap;\r
+ pSnap = NULL;\r
+ m_oKillRing.RemoveTail();\r
+ }\r
}\r
\r
-/**/ \r
-void CXkeymacsDll::CallMacro()\r
+// Return TRUE if there is another data\r
+// Return FALSE if there is no more data\r
+CClipboardSnap* CXkeymacsDll::GetKillRing(CClipboardSnap* pSnap, BOOL bForce)\r
{\r
- BOOL bIsCtrlDown = IsDown(VK_CONTROL);\r
- if (bIsCtrlDown) {\r
- ReleaseKey(VK_CONTROL);\r
- }\r
- BOOL bIsAltDown = IsDown(VK_MENU);\r
- if (bIsAltDown) {\r
- ReleaseKey(VK_MENU);\r
+ if (m_Config.nKillRingMax[m_nAppID] == 0) {\r
+ return NULL;\r
}\r
- BOOL bIsShiftDown = IsDown(VK_SHIFT);\r
- if (bIsShiftDown) {\r
- ReleaseKey(VK_SHIFT);\r
+\r
+ if (m_oKillRing.IsEmpty()) {\r
+ return NULL;\r
}\r
\r
- for (POSITION pos = m_Macro.GetHeadPosition(); pos; ) {\r
- KbdMacro *pKbdMacro = (KbdMacro *)m_Macro.GetNext(pos);\r
- if (pKbdMacro->lParam & BEING_RELEASED) {\r
- ReleaseKey((BYTE)pKbdMacro->wParam);\r
- } else {\r
- DepressKey((BYTE)pKbdMacro->wParam, pKbdMacro->bOriginal);\r
+ m_nKillRing %= m_oKillRing.GetCount();\r
+\r
+ if (!bForce) {\r
+ CClipboardSnap oCurrentSnap;\r
+ oCurrentSnap.Capture();\r
+\r
+ CClipboardSnap *pKillRing = m_oKillRing.GetAt(m_oKillRing.FindIndex(m_nKillRing));\r
+ if (!pKillRing) {\r
+ return NULL;\r
+ }\r
+ for (; pKillRing->GetNext(); pKillRing = pKillRing->GetNext()) {\r
+ ;\r
+ }\r
+ if (*pKillRing != oCurrentSnap) {\r
+ return NULL;\r
}\r
}\r
\r
- if (bIsCtrlDown) {\r
- DepressKey(VK_CONTROL);\r
- }\r
- if (bIsAltDown) {\r
- DepressKey(VK_MENU);\r
- }\r
- if (bIsShiftDown) {\r
- DepressKey(VK_SHIFT);\r
+ if (!pSnap) {\r
+ pSnap = m_oKillRing.GetAt(m_oKillRing.FindIndex(m_nKillRing));\r
}\r
+ pSnap->Restore();\r
+\r
+ return pSnap->GetNext();\r
}\r
\r
-/*\r
-void CXkeymacsDll::CallMacro() // for debug\r
+void CXkeymacsDll::SetOriginal(UINT nType, BYTE bVk)\r
{\r
- CString sz;\r
- for (POSITION pos = m_Macro.GetHeadPosition(); pos; ) {\r
- KbdMacro_t *pKbdMacro = (KbdMacro_t *)m_Macro.GetNext(pos);\r
- if (pKbdMacro->lParam & BEING_RELEASED) {\r
- CString t;\r
- t.Format(_T("0x%xu "), pKbdMacro->wParam);\r
- sz += t;\r
- } else {\r
- CString t;\r
- t.Format(_T("0x%xd "), pKbdMacro->wParam);\r
- sz += t;\r
- }\r
- }\r
-// CUtils::Log(sz);\r
+ m_nOriginal[nType & ~SHIFT][bVk]++;\r
}\r
-*/\r
\r
-void CXkeymacsData::Set106Keyboard(BOOL b106Keyboard)\r
+int CXkeymacsDll::CheckOriginal(UINT nType, BYTE bVk)\r
{\r
- m_b106Keyboard = b106Keyboard;\r
+ nType &= ~SHIFT;\r
+ if (m_nOriginal[nType][bVk])\r
+ return m_nOriginal[nType][bVk]--;\r
+ return 0;\r
}\r
\r
-BOOL CXkeymacsData::Is106Keyboard()\r
+void CXkeymacsDll::IncreaseKillRingIndex(int nKillRing)\r
{\r
- return m_b106Keyboard;\r
+ m_nKillRing += nKillRing;\r
}\r
\r
-int CXkeymacsDll::IsPassThrough(BYTE nKey)\r
+BOOL CXkeymacsDll::GetEnableCUA()\r
{\r
- BYTE bVk = 0;\r
- do {\r
- if (IsDown(bVk)\r
- && (Commands[m_nCommandID[m_nApplicationID][NONE][bVk]].fCommand == CCommands::PassThrough)) {\r
- if (bVk == nKey) {\r
- return GOTO_HOOK;\r
- }\r
-\r
- return GOTO_DO_NOTHING;\r
- }\r
- } while (++bVk);\r
- return CONTINUE;\r
+ return m_Config.bEnableCUA[m_nAppID];\r
}\r
\r
-void CXkeymacsDll::SetKeyboardHookFlag()\r
+void CXkeymacsDll::StartRecordMacro()\r
{\r
- SetKeyboardHookFlag(m_bHook);\r
+ if (CCommands::bC_u())\r
+ CallMacro();\r
+ m_bRecordingMacro = TRUE;\r
+ m_Macro.erase(m_Macro.begin(), m_Macro.end());\r
+ ZeroMemory(m_bDown, MAX_KEY);\r
}\r
\r
-void CXkeymacsDll::SetFunctionKey(int nFunctionID, int nApplicationID, int nCommandType, int nKey)\r
+void CXkeymacsDll::EndRecordMacro()\r
{\r
- if (nApplicationID < 0 || MAX_APP <= nApplicationID\r
- || nCommandType < 0 || MAX_COMMAND_TYPE <= nCommandType\r
- || nKey < 0 || MAX_KEY <= nKey) {\r
- return;\r
+ m_bRecordingMacro = FALSE;\r
+ while (!m_Macro.empty()) { // remove not released push\r
+ const KbdMacro& m = m_Macro.back();\r
+ if (HIWORD(m.lParam) & KF_UP)\r
+ break;\r
+ m_Macro.pop_back();\r
}\r
-\r
- m_nFunctionID[nApplicationID][nCommandType][nKey] = nFunctionID;\r
}\r
\r
-void CXkeymacsDll::ClearFunctionDefinition()\r
+void CXkeymacsDll::CallMacro()\r
{\r
- memset(m_nFunctionID, -1, sizeof(m_nFunctionID));\r
- memset(m_szFunctionDefinition, 0, sizeof(m_szFunctionDefinition));\r
+ if (m_bRecordingMacro)\r
+ m_bRecordingMacro = FALSE;\r
+ UINT before = GetModifierState(FALSE);\r
+ SetModifierState(0, before);\r
+ for (std::list<KbdMacro>::const_iterator m = m_Macro.begin(); m != m_Macro.end(); ++m)\r
+ if (HIWORD(m->lParam) & KF_UP)\r
+ ReleaseKey(static_cast<BYTE>(m->wParam));\r
+ else\r
+ DepressKey(static_cast<BYTE>(m->wParam), m->bOriginal);\r
+ SetModifierState(before, 0);\r
}\r
\r
-void CXkeymacsDll::SetFunctionDefinition(int nFunctionID, CString szDefinition)\r
+BOOL CXkeymacsDll::Is106Keyboard()\r
{\r
- if (nFunctionID < 0 || MAX_FUNCTION <= nFunctionID) {\r
- return;\r
- }\r
-\r
- memset(m_szFunctionDefinition[nFunctionID], 0, sizeof(m_szFunctionDefinition[nFunctionID]));\r
- _stprintf(m_szFunctionDefinition[nFunctionID], _T("%s"), szDefinition);\r
+ return m_Config.b106Keyboard;\r
+}\r
\r
- return;\r
+int CXkeymacsDll::IsPassThrough(BYTE nKey)\r
+{\r
+ BYTE bVk = 0;\r
+ do {\r
+ if (IsDown(bVk)\r
+ && (Commands[m_Config.nCommandID[m_nAppID][NONE][bVk]].fCommand == CCommands::PassThrough)) {\r
+ if (bVk == nKey) {\r
+ return GOTO_HOOK;\r
+ }\r
\r
+ return GOTO_DO_NOTHING;\r
+ }\r
+ } while (++bVk);\r
+ return CONTINUE;\r
}\r
\r
// call an original command which is defined in dot.xkeymacs\r
-void CXkeymacsDll::CallFunction(int nFunctionID)\r
+void CXkeymacsDll::CallFunction(int nFuncID)\r
{\r
- CArray<KeyBind, KeyBind> keybinds;\r
-\r
- if (nFunctionID < 0 || MAX_FUNCTION <= nFunctionID || !_tcslen(m_szFunctionDefinition[nFunctionID])) {\r
+ if (nFuncID < 0 || nFuncID >= MAX_FUNCTION)\r
return;\r
- }\r
-\r
- BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);\r
- BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);\r
- BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);\r
-\r
- if (m_szFunctionDefinition[nFunctionID][0] == _T('"') && m_szFunctionDefinition[nFunctionID][_tcslen(m_szFunctionDefinition[nFunctionID]) - 1] == _T('"')) {\r
- for (unsigned int i = 1; i < _tcslen(m_szFunctionDefinition[nFunctionID]) - 1; ++i) { // skip '"'\r
- keybinds.Add(ParseKey(nFunctionID, i));\r
- }\r
- } else if (m_szFunctionDefinition[nFunctionID][0] == _T('[') && m_szFunctionDefinition[nFunctionID][_tcslen(m_szFunctionDefinition[nFunctionID]) - 1] == _T(']')) {\r
- for (unsigned int i = 1; i < _tcslen(m_szFunctionDefinition[nFunctionID]) - 1; ++i) { // skip '[' and ']'\r
- if (m_szFunctionDefinition[nFunctionID][i] == _T('?')) { // [?f ?o ?o]\r
- ++i;\r
- keybinds.Add(ParseKey(nFunctionID, i));\r
- } else { // [ControlCharacter]\r
- for (int nKeyID = 0; nKeyID < sizeof(ControlCharacters) / sizeof(ControlCharacters[0]); ++nKeyID) {\r
- if (!_tcsncmp(m_szFunctionDefinition[nFunctionID] + i, ControlCharacters[nKeyID].name, _tcslen(ControlCharacters[nKeyID].name))) {\r
- KeyBind keybind = {NONE, ControlCharacters[nKeyID].bVk};\r
- keybinds.Add(keybind);\r
- i += _tcslen(ControlCharacters[nKeyID].name);\r
- break;\r
- }\r
+ LPCTSTR def = m_Config.szFunctionDefinition[nFuncID];\r
+ if (!def[0])\r
+ return;\r
+ std::vector<KeyBind> keybinds;\r
+ const LPCTSTR last = def + _tcslen(def) - 1;\r
+ if (*def == _T('"') && *last == _T('"')) {\r
+ ++def; // skip '"'\r
+ while (def < last)\r
+ keybinds.push_back(ParseKey(def));\r
+ } else if (*def == _T('[') && *last == _T(']')) {\r
+ while (++def < last) { // skip '[', ']', and ' '\r
+ if (*def == _T('?')) { // [?f ?o ?o]\r
+ keybinds.push_back(ParseKey(++def));\r
+ continue;\r
+ }\r
+ // [VK]\r
+ for (int i = 0; i < MAX_KEYNAME; ++i) {\r
+ size_t keylen = _tcslen(KeyNames[i].name);\r
+ if (!_tcsncmp(def, KeyNames[i].name, keylen)) {\r
+ KeyBind keybind = {NONE, KeyNames[i].bVk};\r
+ keybinds.push_back(keybind);\r
+ def += keylen;\r
+ break;\r
}\r
}\r
}\r
- } else {\r
+ } else\r
return;\r
- }\r
\r
BOOL bM_x = FALSE;\r
TCHAR szPath[MAX_PATH] = {'\0'};\r
unsigned int index = 0;\r
BOOL bInitialized = FALSE;\r
-\r
- for (int i = 0; i < keybinds.GetSize(); ++i) {\r
- const int nCommandType = keybinds.GetAt(i).nCommandType;\r
- const BYTE bVk = keybinds.GetAt(i).bVk;\r
-\r
- if (nCommandType < MAX_COMMAND_TYPE && Commands[m_nCommandID[m_nApplicationID][nCommandType][bVk]].fCommand) {\r
- if (Commands[m_nCommandID[m_nApplicationID][nCommandType][bVk]].fCommand == CCommands::ExecuteExtendedCommand) {\r
+ UINT before = GetModifierState(FALSE);\r
+\r
+ for (std::vector<KeyBind>::const_iterator p = keybinds.begin(); p != keybinds.end(); ++p) {\r
+ const int nType = p->nType;\r
+ const BYTE bVk = p->bVk;\r
+ int (*fCommand)() = nType < MAX_COMMAND_TYPE ? Commands[m_Config.nCommandID[m_nAppID][nType][bVk]].fCommand : NULL;\r
+ if (fCommand) {\r
+ if (fCommand == CCommands::ExecuteExtendedCommand)\r
bM_x = TRUE;\r
- } else if (!bInitialized) {\r
- if (bIsCtrlDown) {\r
- CUtils::UpdateKeyboardState(VK_CONTROL, 0);\r
- ReleaseKey(VK_CONTROL);\r
- }\r
-\r
- if (bIsAltDown) {\r
- ReleaseKey(VK_MENU);\r
- }\r
-\r
- if (bIsShiftDown) {\r
- ReleaseKey(VK_SHIFT);\r
- }\r
-\r
+ else if (!bInitialized) {\r
+ SetModifierState(0, before);\r
bInitialized = TRUE;\r
}\r
-// CUtils::Log("CallFunction: Command Name: %s", Commands[m_nCommandID[m_nApplicationID][nCommandType][bVk]].szCommandName);\r
- while (Commands[m_nCommandID[m_nApplicationID][nCommandType][bVk]].fCommand() == GOTO_RECURSIVE) {\r
+// CUtils::Log("CallFunction: Command Name: %s", Commands[m_Config.nCommandID[m_nAppID][nType][bVk]].szCommandName);\r
+ while (fCommand() == GOTO_RECURSIVE)\r
;\r
- }\r
- } else if (bM_x) {\r
- if (bVk == VK_RETURN) {\r
+ continue;\r
+ }\r
+ if (bM_x) {\r
+ if (bVk == VK_RETURN)\r
InvokeM_x(szPath);\r
- } else {\r
- for (TCHAR nAscii = 1; nAscii != 0; ++nAscii) { // repeat until overflow\r
- if (bVk != 0 && a2v(nAscii) == bVk && ((nCommandType & SHIFT) != 0) == IsShift(nAscii)) {\r
+ else if (bVk != 0) {\r
+ TCHAR nAscii = 0;\r
+ do { // 1-127\r
+ if (a2v(++nAscii) == bVk && ((nType & SHIFT) != 0) == IsShift(nAscii)) {\r
// CUtils::Log("M-x: %#X (%c), %#X (%c)", bVk, bVk, nAscii, nAscii);\r
szPath[index++] = nAscii;\r
break;\r
}\r
- }\r
- }\r
- } else {\r
- if (!bInitialized) {\r
- if (bIsCtrlDown) {\r
- CUtils::UpdateKeyboardState(VK_CONTROL, 0);\r
- ReleaseKey(VK_CONTROL);\r
- }\r
-\r
- if (bIsAltDown) {\r
- ReleaseKey(VK_MENU);\r
- }\r
-\r
- if (bIsShiftDown) {\r
- ReleaseKey(VK_SHIFT);\r
- }\r
-\r
- bInitialized = TRUE;\r
- }\r
- if (nCommandType & WIN_WIN) {\r
- DepressKey(VK_LWIN);\r
- }\r
- if (nCommandType & WIN_CTRL) {\r
- DepressKey(VK_CONTROL);\r
- }\r
- if (nCommandType & WIN_ALT) {\r
- DepressKey(VK_MENU);\r
- }\r
- if (nCommandType & SHIFT) {\r
- DepressKey(VK_SHIFT);\r
- }\r
-\r
- Kdu(bVk);\r
-\r
- if (nCommandType & SHIFT && (keybinds.GetSize() <= i + 1 || !(keybinds.GetAt(i + 1).nCommandType & SHIFT))) {\r
- ReleaseKey(VK_SHIFT);\r
- }\r
- if (nCommandType & WIN_ALT && (keybinds.GetSize() <= i + 1 || !(keybinds.GetAt(i + 1).nCommandType & WIN_ALT))) {\r
- ReleaseKey(VK_MENU);\r
- }\r
- if (nCommandType & WIN_CTRL && (keybinds.GetSize() <= i + 1 || !(keybinds.GetAt(i + 1).nCommandType & WIN_CTRL))) {\r
- ReleaseKey(VK_CONTROL);\r
+ } while (nAscii != 127);\r
}\r
- if (nCommandType & WIN_WIN && (keybinds.GetSize() <= i + 1 || !(keybinds.GetAt(i + 1).nCommandType & WIN_WIN))) {\r
- ReleaseKey(VK_LWIN);\r
- }\r
- }\r
- }\r
-\r
- keybinds.RemoveAll();\r
-\r
- if (bInitialized) {\r
- // If these lines are invoked at M-x, a window transition does not work well.\r
-\r
- if (bIsShiftDown) {\r
- DepressKey(VK_SHIFT);\r
+ continue;\r
}\r
-\r
- if (bIsAltDown) {\r
- DepressKey(VK_MENU);\r
+ if (!bInitialized) {\r
+ SetModifierState(0, before);\r
+ bInitialized = TRUE;\r
}\r
-\r
- if (bIsCtrlDown) {\r
+ if (nType & WIN_WIN)\r
+ DepressKey(VK_LWIN);\r
+ if (nType & WIN_CTRL)\r
DepressKey(VK_CONTROL);\r
- CUtils::UpdateKeyboardState(VK_CONTROL, 1);\r
- }\r
+ if (nType & WIN_ALT)\r
+ DepressKey(VK_MENU);\r
+ if (nType & SHIFT)\r
+ DepressKey(VK_SHIFT);\r
+ Kdu(bVk);\r
+ const int nNextType = (p + 1) != keybinds.end() ? (p + 1)->nType : 0;\r
+ if (nType & SHIFT && !(nNextType & SHIFT))\r
+ ReleaseKey(VK_SHIFT);\r
+ if (nType & WIN_ALT && !(nNextType & WIN_ALT))\r
+ ReleaseKey(VK_MENU);\r
+ if (nType & WIN_CTRL && !(nNextType & WIN_CTRL))\r
+ ReleaseKey(VK_CONTROL);\r
+ if (nType & WIN_WIN && !(nNextType & WIN_WIN))\r
+ ReleaseKey(VK_LWIN);\r
}\r
+\r
+ if (bInitialized)\r
+ // If this lines is invoked on M-x, a window transition does not work well.\r
+ SetModifierState(before, 0);\r
return;\r
}\r
\r
-KeyBind CXkeymacsDll::ParseKey(const int nFunctionID, unsigned int &i)\r
+KeyBind CXkeymacsDll::ParseKey(LPCTSTR& def)\r
{\r
KeyBind keybind = {NONE};\r
-\r
- if (m_szFunctionDefinition[nFunctionID][i] == _T('\\')) {\r
- ++i;\r
- BOOL bFound = FALSE;\r
- do {\r
- bFound = FALSE;\r
- for (int ModifierID = 0; ModifierID < sizeof(Modifiers) / sizeof(Modifiers[0]); ++ModifierID) {\r
- if (!_tcsncmp(m_szFunctionDefinition[nFunctionID] + i, Modifiers[ModifierID].name, _tcslen(Modifiers[ModifierID].name))\r
- && _tcslen(Modifiers[ModifierID].name) < _tcslen(m_szFunctionDefinition[nFunctionID] + i)) {\r
- keybind.nCommandType |= Modifiers[ModifierID].id;\r
- i+= _tcslen(Modifiers[ModifierID].name);\r
- bFound = TRUE;\r
- }\r
+ if (*def == _T('\\')) { // set modifiers\r
+ ++def;\r
+ LOOP:\r
+ for (int i = 0; i < MAX_MODIFIER; ++i) {\r
+ size_t len = _tcslen(Modifiers[i].name);\r
+ if (!_tcsncmp(def, Modifiers[i].name, len)) {\r
+ keybind.nType |= Modifiers[i].id;\r
+ def += len;\r
+ goto LOOP;\r
}\r
- } while (bFound);\r
- }\r
- if (IsShift(m_szFunctionDefinition[nFunctionID][i]) && !(keybind.nCommandType & (WIN_CTRL | WIN_ALT | WIN_WIN))) {\r
- keybind.nCommandType |= SHIFT;\r
+ }\r
}\r
-\r
- for (int nKeyID = 0; nKeyID < sizeof(ControlCharacters) / sizeof(ControlCharacters[0]); ++nKeyID) {\r
- if (!_tcsncmp(m_szFunctionDefinition[nFunctionID] + i, ControlCharacters[nKeyID].name, _tcslen(ControlCharacters[nKeyID].name))) {\r
- i += _tcslen(ControlCharacters[nKeyID].name);\r
+ if (IsShift(*def) && !(keybind.nType & (WIN_CTRL | WIN_ALT | WIN_WIN)))\r
+ keybind.nType |= SHIFT;\r
+ int i = 0;\r
+ for (; i < MAX_KEYNAME; ++i) {\r
+ size_t len = _tcslen(KeyNames[i].name);\r
+ if (!_tcsncmp(def, KeyNames[i].name, len)) {\r
+ def += len;\r
break;\r
}\r
}\r
- if (nKeyID < sizeof(ControlCharacters) / sizeof(ControlCharacters[0])) {\r
- keybind.bVk = ControlCharacters[nKeyID].bVk;\r
- } else {\r
- keybind.bVk = a2v(m_szFunctionDefinition[nFunctionID][i]);\r
- }\r
-\r
+ keybind.bVk = i < MAX_KEYNAME ? KeyNames[i].bVk : a2v(*def++);\r
return keybind;\r
}\r
\r
case _T('&'):\r
return TRUE;\r
case _T('\''):\r
- return CXkeymacsData::Is106Keyboard();\r
+ return m_Config.b106Keyboard;\r
case _T('('):\r
case _T(')'):\r
case _T('*'):\r
case _T('0'): case _T('1'): case _T('2'): case _T('3'): case _T('4'): case _T('5'): case _T('6'): case _T('7'): case _T('8'): case _T('9'):\r
return FALSE;\r
case _T(':'):\r
- return !CXkeymacsData::Is106Keyboard();\r
+ return !m_Config.b106Keyboard;\r
case _T(';'):\r
return FALSE;\r
case _T('<'):\r
return TRUE;\r
case _T('='):\r
- return CXkeymacsData::Is106Keyboard();\r
+ return m_Config.b106Keyboard;\r
case _T('>'):\r
case _T('?'):\r
return TRUE;\r
case _T('@'):\r
- return !CXkeymacsData::Is106Keyboard();\r
+ return !m_Config.b106Keyboard;\r
case _T('A'): case _T('B'): case _T('C'): case _T('D'): case _T('E'): case _T('F'): case _T('G'): case _T('H'): case _T('I'): case _T('J'): \r
case _T('K'): case _T('L'): case _T('M'): case _T('N'): case _T('O'): case _T('P'): case _T('Q'): case _T('R'): case _T('S'): case _T('T'): \r
case _T('U'): case _T('V'): case _T('W'): case _T('X'): case _T('Y'): case _T('Z'): \r
case _T(']'):\r
return FALSE;\r
case _T('^'):\r
- return !CXkeymacsData::Is106Keyboard();\r
+ return !m_Config.b106Keyboard;\r
case _T('_'):\r
return TRUE;\r
case _T('`'):\r
- return CXkeymacsData::Is106Keyboard();\r
+ return m_Config.b106Keyboard;\r
case _T('a'): case _T('b'): case _T('c'): case _T('d'): case _T('e'): case _T('f'): case _T('g'): case _T('h'): case _T('i'): case _T('j'): \r
case _T('k'): case _T('l'): case _T('m'): case _T('n'): case _T('o'): case _T('p'): case _T('q'): case _T('r'): case _T('s'): case _T('t'): \r
case _T('u'): case _T('v'): case _T('w'): case _T('x'): case _T('y'): case _T('z'): \r
case _T('!'):\r
return '1';\r
case _T('"'):\r
- return CXkeymacsData::Is106Keyboard() ? '2' : (BYTE) 0xde; // VK_OEM_7\r
+ return m_Config.b106Keyboard ? '2' : (BYTE) 0xde; // VK_OEM_7\r
case _T('#'):\r
return '3';\r
case _T('$'):\r
case _T('%'):\r
return '5';\r
case _T('&'):\r
- return CXkeymacsData::Is106Keyboard() ? '6' : '7';\r
+ return m_Config.b106Keyboard ? '6' : '7';\r
case _T('\''):\r
- return CXkeymacsData::Is106Keyboard() ? '7' : (BYTE) 0xde; // VK_OEM_7\r
+ return m_Config.b106Keyboard ? '7' : (BYTE) 0xde; // VK_OEM_7\r
case _T('('):\r
- return CXkeymacsData::Is106Keyboard() ? '8' : '9';\r
+ return m_Config.b106Keyboard ? '8' : '9';\r
case _T(')'):\r
- return CXkeymacsData::Is106Keyboard() ? '9' : '0';\r
+ return m_Config.b106Keyboard ? '9' : '0';\r
case _T('*'):\r
- return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xba : '8'; // VK_OEM_1\r
+ return m_Config.b106Keyboard ? (BYTE) 0xba : '8'; // VK_OEM_1\r
case _T('+'):\r
return 0xbb; // VK_OEM_PLUS\r
case _T(','):\r
case _T(':'):\r
return 0xba; // VK_OEM_1\r
case _T(';'):\r
- return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xbb : (BYTE) 0xba; // VK_OEM_PLUS VK_OEM_1\r
+ return m_Config.b106Keyboard ? (BYTE) 0xbb : (BYTE) 0xba; // VK_OEM_PLUS VK_OEM_1\r
case _T('<'):\r
return 0xbc; // VK_OEM_COMMA\r
case _T('='):\r
- return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xbd : (BYTE) 0xbb; // VK_OEM_MINUS VK_OEM_PLUS\r
+ return m_Config.b106Keyboard ? (BYTE) 0xbd : (BYTE) 0xbb; // VK_OEM_MINUS VK_OEM_PLUS\r
case _T('>'):\r
return 0xbe; // VK_OEM_PERIOD\r
case _T('?'):\r
return 0xbf; // VK_OEM_2\r
case _T('@'):\r
- return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xc0 : '2';\r
+ return m_Config.b106Keyboard ? (BYTE) 0xc0 : '2';\r
case _T('A'): case _T('B'): case _T('C'): case _T('D'): case _T('E'): case _T('F'): case _T('G'): case _T('H'): case _T('I'): case _T('J'): \r
case _T('K'): case _T('L'): case _T('M'): case _T('N'): case _T('O'): case _T('P'): case _T('Q'): case _T('R'): case _T('S'): case _T('T'): \r
case _T('U'): case _T('V'): case _T('W'): case _T('X'): case _T('Y'): case _T('Z'): \r
case _T(']'):\r
return 0xdd; // VK_OEM_6\r
case _T('^'):\r
- return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xde : '6'; // VK_OEM_7\r
+ return m_Config.b106Keyboard ? (BYTE) 0xde : '6'; // VK_OEM_7\r
case _T('_'):\r
- return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xe2 : (BYTE) 0xbd; // VK_OEM_102 VK_OEM_MINUS\r
+ return m_Config.b106Keyboard ? (BYTE) 0xe2 : (BYTE) 0xbd; // VK_OEM_102 VK_OEM_MINUS\r
case _T('`'):\r
return 0xc0; // VK_OEM_3\r
case _T('a'): case _T('b'): case _T('c'): case _T('d'): case _T('e'): case _T('f'): case _T('g'): case _T('h'): case _T('i'): case _T('j'): \r
case _T('}'):\r
return 0xdd; // VK_OEM_6\r
case _T('~'):\r
- return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xde : (BYTE) 0xc0; // VK_OEM_7 VK_OEM_3\r
+ return m_Config.b106Keyboard ? (BYTE) 0xde : (BYTE) 0xc0; // VK_OEM_7 VK_OEM_3\r
default:\r
return 0;\r
}\r
}\r
\r
-void CXkeymacsDll::DeleteAllShell_NotifyIcon()\r
-{\r
- for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {\r
- DeleteShell_NotifyIcon((ICON_TYPE)icon);\r
- }\r
-}\r
-\r
-void CXkeymacsDll::AddAllShell_NotifyIcon()\r
-{\r
- for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {\r
- AddShell_NotifyIcon((ICON_TYPE)icon);\r
- }\r
-}\r
-\r
-void CXkeymacsData::SetWindowText(LPCTSTR lpszWindowText)\r
-{\r
- m_nWindowTextType = CUtils::GetWindowTextType(lpszWindowText);\r
- if (m_nWindowTextType == IDS_WINDOW_TEXT_IGNORE) {\r
- m_strWindowText = _T('*');\r
- } else {\r
- m_strWindowText.Format(lpszWindowText);\r
- }\r
-}\r
-\r
-CString CXkeymacsData::GetWindowText()\r
-{\r
- return m_strWindowText;\r
-}\r
-\r
-void CXkeymacsData::SetWindowTextType(int nWindowTextType)\r
-{\r
- m_nWindowTextType = nWindowTextType;\r
-}\r
-\r
-int CXkeymacsData::GetWindowTextType()\r
-{\r
- return m_nWindowTextType;\r
-}\r
-\r
BOOL CXkeymacsDll::IsMatchWindowText(CString szWindowText)\r
{\r
BOOL bIsMatchWindowText = TRUE;\r
\r
- TCHAR szCurrentWindowText[0x100] = {'\0'};\r
+ TCHAR szCurrentWindowText[WINDOW_TEXT_LENGTH] = {'\0'};\r
GetWindowText(GetForegroundWindow(), szCurrentWindowText, sizeof(szCurrentWindowText));\r
\r
switch (CUtils::GetWindowTextType(szWindowText)) {\r
}\r
}\r
\r
-BOOL CXkeymacsData::Get326Compatible()\r
-{\r
- return m_b326Compatible;\r
-}\r
-\r
-void CXkeymacsData::Set326Compatible(BOOL b326Compatible)\r
-{\r
- m_b326Compatible = b326Compatible;\r
-}\r
-\r
-void CXkeymacsDll::Set326Compatible(int nApplicationID, BOOL b326Compatible)\r
-{\r
- m_b326Compatible[nApplicationID] = b326Compatible;\r
-}\r
-\r
BOOL CXkeymacsDll::Get326Compatible()\r
{\r
- return m_b326Compatible[m_nApplicationID];\r
+ return m_Config.b326Compatible[m_nAppID];\r
}\r
\r
void CXkeymacsDll::InvokeM_x(const TCHAR *const szPath)\r
// CUtils::Log("M-x: szPath=_%s_", szPath);\r
int (*fCommand)() = NULL;\r
\r
- for (int i = 0; i < sizeof(Commands) / sizeof(Commands[0]); ++i) {\r
+ for (int i = 0; i < MAX_COMMAND; ++i) {\r
if (_tcsicmp(szPath, Commands[i].szCommandName) == 0) {\r
fCommand = Commands[i].fCommand;\r
break;\r
}\r
}\r
\r
-void CXkeymacsDll::ModifyM_xTip(const TCHAR *const szPath)\r
+void CXkeymacsDll::SetM_xTip(const TCHAR *const szPath)\r
{\r
- if (szPath) {\r
- if (_tcslen(szPath) < sizeof(m_stNtfyIcon[MX_ICON].szTip) / sizeof(m_stNtfyIcon[MX_ICON].szTip[0]) - 5) {\r
- memset(m_stNtfyIcon[MX_ICON].szTip, 0, sizeof(m_stNtfyIcon[MX_ICON].szTip));\r
- _stprintf(m_stNtfyIcon[MX_ICON].szTip, "M-x %s", szPath);\r
- }\r
- } else {\r
- memset(m_stNtfyIcon[MX_ICON].szTip, 0, sizeof(m_stNtfyIcon[MX_ICON].szTip));\r
- _stprintf(m_stNtfyIcon[MX_ICON].szTip, "M-x LED");\r
- }\r
+ _tcscpy_s(m_M_xTip, "M-x LED");\r
+ if (szPath && _tcslen(szPath) < 128 - 5)\r
+ _stprintf_s(m_M_xTip, "M-x %s", szPath);\r
+}\r
\r
- ModifyShell_NotifyIcon(MX_ICON, CCommands::bM_x(), TRUE);\r
+BOOL CXkeymacsDll::SendIconMessage(ICONMSG *pMsg, DWORD num)\r
+{\r
+ DWORD ack, read;\r
+ return CallNamedPipe(ICON_PIPE, pMsg, sizeof(ICONMSG) * num, &ack, sizeof(DWORD), &read, NMPWAIT_NOWAIT);\r
}\r