OSDN Git Service

Add FuncDefs class to handle functions defined in dot.xkeymacs.
[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 "xkeymacs.h"\r
7 #include "FuncDefs.h"\r
8 #include "mainfrm.h"\r
9 #include "../xkeymacsdll/xkeymacsdll.h"\r
10 #include "../xkeymacsdll/Utils.h"\r
11 \r
12 #ifdef _DEBUG\r
13 #undef THIS_FILE\r
14 static char THIS_FILE[]=__FILE__;\r
15 #define new DEBUG_NEW\r
16 #endif\r
17 \r
18 Config CProfile::m_Config;\r
19 KeyString CProfile::m_KeyString(CProfile::Is106Keyboard() != FALSE);\r
20 TCHAR CProfile::m_AppTitle[MAX_APP][WINDOW_TEXT_LENGTH];\r
21 \r
22 void CProfile::LoadData()\r
23 {\r
24         FuncDefs::Load();\r
25         LevelUp();\r
26         LoadRegistry();\r
27 }\r
28 \r
29 void CProfile::SaveData()\r
30 {\r
31         DeleteAllRegistryData();\r
32         SaveRegistry();\r
33         SetDllData();\r
34 }\r
35 \r
36 void CProfile::InitDllData()\r
37 {\r
38         LoadData();\r
39         SetDllData();\r
40 }\r
41 \r
42 void CProfile::DeleteAllRegistryData()\r
43 {\r
44         HKEY hkey = NULL;\r
45         if (RegOpenKeyEx(HKEY_CURRENT_USER, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)), 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) {\r
46                 // I am sure that I have to do only one time, but...\r
47                 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
48                         DWORD dwIndex = 0;\r
49                         TCHAR szName[SUB_KEY_NAME_LENGTH] = {'\0'};\r
50                         DWORD dwName = sizeof(szName);\r
51                         FILETIME filetime;\r
52 \r
53                         while (RegEnumKeyEx(hkey, dwIndex++, szName, &dwName, NULL, NULL, NULL, &filetime) == ERROR_SUCCESS) {\r
54 //                              RegDeleteKey(hkey, szName);\r
55                                 SHDeleteKey(hkey, szName);\r
56                                 ZeroMemory(szName, sizeof(szName));\r
57                                 dwName = sizeof(szName);\r
58                         }\r
59                 }\r
60                 RegCloseKey(hkey);\r
61         }\r
62 }\r
63 \r
64 void CProfile::LevelUp()\r
65 {\r
66         int nCurrentLevel = AfxGetApp()->GetProfileInt(_T(""), _T("Level"), 0);\r
67         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
68                 CString entry;\r
69                 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
70                 const CString appName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), entry);\r
71                 if (appName.IsEmpty())\r
72                         continue;\r
73                 switch (nCurrentLevel) {\r
74                 case 0:\r
75                         AddKeyBind2C_(appName, VK_LCONTROL);\r
76                         AddKeyBind2C_(appName, VK_RCONTROL);\r
77                 // fall through\r
78                 case 1:\r
79                         // Set kill-ring-max 1 if it is 0.\r
80                         if (!AfxGetApp()->GetProfileInt(appName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 0))\r
81                                 AfxGetApp()->WriteProfileInt(appName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 1);\r
82                 // fall through\r
83                 case 2:\r
84                         {\r
85                                 // Chaged a label from Enter to newline.\r
86                                 const CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName;\r
87                                 const CString srcKey = subKey + _T("\\") + _T("Enter");\r
88                                 const CString dstKey = subKey + _T("\\") + _T("newline");\r
89                                 HKEY hDstKey = NULL;\r
90                                 if (RegCreateKeyEx(HKEY_CURRENT_USER, dstKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hDstKey, NULL) == ERROR_SUCCESS) {\r
91                                         SHCopyKey(HKEY_CURRENT_USER, srcKey, hDstKey, NULL);\r
92                                         SHDeleteKey(HKEY_CURRENT_USER, srcKey);\r
93                                         RegCloseKey(hDstKey);\r
94                                 }\r
95                         }\r
96                 // fall through\r
97                 case 3:\r
98                         // rename original function to remove IDS_REG_ORIGINAL_PREFIX\r
99                         for (int nFuncID = 0; nFuncID < FuncDefs::GetNumOfDefs(); ++nFuncID) {\r
100                                 HKEY hKey = NULL;\r
101                                 const CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName + _T("\\") + CString(MAKEINTRESOURCE(IDS_REG_ORIGINAL_PREFIX)) + FuncDefs::GetName(nFuncID);\r
102                                 if (RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
103                                         TCHAR szKeyBind[128];\r
104                                         DWORD dwKeyBind = sizeof(szKeyBind);\r
105                                         for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
106                                                 int nType, nKey;\r
107                                                 StringToKey(szKeyBind, nType, nKey);\r
108                                                 SaveKeyBind(appName, FuncDefs::GetName(nFuncID), nType, nKey);\r
109                                                 dwKeyBind = sizeof(szKeyBind);\r
110                                         }\r
111                                         RegCloseKey(hKey);\r
112                                 }\r
113                         }\r
114                 }\r
115         }\r
116         AfxGetApp()->WriteProfileInt(_T(""), _T("Level"), 4);\r
117 }\r
118 \r
119 void CProfile::AddKeyBind2C_(LPCTSTR appName, BYTE bVk)\r
120 {\r
121         int nComID;\r
122         for (nComID = 0; nComID < MAX_COMMAND; ++nComID)\r
123                 if (CmdTable::Command(nComID) == CCommands::C_)\r
124                         break;\r
125         SaveKeyBind(appName, nComID, NONE, bVk);\r
126 }\r
127 \r
128 void CProfile::LoadRegistry()\r
129 {\r
130         bool bDialog = false;\r
131         const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));\r
132         ZeroMemory(&m_Config, sizeof(m_Config));\r
133         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
134                 AppConfig& appConfig = m_Config.AppConfig[nAppID];\r
135                 CString entry;\r
136                 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
137                 CString appName = AfxGetApp()->GetProfileString(section, entry);\r
138                 if (appName.IsEmpty())  {\r
139                         if (nAppID) {\r
140                                 if (bDialog)\r
141                                         continue;\r
142                                 appName.LoadString(IDS_DIALOG);\r
143                                 bDialog = true;\r
144                         } else\r
145                                 appName.LoadString(IDS_DEFAULT);\r
146                 } else if (appName == CString(MAKEINTRESOURCE(IDS_DIALOG)))\r
147                         bDialog = true;\r
148                 _tcsncpy_s(appConfig.AppName, appName, _TRUNCATE);\r
149                 entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
150                 _tcsncpy_s(m_AppTitle[nAppID], AfxGetApp()->GetProfileString(appName, entry), _TRUNCATE);\r
151                 entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
152                 _tcsncpy_s(appConfig.WindowText, AfxGetApp()->GetProfileString(appName, entry, _T("*")), _TRUNCATE);\r
153 \r
154                 const CString regApp = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName;\r
155                 for (BYTE nComID = 1; nComID < MAX_COMMAND; ++nComID) {\r
156                         entry = CmdTable::Name(nComID);\r
157                         HKEY hKey;\r
158                         const CString regKey = regApp + _T("\\") + entry;\r
159                         if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
160                                 TCHAR szKeyBind[128];\r
161                                 DWORD dwKeyBind = _countof(szKeyBind);\r
162                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
163                                         int nType, nKey;\r
164                                         StringToKey(szKeyBind, nType, nKey);\r
165                                         appConfig.CmdID[nType][nKey] = nComID;\r
166                                         dwKeyBind = _countof(szKeyBind);\r
167                                 }\r
168                                 RegCloseKey(hKey);\r
169                         } else {\r
170                                 // Set the default assignment\r
171                                 for (int i = 0; i < MAX_KEY_BIND; ++i) {\r
172                                         KeyBind bind = CmdTable::Bind(nComID, i);\r
173                                         if (bind.bVk == 0)\r
174                                                 break;\r
175                                         if (bind.nControlID == IDC_CO2)\r
176                                                 continue;\r
177                                         appConfig.CmdID[bind.nType][bind.bVk] = nComID;\r
178                                 }\r
179                         }\r
180                 }\r
181                 memset(appConfig.FuncID, -1, sizeof(appConfig.FuncID));\r
182                 for (int nFuncID = 0; nFuncID < FuncDefs::GetNumOfDefs(); ++nFuncID) {\r
183                         HKEY hKey;\r
184                         CString regKey = regApp + _T("\\") + FuncDefs::GetName(nFuncID);\r
185                         if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
186                                 TCHAR szKeyBind[128];\r
187                                 DWORD dwKeyBind = _countof(szKeyBind);\r
188                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
189                                         int nType, nKey;\r
190                                         StringToKey(szKeyBind, nType, nKey);\r
191                                         appConfig.FuncID[nType][nKey] = static_cast<char>(nFuncID);\r
192                                         dwKeyBind = _countof(szKeyBind);\r
193                                 }\r
194                                 RegCloseKey(hKey);\r
195                         }\r
196                 }\r
197 \r
198                 entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
199                 int n = AfxGetApp()->GetProfileInt(appName, entry, 1);\r
200                 appConfig.KillRingMax = static_cast<BYTE>(n > 255 ? 255 : n);\r
201                 entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
202                 appConfig.SettingStyle = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0) ? SETTING_DISABLE : SETTING_SPECIFIC);\r
203                 entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
204                 appConfig.UseDialogSetting = AfxGetApp()->GetProfileInt(appName, entry, 1) != 0;\r
205                 entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
206                 appConfig.IgnoreUndefMetaCtrl = AfxGetApp()->GetProfileInt(appName, entry, 0) != 0;\r
207                 entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
208                 appConfig.IgnoreUndefC_x = AfxGetApp()->GetProfileInt(appName, entry, 0) != 0;\r
209                 entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
210                 appConfig.EnableCUA = AfxGetApp()->GetProfileInt(appName, entry, 0) != 0;\r
211                 entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
212                 appConfig.Is326Compatible = AfxGetApp()->GetProfileInt(appName, entry, 0) != 0;\r
213         }\r
214 }\r
215 \r
216 void CProfile::SaveRegistry()\r
217 {\r
218         const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));    \r
219         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
220                 const AppConfig& appConfig = m_Config.AppConfig[nAppID];\r
221                 LPCTSTR appName = appConfig.AppName;\r
222                 CString entry;\r
223                 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
224                 if (!appName[0]) {\r
225                         if (!AfxGetApp()->GetProfileString(section, entry).IsEmpty())\r
226                                 AfxGetApp()->WriteProfileString(section, entry, _T(""));\r
227                         continue;\r
228                 }\r
229                 AfxGetApp()->WriteProfileString(section, entry, appName);\r
230 \r
231                 entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
232                 CString appTitle = m_AppTitle[nAppID];\r
233                 appTitle.TrimLeft(_T(' '));\r
234                 AfxGetApp()->WriteProfileString(appName, entry, appTitle);\r
235                 entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
236                 AfxGetApp()->WriteProfileString(appName, entry, appConfig.WindowText);\r
237 \r
238                 // Create all commands\r
239                 for (int nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
240                         SaveKeyBind(appName, nComID, 0, 0);\r
241                 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)\r
242                         for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
243                                 SaveKeyBind(appName, appConfig.CmdID[nType][nKey], nType, nKey);\r
244                                 int id = appConfig.FuncID[nType][nKey];\r
245                                 if (id >= 0)\r
246                                         SaveKeyBind(appName, FuncDefs::GetName(id), nType, nKey);\r
247                         }\r
248 \r
249                 entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
250                 AfxGetApp()->WriteProfileInt(appName, entry, appConfig.KillRingMax);\r
251                 entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
252                 AfxGetApp()->WriteProfileInt(appName, entry, appConfig.UseDialogSetting);\r
253                 entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
254                 AfxGetApp()->WriteProfileInt(appName, entry, appConfig.SettingStyle == SETTING_DISABLE);\r
255                 entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
256                 AfxGetApp()->WriteProfileInt(appName, entry, appConfig.IgnoreUndefMetaCtrl);\r
257                 entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
258                 AfxGetApp()->WriteProfileInt(appName, entry, appConfig.IgnoreUndefC_x);\r
259                 entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
260                 AfxGetApp()->WriteProfileInt(appName, entry, appConfig.EnableCUA);\r
261                 entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
262                 AfxGetApp()->WriteProfileInt(appName, entry, appConfig.Is326Compatible);\r
263         }\r
264 }\r
265 \r
266 void CProfile::SetDllData()\r
267 {\r
268         memcpy(m_Config.FuncDefs, FuncDefs::GetDefs(), sizeof(m_Config.FuncDefs));\r
269         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
270                 AppConfig& appConfig = m_Config.AppConfig[nAppID];\r
271                 appConfig.CmdID[CONTROL]['X'] = 0; // C-x is unassigned.\r
272                 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)\r
273                         for (int nKey = 0; nKey < MAX_KEY; ++nKey)\r
274                                 if ((nType & CONTROLX) && (appConfig.CmdID[nType][nKey] || appConfig.FuncID[nType][nKey] >= 0))\r
275                                         appConfig.CmdID[CONTROL]['X'] = 1; // C-x is available.\r
276         }\r
277         m_Config.Is106Keyboard = Is106Keyboard();\r
278         CXkeymacsDll::SetConfig(m_Config);\r
279         CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());\r
280         if (!pApp->IsWow64())\r
281                 return;\r
282         if (!CXkeymacsDll::SaveConfig())\r
283                 return;\r
284         pApp->SendIPCMessage(XKEYMACS_RELOAD);\r
285 }\r
286 \r
287 void CProfile::SaveKeyBind(LPCTSTR appName, int comID, int type, int key)\r
288 {\r
289         if (!comID)\r
290                 return;\r
291         LPCTSTR comName = CmdTable::Name(comID);\r
292         if (!comName[0])\r
293                 return;\r
294         SaveKeyBind(appName, comName, type, key);\r
295 }\r
296 \r
297 void CProfile::SaveKeyBind(LPCTSTR appName, LPCTSTR comName, int type, int key)\r
298 {\r
299         CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName + _T("\\") + comName;\r
300         CString s = KeyToString(type, key);\r
301         if (!s.IsEmpty())\r
302                 subKey = subKey + _T("\\") + s;\r
303         HKEY hKey = NULL;\r
304         if (RegCreateKeyEx(HKEY_CURRENT_USER, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)\r
305                 RegCloseKey(hKey);\r
306 }\r
307 \r
308 void CProfile::StringToKey(LPCTSTR str, int& type, int& key)\r
309 {\r
310         m_KeyString.ToKey(str, type, key);\r
311 }\r
312 \r
313 CString CProfile::KeyToString(int type, int key)\r
314 {\r
315         return m_KeyString.ToString(type, key);\r
316 }\r
317 \r
318 void CProfile::GetAppList(TCHAR (&appTitle)[MAX_APP][WINDOW_TEXT_LENGTH], TCHAR (&appName)[MAX_APP][CLASS_NAME_LENGTH])\r
319 {\r
320         memcpy(appTitle, m_AppTitle, sizeof(m_AppTitle));\r
321         for (int i = 0; i < MAX_APP; ++i)\r
322                 memcpy(appName[i], m_Config.AppConfig[i].AppName, CLASS_NAME_LENGTH);\r
323 }\r
324 \r
325 void CProfile::ClearData(LPCTSTR appName)\r
326 {\r
327         int n = GetAppID(appName);\r
328         if (n == MAX_APP)\r
329                 return;\r
330         AppConfig& appConfig = m_Config.AppConfig[n];\r
331         ZeroMemory(appConfig.CmdID, sizeof(appConfig.CmdID));\r
332         ZeroMemory(appConfig.AppName, sizeof(appConfig.AppName));\r
333 }\r
334 \r
335 void CProfile::CopyDefault(LPCTSTR appName)\r
336 {\r
337         CopyDefault(GetAppID(appName));\r
338 }\r
339 \r
340 void CProfile::CopyDefault(int dst)\r
341 {\r
342         int src = DefaultAppID();\r
343         if (src == MAX_APP || dst == MAX_APP)\r
344                 return;\r
345         m_Config.AppConfig[dst].SettingStyle = SETTING_SPECIFIC;\r
346         size_t size = sizeof(AppConfig) - offsetof(AppConfig, CmdID);\r
347         memcpy_s(&m_Config.AppConfig[dst].CmdID, size, &m_Config.AppConfig[src].CmdID, size);\r
348 }\r
349 \r
350 int CProfile::AssignAppID(LPCTSTR appName)\r
351 {\r
352         int id = GetAppID(appName);\r
353         if (id != MAX_APP)\r
354                 return id;\r
355         for (id = 0; id < MAX_APP; ++id) {\r
356                 AppConfig& appConfig = m_Config.AppConfig[id];\r
357                 if (!appConfig.AppName[0]) {\r
358                         _tcsncpy_s(appConfig.AppName, appName, _TRUNCATE);\r
359                         CopyDefault(id);\r
360                         return id;\r
361                 }\r
362         }\r
363         return id;\r
364 }\r
365 \r
366 int CProfile::DefaultAppID()\r
367 {\r
368         const CString name(MAKEINTRESOURCE(IDS_DEFAULT));\r
369         for(int nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
370                 if (name == m_Config.AppConfig[nAppID].AppName)\r
371                         return nAppID;\r
372         return MAX_APP;\r
373 }\r
374 \r
375 int CProfile::GetAppID(LPCTSTR appName)\r
376 {\r
377         int nAppID = 0;\r
378         for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
379                 if (!_tcscmp(appName, m_Config.AppConfig[nAppID].AppName))\r
380                         break;\r
381         return nAppID;\r
382 }\r
383 \r
384 int CProfile::GetSettingStyle(int nAppID)\r
385 {\r
386         if (nAppID == MAX_APP)\r
387                 return SETTING_DEFAULT;\r
388         return m_Config.AppConfig[nAppID].SettingStyle;\r
389 }\r
390 \r
391 void CProfile::SetSettingStyle(int nAppID, int nSettingStyle)\r
392 {\r
393         if (nAppID == MAX_APP)\r
394                 return;\r
395         m_Config.AppConfig[nAppID].SettingStyle = static_cast<BYTE>(nSettingStyle);\r
396 }\r
397 \r
398 void CProfile::SetAppTitle(int nAppID, const CString& appTitle)\r
399 {\r
400         _tcsncpy_s(m_AppTitle[nAppID], appTitle, _TRUNCATE);\r
401 }\r
402 \r
403 int CProfile::GetCmdID(int nAppID, int nType, int nKey)\r
404 {\r
405         int nComID = m_Config.AppConfig[nAppID].CmdID[nType][nKey];\r
406         if (nKey == 0xf0 && CmdTable::Command(nComID) == CCommands::C_Eisu)\r
407                 // Change CommandID C_\r
408                 for (nComID = 1; nComID < MAX_COMMAND; nComID++)\r
409                         if (CmdTable::Command(nComID) == CCommands::C_)\r
410                                 break;\r
411         return nComID;\r
412 }\r
413 \r
414 void CProfile::SetCmdID(int nAppID, int nType, int nKey, int nComID)\r
415 {\r
416         if (nKey == 0xf0 && CmdTable::Command(nComID) == CCommands::C_)\r
417                 // Change CommandID C_Eisu\r
418                 for (nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
419                         if (CmdTable::Command(nComID) == CCommands::C_Eisu)\r
420                                 break;\r
421         m_Config.AppConfig[nAppID].CmdID[nType][nKey] = static_cast<BYTE>(nComID);\r
422 }\r
423 \r
424 int CProfile::GetFuncID(int nAppID, int nType, int nKey)\r
425 {\r
426         return m_Config.AppConfig[nAppID].FuncID[nType][nKey];\r
427 }\r
428 \r
429 void CProfile::SetFuncID(int nAppID, int nType, int nKey, int nFuncID)\r
430 {\r
431         m_Config.AppConfig[nAppID].FuncID[nType][nKey] = static_cast<BYTE>(nFuncID);\r
432 }\r
433 \r
434 bool CProfile::GetUseDialogSetting(int nAppID)\r
435 {\r
436         return m_Config.AppConfig[nAppID].UseDialogSetting;\r
437 }\r
438 \r
439 void CProfile::SetUseDialogSetting(int nAppID, bool setting)\r
440 {\r
441         m_Config.AppConfig[nAppID].UseDialogSetting = setting;\r
442 }\r
443 \r
444 bool CProfile::GetEnableCUA(int nAppID)\r
445 {\r
446         return m_Config.AppConfig[nAppID].EnableCUA;\r
447 }\r
448 \r
449 void CProfile::SetEnableCUA(int nAppID, bool bEnableCUA)\r
450 {\r
451         m_Config.AppConfig[nAppID].EnableCUA = static_cast<BYTE>(bEnableCUA);\r
452 }\r
453 \r
454 int CProfile::GetKillRingMax(int nAppID)\r
455 {\r
456         return m_Config.AppConfig[nAppID].KillRingMax;\r
457 }\r
458 \r
459 void CProfile::SetKillRingMax(int nAppID, int nKillRingMax)\r
460 {\r
461         m_Config.AppConfig[nAppID].KillRingMax = static_cast<BYTE>(nKillRingMax > 255 ? 255 : nKillRingMax);\r
462 }\r
463 \r
464 LPCTSTR CProfile::GetWindowText(int nAppID)\r
465 {\r
466         return m_Config.AppConfig[nAppID].WindowText;\r
467 }\r
468 \r
469 void CProfile::SetWindowText(int nAppID, const CString& text)\r
470 {\r
471         _tcsncpy_s(m_Config.AppConfig[nAppID].WindowText,\r
472                 CUtils::GetWindowTextType(text) == IDS_WINDOW_TEXT_IGNORE ? _T("*") : text, _TRUNCATE);\r
473 }\r
474 \r
475 bool CProfile::Is106Keyboard()\r
476 {\r
477         static KEYBOARD_TYPE keyboard = UNKNOWN_KEYBOARD;\r
478 \r
479         if (keyboard == UNKNOWN_KEYBOARD) {\r
480                 OSVERSIONINFO verInfo = {0};\r
481                 verInfo.dwOSVersionInfoSize = sizeof (verInfo);\r
482                 GetVersionEx(&verInfo);\r
483 \r
484                 DWORD subtype = 0;\r
485                 DWORD cbData = sizeof(subtype);\r
486 \r
487                 if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {\r
488                         HKEY hKey = NULL;\r
489                         const CString szSubKey(_T("SYSTEM\\CurrentControlSet\\Services\\i8042prt\\Parameters"));\r
490                         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
491                                 static const CString szValueName(_T("OverrideKeyboardSubtype"));\r
492                                 if (RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE)&subtype, &cbData) != ERROR_SUCCESS) {\r
493                                         subtype = 0;\r
494                                 }\r
495                                 RegCloseKey(hKey);\r
496                         }\r
497                 } else if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {\r
498                         subtype = GetPrivateProfileInt(_T("keyboard"), _T("subtype"), 0, _T("system.ini"));\r
499                 }\r
500 \r
501                 keyboard = (subtype & 0x02) ? JAPANESE_KEYBOARD : ENGLISH_KEYBOARD;\r
502         }\r
503 \r
504         return keyboard == JAPANESE_KEYBOARD;\r
505 }\r
506 \r
507 BOOL CProfile::IsVistaOrLater()\r
508 {\r
509         OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};\r
510         GetVersionEx(&info);\r
511 \r
512         if (6 <= info.dwMajorVersion) {\r
513                 return TRUE;\r
514         }\r
515         return FALSE;\r
516 }\r
517 \r
518 void CProfile::RestartComputer()\r
519 {\r
520         if (!AdjustTokenPrivileges(SE_SHUTDOWN_NAME)) {\r
521                 return;\r
522         }\r
523 \r
524         ExitWindowsEx(EWX_REBOOT, 0);\r
525 }\r
526 \r
527 void CProfile::ImportProperties()\r
528 {\r
529         if (!AdjustTokenPrivileges(SE_RESTORE_NAME)) {\r
530                 return;\r
531         }\r
532 \r
533         CFileDialog oFileOpenDialog(TRUE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
534         if (oFileOpenDialog.DoModal() == IDOK) {\r
535                 CString szCommandLine;\r
536                 szCommandLine.Format(_T("regedit \"%s\""), oFileOpenDialog.GetPathName());\r
537                 CUtils::Run(szCommandLine, TRUE);       // regedit "x:\xkeymacs.reg"\r
538         }\r
539 \r
540         DiableTokenPrivileges();\r
541         return;\r
542 }\r
543 \r
544 void CProfile::ExportProperties()\r
545 {\r
546         if (!AdjustTokenPrivileges(SE_BACKUP_NAME)) {\r
547                 return;\r
548         }\r
549 \r
550         CFileDialog oFileOpenDialog(FALSE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
551         if (oFileOpenDialog.DoModal() == IDOK) {\r
552                 CString szCommandLine;\r
553                 szCommandLine.Format(_T("regedit /e \"%s\" HKEY_CURRENT_USER\\%s"), oFileOpenDialog.GetPathName(), CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)));\r
554                 CUtils::Run(szCommandLine, TRUE);       // regedit /e "x:\xkeymacs.reg" HKEY_CURRENT_USER\Software\Oishi\XKeymacs2\r
555         }\r
556 \r
557         DiableTokenPrivileges();\r
558         return;\r
559 }\r
560 \r
561 BOOL CProfile::AdjustTokenPrivileges(LPCTSTR lpName)\r
562 {\r
563         BOOL rc = TRUE;\r
564 \r
565         HANDLE hToken;\r
566         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
567                 LUID luid;\r
568                 if (LookupPrivilegeValue(NULL, lpName, &luid)) {\r
569                         TOKEN_PRIVILEGES tp;\r
570                         tp.PrivilegeCount = 1;\r
571                         tp.Privileges[0].Luid = luid;\r
572                         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\r
573 \r
574                         if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {\r
575                                 rc = FALSE;\r
576                         }\r
577                 } else {\r
578                         rc = FALSE;\r
579                 }\r
580                 CloseHandle(hToken);\r
581         } else {\r
582                 rc = FALSE;\r
583         }\r
584 \r
585         return rc;\r
586 }\r
587 \r
588 BOOL CProfile::DiableTokenPrivileges()\r
589 {\r
590         BOOL rc = TRUE;\r
591 \r
592         HANDLE hToken;\r
593         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
594                 if (!::AdjustTokenPrivileges(hToken, TRUE, NULL, NULL, NULL, NULL)) {\r
595                         rc = FALSE;\r
596                 }\r
597                 CloseHandle(hToken);\r
598         } else {\r
599                 rc = FALSE;\r
600         }\r
601 \r
602         return rc;\r
603 }\r
604 \r
605 int CProfile::GetKeyboardSpeed()\r
606 {\r
607         int nKeyboardSpeed = 31; // default value of Windows\r
608         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_KEYBOARD));\r
609         CString szValueName(MAKEINTRESOURCE(IDS_KEYBOARD_SPEED));\r
610 \r
611         HKEY hKey = NULL;\r
612         if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
613                 // get data size\r
614                 DWORD dwType = REG_SZ;\r
615                 BYTE data[4] = {0};\r
616                 DWORD dwcbData = sizeof(data)/sizeof(data[0]);\r
617                 RegQueryValueEx(hKey, szValueName, NULL, &dwType, (LPBYTE)&data, &dwcbData);\r
618                 RegCloseKey(hKey);\r
619 \r
620                 for (DWORD i = 0; i < dwcbData; ++i) {\r
621                         if (data[i]) {\r
622                                 if (i) {\r
623                                         nKeyboardSpeed = nKeyboardSpeed * 10 + data[i] - _T('0');\r
624                                 } else {\r
625                                         nKeyboardSpeed = data[i] - _T('0');\r
626                                 }\r
627                         } else {\r
628                                 break;\r
629                         }\r
630                 }\r
631         }\r
632 \r
633         return nKeyboardSpeed;\r
634 }\r