OSDN Git Service

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