1 // xkeymacsdll.cpp : Defines the initialization routines for the DLL.
\r
5 #include "resource.h"
\r
7 #include "Commands.h"
\r
13 #define new DEBUG_NEW
\r
15 static char THIS_FILE[] = __FILE__;
\r
19 static AFX_EXTENSION_MODULE XkeymacsdllDLL = { NULL, NULL };
\r
21 static HINSTANCE g_hDllInst = NULL;
\r
23 HINSTANCE GetThisHInst()
\r
28 extern "C" int APIENTRY
\r
29 DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
\r
31 g_hDllInst = hInstance;
\r
33 // Remove this if you use lpReserved
\r
34 UNREFERENCED_PARAMETER(lpReserved);
\r
36 if (dwReason == DLL_PROCESS_ATTACH) {
\r
37 TRACE0("XKEYMACSDLL.DLL Initializing!\n");
\r
39 // Extension DLL one-time initialization
\r
40 if (!AfxInitExtensionModule(XkeymacsdllDLL, hInstance)) {
\r
44 // Insert this DLL into the resource chain
\r
45 // NOTE: If this Extension DLL is being implicitly linked to by
\r
46 // an MFC Regular DLL (such as an ActiveX Control)
\r
47 // instead of an MFC application, then you will want to
\r
48 // remove this line from DllMain and put it in a separate
\r
49 // function exported from this Extension DLL. The Regular DLL
\r
50 // that uses this Extension DLL should then explicitly call that
\r
51 // function to initialize this Extension DLL. Otherwise,
\r
52 // the CDynLinkLibrary object will not be attached to the
\r
53 // Regular DLL's resource chain, and serious problems will
\r
57 new CDynLinkLibrary(XkeymacsdllDLL);
\r
59 catch (CMemoryException* e) {
\r
61 // CUtils::Log("DllMain: 'new' threw an exception");
\r
63 } else if (dwReason == DLL_PROCESS_DETACH) {
\r
64 TRACE0("XKEYMACSDLL.DLL Terminating!\n");
\r
65 // Terminate the library before destructors are called
\r
66 AfxTermExtensionModule(XkeymacsdllDLL);
\r
71 //////////////////////////////////////////////////////////////////////
\r
72 // CXkeymacsDll Class
\r
73 //////////////////////////////////////////////////////////////////////
\r
75 #include "xkeymacsDll.h"
\r
76 #pragma data_seg(".xkmcs")
\r
77 HHOOK CXkeymacsDll::m_hHookKeyboard = NULL;
\r
78 HHOOK CXkeymacsDll::m_hHookCallWnd = NULL;
\r
79 HHOOK CXkeymacsDll::m_hHookCallWndRet = NULL;
\r
80 HHOOK CXkeymacsDll::m_hHookGetMessage = NULL;
\r
81 HHOOK CXkeymacsDll::m_hHookShell = NULL;
\r
82 int CXkeymacsDll::m_nCommandID[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};
\r
83 BOOL CXkeymacsDll::m_bAtIbeamCursorOnly[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};
\r
84 int CXkeymacsDll::m_nFunctionID[MAX_APP][MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};
\r
85 TCHAR CXkeymacsDll::m_szSpecialApp[MAX_APP][CLASS_NAME_LENGTH] = {'\0'};
\r
86 TCHAR CXkeymacsDll::m_szWindowText[MAX_APP][WINDOW_TEXT_LENGTH] = {'\0'};
\r
87 BOOL CXkeymacsDll::m_bRightControl = FALSE;
\r
88 BOOL CXkeymacsDll::m_bRightAlt = FALSE;
\r
89 BOOL CXkeymacsDll::m_bRightShift = FALSE;
\r
90 BOOL CXkeymacsDll::m_bHook = TRUE;
\r
91 BOOL CXkeymacsDll::m_bDefiningMacro = FALSE;
\r
92 DWORD CXkeymacsDll::m_dwOldMessage[MAX_ICON_TYPE] = {'\0'};
\r
93 NOTIFYICONDATA CXkeymacsDll::m_stNtfyIcon[MAX_ICON_TYPE] = {'\0'};
\r
94 NOTIFYICONDATA CXkeymacsDll::m_stOldNtfyIcon[MAX_ICON_TYPE] = {'\0'};
\r
95 HICON CXkeymacsDll::m_hIcon[MAX_ICON_TYPE][MAX_STATUS] = {'\0'};
\r
96 BOOL CXkeymacsDll::m_bIcon[MAX_ICON_TYPE] = {'\0'};
\r
97 int CXkeymacsDll::m_nKillRingMax[MAX_APP] = {'\0'};
\r
98 BOOL CXkeymacsDll::m_bUseDialogSetting[MAX_APP] = {'\0'};
\r
99 CList<CClipboardSnap *, CClipboardSnap *> CXkeymacsDll::m_oKillRing;
\r
100 CObList CXkeymacsDll::m_Macro;
\r
101 int CXkeymacsDll::m_nKillRing = 0;
\r
102 int CXkeymacsDll::m_nOriginal[MAX_COMMAND_TYPE][MAX_KEY] = {'\0'};
\r
103 int CXkeymacsDll::m_nApplicationID = 0;
\r
104 int CXkeymacsDll::m_nSettingStyle[MAX_APP] = {'\0'};
\r
105 BOOL CXkeymacsDll::m_bIgnoreUndefinedMetaCtrl[MAX_APP] = {'\0'};
\r
106 BOOL CXkeymacsDll::m_bIgnoreUndefinedC_x[MAX_APP] = {'\0'};
\r
107 // int CXkeymacsDll::m_nPassThrough = 0;
\r
108 TCHAR CXkeymacsDll::m_szApplicationName[MAX_PATH] = {'\0'};
\r
109 TCHAR CXkeymacsDll::m_szOldApplicationName[MAX_PATH] = {'\0'};
\r
110 BOOL CXkeymacsDll::m_bEnableCUA[MAX_APP] = {'\0'};
\r
111 TCHAR CXkeymacsDll::m_szFunctionDefinition[MAX_FUNCTION][MAX_DEFINITION] = {'\0'};
\r
112 int CXkeymacsDll::m_nAccelerate = 0;
\r
113 int CXkeymacsDll::m_nKeyboardSpeed = 31;
\r
114 HCURSOR CXkeymacsDll::m_hCursor[MAX_STATUS] = {'\0'};
\r
115 HCURSOR CXkeymacsDll::m_hCurrentCursor = NULL;
\r
116 BOOL CXkeymacsDll::m_bCursor = FALSE;
\r
117 BOOL CXkeymacsDll::m_b326Compatible[MAX_APP] = {'\0'};
\r
119 BOOL CXkeymacsData::m_b106Keyboard = FALSE;
\r
122 //////////////////////////////////////////////////////////////////////
\r
123 // Construction/Destruction
\r
124 //////////////////////////////////////////////////////////////////////
\r
126 CXkeymacsDll::CXkeymacsDll()
\r
128 CUtils::InitCUtils();
\r
131 CXkeymacsDll::~CXkeymacsDll()
\r
136 int CXkeymacsDll::ModifyShell_NotifyIcon(ICON_TYPE icon, BOOL bNewStatus, BOOL bForce)
\r
138 if (m_stNtfyIcon[icon].hIcon == (bNewStatus ? m_hIcon[icon][ON_ICON] : m_hIcon[icon][OFF_ICON])) {
\r
143 m_stNtfyIcon[icon].hIcon = (bNewStatus ? m_hIcon[icon][ON_ICON] : m_hIcon[icon][OFF_ICON]);
\r
145 return DoShell_NotifyIcon(icon, NIM_MODIFY);
\r
148 void CXkeymacsDll::SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hEnable, HICON hDisableTMP, HICON hDisableWOCQ, HICON hDisable, BOOL bEnable)
\r
150 m_hIcon[icon][STATUS_ENABLE] = hEnable;
\r
151 m_hIcon[icon][STATUS_DISABLE_TMP] = hDisableTMP;
\r
152 m_hIcon[icon][STATUS_DISABLE_WOCQ] = hDisableWOCQ;
\r
153 m_hIcon[icon][STATUS_DISABLE] = hDisable;
\r
154 m_bIcon[icon] = bEnable;
\r
155 m_stNtfyIcon[icon] = stNtfyIcon;
\r
156 AddShell_NotifyIcon(icon);
\r
159 void CXkeymacsDll::SetNotifyIconData(ICON_TYPE icon, NOTIFYICONDATA stNtfyIcon, HICON hOn, HICON hOff, BOOL bEnable)
\r
161 m_hIcon[icon][ON_ICON] = hOn;
\r
162 m_hIcon[icon][OFF_ICON] = hOff;
\r
163 m_bIcon[icon] = bEnable;
\r
164 m_stNtfyIcon[icon] = stNtfyIcon;
\r
165 AddShell_NotifyIcon(icon);
\r
168 void CXkeymacsDll::EnableShell_NotifyIcon(ICON_TYPE icon, BOOL bEnable)
\r
170 DeleteShell_NotifyIcon(icon);
\r
171 m_bIcon[icon] = bEnable;
\r
172 AddShell_NotifyIcon(icon);
\r
176 BOOL CXkeymacsDll::DoShell_NotifyIcon(ICON_TYPE icon, DWORD dwMessage)
\r
179 && (m_dwOldMessage[icon] != dwMessage
\r
180 || memcmp(&m_stOldNtfyIcon[icon], &m_stNtfyIcon[icon], sizeof(m_stNtfyIcon[icon])))) {
\r
181 m_dwOldMessage[icon] = dwMessage;
\r
182 m_stOldNtfyIcon[icon] = m_stNtfyIcon[icon];
\r
185 for (int retry_count = 0; retry_count < 20; ++retry_count) { // retry for timeout
\r
186 rc = Shell_NotifyIcon(dwMessage, &m_stNtfyIcon[icon]);
\r
187 if (dwMessage != NIM_ADD || rc || (GetLastError() != ERROR_TIMEOUT && 5 < retry_count)) {
\r
190 Sleep(1000); // 1sec
\r
191 if ((rc = Shell_NotifyIcon(NIM_MODIFY, &m_stNtfyIcon[icon])) != FALSE) {
\r
192 break; // ERROR_TIMEOUT was returned but the icon was also added.
\r
201 void CXkeymacsDll::AddShell_NotifyIcon(ICON_TYPE icon)
\r
203 DoShell_NotifyIcon(icon, NIM_ADD);
\r
206 void CXkeymacsDll::DeleteShell_NotifyIcon(ICON_TYPE icon)
\r
208 DoShell_NotifyIcon(icon, NIM_DELETE);
\r
211 // set keyboard hook
\r
212 BOOL CXkeymacsDll::SetKeyboardHook()
\r
214 m_hHookKeyboard = ::SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)KeyboardProc, GetThisHInst(), 0);
\r
215 if (!m_hHookKeyboard) {
\r
219 m_hHookCallWnd = ::SetWindowsHookEx(WH_CALLWNDPROC, (HOOKPROC)CallWndProc, GetThisHInst(), 0);
\r
221 m_hHookCallWndRet = ::SetWindowsHookEx(WH_CALLWNDPROCRET, (HOOKPROC)CallWndRetProc, GetThisHInst(), 0);
\r
223 m_hHookGetMessage = ::SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, GetThisHInst(), 0);
\r
225 m_hHookShell = ::SetWindowsHookEx(WH_SHELL, (HOOKPROC)ShellProc, GetThisHInst(), 0);
\r
227 AddShell_NotifyIcon(MAIN_ICON);
\r
232 // release keyboard hook
\r
233 BOOL CXkeymacsDll::ReleaseKeyboardHook()
\r
235 BOOL bKeyboard = TRUE;
\r
236 BOOL bCallWnd = TRUE;
\r
237 BOOL bCallWndRet = TRUE;
\r
238 BOOL bGetMessage = TRUE;
\r
239 BOOL bShell = TRUE;
\r
241 if (m_hHookKeyboard) {
\r
242 bKeyboard = ::UnhookWindowsHookEx(m_hHookKeyboard);
\r
244 m_hHookKeyboard = NULL;
\r
246 if (m_hHookCallWnd) {
\r
247 bCallWnd = ::UnhookWindowsHookEx(m_hHookCallWnd);
\r
249 m_hHookCallWnd = NULL;
\r
251 if (m_hHookCallWndRet) {
\r
252 bCallWndRet = ::UnhookWindowsHookEx(m_hHookCallWndRet);
\r
254 m_hHookCallWndRet = NULL;
\r
256 if (m_hHookGetMessage) {
\r
257 bGetMessage = ::UnhookWindowsHookEx(m_hHookGetMessage);
\r
259 m_hHookGetMessage = NULL;
\r
261 if (m_hHookShell) {
\r
262 bShell = ::UnhookWindowsHookEx(m_hHookShell);
\r
264 m_hHookShell = NULL;
\r
266 return bKeyboard && bCallWnd && bCallWndRet && bGetMessage && bShell;
\r
269 void CXkeymacsDll::SetKeyboardHookFlag(BOOL bFlag)
\r
274 if (CCommands::IsTemporarilyDisableXKeymacs()) {
\r
275 m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE_TMP];
\r
276 m_hCurrentCursor = m_hCursor[STATUS_DISABLE_TMP];
\r
278 m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_ENABLE];
\r
279 m_hCurrentCursor = m_hCursor[STATUS_ENABLE];
\r
282 m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE_WOCQ];
\r
283 m_hCurrentCursor = m_hCursor[STATUS_DISABLE_WOCQ];
\r
285 if (m_nSettingStyle[m_nApplicationID] == SETTING_DISABLE
\r
286 || (!_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Default"))
\r
287 && CUtils::IsDefaultIgnoreApplication())) {
\r
288 m_stNtfyIcon[MAIN_ICON].hIcon = m_hIcon[MAIN_ICON][STATUS_DISABLE];
\r
289 m_hCurrentCursor = m_hCursor[STATUS_DISABLE];
\r
291 DoShell_NotifyIcon(MAIN_ICON, NIM_MODIFY);
\r
295 // if be keyboard hook, return TRUE
\r
296 BOOL CXkeymacsDll::IsKeyboardHook()
\r
305 void CXkeymacsDll::LogCallWndProcMessage(WPARAM wParam, LPARAM lParam)
\r
307 CWPSTRUCT &cwps = *(CWPSTRUCT *)lParam;
\r
309 switch (cwps.message) {
\r
310 case WM_PAINT: // 0x000F
\r
311 case WM_MDIGETACTIVE: // 0x0229
\r
318 case WM_CREATE: // 0x0001
\r
319 // CUtils::Log(_T("CallWndProc: cwps.message = WM_CREATE"));
\r
321 case WM_DESTROY: // 0x0002
\r
322 // CUtils::Log(_T("CallWndProc: cwps.message = WM_DESTROY"));
\r
324 case WM_MOVE: // 0x0003
\r
325 // CUtils::Log(_T("CallWndProc: cwps.message = WM_MOVE");)
\r
327 case WM_SIZE: // 0x0005
\r
328 // CUtils::Log(_T("CallWndProc: cwps.message = WM_SIZE"));
\r
330 case WM_GETTEXT: // 0x000D
\r
331 // CUtils::Log(_T("CallWndProc: cwps.message = WM_GETTEXT"));
\r
333 case WM_ERASEBKGND: // 0x0014
\r
334 // CUtils::Log(_T("CallWndProc: cwps.message = WM_ERASEBKGND"));
\r
336 case WM_WINDOWPOSCHANGING: // 0x0046
\r
337 // CUtils::Log(_T("CallWndProc: cwps.message = WM_WINDOWPOSCHANGING"));
\r
339 case WM_WINDOWPOSCHANGED: // 0x0047
\r
340 // CUtils::Log(_T("CallWndProc: cwps.message = WM_WINDOWPOSCHANGED"));
\r
342 case WM_COPYDATA: // 0x004A
\r
343 // CUtils::Log(_T("CallWndProc: cwps.message = WM_COPYDATA"));
\r
345 case WM_NCCREATE: // 0x0081
\r
346 // CUtils::Log(_T("CallWndProc: cwps.message = WM_NCCREATE"));
\r
348 case WM_NCDESTROY: // 0x0082
\r
349 // CUtils::Log(_T("CallWndProc: cwps.message = WM_NCDESTROY"));
\r
351 case WM_NCCALCSIZE: // 0x0083
\r
352 // CUtils::Log(_T("CallWndProc: cwps.message = WM_NCCALCSIZE"));
\r
354 case WM_NCPAINT: // 0x0085
\r
355 // CUtils::Log(_T("CallWndProc: cwps.message = WM_NCPAINT"));
\r
357 case WM_IME_STARTCOMPOSITION: // 0x010D
\r
358 // CUtils::Log(_T("CallWndProc: cwps.message = WM_IME_STARTCOMPOSITION"));
\r
360 case WM_IME_ENDCOMPOSITION: // 0x010E
\r
361 // CUtils::Log(_T("CallWndProc: cwps.message = WM_IME_ENDCOMPOSITION"));
\r
363 case WM_IME_KEYLAST: // 0x010F
\r
364 // CUtils::Log(_T("CallWndProc: cwps.message = WM_IME_KEYLAST"));
\r
366 case WM_COMMAND: // 0x0111
\r
367 // CUtils::Log(_T("CallWndProc: cwps.message = WM_COMMAND"));
\r
369 case WM_CTLCOLOREDIT: // 0x0133
\r
370 // CUtils::Log(_T("CallWndProc: cwps.message = WM_CTLCOLOREDIT"));
\r
372 case WM_POWERBROADCAST: // 0x0218
\r
373 // CUtils::Log(_T("CallWndProc: cwps.message = WM_POWERBROADCAST"));
\r
375 case PBT_APMQUERYSUSPEND: // 0x0000
\r
376 // CUtils::Log(_T("PBT_APMQUERYSUSPEND"));
\r
378 case PBT_APMQUERYSTANDBY: // 0x0001
\r
379 // CUtils::Log(_T("PBT_APMQUERYSTANDBY"));
\r
381 case PBT_APMQUERYSUSPENDFAILED: // 0x0002
\r
382 // CUtils::Log(_T("PBT_APMQUERYSUSPENDFAILED"));
\r
384 case PBT_APMQUERYSTANDBYFAILED: // 0x0003
\r
385 // CUtils::Log(_T("PBT_APMQUERYSTANDBYFAILED"));
\r
387 case PBT_APMSUSPEND: // 0x0004
\r
388 // CUtils::Log(_T("PBT_APMSUSPEND"));
\r
390 case PBT_APMSTANDBY: // 0x0005
\r
391 // CUtils::Log(_T("PBT_APMSTANDBY"));
\r
393 case PBT_APMRESUMECRITICAL: // 0x0006
\r
394 // CUtils::Log(_T("PBT_APMRESUMECRITICAL"));
\r
396 case PBT_APMRESUMESUSPEND: // 0x0007
\r
397 // CUtils::Log(_T("PBT_APMRESUMESUSPEND"));
\r
399 case PBT_APMRESUMESTANDBY: // 0x0008
\r
400 // CUtils::Log(_T("PBT_APMRESUMESTANDBY"));
\r
402 case PBT_APMBATTERYLOW: // 0x0009
\r
403 // CUtils::Log(_T("PBT_APMBATTERYLOW"));
\r
405 case PBT_APMPOWERSTATUSCHANGE: // 0x000A
\r
406 // CUtils::Log(_T("PBT_APMPOWERSTATUSCHANGE"));
\r
408 case PBT_APMOEMEVENT: // 0x000B
\r
409 // CUtils::Log(_T("PBT_APMOEMEVENT"));
\r
411 case PBT_APMRESUMEAUTOMATIC: // 0x0012
\r
412 // CUtils::Log(_T("PBT_APMRESUMEAUTOMATIC"));
\r
415 // CUtils::Log(_T("PBT_OTHERS: %d"), wParam);
\r
419 case WM_IME_NOTIFY: // 0x0282
\r
420 // CUtils::Log(_T("CallWndProc: cwps.message = WM_IME_NOTIFY"));
\r
423 // CUtils::Log(_T("CallWndProc: cwps.message = 0x%04X"), cwps.message);
\r
428 LRESULT CALLBACK CXkeymacsDll::CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)
\r
430 // LogCallWndProcMessage(wParam, lParam);
\r
433 CWPSTRUCT &cwps = *(CWPSTRUCT *)lParam;
\r
434 switch (cwps.message) {
\r
435 case WM_IME_STARTCOMPOSITION:
\r
436 InitKeyboardProc(TRUE);
\r
438 case WM_IME_ENDCOMPOSITION:
\r
439 InitKeyboardProc(FALSE);
\r
442 if (cwps.hwnd == GetForegroundWindow()) {
\r
443 InitKeyboardProc(FALSE);
\r
444 SetKeyboardHookFlag(m_bHook);
\r
447 case WM_NCACTIVATE:
\r
449 if (cwps.hwnd == GetForegroundWindow()) {
\r
450 InitKeyboardProc(FALSE);
\r
451 SetKeyboardHookFlag(m_bHook);
\r
455 case WM_POWERBROADCAST:
\r
457 case PBT_APMRESUMECRITICAL: // 0x0006
\r
458 case PBT_APMRESUMESUSPEND: // 0x0007
\r
459 case PBT_APMRESUMESTANDBY: // 0x0008
\r
460 ReleaseKeyboardHook();
\r
471 return CallNextHookEx(m_hHookCallWnd, nCode, wParam, lParam);
\r
474 LRESULT CALLBACK CXkeymacsDll::CallWndRetProc(int nCode, WPARAM wParam, LPARAM lParam)
\r
477 CWPRETSTRUCT &cwprets = *(CWPRETSTRUCT *)lParam;
\r
478 switch (cwprets.message) {
\r
480 if (cwprets.hwnd == GetForegroundWindow()) {
\r
481 InitKeyboardProc(FALSE);
\r
491 return CallNextHookEx(m_hHookCallWndRet, nCode, wParam, lParam);
\r
494 LRESULT CALLBACK CXkeymacsDll::GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
\r
496 MSG &msg = (*(MSG *)lParam);
\r
498 switch (msg.message) {
\r
499 case WM_IME_STARTCOMPOSITION:
\r
500 InitKeyboardProc(TRUE);
\r
502 case WM_IME_ENDCOMPOSITION:
\r
503 InitKeyboardProc(FALSE);
\r
506 return CallNextHookEx(m_hHookGetMessage, nCode, wParam, lParam);
\r
509 LRESULT CALLBACK CXkeymacsDll::ShellProc(int nCode, WPARAM wParam, LPARAM lParam)
\r
512 case HSHELL_WINDOWACTIVATED:
\r
514 TCHAR className[256];
\r
515 ::GetClassName((HWND)wParam, className, 255);
\r
516 if (!_tcsicmp(className, _T("ConsoleWindowClass"))) {
\r
517 InitKeyboardProc(FALSE);
\r
518 SetKeyboardHookFlag(m_bHook);
\r
525 return CallNextHookEx( m_hHookShell, nCode, wParam, lParam );
\r
528 // return true if the key is down
\r
529 BOOL CXkeymacsDll::IsDown(BYTE bVk, BOOL bPhysicalKey)
\r
531 if (bPhysicalKey) {
\r
532 return GetKeyState(bVk) < 0;
\r
534 return GetAsyncKeyState(bVk) < 0;
\r
539 void CXkeymacsDll::DoKeybd_event(BYTE bVk, DWORD dwFlags)
\r
541 // Set KEYEVENTF_EXTENDEDKEY if needed
\r
544 if (m_bRightControl) { // Right Ctrl
\r
545 dwFlags |= KEYEVENTF_EXTENDEDKEY;
\r
550 if (m_bRightAlt) { // Right Alt
\r
551 dwFlags |= KEYEVENTF_EXTENDEDKEY;
\r
552 // CUtils::Log("Right Alt %d", dwFlags);
\r
554 // CUtils::Log("Left Alt %d", dwFlags);
\r
559 if (m_bRightShift) { // Right Shift
\r
560 dwFlags |= KEYEVENTF_EXTENDEDKEY;
\r
565 if (IsDown(VK_CONTROL)) { // Break
\r
566 dwFlags |= KEYEVENTF_EXTENDEDKEY;
\r
582 dwFlags |= KEYEVENTF_EXTENDEDKEY;
\r
589 // CUtils::Log(_T("b: %x, %x, %x, %#x, %#x"), bVk, dwFlags, GetMessageExtraInfo(), GetKeyState(bVk), GetAsyncKeyState(bVk));
\r
590 keybd_event(bVk, 0, dwFlags, GetMessageExtraInfo());
\r
591 // CUtils::Log(_T("a: %x, %x, %x, %#x, %#x"), bVk, dwFlags, GetMessageExtraInfo(), GetKeyState(bVk), GetAsyncKeyState(bVk));
\r
594 // the key is being depressed
\r
595 void CXkeymacsDll::DepressKey(BYTE bVk, BOOL bOriginal) // bVk is virtual-key code, MSDN said
\r
598 // CUtils::Log(_T("i: %x, %d, %d, %d, %d, %d, %d, %d, %d"), bVk,
\r
599 // IsDown(VK_CONTROL), IsDown(VK_CONTROL, FALSE), IsDepressedModifier(CCommands::C_), IsDepressedModifier(CCommands::C_, FALSE),
\r
600 // IsDown(VK_MENU), IsDown(VK_MENU, FALSE), IsDepressedModifier(CCommands::MetaAlt), IsDepressedModifier(CCommands::MetaAlt, FALSE));
\r
602 int nCommandType = NONE;
\r
603 if (IsDown(VK_CONTROL, FALSE)) {
\r
604 nCommandType |= CONTROL;
\r
606 if (IsDown(VK_MENU, FALSE)) {
\r
607 nCommandType |= META;
\r
609 Original(nCommandType, bVk, 1);
\r
612 DoKeybd_event(bVk, 0);
\r
615 // the key is being released
\r
616 void CXkeymacsDll::ReleaseKey(BYTE bVk) // bVk is virtual-key code, MSDN said
\r
618 DoKeybd_event(bVk, KEYEVENTF_KEYUP);
\r
621 // bVk down, bVk up
\r
622 void CXkeymacsDll::Kdu(BYTE bVk, DWORD n, BOOL bOriginal)
\r
625 DepressKey(bVk, bOriginal);
\r
630 void CXkeymacsDll::InitKeyboardProc(BOOL bImeComposition)
\r
632 if (CUtils::IsFindDialog()) {
\r
633 static BOOL bImeCompositionOld = FALSE;
\r
634 if (!bImeComposition
\r
635 && bImeCompositionOld) {
\r
636 DepressKey(VK_END);
\r
637 ReleaseKey(VK_END);
\r
639 bImeCompositionOld = bImeComposition;
\r
642 CUtils::SetApplicationName(bImeComposition);
\r
644 if (_tcsnicmp(m_szSpecialApp[m_nApplicationID], CUtils::GetApplicationName(), 0xF) || !IsMatchWindowText(m_szWindowText[m_nApplicationID])) { // PROCESSENTRY32 has only 0xF bytes of Name
\r
645 m_nApplicationID = -1;
\r
647 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
648 if (!_tcsnicmp(m_szSpecialApp[nApplicationID], CUtils::GetApplicationName(), 0xF) && IsMatchWindowText(m_szWindowText[nApplicationID])) {
\r
650 if (m_nApplicationID < 0
\r
651 || CUtils::GetWindowTextType(m_szWindowText[m_nApplicationID]) < CUtils::GetWindowTextType(m_szWindowText[nApplicationID])
\r
652 || CUtils::GetWindowTextType(m_szWindowText[m_nApplicationID]) == CUtils::GetWindowTextType(m_szWindowText[nApplicationID])
\r
653 && _tcscmp(m_szWindowText[m_nApplicationID], m_szWindowText[nApplicationID]) <= 0) {
\r
654 m_nApplicationID = nApplicationID;
\r
659 if (m_nApplicationID < 0) {
\r
660 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
661 if (!_tcsicmp(m_szSpecialApp[nApplicationID], _T("Default"))) {
\r
662 m_nApplicationID = nApplicationID;
\r
667 if (m_nApplicationID < 0) {
\r
668 m_nApplicationID = 0;
\r
673 if (m_nSettingStyle[m_nApplicationID] != SETTING_DISABLE
\r
674 && (_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Default")) || !CUtils::IsDefaultIgnoreApplication())
\r
675 && !bImeComposition
\r
676 && CUtils::IsDialog()) {
\r
677 // Use Dialog Setting
\r
678 if (m_bUseDialogSetting[m_nApplicationID]) {
\r
679 int nOriginalApplicationID = m_nApplicationID;
\r
680 for (m_nApplicationID = 0; m_nApplicationID < MAX_APP; ++m_nApplicationID) {
\r
681 if (!_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Dialog"))) {
\r
685 if (m_nApplicationID == MAX_APP) {
\r
686 m_nApplicationID = nOriginalApplicationID;
\r
691 ModifyShell_NotifyIcon(CX_ICON, FALSE);
\r
692 ModifyShell_NotifyIcon(MX_ICON, FALSE);
\r
693 ModifyShell_NotifyIcon(META_ICON, FALSE);
\r
694 CCommands::SetMark(FALSE);
\r
695 CCommands::SetTemporarilyDisableXKeymacs(FALSE);
\r
696 CCommands::Reset();
\r
699 // emulate emacs // cf virtual-key code
\r
700 LRESULT CALLBACK CXkeymacsDll::KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
\r
702 ASSERT(0 <= wParam && wParam <= UCHAR_MAX);
\r
704 int nCommandType = NONE;
\r
705 BYTE nKey = (BYTE)wParam;
\r
707 static BOOL bLocked = FALSE;
\r
708 static const BYTE RECURSIVE_KEY = 0x07;
\r
709 static int (*fCommand)() = NULL;
\r
710 static BYTE nOneShotModifier[MAX_KEY] = {'\0'};
\r
711 static BOOL bCherryOneShotModifier = FALSE;
\r
713 // CUtils::Log(_T("nCode = %#x, nKey = %#x, lParam = %#x"), nCode, nKey, lParam);
\r
715 if (nCode < 0 || nCode == HC_NOREMOVE) {
\r
719 if (nKey == RECURSIVE_KEY) {
\r
720 if (lParam & BEING_RELEASED) {
\r
721 goto HOOK_RECURSIVE_KEY;
\r
723 goto RECURSIVE_COMMAND;
\r
728 static BOOL bShift = FALSE;
\r
729 if (IsDepressedShiftKeyOnly(nKey)) {
\r
730 if (lParam & BEING_RELEASED) {
\r
732 CCommands::SetMark(FALSE);
\r
742 if (CUtils::IsNT()) {
\r
745 if (lParam & EXTENDED_KEY) {
\r
746 nKey = VK_RCONTROL;
\r
748 nKey = VK_LCONTROL;
\r
752 if (lParam & EXTENDED_KEY) {
\r
759 if (lParam & EXTENDED_KEY) {
\r
770 if (lParam & BEING_RELEASED) {
\r
771 if (nKey == VK_MENU
\r
775 || nKey == VK_LMENU
\r
776 || nKey == VK_RMENU) {
\r
777 for (int i = 0; i < MAX_COMMAND_TYPE; ++i) {
\r
778 if (Commands[m_nCommandID[m_nApplicationID][i][nKey]].fCommand
\r
779 && (Commands[m_nCommandID[m_nApplicationID][i][nKey]].fCommand != CCommands::MetaAlt
\r
780 || nKey != VK_MENU && nKey != VK_LMENU && nKey != VK_RMENU)) {
\r
786 if (nOneShotModifier[nKey]) {
\r
787 ReleaseKey(nOneShotModifier[nKey]);
\r
788 nOneShotModifier[nKey] = 0;
\r
790 if (bCherryOneShotModifier) {
\r
791 bCherryOneShotModifier = FALSE;
\r
799 if (m_nSettingStyle[m_nApplicationID] == SETTING_DISABLE) {
\r
803 // Do Nothing for Meadow, Mule for Win32, ... if those use default setting.
\r
804 if (!_tcsicmp(m_szSpecialApp[m_nApplicationID], _T("Default"))
\r
805 && CUtils::IsDefaultIgnoreApplication()) {
\r
809 switch (IsPassThrough(nKey)) {
\r
810 case GOTO_DO_NOTHING:
\r
821 // set command type
\r
823 nCommandType = NONE;
\r
824 if (IsDown(VK_SHIFT, FALSE)) {
\r
825 nCommandType |= SHIFT;
\r
828 nCommandType |= CONTROL;
\r
831 nCommandType |= META;
\r
833 if (CCommands::bC_x()) {
\r
834 nCommandType |= CONTROLX;
\r
837 // Ignore undefined C-x ?
\r
838 if (nCommandType & CONTROLX) {
\r
839 if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == NULL
\r
840 && m_nFunctionID[m_nApplicationID][nCommandType][nKey] < 0) {
\r
841 if (m_bIgnoreUndefinedC_x[m_nApplicationID]) {
\r
842 CCommands::Reset(GOTO_HOOK);
\r
845 nCommandType &= ~CONTROLX;
\r
849 // Ignore undefined Meta Ctrl+?
\r
850 if (CCommands::bM_() && (nCommandType & CONTROL)) {
\r
851 if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == NULL
\r
852 && m_nFunctionID[m_nApplicationID][nCommandType][nKey] < 0) {
\r
853 if (m_bIgnoreUndefinedMetaCtrl[m_nApplicationID]) {
\r
854 if (Original(CONTROL, nKey)) {
\r
855 Original(CONTROL, nKey, -1);
\r
858 CCommands::Reset(GOTO_HOOK);
\r
861 nCommandType &= ~META;
\r
867 // CUtils::Log(_T("o: %x, %d, %d, %d, %d, %d, %d, %d, %d"), (BYTE)wParam,
\r
868 // IsDown(VK_CONTROL), IsDown(VK_CONTROL, FALSE), IsDepressedModifier(CCommands::C_), IsDepressedModifier(CCommands::C_, FALSE),
\r
869 // IsDown(VK_MENU), IsDown(VK_MENU, FALSE), IsDepressedModifier(CCommands::MetaAlt), IsDepressedModifier(CCommands::MetaAlt, FALSE));
\r
871 BYTE nKey = (BYTE)wParam; // VK_CONTROL is needed instead of VK_RCONTROL and VK_LCONTROL in this block just for Original()
\r
872 int nVirtualCommandType = NONE;
\r
873 if (IsDown(VK_CONTROL) && nKey != VK_CONTROL) {
\r
874 nVirtualCommandType |= CONTROL;
\r
876 if (IsDown(VK_MENU) && nKey != VK_MENU) {
\r
877 nVirtualCommandType |= META;
\r
879 if (Original(nVirtualCommandType, nKey)) {
\r
880 Original(nVirtualCommandType, nKey, -1);
\r
885 if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::EnableOrDisableXKeymacs) {
\r
886 SetKeyboardHookFlag(!m_bHook);
\r
889 if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::EnableXKeymacs) {
\r
891 SetKeyboardHookFlag(!m_bHook);
\r
895 if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::DisableXKeymacs) {
\r
897 SetKeyboardHookFlag(!m_bHook);
\r
905 if (CCommands::bM_x()) {
\r
906 static unsigned int index = 0;
\r
907 static TCHAR szPath[MAX_PATH] = {'\0'};
\r
909 if (lParam & BEING_RELEASED) {
\r
911 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::BackwardChar) {
\r
916 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::BeginningOfLine) {
\r
919 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::DeleteBackwardChar) {
\r
922 memmove(&szPath[index], &szPath[index + 1], _tcslen(szPath) - index);
\r
923 ModifyM_xTip(szPath);
\r
926 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::DeleteChar) {
\r
927 if (index < _tcslen(szPath)) {
\r
928 memmove(&szPath[index], &szPath[index + 1], _tcslen(szPath) - index);
\r
929 ModifyM_xTip(szPath);
\r
932 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::EndOfLine) {
\r
933 index = _tcslen(szPath);
\r
935 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::ForwardChar) {
\r
936 if (index < _tcslen(szPath)) {
\r
940 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::KeyboardQuit) {
\r
941 CCommands::bM_x(FALSE);
\r
943 memset(szPath, 0, sizeof(szPath));
\r
945 } else if (nKey == VK_RETURN
\r
946 || Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::Newline) {
\r
949 CCommands::bM_x(FALSE);
\r
951 memset(szPath, 0, sizeof(szPath));
\r
953 } else if (index < MAX_PATH - 1) {
\r
954 const BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
\r
955 for (TCHAR nAscii = 1; nAscii != 0; ++nAscii) { // repeat until overflow
\r
956 if (nKey != 0 && a2v(nAscii) == nKey && bIsShiftDown == IsShift(nAscii)) {
\r
957 // CUtils::Log("M-x: %#X (%c), %#X (%c)", nKey, nKey, nAscii, nAscii);
\r
958 if (index < _tcslen(szPath)) {
\r
959 memmove(&szPath[index + 1], &szPath[index], __min(_tcslen(szPath) - index, MAX_PATH - (index + 1) - 1));
\r
961 szPath[index++] = nAscii;
\r
962 // CUtils::Log("M-x: %c(%#04x)", nAscii, nAscii);
\r
963 ModifyM_xTip(szPath);
\r
970 if (CCommands::bC_u()) {
\r
971 if ((nCommandType == NONE) && ('0' <= nKey) && (nKey <= '9')) {
\r
972 CCommands::NumericArgument(nKey - '0');
\r
975 if ((nCommandType == NONE) && (nKey == 0xBD)) {
\r
976 CCommands::NumericArgumentMinus();
\r
981 if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~CONTROL][nKey]].fCommand == CCommands::OneShotModifierCtrl) {
\r
982 nOneShotModifier[nKey] = VK_LCONTROL;
\r
983 DepressKey(nOneShotModifier[nKey]);
\r
984 bCherryOneShotModifier = TRUE;
\r
986 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::OneShotModifierCtrlRepeat) {
\r
987 nOneShotModifier[nKey] = VK_LCONTROL;
\r
988 DepressKey(nOneShotModifier[nKey]);
\r
989 bCherryOneShotModifier = TRUE;
\r
991 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~CONTROL][nKey]].fCommand == CCommands::OneShotModifierCtrlRepeat) {
\r
992 ReleaseKey(nOneShotModifier[nKey]);
\r
993 bCherryOneShotModifier = FALSE;
\r
996 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~META][nKey]].fCommand == CCommands::OneShotModifierAlt) {
\r
997 nOneShotModifier[nKey] = VK_LMENU;
\r
998 DepressKey(nOneShotModifier[nKey]);
\r
999 bCherryOneShotModifier = TRUE;
\r
1001 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::OneShotModifierAltRepeat) {
\r
1002 nOneShotModifier[nKey] = VK_LMENU;
\r
1003 DepressKey(nOneShotModifier[nKey]);
\r
1004 bCherryOneShotModifier = TRUE;
\r
1006 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~META][nKey]].fCommand == CCommands::OneShotModifierAltRepeat) {
\r
1007 ReleaseKey(nOneShotModifier[nKey]);
\r
1008 bCherryOneShotModifier = FALSE;
\r
1011 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~SHIFT][nKey]].fCommand == CCommands::OneShotModifierShift) {
\r
1012 nOneShotModifier[nKey] = VK_SHIFT;
\r
1013 DepressKey(nOneShotModifier[nKey]);
\r
1014 bCherryOneShotModifier = TRUE;
\r
1016 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand == CCommands::OneShotModifierShiftRepeat) {
\r
1017 nOneShotModifier[nKey] = VK_SHIFT;
\r
1018 DepressKey(nOneShotModifier[nKey]);
\r
1019 bCherryOneShotModifier = TRUE;
\r
1021 } else if (Commands[m_nCommandID[m_nApplicationID][nCommandType & ~SHIFT][nKey]].fCommand == CCommands::OneShotModifierShiftRepeat) {
\r
1022 ReleaseKey(nOneShotModifier[nKey]);
\r
1023 bCherryOneShotModifier = FALSE;
\r
1027 for (int i = 0; i < MAX_KEY; ++i) {
\r
1028 if (nOneShotModifier[i] == nKey) {
\r
1032 if (i == MAX_KEY) {
\r
1033 bCherryOneShotModifier = FALSE;
\r
1037 if (0 <= m_nFunctionID[m_nApplicationID][nCommandType][nKey]
\r
1038 && m_nFunctionID[m_nApplicationID][nCommandType][nKey] < MAX_FUNCTION
\r
1039 && _tcslen(m_szFunctionDefinition[m_nFunctionID[m_nApplicationID][nCommandType][nKey]])) {
\r
1040 CallFunction(m_nFunctionID[m_nApplicationID][nCommandType][nKey]);
\r
1041 CCommands::Reset(GOTO_HOOK);
\r
1045 if (!Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand) {
\r
1046 if (nKey == VK_CONTROL
\r
1047 || nKey == VK_LCONTROL
\r
1048 || nKey == VK_RCONTROL
\r
1049 || nKey == VK_MENU
\r
1050 || nKey == VK_LMENU
\r
1051 || nKey == VK_RMENU
\r
1052 || nKey == VK_SHIFT
\r
1053 || nKey == VK_LSHIFT
\r
1054 || nKey == VK_RSHIFT) {
\r
1058 if (!(nCommandType & SHIFT)) {
\r
1059 if (CCommands::IsSetMark()) {
\r
1060 if (CCommands::MoveCaret(nKey, nCommandType & CONTROL) != CONTINUE) {
\r
1061 CCommands::ClearNumericArgument();
\r
1064 CCommands::SetMark(FALSE);
\r
1068 if (1 < CCommands::GetNumericArgument()) {
\r
1069 Kdu(nKey, CCommands::GetNumericArgument());
\r
1070 CCommands::ClearNumericArgument();
\r
1077 if (CCommands::IsTemporarilyDisableXKeymacs()
\r
1078 && Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand != CCommands::KeyboardQuit) {
\r
1079 CCommands::SetTemporarilyDisableXKeymacs(FALSE);
\r
1083 if (m_bAtIbeamCursorOnly[m_nApplicationID][nCommandType][nKey]) {
\r
1084 CURSORINFO cursorinfo = { sizeof(cursorinfo) };
\r
1085 if (GetCursorInfo(&cursorinfo) && cursorinfo.flags && cursorinfo.hCursor != LoadCursor(NULL, IDC_IBEAM)) {
\r
1090 m_bRightControl = IsDown(VK_RCONTROL);
\r
1091 m_bRightAlt = IsDown(VK_RMENU);
\r
1092 m_bRightShift = IsDown(VK_RSHIFT);
\r
1096 fCommand = Commands[m_nCommandID[m_nApplicationID][nCommandType][nKey]].fCommand;
\r
1097 RECURSIVE_COMMAND:
\r
1098 switch (fCommand()) {
\r
1099 case GOTO_DO_NOTHING:
\r
1105 case GOTO_RECURSIVE:
\r
1110 case GOTO_HOOK0_9:
\r
1119 goto HOOK_RECURSIVE_KEY;
\r
1123 ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));
\r
1124 ModifyShell_NotifyIcon(CTRL_ICON, IsControl());
\r
1125 ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));
\r
1128 static BOOL bDefiningMacro = FALSE;
\r
1129 if (m_bDefiningMacro) {
\r
1130 static BOOL bDown[MAX_KEY] = {'\0'};
\r
1132 if (!bDefiningMacro) {
\r
1133 while (m_Macro.GetHeadPosition()) {
\r
1134 void *p = m_Macro.GetAt(m_Macro.GetHeadPosition());
\r
1135 m_Macro.RemoveHead();
\r
1139 memset(bDown, 0, sizeof(bDown));
\r
1142 if ((!(lParam & BEING_RELEASED)) || bDown[wParam]) {
\r
1144 KbdMacro_t *pKbdMacro = new KbdMacro;
\r
1146 pKbdMacro->nCode = nCode;
\r
1147 pKbdMacro->wParam = wParam;
\r
1148 pKbdMacro->lParam = lParam;
\r
1149 pKbdMacro->bOriginal = TRUE;
\r
1150 m_Macro.AddTail((CObject *)pKbdMacro);
\r
1153 catch (CMemoryException* e) {
\r
1155 // CUtils::Log("KeyboardProc: 'new' threw an exception");
\r
1157 if (!(lParam & BEING_RELEASED)) {
\r
1158 bDown[wParam] = TRUE;
\r
1162 bDefiningMacro = m_bDefiningMacro;
\r
1165 return ::CallNextHookEx(m_hHookKeyboard, nCode, wParam, lParam);
\r
1168 Kdu(RECURSIVE_KEY, 1, FALSE);
\r
1169 ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));
\r
1170 ModifyShell_NotifyIcon(CTRL_ICON, IsControl());
\r
1171 ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));
\r
1175 CCommands::SetLastCommand(fCommand);
\r
1178 ModifyShell_NotifyIcon(SHIFT_ICON, IsDown(VK_SHIFT));
\r
1179 ModifyShell_NotifyIcon(CTRL_ICON, IsControl());
\r
1180 ModifyShell_NotifyIcon(ALT_ICON, IsDown(VK_MENU));
\r
1181 HOOK_RECURSIVE_KEY:
\r
1185 //////////////////////////////////////////////////////////////////////
\r
1186 // CXkeymacsData Class
\r
1187 //////////////////////////////////////////////////////////////////////
\r
1189 //////////////////////////////////////////////////////////////////////
\r
1190 // Construction/Destruction
\r
1191 //////////////////////////////////////////////////////////////////////
\r
1193 CXkeymacsData::CXkeymacsData()
\r
1198 CXkeymacsData::~CXkeymacsData()
\r
1203 // set application name
\r
1204 void CXkeymacsData::SetApplicationName(LPCTSTR lpszApplicationName)
\r
1206 m_strApplicationName.Format(lpszApplicationName);
\r
1209 // return application name
\r
1210 CString CXkeymacsData::GetApplicationName()
\r
1212 return m_strApplicationName;
\r
1215 // set hook or not
\r
1216 void CXkeymacsData::SetCommandID(int nCommandType, int nKey, int nCommandID)
\r
1218 ASSERT(0 <= nCommandType || nCommandType < MAX_COMMAND_TYPE);
\r
1219 ASSERT(0 <= nKey || nKey < MAX_KEY);
\r
1221 m_nCommandID[nCommandType][nKey] = nCommandID;
\r
1224 // return hook or not
\r
1225 int CXkeymacsData::GetCommandID(int nCommandType, int nKey)
\r
1227 ASSERT(0 <= nCommandType || nCommandType < MAX_COMMAND_TYPE);
\r
1228 ASSERT(0 <= nKey || nKey < MAX_KEY);
\r
1230 return m_nCommandID[nCommandType][nKey];
\r
1233 // set hook at ibeam cursor only or not
\r
1234 void CXkeymacsData::SetAtIbeamCursorOnly(int nCommandType, int nKey, BOOL bAtIbeamCursorOnly)
\r
1236 ASSERT(0 <= nCommandType || nCommandType < MAX_COMMAND_TYPE);
\r
1237 ASSERT(0 <= nKey || nKey < MAX_KEY);
\r
1239 m_bAtIbeamCursorOnly[nCommandType][nKey] = bAtIbeamCursorOnly;
\r
1242 // get hook at ibeam cursor only or not
\r
1243 BOOL CXkeymacsData::GetAtIbeamCursorOnly(int nCommandType, int nKey)
\r
1245 ASSERT(0 <= nCommandType || nCommandType < MAX_COMMAND_TYPE);
\r
1246 ASSERT(0 <= nKey || nKey < MAX_KEY);
\r
1248 return m_bAtIbeamCursorOnly[nCommandType][nKey];
\r
1252 void CXkeymacsData::ClearAll()
\r
1254 ZeroMemory(m_nCommandID, sizeof(m_nCommandID));
\r
1255 ZeroMemory(m_bAtIbeamCursorOnly, sizeof(m_bAtIbeamCursorOnly));
\r
1256 m_strApplicationName.Empty();
\r
1259 void CXkeymacsDll::SetApplicationName(int nApplicationID, CString szApplicationName)
\r
1261 ZeroMemory(m_szSpecialApp[nApplicationID], sizeof(m_szSpecialApp[nApplicationID]));
\r
1262 _tcsncpy(m_szSpecialApp[nApplicationID], szApplicationName, sizeof(m_szSpecialApp[nApplicationID]));
\r
1265 void CXkeymacsDll::SetWindowText(int nApplicationID, CString szWindowText)
\r
1267 ZeroMemory(m_szWindowText[nApplicationID], sizeof(m_szWindowText[nApplicationID]));
\r
1268 _tcsncpy(m_szWindowText[nApplicationID], szWindowText, sizeof(m_szWindowText[nApplicationID]));
\r
1271 void CXkeymacsDll::SetCommandID(int nApplicationID, int nCommandType, int nKey, int nCommandID)
\r
1273 m_nCommandID[nApplicationID][nCommandType][nKey] = nCommandID;
\r
1276 void CXkeymacsDll::SetAtIbeamCursorOnly(int nApplicationID, int nCommandType, int nKey, BOOL bAtIbeamCursorOnly)
\r
1278 m_bAtIbeamCursorOnly[nApplicationID][nCommandType][nKey] = bAtIbeamCursorOnly;
\r
1281 void CXkeymacsDll::SetKillRingMax(int nApplicationID, int nKillRingMax)
\r
1283 m_nKillRingMax[nApplicationID] = nKillRingMax;
\r
1286 void CXkeymacsDll::SetUseDialogSetting(int nApplicationID, BOOL bUseDialogSetting)
\r
1288 m_bUseDialogSetting[nApplicationID] = bUseDialogSetting;
\r
1291 // Clear data of nApplicationID
\r
1292 void CXkeymacsDll::Clear(int nApplicationID)
\r
1294 if (0 <= nApplicationID && nApplicationID < MAX_APP) {
\r
1295 ZeroMemory(m_szSpecialApp[nApplicationID], sizeof(m_szSpecialApp[nApplicationID]));
\r
1296 ZeroMemory(m_nCommandID[nApplicationID], sizeof(m_nCommandID[nApplicationID]));
\r
1297 ZeroMemory(m_bAtIbeamCursorOnly[nApplicationID], sizeof(m_bAtIbeamCursorOnly[nApplicationID]));
\r
1298 m_nKillRingMax[nApplicationID] = 0;
\r
1299 m_bUseDialogSetting[nApplicationID] = FALSE;
\r
1300 m_nSettingStyle[nApplicationID] = 0;
\r
1306 void CXkeymacsData::SetApplicationTitle(LPCTSTR lpszApplicationTitle)
\r
1308 m_strApplicationTitle.Format(lpszApplicationTitle);
\r
1310 // delete white space at the end of the application title.
\r
1311 while (!m_strApplicationTitle.IsEmpty()
\r
1312 && _istspace(m_strApplicationTitle.GetAt(m_strApplicationTitle.GetLength() - 1))) {
\r
1313 m_strApplicationTitle.Delete(m_strApplicationTitle.GetLength() - 1);
\r
1317 CString CXkeymacsData::GetApplicationTitle()
\r
1319 return m_strApplicationTitle;
\r
1322 void CXkeymacsData::SetKillRingMax(int nKillRingMax)
\r
1324 m_nKillRingMax = nKillRingMax;
\r
1327 int CXkeymacsData::GetKillRingMax()
\r
1329 return m_nKillRingMax;
\r
1332 BOOL CXkeymacsDll::IsValidKey(BYTE bVk)
\r
1334 if (bVk == 0xf0) { // 0xf0: Eisu key. GetAsyncKeyState returns the wrong state of Eisu key.
\r
1338 if (CUtils::IsNT()) {
\r
1352 BOOL CXkeymacsDll::IsDepressedModifier(int (__cdecl *Modifier)(void), BOOL bPhysicalKey)
\r
1356 if (IsValidKey(bVk)
\r
1357 && IsDown(bVk, bPhysicalKey)
\r
1358 && Commands[m_nCommandID[m_nApplicationID][NONE][bVk]].fCommand == Modifier) {
\r
1365 BOOL CXkeymacsDll::IsDepressedShiftKeyOnly(BYTE nKey)
\r
1367 if (nKey != VK_SHIFT
\r
1368 && nKey != VK_LSHIFT
\r
1369 && nKey != VK_RSHIFT) {
\r
1375 if (bVk == VK_SHIFT
\r
1376 || bVk == VK_LSHIFT
\r
1377 || bVk == VK_RSHIFT) {
\r
1381 if (IsDown(bVk)) {
\r
1388 BOOL CXkeymacsDll::IsControl()
\r
1390 return CCommands::bC_() || IsDepressedModifier(CCommands::C_, FALSE);
\r
1393 BOOL CXkeymacsDll::IsMeta()
\r
1395 return CCommands::bM_() || IsDepressedModifier(CCommands::MetaAlt, FALSE);
\r
1398 void CXkeymacsDll::AddKillRing(BOOL bNewData)
\r
1400 if (m_nKillRingMax[m_nApplicationID] == 0) {
\r
1404 CClipboardSnap *pSnap = new CClipboardSnap;
\r
1405 if( !pSnap ) return;
\r
1407 BOOL bCapture = pSnap->Capture();
\r
1408 bCapture = pSnap->Capture(); // for "office drawing shape format". Can CClipboardSnap care this problem?
\r
1412 m_oKillRing.AddHead(pSnap);
\r
1414 if (m_oKillRing.IsEmpty()) {
\r
1415 m_oKillRing.AddHead(pSnap);
\r
1417 for (CClipboardSnap *pParent = m_oKillRing.GetHead(); pParent->GetNext(); pParent = pParent->GetNext()) {
\r
1420 pParent->SetNext(pSnap);
\r
1430 if (m_nKillRingMax[m_nApplicationID] < m_oKillRing.GetCount()) {
\r
1431 CClipboardSnap *pSnap = m_oKillRing.GetTail();
\r
1434 m_oKillRing.RemoveTail();
\r
1438 // Return TRUE if there is another data
\r
1439 // Return FALSE if there is no more data
\r
1440 CClipboardSnap* CXkeymacsDll::GetKillRing(CClipboardSnap* pSnap, BOOL bForce)
\r
1442 if (m_nKillRingMax[m_nApplicationID] == 0) {
\r
1446 if (m_oKillRing.IsEmpty()) {
\r
1450 m_nKillRing %= m_oKillRing.GetCount();
\r
1453 CClipboardSnap oCurrentSnap;
\r
1454 oCurrentSnap.Capture();
\r
1456 CClipboardSnap *pKillRing = m_oKillRing.GetAt(m_oKillRing.FindIndex(m_nKillRing));
\r
1460 for (; pKillRing->GetNext(); pKillRing = pKillRing->GetNext()) {
\r
1463 if (*pKillRing != oCurrentSnap) {
\r
1469 pSnap = m_oKillRing.GetAt(m_oKillRing.FindIndex(m_nKillRing));
\r
1473 return pSnap->GetNext();
\r
1476 void CXkeymacsDll::Original(int nCommandType, BYTE bVk, int nOriginal)
\r
1478 nCommandType &= ~SHIFT;
\r
1480 if (CUtils::IsNT()) {
\r
1483 bVk = VK_LCONTROL;
\r
1496 m_nOriginal[nCommandType][bVk] += nOriginal;
\r
1499 int CXkeymacsDll::Original(int nCommandType, BYTE bVk)
\r
1501 nCommandType &= ~SHIFT;
\r
1503 if (CUtils::IsNT()) {
\r
1506 bVk = VK_LCONTROL;
\r
1519 return m_nOriginal[nCommandType][bVk];
\r
1522 void CXkeymacsDll::IncreaseKillRingIndex(int nKillRing)
\r
1524 m_nKillRing += nKillRing;
\r
1528 CString CXkeymacsData::GetCommandName(int nCommandID)
\r
1530 CString szCommandName(Commands[nCommandID].szCommandName);
\r
1531 return szCommandName;
\r
1535 int CXkeymacsData::GetDefaultCommandType(int nCommandID, int nIndex)
\r
1537 if (nCommandID < 0 || sizeof(Commands) / sizeof(Commands[0]) <= nCommandID
\r
1538 || nIndex < 0 || sizeof(Commands[nCommandID].keybind) / sizeof(Commands[nCommandID].keybind[0]) <= nIndex) {
\r
1543 int nCommandType = Commands[nCommandID].keybind[nIndex].nCommandType;
\r
1544 int bVk = Commands[nCommandID].keybind[nIndex].bVk;
\r
1546 if (m_b106Keyboard) {
\r
1547 if (nCommandType & SHIFT) { // Shift
\r
1551 case 0xBA: // VK_OEM_1 Used for miscellaneous characters; it can vary by keyboard.
\r
1552 // Windows 2000/XP: For the US standard keyboard, the ';:' key
\r
1553 nCommandType &= ~SHIFT;
\r
1558 } else { // Normal
\r
1560 case 0xBB: // VK_OEM_PLUS Windows 2000/XP: For any country/region, the '+' key
\r
1561 case 0xC0: // VK_OEM_3 Used for miscellaneous characters; it can vary by keyboard.
\r
1562 // Windows 2000/XP: For the US standard keyboard, the '`~' key
\r
1563 case 0xDE: // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard.
\r
1564 // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
\r
1565 nCommandType |= SHIFT;
\r
1573 return nCommandType;
\r
1577 int CXkeymacsData::GetDefaultCommandKey(int nCommandID, int nIndex)
\r
1579 if (nCommandID < 0 || sizeof(Commands) / sizeof(Commands[0]) <= nCommandID
\r
1580 || nIndex < 0 || sizeof(Commands[nCommandID].keybind) / sizeof(Commands[nCommandID].keybind[0]) <= nIndex) {
\r
1585 int nCommandType = Commands[nCommandID].keybind[nIndex].nCommandType;
\r
1586 int bVk = Commands[nCommandID].keybind[nIndex].bVk;
\r
1588 if (m_b106Keyboard) {
\r
1589 if (nCommandType & SHIFT) { // Shift
\r
1595 bVk = 0xC0; // VK_OEM_3 Used for miscellaneous characters; it can vary by keyboard.
\r
1596 // Windows 2000/XP: For the US standard keyboard, the '`~' key
\r
1599 bVk = 0xDE; // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard.
\r
1600 // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
\r
1606 bVk = 0xBA; // VK_OEM_1 Used for miscellaneous characters; it can vary by keyboard.
\r
1607 // Windows 2000/XP: For the US standard keyboard, the ';:' key
\r
1612 case 0xBD: // VK_OEM_MINUS Windows 2000/XP: For any country/region, the '-' key
\r
1613 bVk = 0xE2; // VK_OEM_102 Windows 2000/XP: Either the angle bracket key or the backslash key on the RT 102-key keyboard
\r
1616 bVk = 0xDE; // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard.
\r
1617 // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
\r
1619 case 0xDE: // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard.
\r
1620 // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
\r
1626 } else { // Normal
\r
1628 case 0xBA: // VK_OEM_1 Used for miscellaneous characters; it can vary by keyboard.
\r
1629 // Windows 2000/XP: For the US standard keyboard, the ';:' key
\r
1630 bVk = 0xBB; // VK_OEM_PLUS Windows 2000/XP: For any country/region, the '+' key
\r
1632 case 0xBB: // VK_OEM_PLUS Windows 2000/XP: For any country/region, the '+' key
\r
1633 bVk = 0xBD; // VK_OEM_MINUS Windows 2000/XP: For any country/region, the '-' key
\r
1635 case 0xDE: // VK_OEM_7 Used for miscellaneous characters; it can vary by keyboard.
\r
1636 // Windows 2000/XP: For the US standard keyboard, the 'single-quote/double-quote' key
\r
1649 int CXkeymacsData::GetDefaultControlID(int nCommandID, int nIndex)
\r
1651 if (nCommandID < 0 || sizeof(Commands) / sizeof(Commands[0]) <= nCommandID
\r
1652 || nIndex < 0 || sizeof(Commands[nCommandID].keybind) / sizeof(Commands[nCommandID].keybind[0]) <= nIndex) {
\r
1657 return Commands[nCommandID].keybind[nIndex].nControlID;
\r
1661 int CXkeymacsDll::GetMickey(int nDifferential, int nThreshold1, int nThreshold2, int nAcceleration, int nSpeed)
\r
1663 nDifferential = nDifferential * 10 / nSpeed;
\r
1665 switch (nAcceleration) {
\r
1667 if (nThreshold2 < fabs((double)(nDifferential / 4))) {
\r
1668 nDifferential /= 4;
\r
1671 // Do NOT write break; here.
\r
1673 if (nThreshold1 < fabs((double)(nDifferential / 2))) {
\r
1674 nDifferential /= 2;
\r
1684 return nDifferential;
\r
1688 int CXkeymacsData::GetSettingStyle()
\r
1690 return m_nSettingStyle;
\r
1693 void CXkeymacsData::SetSettingStyle(int nSettingStyle)
\r
1695 m_nSettingStyle = nSettingStyle;
\r
1698 void CXkeymacsDll::SetSettingStyle(int nApplicationID, int nSettingStyle)
\r
1700 m_nSettingStyle[nApplicationID] = nSettingStyle;
\r
1703 int CXkeymacsData::GetCategoryID(int nCommandID)
\r
1705 return Commands[nCommandID].nCategoryID;
\r
1708 void CXkeymacsData::SetIgnoreUndefinedMetaCtrl(BOOL bIgnoreUndefinedMetaCtrl)
\r
1710 m_bIgnoreUndefinedMetaCtrl = bIgnoreUndefinedMetaCtrl;
\r
1713 BOOL CXkeymacsData::GetIgnoreUndefinedMetaCtrl()
\r
1715 return m_bIgnoreUndefinedMetaCtrl;
\r
1718 void CXkeymacsDll::SetIgnoreUndefinedMetaCtrl(int nApplicationID, BOOL bIgnoreUndefinedMetaCtrl)
\r
1720 m_bIgnoreUndefinedMetaCtrl[nApplicationID] = bIgnoreUndefinedMetaCtrl;
\r
1723 void CXkeymacsData::SetIgnoreUndefinedC_x(BOOL bIgnoreUndefinedC_x)
\r
1725 m_bIgnoreUndefinedC_x = bIgnoreUndefinedC_x;
\r
1728 BOOL CXkeymacsData::GetIgnoreUndefinedC_x()
\r
1730 return m_bIgnoreUndefinedC_x;
\r
1733 void CXkeymacsDll::SetIgnoreUndefinedC_x(int nApplicationID, BOOL bIgnoreUndefinedC_x)
\r
1735 m_bIgnoreUndefinedC_x[nApplicationID] = bIgnoreUndefinedC_x;
\r
1738 void CXkeymacsData::SetEnableCUA(BOOL bEnableCUA)
\r
1740 m_bEnableCUA = bEnableCUA;
\r
1743 BOOL CXkeymacsData::GetEnableCUA()
\r
1745 return m_bEnableCUA;
\r
1748 void CXkeymacsDll::SetEnableCUA(int nApplicationID, BOOL bEnableCUA)
\r
1750 m_bEnableCUA[nApplicationID] = bEnableCUA;
\r
1753 BOOL CXkeymacsDll::GetEnableCUA()
\r
1755 return m_bEnableCUA[m_nApplicationID];
\r
1758 void CXkeymacsData::SetUseDialogSetting(BOOL bUseDialogSetting)
\r
1760 m_bUseDialogSetting = bUseDialogSetting;
\r
1763 BOOL CXkeymacsData::GetUseDialogSetting()
\r
1765 return m_bUseDialogSetting;
\r
1768 int CXkeymacsData::GetDescriptionID(int nCommandID)
\r
1770 return Commands[nCommandID].nDescriptionID;
\r
1773 int CXkeymacsData::GetToolTipID(int nCommandID)
\r
1775 return Commands[nCommandID].nToolTipID;
\r
1778 void CXkeymacsDll::DefiningMacro(BOOL bDefiningMacro)
\r
1780 m_bDefiningMacro = bDefiningMacro;
\r
1782 if (bDefiningMacro) { // start-kbd-macro
\r
1783 if (CCommands::bC_u()) {
\r
1784 ReleaseKey(VK_SHIFT);
\r
1787 } else { // end-kbd-macro
\r
1788 while (!m_Macro.IsEmpty()) {
\r
1789 KbdMacro_t *pKbdMacro = (KbdMacro_t *)m_Macro.GetTail();
\r
1790 if (pKbdMacro->lParam & BEING_RELEASED) {
\r
1793 m_Macro.RemoveTail();
\r
1799 // CUtils::Log(_T("Macro MemMap: start"));
\r
1800 if (!m_Macro.IsEmpty()) {
\r
1801 static HANDLE hMacro = NULL;
\r
1803 hMacro = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0x3000, _T("macro"));
\r
1806 // CUtils::Log(_T("Macro MemMap: 1"));
\r
1807 PVOID pView = MapViewOfFile(hMacro, FILE_MAP_ALL_ACCESS, 0, 0, 0);
\r
1808 // CUtils::Log(_T("Macro MemMap: 2"));
\r
1810 // CUtils::Log(_T("Macro MemMap: 2.5"));
\r
1811 for (int i = 0; i < m_Macro.GetCount(); ++i) {
\r
1812 // CUtils::Log(_T("Macro MemMap: 3-1 %d"), i);
\r
1813 KbdMacro_t *pKbdMacro = (KbdMacro_t *)m_Macro.GetAt(m_Macro.FindIndex(i));
\r
1814 // CUtils::Log(_T("Macro MemMap: 3-2 %d"), i);
\r
1815 memcpy((LPTSTR) pView + i * sizeof(KbdMacro_t), pKbdMacro, sizeof(KbdMacro_t));
\r
1816 // CUtils::Log(_T("Macro MemMap: 3-3 %d"), i);
\r
1818 // CUtils::Log(_T("Macro MemMap: 4"));
\r
1819 UnmapViewOfFile(pView);
\r
1820 // CUtils::Log(_T("Macro MemMap: 5"));
\r
1822 // CUtils::Log(_T("Macro MemMpa: error: %d"), GetLastError());
\r
1825 // CUtils::Log(_T("Macro MemMap: 6"));
\r
1832 BOOL CXkeymacsDll::DefiningMacro()
\r
1834 return m_bDefiningMacro;
\r
1838 void CXkeymacsDll::CallMacro()
\r
1840 BOOL bIsCtrlDown = IsDown(VK_CONTROL);
\r
1841 if (bIsCtrlDown) {
\r
1842 ReleaseKey(VK_CONTROL);
\r
1844 BOOL bIsAltDown = IsDown(VK_MENU);
\r
1846 ReleaseKey(VK_MENU);
\r
1848 BOOL bIsShiftDown = IsDown(VK_SHIFT);
\r
1849 if (bIsShiftDown) {
\r
1850 ReleaseKey(VK_SHIFT);
\r
1853 for (POSITION pos = m_Macro.GetHeadPosition(); pos; ) {
\r
1854 KbdMacro_t *pKbdMacro = (KbdMacro_t *)m_Macro.GetNext(pos);
\r
1855 if (pKbdMacro->lParam & BEING_RELEASED) {
\r
1856 ReleaseKey((BYTE)pKbdMacro->wParam);
\r
1858 DepressKey((BYTE)pKbdMacro->wParam, pKbdMacro->bOriginal);
\r
1862 if (bIsCtrlDown) {
\r
1863 DepressKey(VK_CONTROL);
\r
1866 DepressKey(VK_MENU);
\r
1868 if (bIsShiftDown) {
\r
1869 DepressKey(VK_SHIFT);
\r
1874 void CXkeymacsDll::CallMacro() // for debug
\r
1877 for (POSITION pos = m_Macro.GetHeadPosition(); pos; ) {
\r
1878 KbdMacro_t *pKbdMacro = (KbdMacro_t *)m_Macro.GetNext(pos);
\r
1879 if (pKbdMacro->lParam & BEING_RELEASED) {
\r
1881 t.Format(_T("0x%xu "), pKbdMacro->wParam);
\r
1885 t.Format(_T("0x%xd "), pKbdMacro->wParam);
\r
1889 // CUtils::Log(sz);
\r
1893 void CXkeymacsData::Set106Keyboard(BOOL b106Keyboard)
\r
1895 m_b106Keyboard = b106Keyboard;
\r
1898 BOOL CXkeymacsData::Is106Keyboard()
\r
1900 return m_b106Keyboard;
\r
1903 int CXkeymacsDll::IsPassThrough(BYTE nKey)
\r
1908 && (Commands[m_nCommandID[m_nApplicationID][NONE][bVk]].fCommand == CCommands::PassThrough)) {
\r
1909 if (bVk == nKey) {
\r
1913 return GOTO_DO_NOTHING;
\r
1919 void CXkeymacsDll::SetKeyboardHookFlag()
\r
1921 SetKeyboardHookFlag(m_bHook);
\r
1924 void CXkeymacsDll::SetFunctionKey(int nFunctionID, int nApplicationID, int nCommandType, int nKey)
\r
1926 if (nApplicationID < 0 || MAX_APP <= nApplicationID
\r
1927 || nCommandType < 0 || MAX_COMMAND_TYPE <= nCommandType
\r
1928 || nKey < 0 || MAX_KEY <= nKey) {
\r
1932 m_nFunctionID[nApplicationID][nCommandType][nKey] = nFunctionID;
\r
1935 void CXkeymacsDll::ClearFunctionDefinition()
\r
1937 memset(m_nFunctionID, -1, sizeof(m_nFunctionID));
\r
1938 memset(m_szFunctionDefinition, 0, sizeof(m_szFunctionDefinition));
\r
1941 void CXkeymacsDll::SetFunctionDefinition(int nFunctionID, CString szDefinition)
\r
1943 if (nFunctionID < 0 || MAX_FUNCTION <= nFunctionID) {
\r
1947 memset(m_szFunctionDefinition[nFunctionID], 0, sizeof(m_szFunctionDefinition[nFunctionID]));
\r
1948 _stprintf(m_szFunctionDefinition[nFunctionID], _T("%s"), szDefinition);
\r
1954 // call an original command which is defined in dot.xkeymacs
\r
1955 void CXkeymacsDll::CallFunction(int nFunctionID)
\r
1957 CArray<KeyBind_t, KeyBind_t> keybinds;
\r
1959 if (nFunctionID < 0 || MAX_FUNCTION <= nFunctionID || !_tcslen(m_szFunctionDefinition[nFunctionID])) {
\r
1963 BOOL bIsCtrlDown = CXkeymacsDll::IsDown(VK_CONTROL);
\r
1964 BOOL bIsAltDown = CXkeymacsDll::IsDown(VK_MENU);
\r
1965 BOOL bIsShiftDown = CXkeymacsDll::IsDown(VK_SHIFT);
\r
1967 if (m_szFunctionDefinition[nFunctionID][0] == _T('"') && m_szFunctionDefinition[nFunctionID][_tcslen(m_szFunctionDefinition[nFunctionID]) - 1] == _T('"')) {
\r
1968 for (unsigned int i = 1; i < _tcslen(m_szFunctionDefinition[nFunctionID]) - 1; ++i) { // skip '"'
\r
1969 keybinds.Add(ParseKey(nFunctionID, i));
\r
1971 } else if (m_szFunctionDefinition[nFunctionID][0] == _T('[') && m_szFunctionDefinition[nFunctionID][_tcslen(m_szFunctionDefinition[nFunctionID]) - 1] == _T(']')) {
\r
1972 for (unsigned int i = 1; i < _tcslen(m_szFunctionDefinition[nFunctionID]) - 1; ++i) { // skip '[' and ']'
\r
1973 if (m_szFunctionDefinition[nFunctionID][i] == _T('?')) { // [?f ?o ?o]
\r
1975 keybinds.Add(ParseKey(nFunctionID, i));
\r
1976 } else { // [ControlCharacter]
\r
1977 for (int nKeyID = 0; nKeyID < sizeof(ControlCharacters) / sizeof(ControlCharacters[0]); ++nKeyID) {
\r
1978 if (!_tcsncmp(m_szFunctionDefinition[nFunctionID] + i, ControlCharacters[nKeyID].name, _tcslen(ControlCharacters[nKeyID].name))) {
\r
1979 KeyBind_t keybind = {NONE, ControlCharacters[nKeyID].bVk};
\r
1980 keybinds.Add(keybind);
\r
1981 i += _tcslen(ControlCharacters[nKeyID].name);
\r
1991 BOOL bM_x = FALSE;
\r
1992 TCHAR szPath[MAX_PATH] = {'\0'};
\r
1993 unsigned int index = 0;
\r
1994 BOOL bInitialized = FALSE;
\r
1996 for (int i = 0; i < keybinds.GetSize(); ++i) {
\r
1997 const int nCommandType = keybinds.GetAt(i).nCommandType;
\r
1998 const BYTE bVk = keybinds.GetAt(i).bVk;
\r
2000 if (nCommandType < MAX_COMMAND_TYPE && Commands[m_nCommandID[m_nApplicationID][nCommandType][bVk]].fCommand) {
\r
2001 if (Commands[m_nCommandID[m_nApplicationID][nCommandType][bVk]].fCommand == CCommands::ExecuteExtendedCommand) {
\r
2003 } else if (!bInitialized) {
\r
2004 if (bIsCtrlDown) {
\r
2005 CUtils::UpdateKeyboardState(VK_CONTROL, 0);
\r
2006 ReleaseKey(VK_CONTROL);
\r
2010 ReleaseKey(VK_MENU);
\r
2013 if (bIsShiftDown) {
\r
2014 ReleaseKey(VK_SHIFT);
\r
2017 bInitialized = TRUE;
\r
2019 // CUtils::Log("CallFunction: Command Name: %s", Commands[m_nCommandID[m_nApplicationID][nCommandType][bVk]].szCommandName);
\r
2020 while (Commands[m_nCommandID[m_nApplicationID][nCommandType][bVk]].fCommand() == GOTO_RECURSIVE) {
\r
2023 } else if (bM_x) {
\r
2024 if (bVk == VK_RETURN) {
\r
2025 InvokeM_x(szPath);
\r
2027 for (TCHAR nAscii = 1; nAscii != 0; ++nAscii) { // repeat until overflow
\r
2028 if (bVk != 0 && a2v(nAscii) == bVk && ((nCommandType & SHIFT) != 0) == IsShift(nAscii)) {
\r
2029 // CUtils::Log("M-x: %#X (%c), %#X (%c)", bVk, bVk, nAscii, nAscii);
\r
2030 szPath[index++] = nAscii;
\r
2036 if (!bInitialized) {
\r
2037 if (bIsCtrlDown) {
\r
2038 CUtils::UpdateKeyboardState(VK_CONTROL, 0);
\r
2039 ReleaseKey(VK_CONTROL);
\r
2043 ReleaseKey(VK_MENU);
\r
2046 if (bIsShiftDown) {
\r
2047 ReleaseKey(VK_SHIFT);
\r
2050 bInitialized = TRUE;
\r
2052 if (nCommandType & WIN_WIN) {
\r
2053 DepressKey(VK_LWIN);
\r
2055 if (nCommandType & WIN_CTRL) {
\r
2056 DepressKey(VK_CONTROL);
\r
2058 if (nCommandType & WIN_ALT) {
\r
2059 DepressKey(VK_MENU);
\r
2061 if (nCommandType & SHIFT) {
\r
2062 DepressKey(VK_SHIFT);
\r
2067 if (nCommandType & SHIFT && (keybinds.GetSize() <= i + 1 || !(keybinds.GetAt(i + 1).nCommandType & SHIFT))) {
\r
2068 ReleaseKey(VK_SHIFT);
\r
2070 if (nCommandType & WIN_ALT && (keybinds.GetSize() <= i + 1 || !(keybinds.GetAt(i + 1).nCommandType & WIN_ALT))) {
\r
2071 ReleaseKey(VK_MENU);
\r
2073 if (nCommandType & WIN_CTRL && (keybinds.GetSize() <= i + 1 || !(keybinds.GetAt(i + 1).nCommandType & WIN_CTRL))) {
\r
2074 ReleaseKey(VK_CONTROL);
\r
2076 if (nCommandType & WIN_WIN && (keybinds.GetSize() <= i + 1 || !(keybinds.GetAt(i + 1).nCommandType & WIN_WIN))) {
\r
2077 ReleaseKey(VK_LWIN);
\r
2082 keybinds.RemoveAll();
\r
2084 if (bInitialized) {
\r
2085 // If these lines are invoked at M-x, a window transition does not work well.
\r
2087 if (bIsShiftDown) {
\r
2088 DepressKey(VK_SHIFT);
\r
2092 DepressKey(VK_MENU);
\r
2095 if (bIsCtrlDown) {
\r
2096 DepressKey(VK_CONTROL);
\r
2097 CUtils::UpdateKeyboardState(VK_CONTROL, 1);
\r
2103 KeyBind_t CXkeymacsDll::ParseKey(const int nFunctionID, unsigned int &i)
\r
2105 KeyBind keybind = {NONE};
\r
2107 if (m_szFunctionDefinition[nFunctionID][i] == _T('\\')) {
\r
2109 BOOL bFound = FALSE;
\r
2112 for (int ModifierID = 0; ModifierID < sizeof(Modifiers) / sizeof(Modifiers[0]); ++ModifierID) {
\r
2113 if (!_tcsncmp(m_szFunctionDefinition[nFunctionID] + i, Modifiers[ModifierID].name, _tcslen(Modifiers[ModifierID].name))
\r
2114 && _tcslen(Modifiers[ModifierID].name) < _tcslen(m_szFunctionDefinition[nFunctionID] + i)) {
\r
2115 keybind.nCommandType |= Modifiers[ModifierID].id;
\r
2116 i+= _tcslen(Modifiers[ModifierID].name);
\r
2122 if (IsShift(m_szFunctionDefinition[nFunctionID][i]) && !(keybind.nCommandType & (WIN_CTRL | WIN_ALT | WIN_WIN))) {
\r
2123 keybind.nCommandType |= SHIFT;
\r
2126 for (int nKeyID = 0; nKeyID < sizeof(ControlCharacters) / sizeof(ControlCharacters[0]); ++nKeyID) {
\r
2127 if (!_tcsncmp(m_szFunctionDefinition[nFunctionID] + i, ControlCharacters[nKeyID].name, _tcslen(ControlCharacters[nKeyID].name))) {
\r
2128 i += _tcslen(ControlCharacters[nKeyID].name);
\r
2132 if (nKeyID < sizeof(ControlCharacters) / sizeof(ControlCharacters[0])) {
\r
2133 keybind.bVk = ControlCharacters[nKeyID].bVk;
\r
2135 keybind.bVk = a2v(m_szFunctionDefinition[nFunctionID][i]);
\r
2141 BOOL CXkeymacsDll::IsShift(TCHAR nAscii)
\r
2154 return CXkeymacsData::Is106Keyboard();
\r
2164 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
2167 return !CXkeymacsData::Is106Keyboard();
\r
2173 return CXkeymacsData::Is106Keyboard();
\r
2178 return !CXkeymacsData::Is106Keyboard();
\r
2179 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
2180 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
2181 case _T('U'): case _T('V'): case _T('W'): case _T('X'): case _T('Y'): case _T('Z'):
\r
2188 return !CXkeymacsData::Is106Keyboard();
\r
2192 return CXkeymacsData::Is106Keyboard();
\r
2193 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
2194 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
2195 case _T('u'): case _T('v'): case _T('w'): case _T('x'): case _T('y'): case _T('z'):
\r
2207 BYTE CXkeymacsDll::a2v(TCHAR nAscii)
\r
2215 return CXkeymacsData::Is106Keyboard() ? '2' : (BYTE) 0xde; // VK_OEM_7
\r
2223 return CXkeymacsData::Is106Keyboard() ? '6' : '7';
\r
2225 return CXkeymacsData::Is106Keyboard() ? '7' : (BYTE) 0xde; // VK_OEM_7
\r
2227 return CXkeymacsData::Is106Keyboard() ? '8' : '9';
\r
2229 return CXkeymacsData::Is106Keyboard() ? '9' : '0';
\r
2231 return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xba : '8'; // VK_OEM_1
\r
2233 return 0xbb; // VK_OEM_PLUS
\r
2235 return 0xbc; // VK_OEM_COMMA
\r
2237 return 0xbd; // VK_OEM_MINUS
\r
2239 return 0xbe; // VK_OEM_PERIOD
\r
2241 return 0xbf; // VK_OEM_2
\r
2242 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
2245 return 0xba; // VK_OEM_1
\r
2247 return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xbb : (BYTE) 0xba; // VK_OEM_PLUS VK_OEM_1
\r
2249 return 0xbc; // VK_OEM_COMMA
\r
2251 return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xbd : (BYTE) 0xbb; // VK_OEM_MINUS VK_OEM_PLUS
\r
2253 return 0xbe; // VK_OEM_PERIOD
\r
2255 return 0xbf; // VK_OEM_2
\r
2257 return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xc0 : '2';
\r
2258 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
2259 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
2260 case _T('U'): case _T('V'): case _T('W'): case _T('X'): case _T('Y'): case _T('Z'):
\r
2263 return 0xdb; // VK_OEM_4
\r
2265 return 0xdc; // VK_OEM_5
\r
2267 return 0xdd; // VK_OEM_6
\r
2269 return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xde : '6'; // VK_OEM_7
\r
2271 return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xe2 : (BYTE) 0xbd; // VK_OEM_102 VK_OEM_MINUS
\r
2273 return 0xc0; // VK_OEM_3
\r
2274 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
2275 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
2276 case _T('u'): case _T('v'): case _T('w'): case _T('x'): case _T('y'): case _T('z'):
\r
2277 return (BYTE) (nAscii - (_T('a') - _T('A')));
\r
2279 return 0xdb; // VK_OEM_4
\r
2281 return 0xdc; // VK_OEM_5
\r
2283 return 0xdd; // VK_OEM_6
\r
2285 return CXkeymacsData::Is106Keyboard() ? (BYTE) 0xde : (BYTE) 0xc0; // VK_OEM_7 VK_OEM_3
\r
2291 void CXkeymacsDll::DeleteAllShell_NotifyIcon()
\r
2293 for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {
\r
2294 DeleteShell_NotifyIcon((ICON_TYPE)icon);
\r
2298 void CXkeymacsDll::AddAllShell_NotifyIcon()
\r
2300 for (int icon = 0; icon < MAX_ICON_TYPE; ++icon) {
\r
2301 AddShell_NotifyIcon((ICON_TYPE)icon);
\r
2305 void CXkeymacsData::SetWindowText(LPCTSTR lpszWindowText)
\r
2307 m_nWindowTextType = CUtils::GetWindowTextType(lpszWindowText);
\r
2308 if (m_nWindowTextType == IDS_WINDOW_TEXT_IGNORE) {
\r
2309 m_strWindowText = _T('*');
\r
2311 m_strWindowText.Format(lpszWindowText);
\r
2315 CString CXkeymacsData::GetWindowText()
\r
2317 return m_strWindowText;
\r
2320 void CXkeymacsData::SetWindowTextType(int nWindowTextType)
\r
2322 m_nWindowTextType = nWindowTextType;
\r
2325 int CXkeymacsData::GetWindowTextType()
\r
2327 return m_nWindowTextType;
\r
2330 BOOL CXkeymacsDll::IsMatchWindowText(CString szWindowText)
\r
2332 BOOL bIsMatchWindowText = TRUE;
\r
2334 TCHAR szCurrentWindowText[0x100] = {'\0'};
\r
2335 GetWindowText(GetForegroundWindow(), szCurrentWindowText, sizeof(szCurrentWindowText));
\r
2337 switch (CUtils::GetWindowTextType(szWindowText)) {
\r
2338 case IDS_WINDOW_TEXT_MATCH: // *foo*
\r
2339 szWindowText.Delete(0); // Delete first '*'
\r
2340 szWindowText.Delete(szWindowText.GetLength() - 1); // Delete last '*'
\r
2341 bIsMatchWindowText = 0 <= CString(szCurrentWindowText).Find(szWindowText);
\r
2343 case IDS_WINDOW_TEXT_MATCH_FORWARD: // foo*
\r
2344 szWindowText.Delete(szWindowText.GetLength() - 1); // Delete last '*'
\r
2345 bIsMatchWindowText = 0 == CString(szCurrentWindowText).Find(szWindowText);
\r
2347 case IDS_WINDOW_TEXT_MATCH_BACKWARD: // *foo
\r
2348 szWindowText.Delete(0); // Delete first '*'
\r
2349 bIsMatchWindowText = 0 <= CString(szCurrentWindowText).Find(szWindowText, CString(szCurrentWindowText).GetLength() - szWindowText.GetLength());
\r
2351 case IDS_WINDOW_TEXT_MATCH_FULL: // foo
\r
2352 bIsMatchWindowText = szWindowText == CString(szCurrentWindowText);
\r
2354 case IDS_WINDOW_TEXT_IGNORE: // *
\r
2355 bIsMatchWindowText = TRUE;
\r
2362 // CUtils::Log(_T("IsMatchWindowText: %d, _%s_, _%s_"), bIsMatchWindowText, szCurrentWindowText, szWindowText);
\r
2363 return bIsMatchWindowText;
\r
2366 void CXkeymacsDll::SetAccelerate(int nAccelerate)
\r
2368 m_nAccelerate = nAccelerate;
\r
2371 int CXkeymacsDll::GetAccelerate()
\r
2373 return m_nAccelerate;
\r
2376 void CXkeymacsDll::SetKeyboardSpeed(int nKeyboardSpeed)
\r
2378 m_nKeyboardSpeed = nKeyboardSpeed;
\r
2381 unsigned int CXkeymacsDll::GetMaxKeyInterval()
\r
2383 // m_nKeyboardSpeed == 0: slowest repeat rate; approximately 2 characters per second
\r
2384 // m_nKeyboardSpeed == 31: fastest repeat rate; approximately 30 characters per second
\r
2385 // 47 ms is max on my machine w/ KeyboardSpeed 31.
\r
2386 // 1000 / 2 + 50 = 550
\r
2387 // 1000 / 30 + 50 = 83
\r
2388 return (unsigned int) (1000.0 / (2.0 + m_nKeyboardSpeed % 32 * 28.0 / 31.0) + 50.0);
\r
2391 void CXkeymacsDll::SetCursorData(HCURSOR hEnable, HCURSOR hDisableTMP, HCURSOR hDisableWOCQ, HICON hDisable, BOOL bEnable)
\r
2393 m_hCursor[STATUS_ENABLE] = hEnable;
\r
2394 m_hCursor[STATUS_DISABLE_TMP] = hDisableTMP;
\r
2395 m_hCursor[STATUS_DISABLE_WOCQ] = hDisableWOCQ;
\r
2396 m_hCursor[STATUS_DISABLE] = hDisable;
\r
2397 m_bCursor = bEnable;
\r
2400 void CXkeymacsDll::DoSetCursor()
\r
2402 if (m_bCursor && m_hCurrentCursor) {
\r
2403 ::SetCursor(m_hCurrentCursor);
\r
2407 BOOL CXkeymacsData::Get326Compatible()
\r
2409 return m_b326Compatible;
\r
2412 void CXkeymacsData::Set326Compatible(BOOL b326Compatible)
\r
2414 m_b326Compatible = b326Compatible;
\r
2417 void CXkeymacsDll::Set326Compatible(int nApplicationID, BOOL b326Compatible)
\r
2419 m_b326Compatible[nApplicationID] = b326Compatible;
\r
2422 BOOL CXkeymacsDll::Get326Compatible()
\r
2424 return m_b326Compatible[m_nApplicationID];
\r
2427 void CXkeymacsDll::InvokeM_x(const TCHAR *const szPath)
\r
2429 // CUtils::Log("M-x: szPath=_%s_", szPath);
\r
2430 int (*fCommand)() = NULL;
\r
2432 for (int i = 0; i < sizeof(Commands) / sizeof(Commands[0]); ++i) {
\r
2433 if (_tcsicmp(szPath, Commands[i].szCommandName) == 0) {
\r
2434 fCommand = Commands[i].fCommand;
\r
2440 // CUtils::Log("M-x: Command: _%s_", Commands[i].szCommandName);
\r
2443 // CUtils::Log("M-x: Path: _%s_", szPath);
\r
2444 ShellExecute(NULL, NULL, szPath, NULL, NULL, SW_SHOWNORMAL);
\r
2448 void CXkeymacsDll::ModifyM_xTip(const TCHAR *const szPath)
\r
2451 if (_tcslen(szPath) < sizeof(m_stNtfyIcon[MX_ICON].szTip) / sizeof(m_stNtfyIcon[MX_ICON].szTip[0]) - 5) {
\r
2452 memset(m_stNtfyIcon[MX_ICON].szTip, 0, sizeof(m_stNtfyIcon[MX_ICON].szTip));
\r
2453 _stprintf(m_stNtfyIcon[MX_ICON].szTip, "M-x %s", szPath);
\r
2456 memset(m_stNtfyIcon[MX_ICON].szTip, 0, sizeof(m_stNtfyIcon[MX_ICON].szTip));
\r
2457 _stprintf(m_stNtfyIcon[MX_ICON].szTip, "M-x LED");
\r
2460 ModifyShell_NotifyIcon(MX_ICON, CCommands::bM_x(), TRUE);
\r