OSDN Git Service

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