OSDN Git Service

Remove typedef of KeyBind_t, KbdMacro_t, Modifier_t, and KeyName_t
[xkeymacs/xkeymacs.git] / xkeymacs / profile.cpp
1 // Profile.cpp: implementation of the CProfile class\r
2 //\r
3 //////////////////////////////////////////////////////////////////////\r
4 \r
5 #include "stdafx.h"\r
6 #include "xkeymacs.h"\r
7 #include "Profile.h"\r
8 #include "MainFrm.h"\r
9 #include "DotXkeymacs.h"\r
10 #include <Imm.h>\r
11 #include <Shlwapi.h>    // Windows NT/2000: Requires Windows 2000 (or Windows NT 4.0 with Internet Explorer 4.0 or later). \r
12                                                 // Windows 95/98/Me: Requires Windows 98 (or Windows 95 with Internet Explorer 4.0 or later). \r
13 \r
14 #ifdef _DEBUG\r
15 #undef THIS_FILE\r
16 static char THIS_FILE[]=__FILE__;\r
17 #define new DEBUG_NEW\r
18 #endif\r
19 \r
20 \r
21 CXkeymacsData CProfile::m_XkeymacsData[MAX_APP];\r
22 TASK_LIST CProfile::m_TaskList[MAX_TASKS];\r
23 DWORD CProfile::m_dwTasks;\r
24 ScanCode CProfile::m_CurrentScanCodeMap[MAX_HKEY_TYPE][4][256];\r
25 ScanCode CProfile::m_ScanCodeMap[MAX_HKEY_TYPE][4][256];\r
26 \r
27 enum { INITIAL_SIZE     = 51200 };\r
28 enum { EXTEND_SIZE      = 25600 };\r
29 \r
30 void CProfile::Item2AppName(CString *const sz)\r
31 {\r
32         if (IsTheString(*sz, IDS_DEFAULT_TITLE)) {\r
33                 sz->LoadString(IDS_DEFAULT);\r
34         }\r
35 \r
36         if (IsTheString(*sz, IDS_DIALOG_TITLE)) {\r
37                 sz->LoadString(IDS_DIALOG);\r
38         }\r
39 \r
40         int nStart, nEnd, nCount;\r
41 \r
42         nStart  = sz->ReverseFind(_T('(')) + 1;\r
43         nEnd    = sz->Find(_T(')'), nStart) - 1;\r
44         nCount  = (nEnd + 1) - nStart;\r
45         *sz             = sz->Mid(nStart, nCount);\r
46 }\r
47 \r
48 int CProfile::IsNotSameString(CComboBox *const pApplication, const CString szListItem)\r
49 {\r
50         CString szItem, szList;\r
51         szList = szListItem;\r
52         Item2AppName(&szList);\r
53 \r
54         for (int i = 0; i < pApplication->GetCount(); ++i) {\r
55                 pApplication->GetLBText(i, szItem);\r
56                 Item2AppName(&szItem);\r
57                 if (!_tcsicmp(szItem, szList)) {\r
58                         return 0;\r
59                 }\r
60         }\r
61 \r
62         return 1;\r
63 }\r
64 \r
65 int CProfile::CountSeparator(const CString szMainString, const CString szSeparator)\r
66 {\r
67         int index       = 0;\r
68         int counter     = 0;\r
69 \r
70         while ((index = szMainString.Find(szSeparator, index)) != -1) {\r
71                 ++index;\r
72                 ++counter;\r
73         }\r
74 \r
75         return counter;\r
76 }\r
77 \r
78 void CProfile::GetNthString(CString *const szAppName, const CString szWindowName, const CString szSeparator, int n)\r
79 {\r
80         int index = -1;\r
81 \r
82         while (--n) {\r
83                 index = szWindowName.Find(szSeparator, index + 1);\r
84         }\r
85 \r
86         int nStart;\r
87         if (index != -1) {\r
88                 nStart = index + szSeparator.GetLength();\r
89         } else {\r
90                 nStart = 0;\r
91         }\r
92 \r
93         int nEnd = szWindowName.Find(szSeparator, nStart);\r
94         if (nEnd == -1) {\r
95                 nEnd = szWindowName.GetLength();\r
96         }\r
97 \r
98         *szAppName = szWindowName.Mid(nStart, nEnd - nStart);\r
99 }\r
100 \r
101 void CProfile::GetAppName(CString *const szAppName, LPCTSTR pWindowName)\r
102 {\r
103         CString szWindowName(pWindowName);\r
104         CString szSeparator(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE));\r
105         int nWord = CountSeparator(szWindowName, szSeparator) + 1;\r
106 \r
107         while (nWord) {\r
108                 GetNthString(szAppName, szWindowName, szSeparator, nWord);\r
109                 if (szAppName->GetAt(0) == _T('[')\r
110                  || szAppName->Find(_T('.'), 0) != -1           // for Microsoft Project\r
111                  || szAppName->Find(_T(']'), 0) != -1) {        // for the file name like [foo - bar]\r
112                         --nWord;\r
113                 } else {\r
114                         return;\r
115                 }\r
116         }\r
117 \r
118         *szAppName = szWindowName;\r
119 }\r
120 \r
121 BOOL CALLBACK CProfile::EnumWindowsProc(const HWND hWnd, const LPARAM lParam)\r
122 {\r
123         CComboBox               *pApplication   = (CComboBox*)lParam;\r
124         PTASK_LIST              pTask                   = CProfile::m_TaskList;\r
125         \r
126         TCHAR szWindowName[WINDOW_NAME_LENGTH];\r
127         TCHAR szClassName[CLASS_NAME_LENGTH];\r
128         WINDOWPLACEMENT wpl;\r
129         \r
130         wpl.length = sizeof(WINDOWPLACEMENT);\r
131         ::GetWindowText(hWnd, szWindowName, sizeof(szWindowName));\r
132         GetClassName(hWnd, szClassName, sizeof(szClassName));\r
133 \r
134         CString szAppName;\r
135         // Get Process Name\r
136         DWORD dwProcessId = 0;\r
137         GetWindowThreadProcessId(hWnd, &dwProcessId);\r
138         for (DWORD i = 0; i < CProfile::m_dwTasks; ++i) {\r
139                 if (pTask[i].dwProcessId == dwProcessId) {\r
140 \r
141                         // Get Application Name\r
142                         if (szWindowName[0] == '\0') {\r
143                                 continue;\r
144                         }\r
145                         if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_B2)), sizeof(pTask[i].ProcessName))) {\r
146                                 szAppName.LoadString(IDS_BECKY);\r
147                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXPLORER)), sizeof(pTask[i].ProcessName))) {\r
148                                 szAppName.LoadString(IDS_PROGRAM_MANAGER);\r
149                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSIMN)), sizeof(pTask[i].ProcessName))) {\r
150                                 szAppName.LoadString(IDS_OUTLOOK_EXPRESS);\r
151                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_PROJECT)), sizeof(pTask[i].ProcessName))\r
152                                         || !_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXCEL)), sizeof(pTask[i].ProcessName))\r
153                                         || !_tcsnicmp(pTask[i].ProcessName, _T("psp.exe"), sizeof(pTask[i].ProcessName))) {\r
154                                 GetNthString(&szAppName, szWindowName, CString(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE)), 1);\r
155                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sakura.exe"), sizeof(pTask[i].ProcessName))) {\r
156                                 GetNthString(&szAppName, szWindowName, CString(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE)), 2);  // '.' is included, so...\r
157                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSDN)), sizeof(pTask[i].ProcessName))) {\r
158                                 szAppName = szWindowName;\r
159                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("devenv.exe"), sizeof(pTask[i].ProcessName))) {\r
160                                 szAppName.Format(_T("Microsoft Visual Studio .NET"));\r
161                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vb6.exe"), sizeof(pTask[i].ProcessName))) {\r
162                                 szAppName.Format(_T("Microsoft Visual Basic"));\r
163                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("ssexp.exe"), sizeof(pTask[i].ProcessName))) {\r
164                                 szAppName.LoadString(IDS_VISUAL_SOURCESAFE_EXPLORER);\r
165                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sh.exe"), sizeof(pTask[i].ProcessName))) {\r
166                                 szAppName.Format(_T("MKS Korn Shell"));\r
167                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("csh.exe"), sizeof(pTask[i].ProcessName))) {\r
168                                 szAppName.Format(_T("C Shell"));\r
169                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vim.exe"), sizeof(pTask[i].ProcessName))) {\r
170                                 szAppName.Format(_T("VIM"));\r
171                         } else {\r
172                                 CUtils::SetCorrectApplicationName(pTask[i].ProcessName, sizeof(pTask[i].ProcessName), szWindowName, sizeof(szWindowName));\r
173                                 GetAppName(&szAppName, szWindowName);\r
174                         }\r
175                         break;\r
176                 }\r
177         }\r
178         \r
179         \r
180         if ((IsWindowVisible(hWnd))                                                                     // Is visible?\r
181          && (GetWindow(hWnd, GW_OWNER) == NULL)                                         // Is top level window?\r
182          && (lstrlen(szWindowName) > 0)                                                         // Have caption?\r
183          && (pApplication->FindString(-1, szClassName) == CB_ERR)) {// Is not same string?\r
184                 CString szListItem;\r
185                 szListItem.Format(IDS_APPLICATION_LIST_ITEM, szAppName, pTask[i].ProcessName);\r
186                 if (IsNotSameString(pApplication, szListItem)) {\r
187                         pApplication->AddString(szListItem);\r
188                 }\r
189         }\r
190         return TRUE;\r
191 }\r
192         \r
193 //////////////////////////////////////////////////////////////////////\r
194 // Construction/Destruction\r
195 //////////////////////////////////////////////////////////////////////\r
196 \r
197 CProfile::CProfile()\r
198 {\r
199 \r
200 }\r
201 \r
202 CProfile::~CProfile()\r
203 {\r
204 \r
205 }\r
206 \r
207 // This method initializes data in the registry, or retrieves and validates registry data.\r
208 // bSaveAndValidate specifies a flag that indicates \r
209 // whether registry data is being initialized (FALSE) or data is being retrieved (TRUE). \r
210 void CProfile::UpdateRegistryData(const BOOL bSaveAndValidate)\r
211 {\r
212         CString szEntry;\r
213         CString szApplicationName;\r
214         CString szApplicationTitle;\r
215         CString szWindowText;\r
216         CString szWindowTextType;\r
217 \r
218         BOOL bUseDialogSetting = FALSE;\r
219 \r
220         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
221                 // application name\r
222                 CString szSection(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));\r
223                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
224                 if (bSaveAndValidate) { // retrieve\r
225                         m_XkeymacsData[nApplicationID].ClearAll();\r
226                         szApplicationName = AfxGetApp()->GetProfileString(szSection, szEntry);\r
227                         if (szApplicationName.IsEmpty()) {\r
228                                 if (nApplicationID) {\r
229                                         if (!bUseDialogSetting) {\r
230                                                 szApplicationName.LoadString(IDS_DIALOG);\r
231                                                 bUseDialogSetting = TRUE;\r
232                                         } else {\r
233                                                 continue;\r
234                                         }\r
235                                 } else {\r
236                                         szApplicationName.LoadString(IDS_DEFAULT);\r
237                                 }\r
238                         } else {\r
239                                 if (szApplicationName == CString(MAKEINTRESOURCE(IDS_DIALOG))) {\r
240                                         bUseDialogSetting = TRUE;\r
241                                 }\r
242                         }\r
243                         m_XkeymacsData[nApplicationID].SetApplicationName(szApplicationName);\r
244                 } else {                                // initialize\r
245                         szApplicationName = m_XkeymacsData[nApplicationID].GetApplicationName();\r
246                         if (szApplicationName.IsEmpty()) {\r
247                                 continue;\r
248                         }\r
249                         AfxGetApp()->WriteProfileString(szSection, szEntry, szApplicationName);\r
250                 }\r
251 \r
252                 // application title\r
253                 szEntry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
254                 if (bSaveAndValidate) { // retrieve\r
255                         szApplicationTitle = AfxGetApp()->GetProfileString(szApplicationName, szEntry);\r
256                         m_XkeymacsData[nApplicationID].SetApplicationTitle(szApplicationTitle);\r
257                 } else {                                // initialize\r
258                         szApplicationTitle = m_XkeymacsData[nApplicationID].GetApplicationTitle();\r
259                         while (!szApplicationTitle.IsEmpty() && szApplicationTitle.GetAt(0) == _T(' ')) {\r
260                                 szApplicationTitle.Delete(0);\r
261                         }\r
262                         AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szApplicationTitle);\r
263                 }\r
264 \r
265                 // window text\r
266                 szEntry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
267                 if (bSaveAndValidate) { // retrieve\r
268                         szWindowText = AfxGetApp()->GetProfileString(szApplicationName, szEntry, _T("*"));\r
269                         if (szWindowText.IsEmpty()) {\r
270                                 szWindowText = _T('*');\r
271                         }\r
272                         m_XkeymacsData[nApplicationID].SetWindowText(szWindowText);\r
273                 } else {                                // initialize\r
274                         szWindowText = m_XkeymacsData[nApplicationID].GetWindowText();\r
275                         AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szWindowText);\r
276                 }\r
277 \r
278                 // window text type\r
279                 szEntry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT_TYPE);\r
280                 if (bSaveAndValidate) { // retrieve\r
281                         szWindowTextType = AfxGetApp()->GetProfileString(szApplicationName, szEntry);\r
282 \r
283                         int nWindowTextType = IDS_WINDOW_TEXT_IGNORE;\r
284                         if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH))) {\r
285                                 nWindowTextType = IDS_WINDOW_TEXT_MATCH;\r
286                         } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_FORWARD))) {\r
287                                 nWindowTextType = IDS_WINDOW_TEXT_MATCH_FORWARD;\r
288                         } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_BACKWARD))) {\r
289                                 nWindowTextType = IDS_WINDOW_TEXT_MATCH_BACKWARD;\r
290                         } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_FULL))) {\r
291                                 nWindowTextType = IDS_WINDOW_TEXT_MATCH_FULL;\r
292                         }\r
293 \r
294                         m_XkeymacsData[nApplicationID].SetWindowTextType(nWindowTextType);\r
295                 } else {                                // initialize\r
296                         szWindowTextType.LoadString(m_XkeymacsData[nApplicationID].GetWindowTextType());\r
297                         AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szWindowTextType);\r
298                 }\r
299 \r
300                 // on/off\r
301                 if (bSaveAndValidate) { // retrieve\r
302                         for (int nCommandID = 1; nCommandID < sizeof(Commands) / sizeof(Commands[0]); ++nCommandID) {\r
303                                 szEntry = CXkeymacsData::GetCommandName(nCommandID);\r
304                                 if (szEntry.IsEmpty()) {\r
305                                         break;\r
306                                 }\r
307 \r
308                                 HKEY hKey = NULL;\r
309                                 CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
310                                 szSubKey += _T("\\") + szApplicationName + _T("\\") + szEntry;\r
311                                 if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
312                                         // Use registry data\r
313                                         TCHAR szKeyBind[128] = {'\0'};\r
314                                         DWORD dwKeyBind = sizeof(szKeyBind);\r
315                                         FILETIME ft = {'\0'};   // not use\r
316                                         for (DWORD dwIndex = 0;\r
317                                                  RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS;\r
318                                                  ++dwIndex) {\r
319                                                 int nCommandType = 0;\r
320                                                 int nKey = 0;\r
321                                                 ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
322                                                 m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
323 \r
324 //                                              if (nCommandType == CONTROL && nKey == 'D') {\r
325 //                                                      CUtils::Log("GetProfileInt(at ibeam cursor only): %s, %s", szSubKey, szKeyBind);\r
326 //                                              }\r
327                                                 const CString szSection = szSubKey.Right(szSubKey.GetLength() - CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)).GetLength() - _tcslen(_T("\\"))) + _T("\\") + szKeyBind;\r
328                                                 const BOOL bAtIbeamCursorOnly = AfxGetApp()->GetProfileInt(szSection, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_AT_IBEAM_CURSOR_ONLY)), FALSE);\r
329                                                 m_XkeymacsData[nApplicationID].SetAtIbeamCursorOnly(nCommandType, nKey, bAtIbeamCursorOnly);\r
330 \r
331                                                 memset(szKeyBind, 0, sizeof(szKeyBind));\r
332                                                 dwKeyBind = sizeof(szKeyBind);\r
333                                         }\r
334                                         RegCloseKey(hKey);\r
335                                 } else {\r
336                                         // Use default setting\r
337                                         for (int i = 0; ; ++i) {\r
338                                                 if (CXkeymacsData::GetDefaultControlID(nCommandID, i) == IDC_CO2) {\r
339                                                         continue;\r
340                                                 }\r
341 \r
342                                                 int nCommandType = CXkeymacsData::GetDefaultCommandType(nCommandID, i);\r
343                                                 int nKey = CXkeymacsData::GetDefaultCommandKey(nCommandID, i);\r
344                                                 if (nKey == 0) {\r
345                                                         break;\r
346                                                 }\r
347                                                 m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
348                                                 m_XkeymacsData[nApplicationID].SetAtIbeamCursorOnly(nCommandType, nKey, FALSE);\r
349                                         }\r
350                                 }\r
351                         }\r
352                         for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
353                                 HKEY hKey = NULL;\r
354                                 CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
355                                 szSubKey += _T("\\") + szApplicationName + _T("\\") + CDotXkeymacs::GetFunctionSymbol(nFunctionID);\r
356                                 if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
357                                         // Use registry data\r
358                                         CDotXkeymacs::ClearKey(nFunctionID, nApplicationID);\r
359                                         TCHAR szKeyBind[128] = {'\0'};\r
360                                         DWORD dwKeyBind = sizeof(szKeyBind);\r
361                                         FILETIME ft = {'\0'};   // not use\r
362                                         for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS; ++dwIndex) {\r
363                                                 int nCommandType = 0;\r
364                                                 int nKey = 0;\r
365                                                 ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
366                                                 CDotXkeymacs::SetKey(nFunctionID, nApplicationID, nCommandType, nKey);\r
367 \r
368                                                 memset(szKeyBind, 0, sizeof(szKeyBind));\r
369                                                 dwKeyBind = sizeof(szKeyBind);\r
370                                         }\r
371                                         RegCloseKey(hKey);\r
372                                 }\r
373                         }\r
374                 } else {                                // initialize\r
375                         // create all commands\r
376                         for (int nCommandID = 1; nCommandID < sizeof(Commands) / sizeof(Commands[0]); ++nCommandID) {\r
377                                 szEntry = CXkeymacsData::GetCommandName(nCommandID);\r
378                                 if (szEntry.IsEmpty()) {\r
379                                         break;\r
380                                 }\r
381 \r
382                                 SaveCommand(szApplicationName, nCommandID);\r
383                         }\r
384                         for (int nCommandType = 0; nCommandType < MAX_COMMAND_TYPE; ++nCommandType) {\r
385                                 for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
386                                         int nCommandID = m_XkeymacsData[nApplicationID].GetCommandID(nCommandType, nKey);\r
387                                         SaveKeyBind(szApplicationName, nCommandID, nCommandType, nKey);\r
388                                 }\r
389                         }\r
390                         for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
391                                 for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFunctionID, nApplicationID); ++nKeyID) {\r
392                                         int nCommandType = 0;\r
393                                         int nKey = 0;\r
394                                         CDotXkeymacs::GetKey(nFunctionID, nApplicationID, nKeyID, &nCommandType, &nKey);\r
395                                         SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFunctionID), nCommandType, nKey);\r
396                                 }\r
397                         }\r
398                 }\r
399 \r
400                 // kill-ring-max\r
401                 szEntry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
402                 if (bSaveAndValidate) { // retrieve\r
403                         int nKillRingMax = AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 1);\r
404                         m_XkeymacsData[nApplicationID].SetKillRingMax(nKillRingMax);\r
405                 } else {                                // initialize\r
406                         int nKillRingMax = m_XkeymacsData[nApplicationID].GetKillRingMax();\r
407                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, nKillRingMax);\r
408                 }\r
409 \r
410                 // Use Dialog Setting\r
411                 szEntry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
412                 if (bSaveAndValidate) { // retrieve\r
413                         BOOL bUseDialogSetting = AfxGetApp()->GetProfileInt(szApplicationName,szEntry, 1);\r
414                         m_XkeymacsData[nApplicationID].SetUseDialogSetting(bUseDialogSetting);\r
415                 } else {                                // initialize\r
416                         BOOL bUseDialogSetting = m_XkeymacsData[nApplicationID].GetUseDialogSetting();\r
417                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, bUseDialogSetting);\r
418                 }\r
419 \r
420                 // Setting Style\r
421                 szEntry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
422                 if (bSaveAndValidate) { // retrieve\r
423                         int nSettingStyle = SETTING_SPECIFIC;\r
424                         if (AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0) != 0) {\r
425                                 nSettingStyle = SETTING_DISABLE;\r
426                         }\r
427                         m_XkeymacsData[nApplicationID].SetSettingStyle(nSettingStyle);\r
428                 } else {                                // initialize\r
429                         BOOL bDisableXkeymacs = FALSE;\r
430                         if (m_XkeymacsData[nApplicationID].GetSettingStyle() == SETTING_DISABLE) {\r
431                                 bDisableXkeymacs = TRUE;\r
432                         }\r
433                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, bDisableXkeymacs);\r
434                 }\r
435 \r
436                 // Ignore Meta Ctrl+? when it is undefined.\r
437                 szEntry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
438                 if (bSaveAndValidate) { // retrieve\r
439                         m_XkeymacsData[nApplicationID].SetIgnoreUndefinedMetaCtrl(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
440                 } else {                                // initialize\r
441                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_XkeymacsData[nApplicationID].GetIgnoreUndefinedMetaCtrl());\r
442                 }\r
443 \r
444                 // Ignore C-x ? when it is undefined.\r
445                 szEntry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
446                 if (bSaveAndValidate) { // retrieve\r
447                         m_XkeymacsData[nApplicationID].SetIgnoreUndefinedC_x(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
448                 } else {                                // initialize\r
449                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_XkeymacsData[nApplicationID].GetIgnoreUndefinedC_x());\r
450                 }\r
451 \r
452                 // Enable CUA-mode\r
453                 szEntry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
454                 if (bSaveAndValidate) { // retrieve\r
455                         m_XkeymacsData[nApplicationID].SetEnableCUA(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
456                 } else {                                // initialize\r
457                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_XkeymacsData[nApplicationID].GetEnableCUA());\r
458                 }\r
459 \r
460                 // Version 3.26 compatible mode\r
461                 szEntry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
462                 if (bSaveAndValidate) { // retrieve\r
463                         m_XkeymacsData[nApplicationID].Set326Compatible(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
464                 } else {                                // initialize\r
465                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_XkeymacsData[nApplicationID].Get326Compatible());\r
466                 }\r
467         }\r
468 }\r
469 \r
470 void CProfile::LoadRegistryData()\r
471 {\r
472         CDotXkeymacs::Load();\r
473         LevelUp();\r
474         UpdateRegistryData(TRUE);\r
475 }\r
476 \r
477 void CProfile::SaveRegistryData()\r
478 {\r
479         DeleteAllRegistryData();\r
480         UpdateRegistryData(FALSE);\r
481         SetDllData();\r
482 }\r
483 \r
484 void CProfile::SetDllData()\r
485 {\r
486         CMainFrame *pMainFrame = (CMainFrame*)AfxGetMainWnd();\r
487 \r
488         pMainFrame->m_pXkeymacsDll->ClearFunctionDefinition();\r
489         for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
490                 pMainFrame->m_pXkeymacsDll->SetFunctionDefinition(nFunctionID, CDotXkeymacs::GetFunctionDefinition(nFunctionID));\r
491         }\r
492 \r
493         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
494 \r
495                 CString szApplicationName = m_XkeymacsData[nApplicationID].GetApplicationName();\r
496 \r
497                 if (szApplicationName.IsEmpty()) {\r
498                         pMainFrame->m_pXkeymacsDll->Clear(nApplicationID);\r
499                         continue;\r
500                 }\r
501 \r
502                 pMainFrame->m_pXkeymacsDll->SetApplicationName(nApplicationID, szApplicationName);\r
503                 pMainFrame->m_pXkeymacsDll->SetWindowText(nApplicationID, m_XkeymacsData[nApplicationID].GetWindowText());\r
504                 pMainFrame->m_pXkeymacsDll->SetCommandID(nApplicationID, CONTROL, 'X', 0);\r
505                 pMainFrame->m_pXkeymacsDll->SetAtIbeamCursorOnly(nApplicationID, CONTROL, 'X', FALSE);\r
506 \r
507                 for (int nCommandType = 0; nCommandType < MAX_COMMAND_TYPE; ++nCommandType) {\r
508                         for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
509                                 const int nCommandID = m_XkeymacsData[nApplicationID].GetCommandID(nCommandType, nKey);\r
510                                 pMainFrame->m_pXkeymacsDll->SetCommandID(nApplicationID, nCommandType, nKey, nCommandID);\r
511                                 const BOOL bAtIbeamCursorOnly = m_XkeymacsData[nApplicationID].GetAtIbeamCursorOnly(nCommandType, nKey);\r
512                                 pMainFrame->m_pXkeymacsDll->SetAtIbeamCursorOnly(nApplicationID, nCommandType, nKey, bAtIbeamCursorOnly);\r
513                                 if ((nCommandType & CONTROLX) && nCommandID) {\r
514                                         pMainFrame->m_pXkeymacsDll->SetCommandID(nApplicationID, CONTROL, 'X', 1);                      // Commands[1] is C-x\r
515                                         pMainFrame->m_pXkeymacsDll->SetAtIbeamCursorOnly(nApplicationID, CONTROL, 'X', bAtIbeamCursorOnly);\r
516                                 }\r
517                         }\r
518                 }\r
519 \r
520                 for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
521                         for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFunctionID, nApplicationID); ++nKeyID) {\r
522                                 int nCommandType = 0;\r
523                                 int nKey = 0;\r
524                                 CDotXkeymacs::GetKey(nFunctionID, nApplicationID, nKeyID, &nCommandType, &nKey);\r
525                                 pMainFrame->m_pXkeymacsDll->SetFunctionKey(nFunctionID, nApplicationID, nCommandType, nKey);\r
526                                 if (nCommandType & CONTROLX) {\r
527                                         pMainFrame->m_pXkeymacsDll->SetCommandID(nApplicationID, CONTROL, 'X', 1);                      // Commands[1] is C-x\r
528                                         const BOOL bAtIbeamCursorOnly = m_XkeymacsData[nApplicationID].GetAtIbeamCursorOnly(nCommandType, nKey);\r
529                                         pMainFrame->m_pXkeymacsDll->SetAtIbeamCursorOnly(nApplicationID, CONTROL, 'X', bAtIbeamCursorOnly);\r
530                                 }\r
531                         }\r
532                 }\r
533 \r
534                 pMainFrame->m_pXkeymacsDll->SetKillRingMax(nApplicationID, m_XkeymacsData[nApplicationID].GetKillRingMax());\r
535                 pMainFrame->m_pXkeymacsDll->SetUseDialogSetting(nApplicationID, m_XkeymacsData[nApplicationID].GetUseDialogSetting());\r
536                 pMainFrame->m_pXkeymacsDll->SetSettingStyle(nApplicationID, m_XkeymacsData[nApplicationID].GetSettingStyle());\r
537                 pMainFrame->m_pXkeymacsDll->SetIgnoreUndefinedMetaCtrl(nApplicationID, m_XkeymacsData[nApplicationID].GetIgnoreUndefinedMetaCtrl());\r
538                 pMainFrame->m_pXkeymacsDll->SetIgnoreUndefinedC_x(nApplicationID, m_XkeymacsData[nApplicationID].GetIgnoreUndefinedC_x());\r
539                 pMainFrame->m_pXkeymacsDll->SetEnableCUA(nApplicationID, m_XkeymacsData[nApplicationID].GetEnableCUA());\r
540                 pMainFrame->m_pXkeymacsDll->Set326Compatible(nApplicationID, m_XkeymacsData[nApplicationID].Get326Compatible());\r
541         }\r
542 }\r
543 \r
544 void CProfile::ReadKeyBind(int *const pnCommandType, int *const pnKey, LPCTSTR szKeyBind)\r
545 {\r
546         *pnCommandType = KeyBind2CommandType(szKeyBind);\r
547         *pnKey = KeyBind2Key(szKeyBind + _tcslen(CommandType2String(*pnCommandType)));\r
548 }\r
549 \r
550 CString CProfile::WriteKeyBind(const int nCommandType, const int nKey)\r
551 {\r
552         CString szKeyBind;\r
553         szKeyBind.Format(_T("%s%s"), CommandType2String(nCommandType), Key2String(nKey));\r
554         return szKeyBind;\r
555 }\r
556 \r
557 int CProfile::KeyBind2CommandType(LPCTSTR szKeyBind)\r
558 {\r
559         for (int nCommandType = MAX_COMMAND_TYPE - 1; nCommandType; --nCommandType) {\r
560                 if (IsCommandType(nCommandType, szKeyBind)) {\r
561                         return nCommandType;\r
562                 }\r
563         }\r
564         return NONE;\r
565 }\r
566 \r
567 int CProfile::KeyBind2Key(LPCTSTR szKey)\r
568 {\r
569         for (int nKey = 1; nKey < 0xff; ++nKey) {\r
570                 if (!_tcscmp(szKey, Key2String(nKey))) {\r
571                         return nKey;\r
572                 }\r
573         }\r
574         return 0;\r
575 }\r
576 \r
577 LPCTSTR CProfile::CommandType2String(int nCommandType)\r
578 {\r
579         if (nCommandType < 0 || sizeof(CommandTypes) / sizeof(CommandTypes[0]) <= nCommandType) {\r
580                 ASSERT(0);\r
581                 nCommandType = NONE;\r
582         }\r
583         return CommandTypes[nCommandType].szCommandTypeName;\r
584 }\r
585 \r
586 LPCTSTR CProfile::Key2String(int nKey)\r
587 {\r
588         if (CProfile::Is106Keyboard()) {\r
589                 switch (nKey) {\r
590                 case 0xBA:\r
591                         return _T(":");\r
592                 case 0xBB:\r
593                         return _T(";");\r
594                 case 0xC0:\r
595                         return _T("@");\r
596                 case 0xDE:\r
597                         return _T("^");\r
598                 default:\r
599                         break;\r
600                 }\r
601         }\r
602 \r
603         if (nKey < 0 || sizeof(KeyNames) / sizeof(KeyNames[0]) <= nKey) {\r
604                 ASSERT(0);\r
605                 nKey = 0;\r
606         }\r
607         return KeyNames[nKey].name;\r
608 }\r
609 \r
610 BOOL CProfile::IsCommandType(const int nCommandType, LPCTSTR szKeyBind)\r
611 {\r
612         LPCTSTR szCommandType = CommandType2String(nCommandType);\r
613 \r
614         if (!_tcsnicmp(szKeyBind, szCommandType, _tcslen(szCommandType))) {\r
615                 return TRUE;\r
616         }\r
617 \r
618         return FALSE;\r
619 }\r
620 \r
621 void CProfile::SaveKeyBind(const CString szApplicationName, const int nCommandID, const int nCommandType, const int nKey)\r
622 {\r
623         if (!nCommandID) {\r
624                 return;\r
625         }\r
626 \r
627         CString szCommandName = CXkeymacsData::GetCommandName(nCommandID);\r
628         if (szCommandName.IsEmpty()) {\r
629                 return;\r
630         }\r
631 \r
632         SaveKeyBind(szApplicationName, szCommandName, nCommandType, nKey);\r
633 }\r
634 \r
635 void CProfile::SaveKeyBind(const CString szApplicationName, const CString szCommandName, const int nCommandType, const int nKey)\r
636 {\r
637         CString szKeyBind = WriteKeyBind(nCommandType, nKey);\r
638         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
639         szSubKey += _T("\\") + szApplicationName + _T("\\") + szCommandName;\r
640         if (!szKeyBind.IsEmpty()) {\r
641                 szSubKey += _T("\\") + szKeyBind;\r
642         }\r
643 \r
644         HKEY hKey = NULL;\r
645         if (RegCreateKeyEx(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS) {\r
646                 RegCloseKey(hKey);\r
647         }\r
648 }\r
649 \r
650 void CProfile::SaveCommand(const CString szApplicationName, const int nCommandID)\r
651 {\r
652         SaveKeyBind(szApplicationName, nCommandID, 0, 0);\r
653 }\r
654 \r
655 void CProfile::AddKeyBind2C_(const CString szApplicationName, const BYTE bVk)\r
656 {\r
657         for (int nCommandID = 0; nCommandID < sizeof(Commands) / sizeof(Commands[0]); ++nCommandID) {\r
658                 if (Commands[nCommandID].fCommand == CCommands::C_) {\r
659                         break;\r
660                 }\r
661         }\r
662 \r
663         SaveKeyBind(szApplicationName, nCommandID, NONE, bVk);\r
664 }\r
665 \r
666 void CProfile::LevelUp()\r
667 {\r
668         const int nDefalutLevel = 0;\r
669         const int nLatestLevel = 4;\r
670 \r
671         CString szSection;\r
672         CString szEntry;\r
673         szEntry.Format(_T("Level"));\r
674 \r
675         switch (AfxGetApp()->GetProfileInt(szSection, szEntry, nDefalutLevel)) {\r
676         case nDefalutLevel:\r
677                 {\r
678                         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
679                                 CString szEntry;\r
680                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
681 \r
682                                 CString szApplicationName;\r
683                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
684                                 if (szApplicationName.IsEmpty()) {\r
685                                         continue;\r
686                                 }\r
687 \r
688                                 AddKeyBind2C_(szApplicationName, VK_LCONTROL);\r
689                                 AddKeyBind2C_(szApplicationName, VK_RCONTROL);\r
690                         }\r
691                 }\r
692                 // Do NOT write break; here.\r
693         case 1:\r
694                 {\r
695                         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
696                                 CString szEntry;\r
697                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
698 \r
699                                 CString szApplicationName;\r
700                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
701                                 if (szApplicationName.IsEmpty()) {\r
702                                         continue;\r
703                                 }\r
704 \r
705                                 // Set kill-ring-max 1 if it is 0.\r
706                                 if (!AfxGetApp()->GetProfileInt(szApplicationName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 0)) {\r
707                                         AfxGetApp()->WriteProfileInt(szApplicationName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 1);\r
708                                 }\r
709                         }\r
710                 }\r
711                 // Do NOT write break; here.\r
712         case 2:\r
713                 {\r
714                         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
715                                 CString szEntry;\r
716                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
717 \r
718                                 CString szApplicationName;\r
719                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
720                                 if (szApplicationName.IsEmpty()) {\r
721                                         continue;\r
722                                 }\r
723 \r
724                                 // Chaged a label from Enter to newline.\r
725                                 CString szSrcSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
726                                 szSrcSubKey += _T("\\") + szApplicationName + _T("\\") + _T("Enter");\r
727                                 CString szDestSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
728                                 szDestSubKey += _T("\\") + szApplicationName + _T("\\") + _T("newline");\r
729                                 HKEY hKeyDest = NULL;\r
730                                 if (RegCreateKeyEx(HKEY_CURRENT_USER, szDestSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyDest, NULL) == ERROR_SUCCESS) {\r
731                                         SHCopyKey(HKEY_CURRENT_USER, szSrcSubKey, hKeyDest, NULL);\r
732                                         SHDeleteKey(HKEY_CURRENT_USER, szSrcSubKey);\r
733                                         RegCloseKey(hKeyDest);\r
734                                 }\r
735                         }\r
736                 }\r
737                 // Do NOT write break; here.\r
738         case 3:\r
739                 {\r
740                         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
741                                 CString szEntry;\r
742                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
743 \r
744                                 CString szApplicationName;\r
745                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
746                                 if (szApplicationName.IsEmpty()) {\r
747                                         continue;\r
748                                 }\r
749 \r
750                                 // rename original function to remove IDS_REG_ORIGINAL_PREFIX\r
751                                 for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
752                                         HKEY hKey = NULL;\r
753                                         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
754                                         szSubKey += _T("\\") + szApplicationName + _T("\\") + CString(MAKEINTRESOURCE(IDS_REG_ORIGINAL_PREFIX)) + CDotXkeymacs::GetFunctionSymbol(nFunctionID);\r
755                                         if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
756                                                 // Use registry data\r
757                                                 TCHAR szKeyBind[128] = {'\0'};\r
758                                                 DWORD dwKeyBind = sizeof(szKeyBind);\r
759                                                 FILETIME ft = {'\0'};   // not use\r
760                                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS; ++dwIndex) {\r
761                                                         int nCommandType = 0;\r
762                                                         int nKey = 0;\r
763                                                         ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
764                                                         SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFunctionID), nCommandType, nKey);\r
765 \r
766                                                         memset(szKeyBind, 0, sizeof(szKeyBind));\r
767                                                         dwKeyBind = sizeof(szKeyBind);\r
768                                                 }\r
769                                                 RegCloseKey(hKey);\r
770                                         }\r
771                                 }\r
772                         }\r
773                 }\r
774 //      case 4:\r
775 //              foo();\r
776 //      ...\r
777 //      case nLatestLevel-1:\r
778 //              bar();\r
779                 AfxGetApp()->WriteProfileInt(szSection, szEntry, nLatestLevel);\r
780                 break;\r
781         default:\r
782                 break;\r
783         }\r
784 }\r
785 \r
786 void CProfile::InitDllData()\r
787 {\r
788         LoadRegistryData();\r
789         SetDllData();\r
790 }\r
791 \r
792 void CProfile::ClearData(const CString szCurrentApplication)\r
793 {\r
794         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
795                 if (m_XkeymacsData[nApplicationID].GetApplicationName() == szCurrentApplication) {\r
796                         break;\r
797                 }\r
798         }\r
799         if (nApplicationID < MAX_APP) {\r
800                 m_XkeymacsData[nApplicationID].ClearAll();\r
801         }\r
802 }\r
803 \r
804 // return count of saved settings\r
805 int CProfile::GetSavedSettingCount()\r
806 {\r
807         int nSavedSetting = 0;\r
808 \r
809         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
810                 CString szApplicationName;\r
811                 szApplicationName = m_XkeymacsData[nApplicationID].GetApplicationName();\r
812                 if (!szApplicationName.IsEmpty()) {\r
813                         ++nSavedSetting;\r
814                 }\r
815         }\r
816 \r
817         return nSavedSetting;\r
818 }\r
819 \r
820 void CProfile::InitApplicationList(CComboBox *const cApplicationList)\r
821 {\r
822         cApplicationList->ResetContent();\r
823 \r
824         m_dwTasks = GetTaskList(m_TaskList, MAX_TASKS);\r
825 \r
826         EnumWindows(EnumWindowsProc, (LPARAM)cApplicationList);\r
827 \r
828         for (int i = 0; i < MAX_APP; ++i) {\r
829                 CString szApplicationName       = m_XkeymacsData[i].GetApplicationName();\r
830                 CString szApplicationTitle      = m_XkeymacsData[i].GetApplicationTitle();\r
831 \r
832                 CString szListItem;\r
833                 szListItem.Format(IDS_APPLICATION_LIST_ITEM, szApplicationTitle, szApplicationName);\r
834                 if (IsNotSameString(cApplicationList, szListItem)\r
835                  && !IsDefault(szApplicationName)\r
836                  && !IsDialog(szApplicationName)\r
837                  && !szApplicationName.IsEmpty()) {\r
838                         cApplicationList->AddString(szListItem);\r
839                 }\r
840         }\r
841 \r
842         // Add IME\r
843         HKL hKL = GetKeyboardLayout(0);\r
844         if (ImmIsIME(hKL)) {\r
845                 LPTSTR szIMEDescription = NULL;\r
846                 UINT nIMEDescription = ImmGetDescription(hKL, NULL, 0);\r
847                 if (nIMEDescription) {\r
848                         nIMEDescription += sizeof(TCHAR);       // for NULL\r
849                         if ((szIMEDescription = new TCHAR[nIMEDescription]) != NULL) {\r
850                                 ImmGetDescription(hKL, szIMEDescription, nIMEDescription);\r
851                         }\r
852 //                      CUtils::Log(_T("nIMEDescription = %d, szIMEDescription = _%s_"), nIMEDescription, szIMEDescription);\r
853                 }\r
854 \r
855                 LPTSTR szIMEFileName = NULL;\r
856                 UINT nIMEFileName = ImmGetIMEFileName(hKL, NULL, 0);\r
857                 if (nIMEFileName) {\r
858                         nIMEFileName += sizeof(TCHAR);\r
859                         if ((szIMEFileName = new TCHAR[nIMEFileName]) != NULL) {\r
860                                 ImmGetIMEFileName(hKL, szIMEFileName, nIMEFileName);\r
861                         }\r
862 //                      CUtils::Log(_T("nIMEFileName = %d, szIMEFileName = _%s_"), nIMEFileName, szIMEFileName);\r
863                 }\r
864 \r
865                 CString szIMETitle;\r
866                 CString szIME(MAKEINTRESOURCE(IDS_IME_FILE_NAME));\r
867                 szIMETitle.Format(IDS_APPLICATION_LIST_ITEM, szIMEDescription ? szIMEDescription : szIME, szIMEFileName ? szIMEFileName : szIME);\r
868 //              CUtils::Log(_T("szIMETitle = _%s_, szIMEDescription = _%s_, szIMEFileName = _%s_"), szIMETitle, szIMEDescription, szIMEFileName);\r
869                 if (IsNotSameString(cApplicationList, szIMETitle)) {\r
870                         cApplicationList->AddString(szIMETitle);\r
871                 }\r
872 \r
873                 delete[] szIMEDescription;\r
874                 szIMEDescription = NULL;\r
875                 delete[] szIMEFileName;\r
876                 szIMEFileName = NULL;\r
877         }\r
878 \r
879         // Add Dialog\r
880         cApplicationList->InsertString(0, CString(MAKEINTRESOURCE(IDS_DIALOG_TITLE)));\r
881 \r
882         // Add Default\r
883         cApplicationList->InsertString( 0, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));\r
884         cApplicationList->SelectString(-1, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));\r
885 }\r
886 \r
887 DWORD CProfile::GetTaskList(PTASK_LIST pTask, const DWORD dwNumTasks)\r
888 {\r
889         for (int i = 0; i < MAX_TASKS; ++i) {\r
890                 ZeroMemory(&pTask[i], sizeof(PTASK_LIST));\r
891         }\r
892 \r
893         OSVERSIONINFO verInfo = {0};\r
894         verInfo.dwOSVersionInfoSize = sizeof (verInfo);\r
895         GetVersionEx(&verInfo);\r
896         if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT\r
897          && verInfo.dwMajorVersion < 5) {\r
898                 return GetTaskListNT(pTask, dwNumTasks);\r
899         }\r
900 \r
901         HMODULE hKernel = GetModuleHandle(_T("KERNEL32.DLL"));\r
902         if (!hKernel) {\r
903                 return 0;\r
904         }\r
905 \r
906         CREATESNAPSHOT pCreateToolhelp32Snapshot = (CREATESNAPSHOT)GetProcAddress(hKernel, "CreateToolhelp32Snapshot");\r
907         if (!pCreateToolhelp32Snapshot) {\r
908                 return 0;\r
909         }\r
910 \r
911         PROCESSWALK pProcess32First = (PROCESSWALK)GetProcAddress(hKernel, "Process32First");\r
912         if (!pProcess32First) {\r
913                 return 0;\r
914         }\r
915 \r
916         PROCESSWALK pProcess32Next = (PROCESSWALK)GetProcAddress(hKernel, "Process32Next");\r
917         if (!pProcess32Next) {\r
918                 return 0;\r
919         }\r
920 \r
921         HANDLE hProcessSnap = pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r
922         if (hProcessSnap == (HANDLE)-1) {\r
923                 return 0;\r
924         }\r
925 \r
926         DWORD dwTaskCount = 0;\r
927         PROCESSENTRY32 processEntry32 = {sizeof(PROCESSENTRY32)};\r
928         if (pProcess32First(hProcessSnap, &processEntry32)) {\r
929                 do {\r
930                         LPTSTR pCurChar = NULL;\r
931                         for (pCurChar = processEntry32.szExeFile + lstrlen(processEntry32.szExeFile); *pCurChar != _T('\\') && pCurChar != processEntry32.szExeFile; --pCurChar) {\r
932                                 ;\r
933                         }\r
934                         if (*pCurChar == _T('\\')) {\r
935                                 ++pCurChar;\r
936                         }\r
937 \r
938                         lstrcpy(pTask->ProcessName, pCurChar);\r
939                         pTask->dwProcessId = processEntry32.th32ProcessID;\r
940 \r
941                         ++dwTaskCount;\r
942                         ++pTask;\r
943                 } while (dwTaskCount < dwNumTasks && pProcess32Next(hProcessSnap, &processEntry32));\r
944         }\r
945 \r
946         CloseHandle(hProcessSnap);\r
947         return dwTaskCount;\r
948 }\r
949 \r
950 LPBYTE CProfile::GetCounters()\r
951 {\r
952         LANGID lid = MAKELANGID(LANG_ENGLISH, SUBLANG_NEUTRAL);\r
953         CString szSubKey;\r
954         szSubKey.Format(CString(MAKEINTRESOURCE(IDS_REGSUBKEY_PERF)), lid);\r
955         HKEY hKey = NULL;\r
956         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS) {\r
957                 return NULL;\r
958         }\r
959 \r
960         DWORD dwSize = 0;\r
961         if (RegQueryValueEx(hKey, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_COUNTERS)), NULL, NULL, NULL, &dwSize) != ERROR_SUCCESS) {\r
962                 RegCloseKey(hKey);\r
963                 return NULL;\r
964         }\r
965         LPBYTE pCounters = (LPBYTE) calloc(dwSize, sizeof(BYTE));\r
966         if (pCounters == NULL) {\r
967                 RegCloseKey(hKey);\r
968                 return NULL;\r
969         }\r
970         if (RegQueryValueEx(hKey, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_COUNTERS)), NULL, NULL, pCounters, &dwSize) != ERROR_SUCCESS) {\r
971                 RegCloseKey(hKey);\r
972                 free(pCounters);\r
973                 return NULL;\r
974         }\r
975         RegCloseKey(hKey);\r
976         return pCounters;\r
977 }\r
978 \r
979 BOOL CProfile::GetProcessInfo(CString *const szProcessName, DWORD *const dwProcessId)\r
980 {\r
981         LPBYTE pCounters = GetCounters();\r
982         if (!pCounters) {\r
983                 return FALSE;\r
984         }\r
985         LPTSTR pTopOfString = (LPTSTR)pCounters;\r
986         while (*pTopOfString) {\r
987                 if (_tcsicmp(pTopOfString, CString(MAKEINTRESOURCE(IDS_PROCESS))) == 0) {\r
988                         for (LPTSTR p2 = pTopOfString - 2; _istdigit(*p2); --p2) {\r
989                                 ;\r
990                         }\r
991                         szProcessName->Format(_T("%s"), p2 + 1);        // 230\r
992                 } else if (_tcsicmp(pTopOfString, CString(MAKEINTRESOURCE(IDS_PROCESSID))) == 0) {\r
993                         for (LPTSTR p2 = pTopOfString - 2; _istdigit(*p2); --p2) {\r
994                                 ;\r
995                         }\r
996                         *dwProcessId = _ttol(p2 + 1);                   // 784\r
997                 }\r
998                 pTopOfString += (_tcslen(pTopOfString) + 1);\r
999         }\r
1000         free(pCounters);\r
1001         return TRUE;\r
1002 }\r
1003 \r
1004 PPERF_DATA_BLOCK CProfile::GetPerformanceData(const CString szProcessName)\r
1005 {\r
1006         DWORD dwSize = INITIAL_SIZE;\r
1007         PPERF_DATA_BLOCK pPerformanceData = (PPERF_DATA_BLOCK) calloc(dwSize, sizeof(BYTE));\r
1008         if (pPerformanceData == NULL) {\r
1009                 return NULL;\r
1010         }\r
1011 \r
1012         for (;;) {\r
1013                 switch (RegQueryValueEx(HKEY_PERFORMANCE_DATA, szProcessName, NULL, NULL, (LPBYTE)pPerformanceData, &dwSize)) {\r
1014                 case ERROR_SUCCESS:\r
1015                         if (0 < dwSize\r
1016                          && pPerformanceData->Signature[0] == (WCHAR)'P'\r
1017                          && pPerformanceData->Signature[1] == (WCHAR)'E'\r
1018                          && pPerformanceData->Signature[2] == (WCHAR)'R'\r
1019                          && pPerformanceData->Signature[3] == (WCHAR)'F') {\r
1020                                 return pPerformanceData;\r
1021                         }\r
1022                 case ERROR_MORE_DATA:\r
1023                         dwSize += EXTEND_SIZE;\r
1024                         pPerformanceData = (PPERF_DATA_BLOCK) realloc(pPerformanceData, dwSize);\r
1025                         if (!pPerformanceData) {\r
1026                                 return NULL;\r
1027                         }\r
1028                         memset(pPerformanceData, 0, dwSize);\r
1029                         break;\r
1030                 default:\r
1031                         free(pPerformanceData);\r
1032                         return NULL;\r
1033                 }\r
1034         }\r
1035 }\r
1036 \r
1037 // Add running application's names to the list\r
1038 // only for _Windows NT_\r
1039 DWORD CProfile::GetTaskListNT(PTASK_LIST pTask, DWORD dwNumTasks)\r
1040 {\r
1041         CString szProcessName;\r
1042         DWORD dwProcessIdTitle = 0;\r
1043         if (!GetProcessInfo(&szProcessName, &dwProcessIdTitle)) {\r
1044                 return dwNumTasks;\r
1045         }\r
1046 \r
1047         PPERF_DATA_BLOCK pPerformanceData = GetPerformanceData(szProcessName);\r
1048         if (!pPerformanceData) {\r
1049                 return dwNumTasks;\r
1050         }\r
1051 \r
1052         PPERF_OBJECT_TYPE pObj = (PPERF_OBJECT_TYPE) ((DWORD)pPerformanceData + pPerformanceData->HeaderLength);\r
1053         PPERF_COUNTER_DEFINITION pCounterDef = (PPERF_COUNTER_DEFINITION) ((DWORD)pObj + pObj->HeaderLength);\r
1054         DWORD dwProcessIdCounter = 0;\r
1055         for (DWORD i = 0; i < pObj->NumCounters; ++i) {\r
1056                 if (pCounterDef->CounterNameTitleIndex == dwProcessIdTitle) {\r
1057                         dwProcessIdCounter = pCounterDef->CounterOffset;\r
1058                         break;\r
1059                 }\r
1060                 ++pCounterDef;\r
1061         }\r
1062 \r
1063         dwNumTasks = min(dwNumTasks - 1, (DWORD)pObj->NumInstances);\r
1064         PPERF_INSTANCE_DEFINITION pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pObj + pObj->DefinitionLength);\r
1065         for (i = 0; i < dwNumTasks; ++i) {\r
1066                 LPCWSTR pProcessName = (LPCWSTR) ((DWORD)pInst + pInst->NameOffset);\r
1067 \r
1068                 CHAR szProcessName[MAX_PATH] = {'\0'};\r
1069                 if (!WideCharToMultiByte(CP_ACP, 0, pProcessName, -1, szProcessName, sizeof(szProcessName), NULL, NULL)) {\r
1070                         _tcscpy(pTask->ProcessName, CString(MAKEINTRESOURCE(IDS_UNKNOWN_TASK)));\r
1071                 }\r
1072 \r
1073                 if (_tcslen(szProcessName)+4 <= sizeof(pTask->ProcessName)) {\r
1074                         _tcscpy(pTask->ProcessName, szProcessName);\r
1075                         _tcscat(pTask->ProcessName, CString(MAKEINTRESOURCE(IDS_EXTENSION_EXECUTABLE)));\r
1076                 }\r
1077 \r
1078                 PPERF_COUNTER_BLOCK pCounter = (PPERF_COUNTER_BLOCK) ((DWORD)pInst + pInst->ByteLength);\r
1079                 pTask->dwProcessId = *((LPDWORD) ((DWORD)pCounter + dwProcessIdCounter));\r
1080                 if (pTask->dwProcessId == 0) {\r
1081                         pTask->dwProcessId = (DWORD) -2;\r
1082                 }\r
1083 \r
1084                 ++pTask;\r
1085                 pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pCounter + pCounter->ByteLength);\r
1086         }\r
1087 \r
1088         free(pPerformanceData);\r
1089         return dwNumTasks;\r
1090 }\r
1091 \r
1092 // return application index\r
1093 // and update setting style\r
1094 // if there is NOT the application in the data, this function takes care of it.\r
1095 int CProfile::GetApplicationIndex(const CString szApplicationName, const BOOL bSaveAndValidate, int *const nSettingStyle)\r
1096 {\r
1097         if (!bSaveAndValidate) {        // SetDialogData\r
1098                 *nSettingStyle = SETTING_UNDEFINED;\r
1099         }\r
1100 \r
1101         int nApplicationID = GetApplicationIndex(szApplicationName);\r
1102 \r
1103         if (nApplicationID == MAX_APP) {\r
1104                 if (bSaveAndValidate) { // GetDialogData\r
1105                         for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1106                                 CString sz = m_XkeymacsData[nApplicationID].GetApplicationName();\r
1107                                 if (sz.IsEmpty()) {\r
1108                                         m_XkeymacsData[nApplicationID].SetApplicationName(szApplicationName);\r
1109                                         break;\r
1110                                 }\r
1111                         }\r
1112                         if (nApplicationID == MAX_APP) {\r
1113                                 return nApplicationID;\r
1114                         }\r
1115                 } else {                                // SetDialogData\r
1116                         for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1117                                 if (IsDefault(m_XkeymacsData[nApplicationID].GetApplicationName())) {\r
1118                                         *nSettingStyle = SETTING_DEFAULT;\r
1119                                         break;\r
1120                                 }\r
1121                         }\r
1122                         if (nApplicationID == MAX_APP) {\r
1123                                 return nApplicationID;\r
1124                         }\r
1125                 }\r
1126         }\r
1127 \r
1128         if (bSaveAndValidate) { // GetDialogData\r
1129                 m_XkeymacsData[nApplicationID].SetSettingStyle(*nSettingStyle);\r
1130         } else {                                // SetDialogData\r
1131                 if (*nSettingStyle == SETTING_UNDEFINED) {      // It means that *nSettingStyle != SETTING_DEFAULT.\r
1132                         *nSettingStyle = m_XkeymacsData[nApplicationID].GetSettingStyle();\r
1133                 }\r
1134         }\r
1135 \r
1136         return nApplicationID;\r
1137 }\r
1138 \r
1139 BOOL CProfile::IsTheString(const CString sz, const UINT nID)\r
1140 {\r
1141         return sz == CString(MAKEINTRESOURCE(nID));\r
1142 }\r
1143 \r
1144 // if sz is "Default", return TRUE\r
1145 BOOL CProfile::IsDefault(const CString sz)\r
1146 {\r
1147         return IsTheString(sz, IDS_DEFAULT);\r
1148 }\r
1149 \r
1150 // if sz is "Dialog", return TRUE\r
1151 BOOL CProfile::IsDialog(const CString sz)\r
1152 {\r
1153         return IsTheString(sz, IDS_DIALOG);\r
1154 }\r
1155 \r
1156 void CProfile::GetApplicationTitle(CComboBox *const cApplicationList, CString &rList, const int nIndex)\r
1157 {\r
1158         if (0 <= nIndex) {\r
1159                 cApplicationList->GetLBText(nIndex, rList);\r
1160         } else {\r
1161                 cApplicationList->GetWindowText(rList);\r
1162         }\r
1163 \r
1164         if (IsTheString(rList, IDS_DEFAULT_TITLE)) {\r
1165                 rList.LoadString(IDS_DEFAULT);\r
1166         }\r
1167 \r
1168         if (IsTheString(rList, IDS_DIALOG_TITLE)) {\r
1169                 rList.LoadString(IDS_DIALOG);\r
1170         }\r
1171 \r
1172         return;\r
1173 }\r
1174 \r
1175 void CProfile::UpdateApplicationTitle(CComboBox *const cApplicationList, const CString szCurrentApplication, const int nApplicationID, const BOOL bSaveAndValidate)\r
1176 {\r
1177         static CString szApplicationTitle;\r
1178         if (bSaveAndValidate) { // GetDialogData\r
1179                 if (!CProfile::IsDefault(szCurrentApplication)) {\r
1180                         m_XkeymacsData[nApplicationID].SetApplicationTitle(szApplicationTitle);\r
1181                 }\r
1182                 szApplicationTitle.Empty();\r
1183         } else {                                // SetDialogData\r
1184                 CString szListItem;\r
1185                 CProfile::GetApplicationTitle(cApplicationList, szListItem);\r
1186                 int nEndTitle = szListItem.ReverseFind(_T('('));\r
1187                 if (nEndTitle > 0) {\r
1188                         szApplicationTitle = szListItem.Left(nEndTitle);\r
1189                 }\r
1190         }\r
1191 }\r
1192 \r
1193 void CProfile::SetCommandID(const int nApplicationID, const int nCommandType, const int nKey, int nCommandID)\r
1194 {\r
1195         if (nKey == 0xf0 && Commands[nCommandID].fCommand == CCommands::C_) {\r
1196                 // Change CommandID C_Eisu\r
1197                 for (nCommandID = 1; nCommandID < sizeof(Commands) / sizeof(Commands[0]); ++nCommandID) {\r
1198                         if (Commands[nCommandID].fCommand == CCommands::C_Eisu) {\r
1199                                 break;\r
1200                         }\r
1201                 }\r
1202         }\r
1203         m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
1204 }\r
1205 \r
1206 int CProfile::GetCommandID(const int nApplicationID, const int nCommandType, const int nKey)\r
1207 {\r
1208         int nCommandID = m_XkeymacsData[nApplicationID].GetCommandID(nCommandType, nKey);\r
1209         if (nKey == 0xf0 && Commands[nCommandID].fCommand == CCommands::C_Eisu) {\r
1210                 // Change CommandID C_\r
1211                 for (nCommandID = 1; nCommandID < sizeof(Commands) / sizeof(Commands[0]); ++nCommandID) {\r
1212                         if (Commands[nCommandID].fCommand == CCommands::C_) {\r
1213                                 break;\r
1214                         }\r
1215                 }\r
1216         }\r
1217         return nCommandID;\r
1218 }\r
1219 \r
1220 void CProfile::SetKillRingMax(const int nApplicationID, const int nKillRingMax)\r
1221 {\r
1222         m_XkeymacsData[nApplicationID].SetKillRingMax(nKillRingMax);\r
1223 }\r
1224 \r
1225 int CProfile::GetKillRingMax(const int nApplicationID)\r
1226 {\r
1227         return m_XkeymacsData[nApplicationID].GetKillRingMax();\r
1228 }\r
1229 \r
1230 void CProfile::SetUseDialogSetting(const int nApplicationID, const BOOL bUseDialogSetting)\r
1231 {\r
1232         m_XkeymacsData[nApplicationID].SetUseDialogSetting(bUseDialogSetting);\r
1233 }\r
1234 \r
1235 BOOL CProfile::GetUseDialogSetting(const int nApplicationID)\r
1236 {\r
1237         return m_XkeymacsData[nApplicationID].GetUseDialogSetting();\r
1238 }\r
1239 \r
1240 void CProfile::SetWindowText(const int nApplicationID, const CString szWindowText)\r
1241 {\r
1242         m_XkeymacsData[nApplicationID].SetWindowText(szWindowText);\r
1243 }\r
1244 \r
1245 CString CProfile::GetWindowText(const int nApplicationID)\r
1246 {\r
1247         return m_XkeymacsData[nApplicationID].GetWindowText();\r
1248 }\r
1249 \r
1250 void CProfile::DeleteAllRegistryData()\r
1251 {\r
1252         HKEY hkey = NULL;\r
1253         if (RegOpenKeyEx(HKEY_CURRENT_USER, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)), 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) {\r
1254                 // I am sure that I have to do only one time, but...\r
1255                 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1256                         DWORD dwIndex = 0;\r
1257                         TCHAR szName[SUB_KEY_NAME_LENGTH] = {'\0'};\r
1258                         DWORD dwName = sizeof(szName);\r
1259                         FILETIME filetime;\r
1260 \r
1261                         while (RegEnumKeyEx(hkey, dwIndex++, szName, &dwName, NULL, NULL, NULL, &filetime) == ERROR_SUCCESS) {\r
1262 //                              RegDeleteKey(hkey, szName);\r
1263                                 SHDeleteKey(hkey, szName);\r
1264                                 ZeroMemory(szName, sizeof(szName));\r
1265                                 dwName = sizeof(szName);\r
1266                         }\r
1267                 }\r
1268                 RegCloseKey(hkey);\r
1269         }\r
1270 }\r
1271 \r
1272 int CProfile::GetCurrentApplicationID(CComboBox *const cApplicationList, const CString szCurrentApplication)\r
1273 {\r
1274         int nCounter = cApplicationList->GetCount();\r
1275         CString szListItem;\r
1276         int nCurSel = cApplicationList->GetCurSel();\r
1277 \r
1278         for (int i = 0; i < nCounter; ++i) {\r
1279                 cApplicationList->SetCurSel(i);\r
1280                 CProfile::GetApplicationTitle(cApplicationList, szListItem);\r
1281                 if (szListItem.Find(szCurrentApplication) != -1) {\r
1282                         cApplicationList->SetCurSel(nCurSel);\r
1283                         return i;\r
1284                 }\r
1285         }\r
1286         return -1;\r
1287 }\r
1288 \r
1289 void CProfile::CopyData(const CString szDestinationApplication, const CString szSourceApplication)\r
1290 {\r
1291         int nSettingStyle = SETTING_SPECIFIC;\r
1292         int nDestinationApplication = GetApplicationIndex(szDestinationApplication, TRUE, &nSettingStyle);\r
1293         int nSourceApplication = GetApplicationIndex(szSourceApplication);\r
1294 \r
1295         CString szApplicationName = m_XkeymacsData[nDestinationApplication].GetApplicationName();\r
1296         CString szApplicationTitle = m_XkeymacsData[nDestinationApplication].GetApplicationTitle();\r
1297         CString szWindowText = m_XkeymacsData[nDestinationApplication].GetWindowText();\r
1298         int nWindowTextType = m_XkeymacsData[nDestinationApplication].GetWindowTextType();\r
1299 \r
1300         m_XkeymacsData[nDestinationApplication] = m_XkeymacsData[nSourceApplication];\r
1301 \r
1302         m_XkeymacsData[nDestinationApplication].SetApplicationName(szApplicationName);\r
1303         m_XkeymacsData[nDestinationApplication].SetApplicationTitle(szApplicationTitle);\r
1304         m_XkeymacsData[nDestinationApplication].SetWindowText(szWindowText);\r
1305         m_XkeymacsData[nDestinationApplication].SetWindowTextType(nWindowTextType);\r
1306 }\r
1307 \r
1308 // return application index\r
1309 // if there is NOT the application in the data, return MAX_APP\r
1310 int CProfile::GetApplicationIndex(const CString szApplicationName)\r
1311 {\r
1312         int nApplicationID = 0;\r
1313         for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1314                 if (m_XkeymacsData[nApplicationID].GetApplicationName() == szApplicationName) {\r
1315                         break;\r
1316                 }\r
1317         }\r
1318         return nApplicationID;\r
1319 }\r
1320 \r
1321 BOOL CProfile::Is106Keyboard()\r
1322 {\r
1323         static KEYBOARD_TYPE keyboard = UNKNOWN_KEYBOARD;\r
1324 \r
1325         if (keyboard == UNKNOWN_KEYBOARD) {\r
1326                 OSVERSIONINFO verInfo = {0};\r
1327                 verInfo.dwOSVersionInfoSize = sizeof (verInfo);\r
1328                 GetVersionEx(&verInfo);\r
1329 \r
1330                 DWORD subtype = 0;\r
1331                 DWORD cbData = sizeof(subtype);\r
1332 \r
1333                 if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {\r
1334                         HKEY hKey = NULL;\r
1335                         CString szSubKey(_T("SYSTEM\\CurrentControlSet\\Services\\i8042prt\\Parameters"));\r
1336                         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
1337                                 static const CString szValueName(_T("OverrideKeyboardSubtype"));\r
1338                                 if (RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE)&subtype, &cbData) != ERROR_SUCCESS) {\r
1339                                         subtype = 0;\r
1340                                 }\r
1341                                 RegCloseKey(hKey);\r
1342                         }\r
1343                 } else if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {\r
1344                         subtype = GetPrivateProfileInt(_T("keyboard"), _T("subtype"), 0, _T("system.ini"));\r
1345                 }\r
1346 \r
1347                 keyboard = (subtype & 0x02) ? JAPANESE_KEYBOARD : ENGLISH_KEYBOARD;\r
1348         }\r
1349 \r
1350         return keyboard == JAPANESE_KEYBOARD;\r
1351 }\r
1352 \r
1353 void CProfile::LoadScanCodeMap(const HKEY_TYPE hkeyType)\r
1354 {\r
1355         memset(m_ScanCodeMap[hkeyType], 0, sizeof(m_ScanCodeMap[hkeyType]));\r
1356         memset(m_CurrentScanCodeMap[hkeyType], 0, sizeof(m_CurrentScanCodeMap[hkeyType]));\r
1357 \r
1358         CString szSubKey;\r
1359         CString szValueName;\r
1360         HKEY hKey = HKEY_LOCAL_MACHINE;\r
1361         if (IsNT()) {\r
1362                 switch (hkeyType) {\r
1363                 case CURRENT_USER:\r
1364                         hKey = HKEY_CURRENT_USER;\r
1365                         szSubKey.LoadString(IDS_REGSUBKEY_KEYBOARD_LAYOUT);\r
1366                         break;\r
1367                 case LOCAL_MACHINE:\r
1368                         szSubKey.LoadString(IDS_REGSUBKEY_KEYBOARD_LAYOUT_ANY_USER);\r
1369                         break;\r
1370                 default:\r
1371                         return;\r
1372                 }\r
1373                 szValueName.LoadString(IDS_SCANCODE_MAP);\r
1374         } else if (Is9x()) {\r
1375                 szSubKey.LoadString(IDS_REGSUBKEY_KEY_REMAP);\r
1376                 szValueName.LoadString(IDS_0);\r
1377         } else {\r
1378                 return;\r
1379         }\r
1380 \r
1381         HKEY hkResult = NULL;\r
1382         if (RegOpenKeyEx(hKey, szSubKey, 0, KEY_QUERY_VALUE, &hkResult) == ERROR_SUCCESS) {\r
1383                 // get data size\r
1384                 DWORD dwType = REG_BINARY;\r
1385                 DWORD dwData = 0;\r
1386                 RegQueryValueEx(hkResult, szValueName, NULL, &dwType, NULL, &dwData);\r
1387 \r
1388                 // get data\r
1389                 LPBYTE lpData = new BYTE[dwData];\r
1390                 if (lpData) {\r
1391                         RegQueryValueEx(hkResult, szValueName, NULL, &dwType, lpData, &dwData);\r
1392                 }\r
1393                 RegCloseKey(hkResult);\r
1394 \r
1395                 if (IsNT()) {\r
1396                         if (lpData && dwData) {\r
1397                                 DWORD offset = 0;\r
1398                                 offset += 8;    // skip Version Information and Flags\r
1399                                 DWORD *pdwMappings = (DWORD *)(lpData + offset);\r
1400                                 offset += 4;    // skip Number of Mappings\r
1401                                 DWORD *pdwNullTerminator = (DWORD *)(lpData + dwData - 4);\r
1402 \r
1403                                 if (4 * *pdwMappings + 12 != dwData) {\r
1404                                         // illegal data\r
1405                                 } else if (*pdwNullTerminator != 0) {\r
1406                                         // illegal data\r
1407                                 } else {\r
1408                                         while (offset < dwData - 4) {\r
1409                                                 ScanCodeMapping *pMapping = (ScanCodeMapping *)(lpData + offset);\r
1410                                                 offset += 4;    // go to next data\r
1411                                                 m_CurrentScanCodeMap[hkeyType][PrefixedScanCode2ID(pMapping->original.nPrefixedScanCode)][pMapping->original.nScanCode].nPrefixedScanCode = pMapping->current.nPrefixedScanCode;\r
1412                                                 m_CurrentScanCodeMap[hkeyType][PrefixedScanCode2ID(pMapping->original.nPrefixedScanCode)][pMapping->original.nScanCode].nScanCode = pMapping->current.nScanCode;\r
1413                                                 m_ScanCodeMap[hkeyType][PrefixedScanCode2ID(pMapping->original.nPrefixedScanCode)][pMapping->original.nScanCode].nPrefixedScanCode = pMapping->current.nPrefixedScanCode;\r
1414                                                 m_ScanCodeMap[hkeyType][PrefixedScanCode2ID(pMapping->original.nPrefixedScanCode)][pMapping->original.nScanCode].nScanCode = pMapping->current.nScanCode;\r
1415                                         }\r
1416                                 }\r
1417                         }\r
1418                 }\r
1419                 delete[] lpData;\r
1420                 lpData = NULL;\r
1421         }\r
1422 }\r
1423 \r
1424 int CProfile::LostKeyWarning(const HKEY_TYPE hkeyType)\r
1425 {\r
1426         if (!ChangedKeyboardLayout(hkeyType)) {\r
1427                 return IDOK;\r
1428         }\r
1429 \r
1430         CString szLostKeysList;\r
1431 \r
1432         for (int nPrefixedScanCodeID = 0; nPrefixedScanCodeID < 3; ++nPrefixedScanCodeID) {\r
1433                 for (int nScanCode = 0; nScanCode < 256; ++nScanCode) {\r
1434                         if (m_ScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nScanCode) {\r
1435                                 BOOL lostKey = TRUE;\r
1436 \r
1437                                 for (int i = 0; i < 3 && lostKey; ++i) {\r
1438                                         for (int j = 0; j < 256 && lostKey; ++j) {\r
1439                                                 if (m_ScanCodeMap[hkeyType][i][j].nPrefixedScanCode == nPrefixedScanCodeID\r
1440                                                  && m_ScanCodeMap[hkeyType][i][j].nScanCode == nScanCode) {\r
1441                                                         lostKey = FALSE;\r
1442                                                 }\r
1443                                         }\r
1444                                 }\r
1445 \r
1446                                 if (lostKey) {\r
1447                                         for (int i = 0; i < sizeof(KeyboardLayouts)/sizeof(KeyboardLayouts[0]); ++i) {\r
1448                                                 if (KeyboardLayouts[i].scancode.nScanCode == nScanCode\r
1449                                                         && KeyboardLayouts[i].scancode.nPrefixedScanCode == nPrefixedScanCodeID) {\r
1450                                                         CString szLostKey;\r
1451                                                         szLostKey.Format(IDS_ERR_LOST_KEY, CString(MAKEINTRESOURCE(GetToolTipID(KeyboardLayouts[i].nToolTipID))));\r
1452                                                         szLostKeysList += szLostKey;\r
1453                                                         break;\r
1454                                                 }\r
1455                                         }\r
1456                                 }\r
1457                         }\r
1458                 }\r
1459         }\r
1460 \r
1461         if (szLostKeysList.IsEmpty()) {\r
1462                 return IDOK;\r
1463         }\r
1464 \r
1465         return AfxMessageBox(szLostKeysList, MB_OKCANCEL | MB_ICONEXCLAMATION);\r
1466 }\r
1467 \r
1468 void CProfile::SaveScanCodeMap(const HKEY_TYPE hkeyType)\r
1469 {\r
1470         CString szSubKey;\r
1471         CString szValueName;\r
1472         HKEY hKey = HKEY_LOCAL_MACHINE;\r
1473         if (IsNT()) {\r
1474                 switch (hkeyType) {\r
1475                 case CURRENT_USER:\r
1476                         hKey = HKEY_CURRENT_USER;\r
1477                         szSubKey.LoadString(IDS_REGSUBKEY_KEYBOARD_LAYOUT);\r
1478                         break;\r
1479                 case LOCAL_MACHINE:\r
1480                         szSubKey.LoadString(IDS_REGSUBKEY_KEYBOARD_LAYOUT_ANY_USER);\r
1481                         break;\r
1482                 default:\r
1483                         return;\r
1484                 }\r
1485                 szValueName.LoadString(IDS_SCANCODE_MAP);\r
1486         } else if (Is9x()) {\r
1487                 szSubKey.LoadString(IDS_REGSUBKEY_KEY_REMAP);\r
1488                 szValueName.LoadString(IDS_0);\r
1489         } else {\r
1490                 return;\r
1491         }\r
1492 \r
1493         HKEY hkResult = NULL;\r
1494         if (RegCreateKeyEx(hKey, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hkResult, NULL) == ERROR_SUCCESS) {\r
1495                 if (IsNT()) {\r
1496                         DWORD cbData = GetScanCodeLength(hkeyType);\r
1497                         if (cbData <= 16) {\r
1498                                 RegDeleteValue(hkResult, szValueName);\r
1499                         } else {\r
1500                                 LPBYTE lpData = new BYTE[cbData];\r
1501                                 memset(lpData, 0, sizeof(BYTE) * cbData);\r
1502 \r
1503                                 {\r
1504                                         DWORD dwMappings = (cbData - 12) / 4;\r
1505                                         memmove(lpData + 8, &dwMappings, 4);\r
1506                                 }\r
1507 \r
1508                                 int offset = 12;\r
1509                                 for (int nPrefixedScanCodeID = 0; nPrefixedScanCodeID < 3; ++nPrefixedScanCodeID) {\r
1510                                         for (int nScanCode = 0; nScanCode < 256; ++nScanCode) {\r
1511                                                 if (m_ScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nScanCode) {\r
1512                                                         ScanCodeMapping sScanCodeMapping = {'\0'};\r
1513                                                         sScanCodeMapping.original.nPrefixedScanCode = PrefixedScanCodeID2Code(nPrefixedScanCodeID);\r
1514                                                         sScanCodeMapping.original.nScanCode = (BYTE)nScanCode;\r
1515                                                         sScanCodeMapping.current.nPrefixedScanCode = m_ScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nPrefixedScanCode;\r
1516                                                         sScanCodeMapping.current.nScanCode = m_ScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nScanCode;\r
1517                                                         memcpy(lpData + offset, &sScanCodeMapping, sizeof(sScanCodeMapping));\r
1518                                                         offset += sizeof(sScanCodeMapping);\r
1519                                                 }\r
1520                                         }\r
1521                                 }\r
1522                                 RegSetValueEx(hkResult, szValueName, 0, REG_BINARY, lpData, cbData);\r
1523 \r
1524                                 delete[] lpData;\r
1525                                 lpData = NULL;\r
1526                         }\r
1527                 }\r
1528                 RegCloseKey(hkResult);\r
1529         }\r
1530 \r
1531         // Do you want to restart computer?\r
1532         if (ChangedKeyboardLayout(hkeyType)) {\r
1533                 if (AfxMessageBox(CString(MAKEINTRESOURCE(IDS_RESTART_OR_NOT)), MB_YESNO | MB_ICONQUESTION) == IDYES) {\r
1534                         RestartComputer();\r
1535                 }\r
1536         }\r
1537 }\r
1538 \r
1539 // Return True if Windows 95, Windows 98, or Windows Me. \r
1540 BOOL CProfile::Is9x()\r
1541 {\r
1542         OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};\r
1543         GetVersionEx(&info);\r
1544 \r
1545         if (info.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {\r
1546                 return TRUE;\r
1547         }\r
1548         return FALSE;\r
1549 }\r
1550 \r
1551 // Return True if Windows NT 4.0, Windows 2000, Windows XP, Windows 2003 or Windows Vista.\r
1552 BOOL CProfile::IsNT()\r
1553 {\r
1554         OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};\r
1555         GetVersionEx(&info);\r
1556 \r
1557         if (info.dwPlatformId == VER_PLATFORM_WIN32_NT) {\r
1558                 return TRUE;\r
1559         }\r
1560         return FALSE;\r
1561 }\r
1562 \r
1563 // Return True if Windows Vista or later.\r
1564 BOOL CProfile::IsVistaOrLater()\r
1565 {\r
1566         OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};\r
1567         GetVersionEx(&info);\r
1568 \r
1569         if (6 <= info.dwMajorVersion) {\r
1570                 return TRUE;\r
1571         }\r
1572         return FALSE;\r
1573 }\r
1574 \r
1575 void CProfile::RestartComputer()\r
1576 {\r
1577         if (!AdjustTokenPrivileges(SE_SHUTDOWN_NAME)) {\r
1578                 return;\r
1579         }\r
1580 \r
1581         ExitWindowsEx(EWX_REBOOT, 0);\r
1582 }\r
1583 \r
1584 int CProfile::GetControlID(const ScanCode scancode, const BOOL bBase)\r
1585 {\r
1586         for (int i = 0; ; ++i) {\r
1587                 if (KeyboardLayouts[i].scancode.nPrefixedScanCode == scancode.nPrefixedScanCode\r
1588                  && KeyboardLayouts[i].scancode.nScanCode == scancode.nScanCode) {\r
1589                         if (bBase) {\r
1590                                 return KeyboardLayouts[i].nBaseControlID;\r
1591                         } else {\r
1592                                 return KeyboardLayouts[i].nCurrentControlID;\r
1593                         }\r
1594                 }\r
1595         }\r
1596         return 0;\r
1597 }\r
1598 \r
1599 int CProfile::GetBaseControlID(const ScanCode scancode)\r
1600 {\r
1601         return GetControlID(scancode, TRUE);\r
1602 }\r
1603 \r
1604 int CProfile::GetCurrentControlID(const ScanCode scancode)\r
1605 {\r
1606         return GetControlID(scancode, FALSE);\r
1607 }\r
1608 \r
1609 BOOL CProfile::GetScanCodeMap(const HKEY_TYPE hkeyType, const ScanCode original, ScanCode *const current)\r
1610 {\r
1611         if (!current) {\r
1612                 return FALSE;\r
1613         }\r
1614         *current = m_ScanCodeMap[hkeyType][PrefixedScanCode2ID(original.nPrefixedScanCode)][original.nScanCode];\r
1615         return 0 < current->nScanCode;\r
1616 }\r
1617 \r
1618 void CProfile::SetScanCodeMap(const HKEY_TYPE hkeyType, const ScanCodeMapping ScanCodeMappeing)\r
1619 {\r
1620         m_ScanCodeMap[hkeyType][PrefixedScanCode2ID(ScanCodeMappeing.original.nPrefixedScanCode)][ScanCodeMappeing.original.nScanCode] = ScanCodeMappeing.current;\r
1621 }\r
1622 \r
1623 int CProfile::PrefixedScanCode2ID(const BYTE nPrefixedScanCode)\r
1624 {\r
1625         int nID = 0;\r
1626 \r
1627         switch (nPrefixedScanCode) {\r
1628         case 0x00:\r
1629                 nID = 0;\r
1630                 break;\r
1631         case 0xe0:\r
1632                 nID = 1;\r
1633                 break;\r
1634         case 0xe1:\r
1635                 nID = 2;\r
1636                 break;\r
1637         default:\r
1638                 // invalid scan code\r
1639                 nID = 3;\r
1640                 break;\r
1641         }\r
1642 \r
1643         return nID;\r
1644 }\r
1645 \r
1646 BYTE CProfile::PrefixedScanCodeID2Code(const int nPrefixedScanCodeID)\r
1647 {\r
1648         BYTE nCode = 0;\r
1649 \r
1650         switch (nPrefixedScanCodeID) {\r
1651         case 0:\r
1652                 nCode = 0x00;\r
1653                 break;\r
1654         case 1:\r
1655                 nCode = 0xe0;\r
1656                 break;\r
1657         case 2:\r
1658                 nCode = 0xe1;\r
1659                 break;\r
1660         default:\r
1661                 ASSERT(0);\r
1662                 break;\r
1663         }\r
1664 \r
1665         return nCode;\r
1666 }\r
1667 \r
1668 DWORD CProfile::GetScanCodeLength(const HKEY_TYPE hkeyType)\r
1669 {\r
1670         DWORD dwScanCodeLength = 0;\r
1671         dwScanCodeLength += 4;  // Header: Version Information\r
1672         dwScanCodeLength += 4;  // Header: Flags\r
1673         dwScanCodeLength += 4;  // Header: Number of Mappings\r
1674         for (int nPrefixedScanCodeID = 0; nPrefixedScanCodeID < 3; ++nPrefixedScanCodeID) {\r
1675                 for (int nScanCode = 0; nScanCode < 256; ++nScanCode) {\r
1676                         if (m_ScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nScanCode) {\r
1677                                 dwScanCodeLength += 4;  // Individual Mappings\r
1678                         }\r
1679                 }\r
1680         }\r
1681         dwScanCodeLength += 4;  // Null Terminator (0x00000000)\r
1682         return dwScanCodeLength;\r
1683 }\r
1684 \r
1685 BOOL CProfile::ChangedKeyboardLayout(const HKEY_TYPE hkeyType)\r
1686 {\r
1687         for (int nPrefixedScanCodeID = 0; nPrefixedScanCodeID < 3; ++nPrefixedScanCodeID) {\r
1688                 for (int nScanCode = 0; nScanCode < 256; ++nScanCode) {\r
1689                         if (m_ScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nPrefixedScanCode   != m_CurrentScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nPrefixedScanCode\r
1690                          || m_ScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nScanCode                   != m_CurrentScanCodeMap[hkeyType][nPrefixedScanCodeID][nScanCode].nScanCode) {\r
1691                                 return TRUE;\r
1692                         }\r
1693                 }\r
1694         }\r
1695 \r
1696         return FALSE;\r
1697 }\r
1698 \r
1699 void CProfile::SetDraggingCursor()\r
1700 {\r
1701         HCURSOR hCursor = (HCURSOR)LoadImage(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDC_DRAG_CURSOR),\r
1702                                                                                  IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);\r
1703         SetCursor(hCursor);\r
1704 }\r
1705 \r
1706 void CProfile::SetNormalCursor()\r
1707 {\r
1708         HCURSOR hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_ARROW),\r
1709                                                                                  IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);\r
1710         SetCursor(hCursor);\r
1711 }\r
1712 \r
1713 void CProfile::SetNoCursor()\r
1714 {\r
1715         HCURSOR hCursor = (HCURSOR)LoadImage(NULL, MAKEINTRESOURCE(IDC_NO),\r
1716                                                                                  IMAGE_CURSOR, 0, 0, LR_DEFAULTSIZE | LR_SHARED);\r
1717         SetCursor(hCursor);\r
1718 }\r
1719 \r
1720 int CProfile::GetToolTipID(int nToolTipID)\r
1721 {\r
1722         if (Is106Keyboard()) {\r
1723                 switch (nToolTipID) {\r
1724                 case IDS_EQUAL:                 // ^\r
1725                         nToolTipID = IDS_CARET;\r
1726                         break;\r
1727                 case IDS_SQUARE_BRA:    // @\r
1728                         nToolTipID = IDS_AT_MARK;\r
1729                         break;\r
1730                 case IDS_SQUARE_CKET:   // [\r
1731                         nToolTipID = IDS_SQUARE_BRA;\r
1732                         break;\r
1733                 case IDS_QUOTE:                 // :\r
1734                         nToolTipID = IDS_COLON;\r
1735                         break;\r
1736                 case IDS_BACK_QUOTE:    // Hankaku/Zenkaku\r
1737                         nToolTipID = IDS_HANKAKU;\r
1738                         break;\r
1739                 case IDS_BACKSLASH:             // ]\r
1740                         nToolTipID = IDS_SQUARE_CKET;\r
1741                         break;\r
1742                 }\r
1743         }\r
1744 \r
1745         return nToolTipID;\r
1746 }\r
1747 \r
1748 KeyboardLayout* CProfile::GetKeyboardLayouts(const int nKey)\r
1749 {\r
1750         for (int i = 0; i < sizeof(KeyboardLayouts) / sizeof(KeyboardLayouts[0]); ++i) {\r
1751                 if (KeyboardLayouts[i].nBaseControlID == nKey\r
1752                  || KeyboardLayouts[i].nCurrentControlID == nKey) {\r
1753                         return &KeyboardLayouts[i];\r
1754                 }\r
1755         }\r
1756         return NULL;\r
1757 }\r
1758 \r
1759 BOOL CProfile::AdjustTokenPrivileges(LPCTSTR lpName)\r
1760 {\r
1761         BOOL rc = TRUE;\r
1762 \r
1763         if (IsNT()) {\r
1764                 HANDLE hToken;\r
1765                 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
1766                         LUID luid;\r
1767                         if (LookupPrivilegeValue(NULL, lpName, &luid)) {\r
1768                                 TOKEN_PRIVILEGES tp;\r
1769                                 tp.PrivilegeCount = 1;\r
1770                                 tp.Privileges[0].Luid = luid;\r
1771                                 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\r
1772 \r
1773                                 if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {\r
1774                                         rc = FALSE;\r
1775                                 }\r
1776                         } else {\r
1777                                 rc = FALSE;\r
1778                         }\r
1779                         CloseHandle(hToken);\r
1780                 } else {\r
1781                         rc = FALSE;\r
1782                 }\r
1783         }\r
1784 \r
1785         return rc;\r
1786 }\r
1787 \r
1788 BOOL CProfile::DiableTokenPrivileges()\r
1789 {\r
1790         BOOL rc = TRUE;\r
1791 \r
1792         if (IsNT()) {\r
1793                 HANDLE hToken;\r
1794                 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
1795                         if (!::AdjustTokenPrivileges(hToken, TRUE, NULL, NULL, NULL, NULL)) {\r
1796                                 rc = FALSE;\r
1797                         }\r
1798                         CloseHandle(hToken);\r
1799                 } else {\r
1800                         rc = FALSE;\r
1801                 }\r
1802         }\r
1803 \r
1804         return rc;\r
1805 }\r
1806 \r
1807 void CProfile::ExportProperties()\r
1808 {\r
1809         if (!AdjustTokenPrivileges(SE_BACKUP_NAME)) {\r
1810                 return;\r
1811         }\r
1812 \r
1813         CFileDialog oFileOpenDialog(FALSE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
1814         if (oFileOpenDialog.DoModal() == IDOK) {\r
1815                 CString szCommandLine;\r
1816                 szCommandLine.Format(_T("regedit /e \"%s\" HKEY_CURRENT_USER\\%s"), oFileOpenDialog.GetPathName(), CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)));\r
1817                 CUtils::Run(szCommandLine, TRUE);       // regedit /e "x:\xkeymacs.reg" HKEY_CURRENT_USER\Software\Oishi\XKeymacs2\r
1818         }\r
1819 \r
1820         DiableTokenPrivileges();\r
1821         return;\r
1822 }\r
1823 \r
1824 void CProfile::ImportProperties()\r
1825 {\r
1826         if (!AdjustTokenPrivileges(SE_RESTORE_NAME)) {\r
1827                 return;\r
1828         }\r
1829 \r
1830         CFileDialog oFileOpenDialog(TRUE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
1831         if (oFileOpenDialog.DoModal() == IDOK) {\r
1832                 CString szCommandLine;\r
1833                 szCommandLine.Format(_T("regedit \"%s\""), oFileOpenDialog.GetPathName());\r
1834                 CUtils::Run(szCommandLine, TRUE);       // regedit "x:\xkeymacs.reg"\r
1835         }\r
1836 \r
1837         DiableTokenPrivileges();\r
1838         return;\r
1839 }\r
1840 \r
1841 BOOL CProfile::GetEnableCUA(const int nApplicationID)\r
1842 {\r
1843         return m_XkeymacsData[nApplicationID].GetEnableCUA();\r
1844 }\r
1845 \r
1846 void CProfile::SetEnableCUA(const int nApplicationID, const BOOL bEnableCUA)\r
1847 {\r
1848         m_XkeymacsData[nApplicationID].SetEnableCUA(bEnableCUA);\r
1849 }\r
1850 \r
1851 int CProfile::GetKeyboardSpeed()\r
1852 {\r
1853         int nKeyboardSpeed = 31; // default value of Windows\r
1854         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_KEYBOARD));\r
1855         CString szValueName(MAKEINTRESOURCE(IDS_KEYBOARD_SPEED));\r
1856 \r
1857         HKEY hKey = NULL;\r
1858         if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
1859                 // get data size\r
1860                 DWORD dwType = REG_SZ;\r
1861                 BYTE data[4] = {0};\r
1862                 DWORD dwcbData = sizeof(data)/sizeof(data[0]);\r
1863                 RegQueryValueEx(hKey, szValueName, NULL, &dwType, (LPBYTE)&data, &dwcbData);\r
1864                 RegCloseKey(hKey);\r
1865 \r
1866                 for (DWORD i = 0; i < dwcbData; ++i) {\r
1867                         if (data[i]) {\r
1868                                 if (i) {\r
1869                                         nKeyboardSpeed = nKeyboardSpeed * 10 + data[i] - _T('0');\r
1870                                 } else {\r
1871                                         nKeyboardSpeed = data[i] - _T('0');\r
1872                                 }\r
1873                         } else {\r
1874                                 break;\r
1875                         }\r
1876                 }\r
1877         }\r
1878 \r
1879         return nKeyboardSpeed;\r
1880 }\r