OSDN Git Service

Add a new class CmdTable to handle the table of the commands.
[xkeymacs/xkeymacs.git] / xkeymacsdll / AppName.cpp
1 #include "AppName.h"\r
2 #include "Utils.h"\r
3 #include <Imm.h>\r
4 \r
5 #pragma data_seg(".xkmcs")\r
6 TCHAR AppName::m_FallbackIMEName[MAX_PATH] = _T("");\r
7 #pragma data_seg()\r
8 TCHAR AppName::m_AppName[CLASS_NAME_LENGTH] = _T("");\r
9 TCHAR AppName::m_IMEName[MAX_PATH] = _T("");\r
10 bool AppName::m_Inited = false;\r
11 bool AppName::m_IMEState = false;\r
12 \r
13 void AppName::Init()\r
14 {\r
15         if (m_Inited)\r
16                 return;\r
17         if (m_FallbackIMEName[0] == _T('\0')) {\r
18                 // preserve the IME file name of the current TIF if it works as an Imm32 IME.\r
19                 HKL hKL = GetKeyboardLayout(0);\r
20                 if (!ImmIsIME(hKL) || !ImmGetIMEFileName(hKL, m_FallbackIMEName, MAX_PATH))\r
21                         _tcscpy_s(m_FallbackIMEName, _T("IME"));\r
22         }\r
23         TCHAR path[MAX_PATH];\r
24         GetModuleFileName(NULL, path, MAX_PATH);\r
25         CString s(path);\r
26         s.Delete(0, s.ReverseFind(_T('\\')) + 1);\r
27         _tcscpy_s(m_AppName, s);\r
28         TCHAR text[WINDOW_TEXT_LENGTH];\r
29         GetWindowText(GetForegroundWindow(), text, sizeof(text));\r
30         CorrectAppName(text, m_AppName);\r
31 }\r
32 \r
33 LPCTSTR AppName::GetAppName()\r
34 {\r
35         return m_IMEState ? m_IMEName : m_AppName;\r
36 }\r
37 \r
38 void AppName::SetIMEState(bool on)\r
39 {\r
40         m_IMEState = on;\r
41         if (!on)\r
42                 return;\r
43         HKL hKL = GetKeyboardLayout(0);\r
44         if (ImmIsIME(hKL)) {\r
45                 if (!ImmGetIMEFileName(hKL, m_IMEName, sizeof(m_IMEName)))\r
46                         _tcscpy_s(m_IMEName, _T("IME")); // TIP on TSF\r
47                 return;\r
48         }\r
49         // ImmIsIME returns false if you use TSF aware applications with a TIF (aka IME).\r
50         // The following take the preserved IME file name of it.\r
51         _tcscpy_s(m_IMEName, m_FallbackIMEName);\r
52 }\r
53 \r
54 // The code starting here is derived from work by co <cogood\81\97gmail.com>.\r
55 void AppName::CorrectAppName(TCHAR (&text)[WINDOW_TEXT_LENGTH], TCHAR (&appName)[CLASS_NAME_LENGTH])\r
56 {\r
57         CString s(text);\r
58         if (IsConsole(appName)) {\r
59                 RemovePrefixes(s);\r
60                 int prev, sep;\r
61                 for (prev = -1, sep = 0; (sep = s.Find(_T(" - "), sep)) >= 0; prev = sep, sep += 3)\r
62                         ;\r
63                 if (prev >= 0) {\r
64                         s.Delete(0, prev + 3);\r
65                         ConsoleAppName(s, appName);\r
66                         _tcscpy_s(text, s);\r
67                         return;\r
68                 }\r
69                 if (IsCmdExe(s)) {\r
70                         _tcscpy_s(appName, "cmd.exe");\r
71                         _tcscpy_s(text, s);\r
72                         return;\r
73                 }\r
74                 if (s.Find(_T("Cygwin Bash Shell")) == 0 ||\r
75                                 s[0] == _T('~') || s[0] == _T('/')) {\r
76                         _tcscpy_s(appName, _T("bash.exe"));\r
77                         _tcscpy_s(text, _T("Cygwin Bash Shell"));\r
78                 } else if (s.Find(_T("MKS Korn Shell")) == 0 || s.Find(_T("cat")) == 0) {\r
79                         _tcscpy_s(appName, _T("sh.exe"));\r
80                 } else if (s.Find(_T(":/"), 1) == 1 || s.Find(_T(":\\"), 1) == 1) {\r
81                         _tcscpy_s(appName, _T("csh.exe"));\r
82                         _tcscpy_s(text, "C Shell");\r
83                 } else {\r
84                         ConsoleAppName(s, appName);\r
85                         _tcscpy_s(text, s);\r
86                 }\r
87         } else if (!_tcsicmp(appName, _T("javaw.exe"))) {\r
88                 if (s.Find(_T(" - Eclipse Platform")) || s == _T("Find/Replace"))\r
89                         _tcscpy_s(appName, "eclipse.exe");\r
90                 else if (s.Find(_T("BlueJ")))\r
91                         _tcscpy_s(appName, "bluej.exe");\r
92                 else if (s.Find(_T("JUDE")))\r
93                         _tcscpy_s(appName, "jude.exe");\r
94         }\r
95 }\r
96 \r
97 bool AppName::IsConsole()\r
98 {\r
99         return IsConsole(m_AppName);\r
100 }\r
101 \r
102 bool AppName::IsConsole(LPCTSTR appName)\r
103 {\r
104         LPCTSTR names[] = {\r
105                 "conhost.exe",\r
106                 "conime.exe",\r
107                 "csh.exe",\r
108                 "cmd.exe",\r
109                 "bash.exe",\r
110                 "ftp.exe",\r
111                 "sh.exe",\r
112                 "telnet.exe",\r
113         };\r
114         if (!appName[0])\r
115                 return true;\r
116         for (int i = 0; i < _countof(names); ++i)\r
117                 if (!_tcsicmp(appName, names[i]))\r
118                         return true;\r
119         return false;\r
120 }\r
121 \r
122 bool AppName::IsCmdExe(const CString& text)\r
123 {\r
124         LPCTSTR prompts[] = {\r
125                 _T("command prompt"),\r
126                 _T("\83R\83}\83\93\83\83v\83\8d\83\93\83v\83g"),\r
127                 _T("system32\\cmd.exe"),\r
128                 _T("syswow64\\cmd.exe")\r
129         };\r
130         for (int i = 0; i < _countof(prompts); ++i)\r
131                 if (text.Right(_tcslen(prompts[i])).CompareNoCase(prompts[i]) == 0)\r
132                         return true;\r
133         return false;\r
134 }\r
135 \r
136 void AppName::ConsoleAppName(CString& text, TCHAR (&appName)[CLASS_NAME_LENGTH])\r
137 {\r
138         int endQuote = text.Find(_T('"'), 1);\r
139         int space = text.Find(_T(' '), 1);\r
140         if (text[0] == _T('"') && endQuote > 0)\r
141                 text = text.Mid(1, endQuote - 1); // A string surrounded by " is a command name.\r
142         else if (space >= 0)\r
143                 text = text.Left(space + 1); // The first token is a command name.\r
144         int backSlash = text.ReverseFind(_T('\\')); // remove its directory.\r
145         if (backSlash >= 0)\r
146                 text.Delete(0, backSlash + 1);\r
147         _tcsncpy_s(appName,\r
148                 text.Right(4).CompareNoCase(_T(".exe")) == 0\r
149                 ? text : text + _T(".exe"), _TRUNCATE);\r
150 }\r
151 \r
152 void AppName::RemovePrefixes(CString& text)\r
153 {\r
154         LPCTSTR prefixes[] = {\r
155                 _T("\94Í\88Í\8ew\92è "), // via the edit menu\r
156                 _T("\83X\83N\83\8d\81[\83\8b "), // via the edit menu\r
157                 _T("\91I\91ð "), // via QuickEdit\r
158                 _T("\8aÇ\97\9d\8eÒ: "), // remove it last\r
159                 _T("Mark "),\r
160                 _T("Scroll "),\r
161                 _T("Select "),\r
162                 _T("Administrator: "),\r
163         };\r
164         for (int i = 0; i < _countof(prefixes); ++i)\r
165                 if (text.Find(prefixes[i]) == 0)\r
166                         text.Delete(0, static_cast<int>(_tcslen(prefixes[i])));\r
167 }\r
168 // The derived code ends here.\r
169 \r
170 bool AppName::Match(LPCTSTR name)\r
171 {\r
172         LPCTSTR names[1] = { name };\r
173         return Match(names);\r
174 }\r