OSDN Git Service

Remove unhelpful const declarations in profile.{cpp,h} and xkeymacsdll.cpp.
[xkeymacs/xkeymacs.git] / xkeymacs / profile.cpp
1 // Profile.cpp: implementation of the CProfile class\r
2 //\r
3 //////////////////////////////////////////////////////////////////////\r
4 \r
5 #include "profile.h"\r
6 #include "imelist.h"\r
7 #include "xkeymacs.h"\r
8 #include "dotxkeymacs.h"\r
9 #include "mainfrm.h"\r
10 #include "../xkeymacsdll/xkeymacsdll.h"\r
11 #include "../xkeymacsdll/AppName.h"\r
12 #include "../xkeymacsdll/Utils.h"\r
13 #include <TlHelp32.h>\r
14 \r
15 #ifdef _DEBUG\r
16 #undef THIS_FILE\r
17 static char THIS_FILE[]=__FILE__;\r
18 #define new DEBUG_NEW\r
19 #endif\r
20 \r
21 Config CProfile::m_Config;\r
22 KeyString CProfile::m_KeyString(CProfile::Is106Keyboard() != FALSE);\r
23 TCHAR CProfile::m_szAppTitle[MAX_APP][WINDOW_TEXT_LENGTH];\r
24 TASK_LIST CProfile::m_TaskList[MAX_TASKS];\r
25 DWORD CProfile::m_dwTasks;\r
26 \r
27 void CProfile::LoadData()\r
28 {\r
29         CDotXkeymacs::Load();\r
30         LevelUp();\r
31         LoadRegistry();\r
32 }\r
33 \r
34 void CProfile::SaveData()\r
35 {\r
36         DeleteAllRegistryData();\r
37         SaveRegistry();\r
38         SetDllData();\r
39 }\r
40 \r
41 void CProfile::InitDllData()\r
42 {\r
43         LoadData();\r
44         SetDllData();\r
45 }\r
46 \r
47 void CProfile::DeleteAllRegistryData()\r
48 {\r
49         HKEY hkey = NULL;\r
50         if (RegOpenKeyEx(HKEY_CURRENT_USER, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)), 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) {\r
51                 // I am sure that I have to do only one time, but...\r
52                 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
53                         DWORD dwIndex = 0;\r
54                         TCHAR szName[SUB_KEY_NAME_LENGTH] = {'\0'};\r
55                         DWORD dwName = sizeof(szName);\r
56                         FILETIME filetime;\r
57 \r
58                         while (RegEnumKeyEx(hkey, dwIndex++, szName, &dwName, NULL, NULL, NULL, &filetime) == ERROR_SUCCESS) {\r
59 //                              RegDeleteKey(hkey, szName);\r
60                                 SHDeleteKey(hkey, szName);\r
61                                 ZeroMemory(szName, sizeof(szName));\r
62                                 dwName = sizeof(szName);\r
63                         }\r
64                 }\r
65                 RegCloseKey(hkey);\r
66         }\r
67 }\r
68 \r
69 void CProfile::LevelUp()\r
70 {\r
71         int nCurrentLevel = AfxGetApp()->GetProfileInt(_T(""), _T("Level"), 0);\r
72         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
73                 CString entry;\r
74                 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
75                 const CString appName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), entry);\r
76                 if (appName.IsEmpty())\r
77                         continue;\r
78                 switch (nCurrentLevel) {\r
79                 case 0:\r
80                         AddKeyBind2C_(appName, VK_LCONTROL);\r
81                         AddKeyBind2C_(appName, VK_RCONTROL);\r
82                 // fall through\r
83                 case 1:\r
84                         // Set kill-ring-max 1 if it is 0.\r
85                         if (!AfxGetApp()->GetProfileInt(appName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 0))\r
86                                 AfxGetApp()->WriteProfileInt(appName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 1);\r
87                 // fall through\r
88                 case 2:\r
89                         {\r
90                                 // Chaged a label from Enter to newline.\r
91                                 const CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName;\r
92                                 const CString srcKey = subKey + _T("\\") + _T("Enter");\r
93                                 const CString dstKey = subKey + _T("\\") + _T("newline");\r
94                                 HKEY hDstKey = NULL;\r
95                                 if (RegCreateKeyEx(HKEY_CURRENT_USER, dstKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hDstKey, NULL) == ERROR_SUCCESS) {\r
96                                         SHCopyKey(HKEY_CURRENT_USER, srcKey, hDstKey, NULL);\r
97                                         SHDeleteKey(HKEY_CURRENT_USER, srcKey);\r
98                                         RegCloseKey(hDstKey);\r
99                                 }\r
100                         }\r
101                 // fall through\r
102                 case 3:\r
103                         // rename original function to remove IDS_REG_ORIGINAL_PREFIX\r
104                         for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {\r
105                                 HKEY hKey = NULL;\r
106                                 const CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName + _T("\\") + CString(MAKEINTRESOURCE(IDS_REG_ORIGINAL_PREFIX)) + CDotXkeymacs::GetFunctionSymbol(nFuncID);\r
107                                 if (RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
108                                         // Use registry data\r
109                                         TCHAR szKeyBind[128];\r
110                                         DWORD dwKeyBind = sizeof(szKeyBind);\r
111                                         for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
112                                                 int nType, nKey;\r
113                                                 StringToKey(szKeyBind, nType, nKey);\r
114                                                 SaveKeyBind(appName, CDotXkeymacs::GetFunctionSymbol(nFuncID), nType, nKey);\r
115                                                 dwKeyBind = sizeof(szKeyBind);\r
116                                         }\r
117                                         RegCloseKey(hKey);\r
118                                 }\r
119                         }\r
120                 }\r
121         }\r
122         AfxGetApp()->WriteProfileInt(_T(""), _T("Level"), 4);\r
123 }\r
124 \r
125 void CProfile::AddKeyBind2C_(LPCSTR szAppName, BYTE bVk)\r
126 {\r
127         int nComID;\r
128         for (nComID = 0; nComID < MAX_COMMAND; ++nComID)\r
129                 if (Commands[nComID].fCommand == CCommands::C_)\r
130                         break;\r
131         SaveKeyBind(szAppName, nComID, NONE, bVk);\r
132 }\r
133 \r
134 void CProfile::LoadRegistry()\r
135 {\r
136         bool bDialog = false;\r
137         const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));    \r
138         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
139                 CString entry;\r
140                 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
141                 CString appName = AfxGetApp()->GetProfileString(section, entry);\r
142                 if (appName.IsEmpty())  {\r
143                         if (nAppID) {\r
144                                 if (bDialog)\r
145                                         continue;\r
146                                 appName.LoadString(IDS_DIALOG);\r
147                                 bDialog = true;\r
148                         } else\r
149                                 appName.LoadString(IDS_DEFAULT);\r
150                 } else if (appName == CString(MAKEINTRESOURCE(IDS_DIALOG)))\r
151                         bDialog = true;\r
152                 _tcsncpy_s(m_Config.szSpecialApp[nAppID], appName, _TRUNCATE);\r
153                 entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
154                 _tcsncpy_s(m_szAppTitle[nAppID], AfxGetApp()->GetProfileString(appName, entry), _TRUNCATE);\r
155                 entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
156                 _tcsncpy_s(m_Config.szWindowText[nAppID], AfxGetApp()->GetProfileString(appName, entry, _T("*")), _TRUNCATE);\r
157 \r
158                 const CString regApp = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName;\r
159                 for (BYTE nComID = 1; nComID < MAX_COMMAND; ++nComID) {\r
160                         entry = CCommands::GetCommandName(nComID);\r
161                         HKEY hKey;\r
162                         const CString regKey = regApp + _T("\\") + entry;\r
163                         if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
164                                 TCHAR szKeyBind[128];\r
165                                 DWORD dwKeyBind = _countof(szKeyBind);\r
166                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
167                                         int nType, nKey;\r
168                                         StringToKey(szKeyBind, nType, nKey);\r
169                                         m_Config.nCommandID[nAppID][nType][nKey] = nComID;\r
170                                         dwKeyBind = _countof(szKeyBind);\r
171                                 }\r
172                                 RegCloseKey(hKey);\r
173                         } else {\r
174                                 // Set the default assignment\r
175                                 for (int i = 0; int nKey = CCommands::GetDefaultCommandKey(nComID, i); ++i) {\r
176                                         if (CCommands::GetDefaultControlID(nComID, i) == IDC_CO2)\r
177                                                 continue;\r
178                                         int nType = CCommands::GetDefaultCommandType(nComID, i);\r
179                                         m_Config.nCommandID[nAppID][nType][nKey] = nComID;\r
180                                 }\r
181                         }\r
182                 }\r
183                 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {\r
184                         HKEY hKey;\r
185                         const CString regKey = regApp + _T("\\") + CDotXkeymacs::GetFunctionSymbol(nFuncID);\r
186                         if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
187                                 CDotXkeymacs::ClearKey(nFuncID, nAppID);\r
188                                 TCHAR szKeyBind[128];\r
189                                 DWORD dwKeyBind = _countof(szKeyBind);\r
190                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
191                                         int nType, nKey;\r
192                                         StringToKey(szKeyBind, nType, nKey);\r
193                                         CDotXkeymacs::SetKey(nFuncID, nAppID, nType, nKey);\r
194                                         dwKeyBind = _countof(szKeyBind);\r
195                                 }\r
196                                 RegCloseKey(hKey);\r
197                         }\r
198                 }\r
199 \r
200                 entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
201                 int n = AfxGetApp()->GetProfileInt(appName, entry, 1);\r
202                 m_Config.nKillRingMax[nAppID] = static_cast<BYTE>(n > 255 ? 255 : n);\r
203                 entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
204                 m_Config.bUseDialogSetting[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 1));\r
205                 entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
206                 m_Config.nSettingStyle[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0) ? SETTING_DISABLE : SETTING_SPECIFIC);\r
207                 entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
208                 m_Config.bIgnoreUndefinedMetaCtrl[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0));\r
209                 entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
210                 m_Config.bIgnoreUndefinedC_x[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0));\r
211                 entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
212                 m_Config.bEnableCUA[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0));\r
213                 entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
214                 m_Config.b326Compatible[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0));\r
215         }\r
216 }\r
217 \r
218 void CProfile::SaveRegistry()\r
219 {\r
220         const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));    \r
221         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
222                 LPCTSTR szAppName = m_Config.szSpecialApp[nAppID];\r
223                 CString entry;\r
224                 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
225                 if (!szAppName[0]) {\r
226                         if (!AfxGetApp()->GetProfileString(section, entry).IsEmpty())\r
227                                 AfxGetApp()->WriteProfileString(section, entry, _T(""));\r
228                         continue;\r
229                 }\r
230                 AfxGetApp()->WriteProfileString(section, entry, szAppName);\r
231 \r
232                 entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
233                 CString appTitle = m_szAppTitle[nAppID];\r
234                 appTitle.TrimLeft(_T(' '));\r
235                 AfxGetApp()->WriteProfileString(szAppName, entry, appTitle);\r
236                 entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
237                 AfxGetApp()->WriteProfileString(szAppName, entry, m_Config.szWindowText[nAppID]);\r
238 \r
239                 // Create all commands\r
240                 for (int nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
241                         SaveKeyBind(szAppName, nComID, 0, 0);\r
242                 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)\r
243                         for (int nKey = 0; nKey < MAX_KEY; ++nKey)\r
244                                 SaveKeyBind(szAppName, m_Config.nCommandID[nAppID][nType][nKey], nType, nKey);\r
245                 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
246                         for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFuncID, nAppID); ++nKeyID) {\r
247                                 int nType, nKey;\r
248                                 CDotXkeymacs::GetKey(nFuncID, nAppID, nKeyID, &nType, &nKey);\r
249                                 SaveKeyBind(szAppName, CDotXkeymacs::GetFunctionSymbol(nFuncID), nType, nKey);\r
250                         }\r
251 \r
252                 entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
253                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.nKillRingMax[nAppID]);\r
254                 entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
255                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bUseDialogSetting[nAppID]);\r
256                 entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
257                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.nSettingStyle[nAppID] == SETTING_DISABLE);\r
258                 entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
259                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bIgnoreUndefinedMetaCtrl[nAppID]);\r
260                 entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
261                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bIgnoreUndefinedC_x[nAppID]);\r
262                 entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
263                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bEnableCUA[nAppID]);\r
264                 entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
265                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.b326Compatible[nAppID]);\r
266         }\r
267 }\r
268 \r
269 void CProfile::SetDllData()\r
270 {\r
271         memset(m_Config.nFunctionID, -1, sizeof(m_Config.nFunctionID));\r
272         for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
273                 _tcscpy_s(m_Config.szFunctionDefinition[nFuncID], CDotXkeymacs::GetFunctionDefinition(nFuncID));\r
274 \r
275         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
276                 m_Config.nCommandID[nAppID][CONTROL]['X'] = 0; // C-x is unassigned.\r
277                 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)\r
278                         for (int nKey = 0; nKey < MAX_KEY; ++nKey)\r
279                                 if ((nType & CONTROLX) && m_Config.nCommandID[nAppID][nType][nKey])\r
280                                         m_Config.nCommandID[nAppID][CONTROL]['X'] = 1; // C-x is available.\r
281                 for (BYTE nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
282                         for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFuncID, nAppID); ++nKeyID) {\r
283                                 int nType, nKey;\r
284                                 CDotXkeymacs::GetKey(nFuncID, nAppID, nKeyID, &nType, &nKey);\r
285                                 m_Config.nFunctionID[nAppID][nType][nKey] = nFuncID;\r
286                                 if (nType & CONTROLX)\r
287                                         m_Config.nCommandID[nAppID][CONTROL]['X'] = 1; // C-x is available.\r
288                         }\r
289         }\r
290         m_Config.b106Keyboard = static_cast<BYTE>(Is106Keyboard());\r
291         CXkeymacsDll::SetConfig(m_Config);\r
292         CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());\r
293         if (!pApp->IsWow64())\r
294                 return;\r
295         if (!CXkeymacsDll::SaveConfig())\r
296                 return;\r
297         pApp->SendIPCMessage(XKEYMACS_RELOAD);\r
298 }\r
299 \r
300 void CProfile::SaveKeyBind(LPCTSTR appName, int comID, int type, int key)\r
301 {\r
302         if (!comID)\r
303                 return;\r
304         LPCTSTR comName = CCommands::GetCommandName(comID);\r
305         if (!comName[0])\r
306                 return;\r
307         SaveKeyBind(appName, comName, type, key);\r
308 }\r
309 \r
310 void CProfile::SaveKeyBind(LPCTSTR appName, LPCTSTR comName, int type, int key)\r
311 {\r
312         CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName + _T("\\") + comName;\r
313         CString s = KeyToString(type, key);\r
314         if (!s.IsEmpty())\r
315                 subKey = subKey + _T("\\") + s;\r
316         HKEY hKey = NULL;\r
317         if (RegCreateKeyEx(HKEY_CURRENT_USER, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)\r
318                 RegCloseKey(hKey);\r
319 }\r
320 \r
321 void CProfile::StringToKey(LPCTSTR str, int& type, int& key)\r
322 {\r
323         m_KeyString.ToKey(str, type, key);\r
324 }\r
325 \r
326 CString CProfile::KeyToString(int type, int key)\r
327 {\r
328         return m_KeyString.ToString(type, key);\r
329 }\r
330 \r
331 void CProfile::InitAppList(CProperties& cProperties)\r
332 {\r
333         GetTaskList();\r
334 \r
335         EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&cProperties));\r
336 \r
337         for (int i = 0; i < MAX_APP; ++i) {\r
338                 LPCTSTR szAppName = m_Config.szSpecialApp[i];\r
339                 LPCTSTR szAppTitle = m_szAppTitle[i];\r
340                 if (!szAppName[0] || !_tcscmp(szAppName, _T("IME")))\r
341                         continue;\r
342                 if (CString(MAKEINTRESOURCE(IDS_DEFAULT)) == szAppName ||\r
343                                 CString(MAKEINTRESOURCE(IDS_DIALOG)) == szAppName)\r
344                         continue;\r
345                 cProperties.AddItem(szAppTitle, szAppName);\r
346         }\r
347         AddIMEInfo(cProperties);\r
348 }\r
349 \r
350 void CProfile::GetTaskList()\r
351 {\r
352         ZeroMemory(m_TaskList, sizeof(m_TaskList));\r
353 \r
354         HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r
355         if (hProcessSnap == (HANDLE)-1)\r
356                 return;\r
357 \r
358         m_dwTasks = 0;\r
359         PROCESSENTRY32 processEntry32 = {sizeof(PROCESSENTRY32)};\r
360         if (Process32First(hProcessSnap, &processEntry32)) {\r
361                 do {\r
362                         lstrcpy(m_TaskList[m_dwTasks].ProcessName, processEntry32.szExeFile);\r
363                         m_TaskList[m_dwTasks++].dwProcessId = processEntry32.th32ProcessID;\r
364                 } while (m_dwTasks < MAX_TASKS && Process32Next(hProcessSnap, &processEntry32));\r
365         }\r
366 \r
367         CloseHandle(hProcessSnap);\r
368 }\r
369 \r
370 BOOL CALLBACK CProfile::EnumWindowsProc(HWND hWnd, LPARAM lParam)\r
371 {\r
372         CProperties *pProperties = reinterpret_cast<CProperties*>(lParam);\r
373         PTASK_LIST pTask = CProfile::m_TaskList;\r
374         \r
375         TCHAR szWindowName[WINDOW_TEXT_LENGTH];\r
376         TCHAR szClassName[CLASS_NAME_LENGTH];\r
377         WINDOWPLACEMENT wpl;\r
378         \r
379         wpl.length = sizeof(WINDOWPLACEMENT);\r
380         ::GetWindowText(hWnd, szWindowName, sizeof(szWindowName));\r
381         GetClassName(hWnd, szClassName, sizeof(szClassName));\r
382 \r
383         CString appTitle;\r
384         // Get Process Name\r
385         DWORD dwProcessId = 0;\r
386         GetWindowThreadProcessId(hWnd, &dwProcessId);\r
387         DWORD i;\r
388         for (i = 0; i < CProfile::m_dwTasks; ++i) {\r
389                 if (pTask[i].dwProcessId == dwProcessId) {\r
390 \r
391                         // Get Application Name\r
392                         if (szWindowName[0] == '\0') {\r
393                                 continue;\r
394                         }\r
395                         if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_B2)), sizeof(pTask[i].ProcessName))) {\r
396                                 appTitle.LoadString(IDS_BECKY);\r
397                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXPLORER)), sizeof(pTask[i].ProcessName))) {\r
398                                 appTitle.LoadString(IDS_PROGRAM_MANAGER);\r
399                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSIMN)), sizeof(pTask[i].ProcessName))) {\r
400                                 appTitle.LoadString(IDS_OUTLOOK_EXPRESS);\r
401                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_PROJECT)), sizeof(pTask[i].ProcessName))\r
402                                         || !_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXCEL)), sizeof(pTask[i].ProcessName))\r
403                                         || !_tcsnicmp(pTask[i].ProcessName, _T("psp.exe"), sizeof(pTask[i].ProcessName))) {\r
404                                 GetAppTitle(appTitle, szWindowName, 1);\r
405                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sakura.exe"), sizeof(pTask[i].ProcessName))) {\r
406                                 GetAppTitle(appTitle, szWindowName, 2); // '.' is included, so...\r
407                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSDN)), sizeof(pTask[i].ProcessName))) {\r
408                                 appTitle = szWindowName;\r
409                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("devenv.exe"), sizeof(pTask[i].ProcessName))) {\r
410                                 appTitle.Format(_T("Microsoft Visual Studio .NET"));\r
411                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vb6.exe"), sizeof(pTask[i].ProcessName))) {\r
412                                 appTitle.Format(_T("Microsoft Visual Basic"));\r
413                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("ssexp.exe"), sizeof(pTask[i].ProcessName))) {\r
414                                 appTitle.LoadString(IDS_VISUAL_SOURCESAFE_EXPLORER);\r
415                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sh.exe"), sizeof(pTask[i].ProcessName))) {\r
416                                 appTitle.Format(_T("MKS Korn Shell"));\r
417                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("csh.exe"), sizeof(pTask[i].ProcessName))) {\r
418                                 appTitle.Format(_T("C Shell"));\r
419                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vim.exe"), sizeof(pTask[i].ProcessName))) {\r
420                                 appTitle.Format(_T("VIM"));\r
421                         } else {\r
422                                 AppName::CorrectAppName(szWindowName, pTask[i].ProcessName);\r
423                                 GetAppTitle(appTitle, szWindowName);\r
424                         }\r
425                         break;\r
426                 }\r
427         }\r
428         \r
429         if (IsWindowVisible(hWnd) && // Is visible?\r
430                         GetWindow(hWnd, GW_OWNER) == NULL && // Is top level window?\r
431                         lstrlen(szWindowName) > 0) { // Have caption?\r
432                 pProperties->AddItem(appTitle, pTask[i].ProcessName);\r
433         }\r
434         return TRUE;\r
435 }\r
436 \r
437 // This function returns the nth string in a window name separated by " - ".\r
438 // If there aren't a sufficient number of strings, it returns the last string\r
439 // appropriate for the title.\r
440 bool CProfile::GetAppTitle(CString& appTitle, const CString& windowName, int nth)\r
441 {\r
442         const CString sep(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE));\r
443         int nSep = windowName.Find(sep);\r
444         if (nSep < 0) {\r
445                 appTitle = windowName;\r
446                 return false;\r
447         }\r
448         if (GetAppTitle(appTitle, windowName.Right(windowName.GetLength() - nSep - sep.GetLength()), --nth) ||\r
449                         !nth || nth > 0 && appTitle.GetAt(0) != _T('[') && appTitle.FindOneOf(_T(".]")) == -1)\r
450                 return true;\r
451         appTitle = windowName.Left(nSep);\r
452         return false;\r
453 }\r
454 \r
455 void CProfile::AddIMEInfo(CProperties& cProperties)\r
456 {\r
457         IMEList imeList;\r
458         for (IMEListIterator p = imeList.begin(); p != imeList.end(); ++p)\r
459                 cProperties.AddItem(p->szDescription, p->szFileName);\r
460 }\r
461 \r
462 void CProfile::ClearData(const CString szCurrentApplication)\r
463 {\r
464         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
465                 if (szCurrentApplication == m_Config.szSpecialApp[nAppID]) {\r
466                         ZeroMemory(m_Config.nCommandID[nAppID], sizeof(m_Config.nCommandID[nAppID]));\r
467                         ZeroMemory(m_Config.szSpecialApp[nAppID], CLASS_NAME_LENGTH);\r
468                         return;\r
469                 }\r
470 }\r
471 \r
472 void CProfile::CopyData(const CString szDstApp, const CString szSrcApp)\r
473 {\r
474         int nDstApp = AssignAppID(szDstApp);\r
475         int nSrcApp = GetAppID(szSrcApp);\r
476         if (nDstApp == MAX_APP || nSrcApp == MAX_APP)\r
477                 return;\r
478         SetSettingStyle(nDstApp, SETTING_SPECIFIC);\r
479 \r
480 #define CopyMember(member) CopyMemory(&m_Config. ## member ## [nDstApp], &m_Config. ## member ## [nSrcApp], sizeof(m_Config. ## member ## [nSrcApp]))\r
481         CopyMember(b326Compatible);\r
482         CopyMember(nFunctionID);\r
483         CopyMember(bEnableCUA);\r
484         CopyMember(bUseDialogSetting);\r
485         CopyMember(bIgnoreUndefinedC_x);\r
486         CopyMember(bIgnoreUndefinedMetaCtrl);\r
487         CopyMember(nKillRingMax);\r
488         CopyMember(nCommandID);\r
489 #undef CopyMember\r
490 }\r
491 \r
492 int CProfile::AssignAppID(LPCSTR szAppName)\r
493 {\r
494         int nAppID = GetAppID(szAppName);\r
495         if (nAppID != MAX_APP)\r
496                 return nAppID;\r
497         for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
498                 if (!m_Config.szSpecialApp[nAppID][0]) {\r
499                         _tcsncpy_s(m_Config.szSpecialApp[nAppID], szAppName, _TRUNCATE);\r
500                         return nAppID;\r
501                 }\r
502         return nAppID;\r
503 }\r
504 \r
505 int CProfile::DefaultAppID()\r
506 {\r
507         const CString name(MAKEINTRESOURCE(IDS_DEFAULT));\r
508         for(int nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
509                 if (name == m_Config.szSpecialApp[nAppID])\r
510                         return nAppID;\r
511         return MAX_APP;\r
512 }\r
513 \r
514 int CProfile::GetAppID(LPCSTR szAppName)\r
515 {\r
516         int nAppID = 0;\r
517         for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
518                 if (!_tcscmp(szAppName, m_Config.szSpecialApp[nAppID]))\r
519                         break;\r
520         return nAppID;\r
521 }\r
522 \r
523 int CProfile::GetSettingStyle(int nAppID)\r
524 {\r
525         if (nAppID == MAX_APP)\r
526                 return SETTING_DEFAULT;\r
527         return m_Config.nSettingStyle[nAppID];\r
528 }\r
529 \r
530 void CProfile::SetSettingStyle(int nAppID, int nSettingStyle)\r
531 {\r
532         if (nAppID == MAX_APP)\r
533                 return;\r
534         m_Config.nSettingStyle[nAppID] = static_cast<BYTE>(nSettingStyle);\r
535 }\r
536 \r
537 void CProfile::SetAppTitle(int nAppID, const CString& appTitle)\r
538 {\r
539         _tcsncpy_s(m_szAppTitle[nAppID], appTitle, _TRUNCATE);\r
540 }\r
541 \r
542 int CProfile::GetCommandID(int nAppID, int nType, int nKey)\r
543 {\r
544         int nComID = m_Config.nCommandID[nAppID][nType][nKey];\r
545         if (nKey == 0xf0 && Commands[nComID].fCommand == CCommands::C_Eisu)\r
546                 // Change CommandID C_\r
547                 for (nComID = 1; nComID < MAX_COMMAND; nComID++)\r
548                         if (Commands[nComID].fCommand == CCommands::C_)\r
549                                 break;\r
550         return nComID;\r
551 }\r
552 \r
553 void CProfile::SetCommandID(int nAppID, int nType, int nKey, int nComID)\r
554 {\r
555         if (nKey == 0xf0 && Commands[nComID].fCommand == CCommands::C_)\r
556                 // Change CommandID C_Eisu\r
557                 for (nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
558                         if (Commands[nComID].fCommand == CCommands::C_Eisu)\r
559                                 break;\r
560         m_Config.nCommandID[nAppID][nType][nKey] = static_cast<BYTE>(nComID);\r
561 }\r
562 \r
563 BOOL CProfile::GetUseDialogSetting(int nAppID)\r
564 {\r
565         return m_Config.bUseDialogSetting[nAppID];\r
566 }\r
567 \r
568 void CProfile::SetUseDialogSetting(int nAppID, BOOL bUseDialogSetting)\r
569 {\r
570         m_Config.bUseDialogSetting[nAppID] = static_cast<BYTE>(bUseDialogSetting);\r
571 }\r
572 \r
573 BOOL CProfile::GetEnableCUA(int nAppID)\r
574 {\r
575         return m_Config.bEnableCUA[nAppID];\r
576 }\r
577 \r
578 void CProfile::SetEnableCUA(int nAppID, BOOL bEnableCUA)\r
579 {\r
580         m_Config.bEnableCUA[nAppID] = static_cast<BYTE>(bEnableCUA);\r
581 }\r
582 \r
583 int CProfile::GetKillRingMax(int nAppID)\r
584 {\r
585         return m_Config.nKillRingMax[nAppID];\r
586 }\r
587 \r
588 void CProfile::SetKillRingMax(int nAppID, int nKillRingMax)\r
589 {\r
590         m_Config.nKillRingMax[nAppID] = static_cast<BYTE>(nKillRingMax > 255 ? 255 : nKillRingMax);\r
591 }\r
592 \r
593 CString CProfile::GetWindowText(int nAppID)\r
594 {\r
595         return m_Config.szWindowText[nAppID];\r
596 }\r
597 \r
598 void CProfile::SetWindowText(int nAppID, const CString szWindowText)\r
599 {\r
600         if (CUtils::GetWindowTextType(szWindowText) == IDS_WINDOW_TEXT_IGNORE)\r
601                 _tcscpy_s(m_Config.szWindowText[nAppID], _T("*"));\r
602         else\r
603                 _tcsncpy_s(m_Config.szWindowText[nAppID], szWindowText, _TRUNCATE);\r
604 }\r
605 \r
606 BOOL CProfile::Is106Keyboard()\r
607 {\r
608         static KEYBOARD_TYPE keyboard = UNKNOWN_KEYBOARD;\r
609 \r
610         if (keyboard == UNKNOWN_KEYBOARD) {\r
611                 OSVERSIONINFO verInfo = {0};\r
612                 verInfo.dwOSVersionInfoSize = sizeof (verInfo);\r
613                 GetVersionEx(&verInfo);\r
614 \r
615                 DWORD subtype = 0;\r
616                 DWORD cbData = sizeof(subtype);\r
617 \r
618                 if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {\r
619                         HKEY hKey = NULL;\r
620                         const CString szSubKey(_T("SYSTEM\\CurrentControlSet\\Services\\i8042prt\\Parameters"));\r
621                         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
622                                 static const CString szValueName(_T("OverrideKeyboardSubtype"));\r
623                                 if (RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE)&subtype, &cbData) != ERROR_SUCCESS) {\r
624                                         subtype = 0;\r
625                                 }\r
626                                 RegCloseKey(hKey);\r
627                         }\r
628                 } else if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {\r
629                         subtype = GetPrivateProfileInt(_T("keyboard"), _T("subtype"), 0, _T("system.ini"));\r
630                 }\r
631 \r
632                 keyboard = (subtype & 0x02) ? JAPANESE_KEYBOARD : ENGLISH_KEYBOARD;\r
633         }\r
634 \r
635         return keyboard == JAPANESE_KEYBOARD;\r
636 }\r
637 \r
638 BOOL CProfile::IsVistaOrLater()\r
639 {\r
640         OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};\r
641         GetVersionEx(&info);\r
642 \r
643         if (6 <= info.dwMajorVersion) {\r
644                 return TRUE;\r
645         }\r
646         return FALSE;\r
647 }\r
648 \r
649 void CProfile::RestartComputer()\r
650 {\r
651         if (!AdjustTokenPrivileges(SE_SHUTDOWN_NAME)) {\r
652                 return;\r
653         }\r
654 \r
655         ExitWindowsEx(EWX_REBOOT, 0);\r
656 }\r
657 \r
658 void CProfile::ImportProperties()\r
659 {\r
660         if (!AdjustTokenPrivileges(SE_RESTORE_NAME)) {\r
661                 return;\r
662         }\r
663 \r
664         CFileDialog oFileOpenDialog(TRUE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
665         if (oFileOpenDialog.DoModal() == IDOK) {\r
666                 CString szCommandLine;\r
667                 szCommandLine.Format(_T("regedit \"%s\""), oFileOpenDialog.GetPathName());\r
668                 CUtils::Run(szCommandLine, TRUE);       // regedit "x:\xkeymacs.reg"\r
669         }\r
670 \r
671         DiableTokenPrivileges();\r
672         return;\r
673 }\r
674 \r
675 void CProfile::ExportProperties()\r
676 {\r
677         if (!AdjustTokenPrivileges(SE_BACKUP_NAME)) {\r
678                 return;\r
679         }\r
680 \r
681         CFileDialog oFileOpenDialog(FALSE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
682         if (oFileOpenDialog.DoModal() == IDOK) {\r
683                 CString szCommandLine;\r
684                 szCommandLine.Format(_T("regedit /e \"%s\" HKEY_CURRENT_USER\\%s"), oFileOpenDialog.GetPathName(), CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)));\r
685                 CUtils::Run(szCommandLine, TRUE);       // regedit /e "x:\xkeymacs.reg" HKEY_CURRENT_USER\Software\Oishi\XKeymacs2\r
686         }\r
687 \r
688         DiableTokenPrivileges();\r
689         return;\r
690 }\r
691 \r
692 BOOL CProfile::AdjustTokenPrivileges(LPCTSTR lpName)\r
693 {\r
694         BOOL rc = TRUE;\r
695 \r
696         HANDLE hToken;\r
697         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
698                 LUID luid;\r
699                 if (LookupPrivilegeValue(NULL, lpName, &luid)) {\r
700                         TOKEN_PRIVILEGES tp;\r
701                         tp.PrivilegeCount = 1;\r
702                         tp.Privileges[0].Luid = luid;\r
703                         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\r
704 \r
705                         if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {\r
706                                 rc = FALSE;\r
707                         }\r
708                 } else {\r
709                         rc = FALSE;\r
710                 }\r
711                 CloseHandle(hToken);\r
712         } else {\r
713                 rc = FALSE;\r
714         }\r
715 \r
716         return rc;\r
717 }\r
718 \r
719 BOOL CProfile::DiableTokenPrivileges()\r
720 {\r
721         BOOL rc = TRUE;\r
722 \r
723         HANDLE hToken;\r
724         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
725                 if (!::AdjustTokenPrivileges(hToken, TRUE, NULL, NULL, NULL, NULL)) {\r
726                         rc = FALSE;\r
727                 }\r
728                 CloseHandle(hToken);\r
729         } else {\r
730                 rc = FALSE;\r
731         }\r
732 \r
733         return rc;\r
734 }\r
735 \r
736 int CProfile::GetKeyboardSpeed()\r
737 {\r
738         int nKeyboardSpeed = 31; // default value of Windows\r
739         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_KEYBOARD));\r
740         CString szValueName(MAKEINTRESOURCE(IDS_KEYBOARD_SPEED));\r
741 \r
742         HKEY hKey = NULL;\r
743         if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
744                 // get data size\r
745                 DWORD dwType = REG_SZ;\r
746                 BYTE data[4] = {0};\r
747                 DWORD dwcbData = sizeof(data)/sizeof(data[0]);\r
748                 RegQueryValueEx(hKey, szValueName, NULL, &dwType, (LPBYTE)&data, &dwcbData);\r
749                 RegCloseKey(hKey);\r
750 \r
751                 for (DWORD i = 0; i < dwcbData; ++i) {\r
752                         if (data[i]) {\r
753                                 if (i) {\r
754                                         nKeyboardSpeed = nKeyboardSpeed * 10 + data[i] - _T('0');\r
755                                 } else {\r
756                                         nKeyboardSpeed = data[i] - _T('0');\r
757                                 }\r
758                         } else {\r
759                                 break;\r
760                         }\r
761                 }\r
762         }\r
763 \r
764         return nKeyboardSpeed;\r
765 }\r