OSDN Git Service

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