OSDN Git Service

Remove the argument of CString of SetDialogData and UpdateDialogData
[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>\r
12 #include <TlHelp32.h>\r
13 #include <vector>\r
14 \r
15 #ifdef _DEBUG\r
16 #undef THIS_FILE\r
17 static char THIS_FILE[]=__FILE__;\r
18 #define new DEBUG_NEW\r
19 #endif\r
20 \r
21 struct CommandTypeName\r
22 {\r
23         int nType;\r
24         LPCTSTR szName;\r
25 };\r
26 \r
27 static const CommandTypeName CommandTypes[] = {\r
28         {NONE,                                                  _T("")},\r
29         {SHIFT,                                                 _T("Shift+")},\r
30         {CONTROL,                                               _T("Ctrl+")},\r
31         {CONTROL+SHIFT,                                 _T("Ctrl+Shift+")},\r
32         {META,                                                  _T("Meta+")},\r
33         {META+SHIFT,                                    _T("Meta+Shift+")},\r
34         {CONTROL+META,                                  _T("Ctrl+Meta+")},\r
35         {CONTROL+META+SHIFT,                    _T("Ctrl+Meta+Shift+")},\r
36         {CONTROLX+NONE,                                 _T("Ctrl+X ")},\r
37         {CONTROLX+SHIFT,                                _T("Ctrl+X Shift+")},\r
38         {CONTROLX+CONTROL,                              _T("Ctrl+X Ctrl+")},\r
39         {CONTROLX+CONTROL+SHIFT,                _T("Ctrl+X Ctrl+Shift+")},\r
40         {CONTROLX+META,                                 _T("Ctrl+X Meta+")},\r
41         {CONTROLX+META+SHIFT,                   _T("Ctrl+X Meta+Shift+")},\r
42         {CONTROLX+CONTROL+META,                 _T("Ctrl+X Ctrl+Meta+")},\r
43         {CONTROLX+CONTROL+META+SHIFT,   _T("Ctrl+X Ctrl+Meta+Shift+")},\r
44 };\r
45 \r
46 static const KeyName KeyNames[] = {\r
47         {0,                             _T("")},\r
48         {VK_LBUTTON,    _T("Left mouse button")},\r
49         {VK_RBUTTON,    _T("Right mouse button")},\r
50         {VK_CANCEL,             _T("Break")},\r
51         {VK_MBUTTON,    _T("Middle mouse button")},\r
52         {0x05,                  _T("X1 mouse button")}, // VK_XBUTTON1\r
53         {0x06,                  _T("X2 mouse button")}, // VK_XBUTTON2\r
54         {0x07,                  _T("Undefined")},\r
55         {VK_BACK,               _T("Backspace")},\r
56         {VK_TAB,                _T("Tab")},\r
57         {0x0a,                  _T("Reserved")},\r
58         {0x0b,                  _T("Reserved")},\r
59         {VK_CLEAR,              _T("Clear")},\r
60         {VK_RETURN,             _T("Enter")},\r
61         {0x0e,                  _T("Undefined")},\r
62         {0x0f,                  _T("Undefined")},\r
63         {VK_SHIFT,              _T("Shift")},\r
64         {VK_CONTROL,    _T("Ctrl")},\r
65         {VK_MENU,               _T("Alt")},\r
66         {VK_PAUSE,              _T("Pause")},\r
67         {VK_CAPITAL,    _T("Caps Lock")},\r
68         {VK_KANA,               _T("Kana")},    //      {VK_HANGUEL,    "Hanguel"},     {VK_HANGUL,             "Hangul"},\r
69         {0x16,                  _T("Undefined")},\r
70         {VK_JUNJA,              _T("Junja")},\r
71         {VK_FINAL,              _T("Final")},\r
72         {VK_KANJI,              _T("Kanji")},   //      {VK_HANJA,              "Hanja"},\r
73         {0x1a,                  _T("Undefined")},\r
74         {VK_ESCAPE,             _T("Esc")},\r
75         {VK_CONVERT,    _T("Convert")},         // \95Ï\8a·\r
76         {VK_NONCONVERT, _T("Nonconvert")},      // \96³\95Ï\8a·\r
77         {VK_ACCEPT,             _T("Accept")},\r
78         {VK_MODECHANGE, _T("Mode change")},\r
79         {VK_SPACE,              _T("Space")},\r
80         {VK_PRIOR,              _T("Page Up")},\r
81         {VK_NEXT,               _T("Page Down")},\r
82         {VK_END,                _T("End")},\r
83         {VK_HOME,               _T("Home")},\r
84         {VK_LEFT,               _T("Left")},\r
85         {VK_UP,                 _T("Up")},\r
86         {VK_RIGHT,              _T("Right")},\r
87         {VK_DOWN,               _T("Down")},\r
88         {VK_SELECT,             _T("Select")},\r
89         {VK_PRINT,              _T("Print")},\r
90         {VK_EXECUTE,    _T("Execute")},\r
91         {VK_SNAPSHOT,   _T("Print Screen")},\r
92         {VK_INSERT,             _T("Ins")},\r
93         {VK_DELETE,             _T("Del")},\r
94         {VK_HELP,               _T("Help")},\r
95         {'0',                   _T("0")},\r
96         {'1',                   _T("1")},\r
97         {'2',                   _T("2")},\r
98         {'3',                   _T("3")},\r
99         {'4',                   _T("4")},\r
100         {'5',                   _T("5")},\r
101         {'6',                   _T("6")},\r
102         {'7',                   _T("7")},\r
103         {'8',                   _T("8")},\r
104         {'9',                   _T("9")},\r
105         {0x3a,                  _T("Undefined")},\r
106         {0x3b,                  _T("Undefined")},\r
107         {0x3c,                  _T("Undefined")},\r
108         {0x3d,                  _T("Undefined")},\r
109         {0x3e,                  _T("Undefined")},\r
110         {0x3f,                  _T("Undefined")},\r
111         {0x40,                  _T("Undefined")},\r
112         {'A',                   _T("A")},\r
113         {'B',                   _T("B")},\r
114         {'C',                   _T("C")},\r
115         {'D',                   _T("D")},\r
116         {'E',                   _T("E")},\r
117         {'F',                   _T("F")},\r
118         {'G',                   _T("G")},\r
119         {'H',                   _T("H")},\r
120         {'I',                   _T("I")},\r
121         {'J',                   _T("J")},\r
122         {'K',                   _T("K")},\r
123         {'L',                   _T("L")},\r
124         {'M',                   _T("M")},\r
125         {'N',                   _T("N")},\r
126         {'O',                   _T("O")},\r
127         {'P',                   _T("P")},\r
128         {'Q',                   _T("Q")},\r
129         {'R',                   _T("R")},\r
130         {'S',                   _T("S")},\r
131         {'T',                   _T("T")},\r
132         {'U',                   _T("U")},\r
133         {'V',                   _T("V")},\r
134         {'W',                   _T("W")},\r
135         {'X',                   _T("X")},\r
136         {'Y',                   _T("Y")},\r
137         {'Z',                   _T("Z")},\r
138         {VK_LWIN,               _T("Left Windows")},\r
139         {VK_RWIN,               _T("Right Windows")},\r
140         {VK_APPS,               _T("Application")},\r
141         {0x5e,                  _T("Reserved")},\r
142         {0x5f,                  _T("Sleep")},   // VK_SLEEP\r
143         {VK_NUMPAD0,    _T("Num 0")},\r
144         {VK_NUMPAD1,    _T("Num 1")},\r
145         {VK_NUMPAD2,    _T("Num 2")},\r
146         {VK_NUMPAD3,    _T("Num 3")},\r
147         {VK_NUMPAD4,    _T("Num 4")},\r
148         {VK_NUMPAD5,    _T("Num 5")},\r
149         {VK_NUMPAD6,    _T("Num 6")},\r
150         {VK_NUMPAD7,    _T("Num 7")},\r
151         {VK_NUMPAD8,    _T("Num 8")},\r
152         {VK_NUMPAD9,    _T("Num 9")},\r
153         {VK_MULTIPLY,   _T("Num *")},\r
154         {VK_ADD,                _T("Num +")},\r
155         {VK_SEPARATOR,  _T("Separator")},\r
156         {VK_SUBTRACT,   _T("Num -")},\r
157         {VK_DECIMAL,    _T("Num .")},\r
158         {VK_DIVIDE,             _T("Num /")},\r
159         {VK_F1,                 _T("F1")},\r
160         {VK_F2,                 _T("F2")},\r
161         {VK_F3,                 _T("F3")},\r
162         {VK_F4,                 _T("F4")},\r
163         {VK_F5,                 _T("F5")},\r
164         {VK_F6,                 _T("F6")},\r
165         {VK_F7,                 _T("F7")},\r
166         {VK_F8,                 _T("F8")},\r
167         {VK_F9,                 _T("F9")},\r
168         {VK_F10,                _T("F10")},\r
169         {VK_F11,                _T("F11")},\r
170         {VK_F12,                _T("F12")},\r
171         {VK_F13,                _T("F13")},\r
172         {VK_F14,                _T("F14")},\r
173         {VK_F15,                _T("F15")},\r
174         {VK_F16,                _T("F16")},\r
175         {VK_F17,                _T("F17")},\r
176         {VK_F18,                _T("F18")},\r
177         {VK_F19,                _T("F19")},\r
178         {VK_F20,                _T("F20")},\r
179         {VK_F21,                _T("F21")},\r
180         {VK_F22,                _T("F22")},\r
181         {VK_F23,                _T("F23")},\r
182         {VK_F24,                _T("F24")},\r
183         {0x88,                  _T("Unassigned")},\r
184         {0x89,                  _T("Unassigned")},\r
185         {0x8a,                  _T("Unassigned")},\r
186         {0x8b,                  _T("Unassigned")},\r
187         {0x8c,                  _T("Unassigned")},\r
188         {0x8d,                  _T("Unassigned")},\r
189         {0x8e,                  _T("Unassigned")},\r
190         {0x8f,                  _T("Unassigned")},\r
191         {VK_NUMLOCK,    _T("Num Lock")},\r
192         {VK_SCROLL,             _T("Scroll Lock")},\r
193         {0x92,                  _T("OEM specific")},\r
194         {0x93,                  _T("OEM specific")},\r
195         {0x94,                  _T("OEM specific")},\r
196         {0x95,                  _T("OEM specific")},\r
197         {0x96,                  _T("OEM specific")},\r
198         {0x97,                  _T("Unassigned")},\r
199         {0x98,                  _T("Unassigned")},\r
200         {0x99,                  _T("Unassigned")},\r
201         {0x9a,                  _T("Unassigned")},\r
202         {0x9b,                  _T("Unassigned")},\r
203         {0x9c,                  _T("Unassigned")},\r
204         {0x9d,                  _T("Unassigned")},\r
205         {0x9e,                  _T("Unassigned")},\r
206         {0x9f,                  _T("Unassigned")},\r
207         {VK_LSHIFT,             _T("Left Shift")},\r
208         {VK_RSHIFT,             _T("Right Shift")},\r
209         {VK_LCONTROL,   _T("Left Ctrl")},\r
210         {VK_RCONTROL,   _T("Right Ctrl")},\r
211         {VK_LMENU,              _T("Left Alt")},\r
212         {VK_RMENU,              _T("Right Alt")},\r
213         {0xa6,                  _T("Browser Back")},            // VK_BROWSER_BACK\r
214         {0xa7,                  _T("Browser Forward")},         // VK_BROWSER_FORWARD\r
215         {0xa8,                  _T("Browser Refresh")},         // VK_BROWSER_REFRESH\r
216         {0xa9,                  _T("Browser Stop")},            // VK_BROWSER_STOP\r
217         {0xaa,                  _T("Browser Search")},          // VK_BROWSER_SEARCH\r
218         {0xab,                  _T("Browser Favorites")},       // VK_BROWSER_FAVORITES\r
219         {0xac,                  _T("Browser Start")},           // VK_BROWSER_HOME\r
220         {0xad,                  _T("Volume Mute")},                     // VK_VOLUME_MUTE\r
221         {0xae,                  _T("Volume Down")},                     // VK_VOLUME_DOWN\r
222         {0xaf,                  _T("Volume Up")},                       // VK_VOLUME_UP\r
223         {0xb0,                  _T("Next Track")},                      // VK_MEDIA_NEXT_TRACK\r
224         {0xb1,                  _T("Previous Track")},          // VK_MEDIA_PREV_TRACK\r
225         {0xb2,                  _T("Stop Media")},                      // VK_MEDIA_STOP\r
226         {0xb3,                  _T("Play/Pause Media")},        // VK_MEDIA_PLAY_PAUSE\r
227         {0xb4,                  _T("Start Mail")},                      // VK_LAUNCH_MAIL\r
228         {0xb5,                  _T("Select Media")},            // VK_LAUNCH_MEDIA_SELECT\r
229         {0xb6,                  _T("Start Application 1")},     // VK_LAUNCH_APP1\r
230         {0xb7,                  _T("Start Application 2")},     // VK_LAUNCH_APP2\r
231         {0xb8,                  _T("Reserved")},\r
232         {0xb9,                  _T("Reserved")},\r
233         {0xba,                  _T(";")},                                       // VK_OEM_1\r
234 //      {0xba,                  _T(":")},                                       // VK_OEM_1             // for Japanese keyboard\r
235         {0xbb,                  _T("+")},                                       // VK_OEM_PLUS\r
236 //      {0xbb,                  _T(";")},                                       // VK_OEM_PLUS  // for Japanese keyboard\r
237         {0xbc,                  _T(",")},                                       // VK_OEM_COMMA\r
238         {0xbd,                  _T("-")},                                       // VK_OEM_MINUS\r
239         {0xbe,                  _T(".")},                                       // VK_OEM_PERIOD\r
240         {0xbf,                  _T("/")},                                       // VK_OEM_2\r
241         {0xc0,                  _T("`")},                                       // VK_OEM_3\r
242 //      {0xc0,                  _T("@")},                                       // VK_OEM_3             // for Japanese keyboard\r
243         {0xc1,                  _T("Reserved")},\r
244         {0xc2,                  _T("Reserved")},\r
245         {0xc3,                  _T("Reserved")},\r
246         {0xc4,                  _T("Reserved")},\r
247         {0xc5,                  _T("Reserved")},\r
248         {0xc6,                  _T("Reserved")},\r
249         {0xc7,                  _T("Reserved")},\r
250         {0xc8,                  _T("Reserved")},\r
251         {0xc9,                  _T("Reserved")},\r
252         {0xca,                  _T("Reserved")},\r
253         {0xcb,                  _T("Reserved")},\r
254         {0xcc,                  _T("Reserved")},\r
255         {0xcd,                  _T("Reserved")},\r
256         {0xce,                  _T("Reserved")},\r
257         {0xcf,                  _T("Reserved")},\r
258         {0xd0,                  _T("Reserved")},\r
259         {0xd1,                  _T("Reserved")},\r
260         {0xd2,                  _T("Reserved")},\r
261         {0xd3,                  _T("Reserved")},\r
262         {0xd4,                  _T("Reserved")},\r
263         {0xd5,                  _T("Reserved")},\r
264         {0xd6,                  _T("Reserved")},\r
265         {0xd7,                  _T("Reserved")},\r
266         {0xd8,                  _T("Unassigned")},\r
267         {0xd9,                  _T("Unassigned")},\r
268         {0xda,                  _T("Unassigned")},\r
269         {0xdb,                  _T("[")},                                       // VK_OEM_4\r
270         {0xdc,                  _T("Backslash")},                       // VK_OEM_5\r
271         {0xdd,                  _T("]")},                                       // VK_OEM_6\r
272         {0xde,                  _T("'")},                                       // VK_OEM_7\r
273         {0xdf,                  _T("OEM specific")},            // VK_OEM_8\r
274         {0xe0,                  _T("Reserved")},\r
275         {0xe1,                  _T("OEM specific")},\r
276         {0xe2,                  _T("Backslash for 106 keyboard")},      // VK_OEM_102\r
277         {0xe3,                  _T("OEM specific")},\r
278         {0xe4,                  _T("OEM specific")},\r
279         {0xe5,                  _T("Process")},                         // VK_PROCESSKEY\r
280         {0xe6,                  _T("OEM specific")},\r
281         {0xe7,                  _T("Packet")},  // VK_PACKET\r
282         {0xe8,                  _T("Unassigned")},\r
283         {0xe9,                  _T("OEM specific")},\r
284         {0xea,                  _T("OEM specific")},\r
285         {0xeb,                  _T("OEM specific")},\r
286         {0xec,                  _T("OEM specific")},\r
287         {0xed,                  _T("OEM specific")},\r
288         {0xee,                  _T("OEM specific")},\r
289         {0xef,                  _T("OEM specific")},\r
290         {0xf0,                  _T("Eisu")},                                    // \89p\90\94\r
291         {0xf1,                  _T("OEM specific")},\r
292         {0xf2,                  _T("Hiragana")},                                // \82Ð\82ç\82ª\82È\r
293         {0xf3,                  _T("Hankaku/Zenkaku 0xf3")},    // "\94¼\8ap/\91S\8ap"\r
294         {0xf4,                  _T("Hankaku/Zenkaku 0xf4")},    // "\94¼\8ap/\91S\8ap"\r
295         {0xf5,                  _T("OEM specific")},\r
296         {VK_ATTN,               _T("Attn")},\r
297         {VK_CRSEL,              _T("CrSel")},\r
298         {VK_EXSEL,              _T("ExSel")},\r
299         {VK_EREOF,              _T("Erace EOF")},\r
300         {VK_PLAY,               _T("Play")},\r
301         {VK_ZOOM,               _T("Zoom")},\r
302         {VK_NONAME,             _T("Noname")},\r
303         {VK_PA1,                _T("PA1")},\r
304         {VK_OEM_CLEAR,  _T("OEM Clear")},\r
305         {0xff,                  _T("Fn")},\r
306 };\r
307 \r
308 CONFIG CProfile::m_Config;\r
309 TCHAR CProfile::m_szAppTitle[MAX_APP][WINDOW_TEXT_LENGTH];\r
310 TASK_LIST CProfile::m_TaskList[MAX_TASKS];\r
311 DWORD CProfile::m_dwTasks;\r
312 \r
313 enum { INITIAL_SIZE     = 51200 };\r
314 enum { EXTEND_SIZE      = 25600 };\r
315 \r
316 void CProfile::Item2AppName(CString *const sz)\r
317 {\r
318         if (IsTheString(*sz, IDS_DEFAULT_TITLE)) {\r
319                 sz->LoadString(IDS_DEFAULT);\r
320         }\r
321 \r
322         if (IsTheString(*sz, IDS_DIALOG_TITLE)) {\r
323                 sz->LoadString(IDS_DIALOG);\r
324         }\r
325 \r
326         int nStart, nEnd, nCount;\r
327 \r
328         nStart  = sz->ReverseFind(_T('(')) + 1;\r
329         nEnd    = sz->Find(_T(')'), nStart) - 1;\r
330         nCount  = (nEnd + 1) - nStart;\r
331         *sz             = sz->Mid(nStart, nCount);\r
332 }\r
333 \r
334 int CProfile::IsNotSameString(CComboBox *const pApplication, const CString szListItem)\r
335 {\r
336         CString szItem, szList;\r
337         szList = szListItem;\r
338         Item2AppName(&szList);\r
339 \r
340         for (int i = 0; i < pApplication->GetCount(); ++i) {\r
341                 pApplication->GetLBText(i, szItem);\r
342                 Item2AppName(&szItem);\r
343                 if (!_tcsicmp(szItem, szList)) {\r
344                         return 0;\r
345                 }\r
346         }\r
347 \r
348         return 1;\r
349 }\r
350 \r
351 int CProfile::CountSeparator(const CString szMainString, const CString szSeparator)\r
352 {\r
353         int index       = 0;\r
354         int counter     = 0;\r
355 \r
356         while ((index = szMainString.Find(szSeparator, index)) != -1) {\r
357                 ++index;\r
358                 ++counter;\r
359         }\r
360 \r
361         return counter;\r
362 }\r
363 \r
364 void CProfile::GetNthString(CString *const szAppName, const CString szWindowName, const CString szSeparator, int n)\r
365 {\r
366         int index = -1;\r
367 \r
368         while (--n) {\r
369                 index = szWindowName.Find(szSeparator, index + 1);\r
370         }\r
371 \r
372         int nStart;\r
373         if (index != -1) {\r
374                 nStart = index + szSeparator.GetLength();\r
375         } else {\r
376                 nStart = 0;\r
377         }\r
378 \r
379         int nEnd = szWindowName.Find(szSeparator, nStart);\r
380         if (nEnd == -1) {\r
381                 nEnd = szWindowName.GetLength();\r
382         }\r
383 \r
384         *szAppName = szWindowName.Mid(nStart, nEnd - nStart);\r
385 }\r
386 \r
387 void CProfile::GetAppName(CString *const szAppName, LPCTSTR pWindowName)\r
388 {\r
389         CString szWindowName(pWindowName);\r
390         CString szSeparator(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE));\r
391         int nWord = CountSeparator(szWindowName, szSeparator) + 1;\r
392 \r
393         while (nWord) {\r
394                 GetNthString(szAppName, szWindowName, szSeparator, nWord);\r
395                 if (szAppName->GetAt(0) == _T('[')\r
396                  || szAppName->Find(_T('.'), 0) != -1           // for Microsoft Project\r
397                  || szAppName->Find(_T(']'), 0) != -1) {        // for the file name like [foo - bar]\r
398                         --nWord;\r
399                 } else {\r
400                         return;\r
401                 }\r
402         }\r
403 \r
404         *szAppName = szWindowName;\r
405 }\r
406 \r
407 BOOL CALLBACK CProfile::EnumWindowsProc(const HWND hWnd, const LPARAM lParam)\r
408 {\r
409         CComboBox               *pApplication   = (CComboBox*)lParam;\r
410         PTASK_LIST              pTask                   = CProfile::m_TaskList;\r
411         \r
412         TCHAR szWindowName[WINDOW_TEXT_LENGTH];\r
413         TCHAR szClassName[CLASS_NAME_LENGTH];\r
414         WINDOWPLACEMENT wpl;\r
415         \r
416         wpl.length = sizeof(WINDOWPLACEMENT);\r
417         ::GetWindowText(hWnd, szWindowName, sizeof(szWindowName));\r
418         GetClassName(hWnd, szClassName, sizeof(szClassName));\r
419 \r
420         CString szAppName;\r
421         // Get Process Name\r
422         DWORD dwProcessId = 0;\r
423         GetWindowThreadProcessId(hWnd, &dwProcessId);\r
424         DWORD i;\r
425         for (i = 0; i < CProfile::m_dwTasks; ++i) {\r
426                 if (pTask[i].dwProcessId == dwProcessId) {\r
427 \r
428                         // Get Application Name\r
429                         if (szWindowName[0] == '\0') {\r
430                                 continue;\r
431                         }\r
432                         if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_B2)), sizeof(pTask[i].ProcessName))) {\r
433                                 szAppName.LoadString(IDS_BECKY);\r
434                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXPLORER)), sizeof(pTask[i].ProcessName))) {\r
435                                 szAppName.LoadString(IDS_PROGRAM_MANAGER);\r
436                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSIMN)), sizeof(pTask[i].ProcessName))) {\r
437                                 szAppName.LoadString(IDS_OUTLOOK_EXPRESS);\r
438                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_PROJECT)), sizeof(pTask[i].ProcessName))\r
439                                         || !_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXCEL)), sizeof(pTask[i].ProcessName))\r
440                                         || !_tcsnicmp(pTask[i].ProcessName, _T("psp.exe"), sizeof(pTask[i].ProcessName))) {\r
441                                 GetNthString(&szAppName, szWindowName, CString(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE)), 1);\r
442                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sakura.exe"), sizeof(pTask[i].ProcessName))) {\r
443                                 GetNthString(&szAppName, szWindowName, CString(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE)), 2);  // '.' is included, so...\r
444                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSDN)), sizeof(pTask[i].ProcessName))) {\r
445                                 szAppName = szWindowName;\r
446                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("devenv.exe"), sizeof(pTask[i].ProcessName))) {\r
447                                 szAppName.Format(_T("Microsoft Visual Studio .NET"));\r
448                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vb6.exe"), sizeof(pTask[i].ProcessName))) {\r
449                                 szAppName.Format(_T("Microsoft Visual Basic"));\r
450                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("ssexp.exe"), sizeof(pTask[i].ProcessName))) {\r
451                                 szAppName.LoadString(IDS_VISUAL_SOURCESAFE_EXPLORER);\r
452                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sh.exe"), sizeof(pTask[i].ProcessName))) {\r
453                                 szAppName.Format(_T("MKS Korn Shell"));\r
454                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("csh.exe"), sizeof(pTask[i].ProcessName))) {\r
455                                 szAppName.Format(_T("C Shell"));\r
456                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vim.exe"), sizeof(pTask[i].ProcessName))) {\r
457                                 szAppName.Format(_T("VIM"));\r
458                         } else {\r
459                                 CUtils::SetCorrectApplicationName(pTask[i].ProcessName, szWindowName);\r
460                                 GetAppName(&szAppName, szWindowName);\r
461                         }\r
462                         break;\r
463                 }\r
464         }\r
465         \r
466         \r
467         if ((IsWindowVisible(hWnd))                                                                     // Is visible?\r
468          && (GetWindow(hWnd, GW_OWNER) == NULL)                                         // Is top level window?\r
469          && (lstrlen(szWindowName) > 0)                                                         // Have caption?\r
470          && (pApplication->FindString(-1, szClassName) == CB_ERR)) {// Is not same string?\r
471                 CString szListItem;\r
472                 szListItem.Format(IDS_APPLICATION_LIST_ITEM, szAppName, pTask[i].ProcessName);\r
473                 if (IsNotSameString(pApplication, szListItem)) {\r
474                         pApplication->AddString(szListItem);\r
475                 }\r
476         }\r
477         return TRUE;\r
478 }\r
479 \r
480 void CProfile::LoadRegistry()\r
481 {\r
482         bool bDialog = false;\r
483         const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));    \r
484         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
485                 CString entry;\r
486                 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
487                 CString appName = AfxGetApp()->GetProfileString(section, entry);\r
488                 if (appName.IsEmpty())  {\r
489                         if (nAppID) {\r
490                                 if (bDialog)\r
491                                         continue;\r
492                                 appName.LoadString(IDS_DIALOG);\r
493                                 bDialog = true;\r
494                         } else\r
495                                 appName.LoadString(IDS_DEFAULT);\r
496                 } else if (appName == CString(MAKEINTRESOURCE(IDS_DIALOG)))\r
497                         bDialog = true;\r
498                 _tcsncpy_s(m_Config.szSpecialApp[nAppID], appName, _TRUNCATE);\r
499                 entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
500                 _tcsncpy_s(m_szAppTitle[nAppID], AfxGetApp()->GetProfileString(appName, entry), _TRUNCATE);\r
501                 entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
502                 _tcsncpy_s(m_Config.szWindowText[nAppID], AfxGetApp()->GetProfileString(appName, entry, _T("*")), _TRUNCATE);\r
503 \r
504                 const CString regApp = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName;\r
505                 for (int nComID = 1; nComID < MAX_COMMAND; ++nComID) {\r
506                         entry = CCommands::GetCommandName(nComID);\r
507                         HKEY hKey;\r
508                         const CString regKey = regApp + _T("\\") + entry;\r
509                         if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
510                                 TCHAR szKeyBind[128];\r
511                                 DWORD dwKeyBind = _countof(szKeyBind);\r
512                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
513                                         int nType, nKey;\r
514                                         ReadKeyBind(nType, nKey, szKeyBind);\r
515                                         m_Config.nCommandID[nAppID][nType][nKey] = nComID;\r
516                                         dwKeyBind = _countof(szKeyBind);\r
517                                 }\r
518                                 RegCloseKey(hKey);\r
519                         } else {\r
520                                 // Set the default assignment\r
521                                 for (int i = 0; const int nKey = CCommands::GetDefaultCommandKey(nComID, i); ++i) {\r
522                                         if (CCommands::GetDefaultControlID(nComID, i) == IDC_CO2)\r
523                                                 continue;\r
524                                         const int nType = CCommands::GetDefaultCommandType(nComID, i);\r
525                                         m_Config.nCommandID[nAppID][nType][nKey] = nComID;\r
526                                 }\r
527                         }\r
528                 }\r
529                 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {\r
530                         HKEY hKey;\r
531                         const CString regKey = regApp + _T("\\") + CDotXkeymacs::GetFunctionSymbol(nFuncID);\r
532                         if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
533                                 CDotXkeymacs::ClearKey(nFuncID, nAppID);\r
534                                 TCHAR szKeyBind[128];\r
535                                 DWORD dwKeyBind = _countof(szKeyBind);\r
536                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
537                                         int nType, nKey;\r
538                                         ReadKeyBind(nType, nKey, szKeyBind);\r
539                                         CDotXkeymacs::SetKey(nFuncID, nAppID, nType, nKey);\r
540                                         dwKeyBind = _countof(szKeyBind);\r
541                                 }\r
542                                 RegCloseKey(hKey);\r
543                         }\r
544                 }\r
545 \r
546                 entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
547                 m_Config.nKillRingMax[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 1);\r
548                 entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
549                 m_Config.bUseDialogSetting[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 1);\r
550                 entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
551                 m_Config.nSettingStyle[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0) ? SETTING_DISABLE : SETTING_SPECIFIC;\r
552                 entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
553                 m_Config.bIgnoreUndefinedMetaCtrl[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0);\r
554                 entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
555                 m_Config.bIgnoreUndefinedC_x[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0);\r
556                 entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
557                 m_Config.bEnableCUA[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0);\r
558                 entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
559                 m_Config.b326Compatible[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0);\r
560         }\r
561 }\r
562 \r
563 void CProfile::SaveRegistry()\r
564 {\r
565         const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));    \r
566         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
567                 const LPCTSTR szAppName = m_Config.szSpecialApp[nAppID];\r
568                 CString entry;\r
569                 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
570                 if (!szAppName[0]) {\r
571                         if (!AfxGetApp()->GetProfileString(section, entry).IsEmpty())\r
572                                 AfxGetApp()->WriteProfileString(section, entry, _T(""));\r
573                         continue;\r
574                 }\r
575                 AfxGetApp()->WriteProfileString(section, entry, szAppName);\r
576 \r
577                 entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
578                 CString appTitle = m_szAppTitle[nAppID];\r
579                 appTitle.TrimLeft(_T(' '));\r
580                 AfxGetApp()->WriteProfileString(szAppName, entry, appTitle);\r
581                 entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
582                 AfxGetApp()->WriteProfileString(szAppName, entry, m_Config.szWindowText[nAppID]);\r
583 \r
584                 const CString regApp = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + szAppName;\r
585                 // Create all commands\r
586                 for (int nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
587                         SaveCommand(szAppName, nComID);\r
588                 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)\r
589                         for (int nKey = 0; nKey < MAX_KEY; ++nKey)\r
590                                 SaveKeyBind(szAppName, m_Config.nCommandID[nAppID][nType][nKey], nType, nKey);\r
591                 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
592                         for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFuncID, nAppID); ++nKeyID) {\r
593                                 int nType, nKey;\r
594                                 CDotXkeymacs::GetKey(nFuncID, nAppID, nKeyID, &nType, &nKey);\r
595                                 SaveKeyBind(szAppName, CDotXkeymacs::GetFunctionSymbol(nFuncID), nType, nKey);\r
596                         }\r
597 \r
598                 entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
599                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.nKillRingMax[nAppID]);\r
600                 entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
601                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bUseDialogSetting[nAppID]);\r
602                 entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
603                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.nSettingStyle[nAppID] == SETTING_DISABLE);\r
604                 entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
605                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bIgnoreUndefinedMetaCtrl[nAppID]);\r
606                 entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
607                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bIgnoreUndefinedC_x[nAppID]);\r
608                 entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
609                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bEnableCUA[nAppID]);\r
610                 entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
611                 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.b326Compatible[nAppID]);\r
612         }\r
613 }\r
614 \r
615 void CProfile::LoadData()\r
616 {\r
617         CDotXkeymacs::Load();\r
618         LevelUp();\r
619         LoadRegistry();\r
620 }\r
621 \r
622 void CProfile::SaveData()\r
623 {\r
624         DeleteAllRegistryData();\r
625         SaveRegistry();\r
626         SetDllData();\r
627 }\r
628 \r
629 void CProfile::SetDllData()\r
630 {\r
631         memset(m_Config.nFunctionID, -1, sizeof(m_Config.nFunctionID));\r
632         for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
633                 _tcscpy_s(m_Config.szFunctionDefinition[nFuncID], CDotXkeymacs::GetFunctionDefinition(nFuncID));\r
634 \r
635         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
636                 m_Config.nCommandID[nAppID][CONTROL]['X'] = 0; // C-x is unassigned.\r
637                 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)\r
638                         for (int nKey = 0; nKey < MAX_KEY; ++nKey)\r
639                                 if ((nType & CONTROLX) && m_Config.nCommandID[nAppID][nType][nKey])\r
640                                         m_Config.nCommandID[nAppID][CONTROL]['X'] = 1; // C-x is available.\r
641                 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
642                         for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFuncID, nAppID); ++nKeyID) {\r
643                                 int nType, nKey;\r
644                                 CDotXkeymacs::GetKey(nFuncID, nAppID, nKeyID, &nType, &nKey);\r
645                                 m_Config.nFunctionID[nAppID][nType][nKey] = nFuncID;\r
646                                 if (nType & CONTROLX)\r
647                                         m_Config.nCommandID[nAppID][CONTROL]['X'] = 1; // C-x is available.\r
648                         }\r
649         }\r
650         m_Config.b106Keyboard = Is106Keyboard();\r
651         CXkeymacsDll::SetConfig(m_Config);\r
652         CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());\r
653         if (!pApp->IsWow64())\r
654                 return;\r
655         if (!CXkeymacsDll::SaveConfig())\r
656                 return;\r
657         pApp->SendIPCMessage(XKEYMACS_RELOAD);\r
658 }\r
659 \r
660 void CProfile::ReadKeyBind(int& nCommandType, int& nKey, const LPCTSTR szKeyBind)\r
661 {\r
662         nCommandType = KeyBind2CommandType(szKeyBind);\r
663         nKey = KeyBind2Key(szKeyBind + _tcslen(CommandType2String(nCommandType)));\r
664 }\r
665 \r
666 CString CProfile::WriteKeyBind(const int nType, const int nKey)\r
667 {\r
668         CString szKeyBind;\r
669         szKeyBind.Format(_T("%s%s"), CommandType2String(nType), Key2String(nKey));\r
670         return szKeyBind;\r
671 }\r
672 \r
673 int CProfile::KeyBind2CommandType(LPCTSTR szKeyBind)\r
674 {\r
675         for (int nType = MAX_COMMAND_TYPE - 1; nType; --nType) {\r
676                 if (IsCommandType(nType, szKeyBind)) {\r
677                         return nType;\r
678                 }\r
679         }\r
680         return NONE;\r
681 }\r
682 \r
683 int CProfile::KeyBind2Key(LPCTSTR szKey)\r
684 {\r
685         for (int nKey = 1; nKey <= 0xff; ++nKey) {\r
686                 if (!_tcscmp(szKey, Key2String(nKey))) {\r
687                         return nKey;\r
688                 }\r
689         }\r
690         return 0;\r
691 }\r
692 \r
693 LPCTSTR CProfile::CommandType2String(int nType)\r
694 {\r
695         if (nType < 0 || sizeof(CommandTypes) / sizeof(CommandTypes[0]) <= nType) {\r
696                 ASSERT(0);\r
697                 nType = NONE;\r
698         }\r
699         return CommandTypes[nType].szName;\r
700 }\r
701 \r
702 LPCTSTR CProfile::Key2String(int nKey)\r
703 {\r
704         if (CProfile::Is106Keyboard()) {\r
705                 switch (nKey) {\r
706                 case 0xBA:\r
707                         return _T(":");\r
708                 case 0xBB:\r
709                         return _T(";");\r
710                 case 0xC0:\r
711                         return _T("@");\r
712                 case 0xDE:\r
713                         return _T("^");\r
714                 default:\r
715                         break;\r
716                 }\r
717         }\r
718 \r
719         if (nKey < 0 || sizeof(KeyNames) / sizeof(KeyNames[0]) <= nKey) {\r
720                 ASSERT(0);\r
721                 nKey = 0;\r
722         }\r
723         return KeyNames[nKey].name;\r
724 }\r
725 \r
726 BOOL CProfile::IsCommandType(const int nType, LPCTSTR szKeyBind)\r
727 {\r
728         LPCTSTR szCommandType = CommandType2String(nType);\r
729 \r
730         if (!_tcsnicmp(szKeyBind, szCommandType, _tcslen(szCommandType))) {\r
731                 return TRUE;\r
732         }\r
733 \r
734         return FALSE;\r
735 }\r
736 \r
737 void CProfile::SaveKeyBind(const LPCSTR szAppName, const int nComID, const int nType, const int nKey)\r
738 {\r
739         if (!nComID)\r
740                 return;\r
741         const LPCSTR szComName = CCommands::GetCommandName(nComID);\r
742         if (!szComName[0])\r
743                 return;\r
744         SaveKeyBind(szAppName, szComName, nType, nKey);\r
745 }\r
746 \r
747 void CProfile::SaveKeyBind(const LPCSTR szAppName, const LPCSTR szComName, const int nType, const int nKey)\r
748 {\r
749         const CString szKeyBind = WriteKeyBind(nType, nKey);\r
750         CString szSubKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + szAppName + _T("\\") + szComName;\r
751         if (!szKeyBind.IsEmpty())\r
752                 szSubKey += _T("\\") + szKeyBind;\r
753         HKEY hKey = NULL;\r
754         if (RegCreateKeyEx(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)\r
755                 RegCloseKey(hKey);\r
756 }\r
757 \r
758 void CProfile::SaveCommand(const LPCSTR szAppName, const int nComID)\r
759 {\r
760         SaveKeyBind(szAppName, nComID, 0, 0);\r
761 }\r
762 \r
763 void CProfile::AddKeyBind2C_(const LPCSTR szAppName, const BYTE bVk)\r
764 {\r
765         int nComID;\r
766         for (nComID = 0; nComID < MAX_COMMAND; ++nComID)\r
767                 if (Commands[nComID].fCommand == CCommands::C_)\r
768                         break;\r
769         SaveKeyBind(szAppName, nComID, NONE, bVk);\r
770 }\r
771 \r
772 void CProfile::LevelUp()\r
773 {\r
774         const int nDefalutLevel = 0;\r
775         const int nLatestLevel = 4;\r
776 \r
777         CString szSection;\r
778         CString szEntry;\r
779         szEntry.Format(_T("Level"));\r
780 \r
781         switch (AfxGetApp()->GetProfileInt(szSection, szEntry, nDefalutLevel)) {\r
782         case nDefalutLevel:\r
783                 {\r
784                         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
785                                 CString szEntry;\r
786                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
787 \r
788                                 CString szApplicationName;\r
789                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
790                                 if (szApplicationName.IsEmpty()) {\r
791                                         continue;\r
792                                 }\r
793 \r
794                                 AddKeyBind2C_(szApplicationName, VK_LCONTROL);\r
795                                 AddKeyBind2C_(szApplicationName, VK_RCONTROL);\r
796                         }\r
797                 }\r
798                 // Do NOT write break; here.\r
799         case 1:\r
800                 {\r
801                         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
802                                 CString szEntry;\r
803                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
804 \r
805                                 CString szApplicationName;\r
806                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
807                                 if (szApplicationName.IsEmpty()) {\r
808                                         continue;\r
809                                 }\r
810 \r
811                                 // Set kill-ring-max 1 if it is 0.\r
812                                 if (!AfxGetApp()->GetProfileInt(szApplicationName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 0)) {\r
813                                         AfxGetApp()->WriteProfileInt(szApplicationName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 1);\r
814                                 }\r
815                         }\r
816                 }\r
817                 // Do NOT write break; here.\r
818         case 2:\r
819                 {\r
820                         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
821                                 CString szEntry;\r
822                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
823 \r
824                                 CString szApplicationName;\r
825                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
826                                 if (szApplicationName.IsEmpty()) {\r
827                                         continue;\r
828                                 }\r
829 \r
830                                 // Chaged a label from Enter to newline.\r
831                                 CString szSrcSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
832                                 szSrcSubKey += _T("\\") + szApplicationName + _T("\\") + _T("Enter");\r
833                                 CString szDestSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
834                                 szDestSubKey += _T("\\") + szApplicationName + _T("\\") + _T("newline");\r
835                                 HKEY hKeyDest = NULL;\r
836                                 if (RegCreateKeyEx(HKEY_CURRENT_USER, szDestSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyDest, NULL) == ERROR_SUCCESS) {\r
837                                         SHCopyKey(HKEY_CURRENT_USER, szSrcSubKey, hKeyDest, NULL);\r
838                                         SHDeleteKey(HKEY_CURRENT_USER, szSrcSubKey);\r
839                                         RegCloseKey(hKeyDest);\r
840                                 }\r
841                         }\r
842                 }\r
843                 // Do NOT write break; here.\r
844         case 3:\r
845                 {\r
846                         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
847                                 CString szEntry;\r
848                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
849 \r
850                                 CString szApplicationName;\r
851                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
852                                 if (szApplicationName.IsEmpty()) {\r
853                                         continue;\r
854                                 }\r
855 \r
856                                 // rename original function to remove IDS_REG_ORIGINAL_PREFIX\r
857                                 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {\r
858                                         HKEY hKey = NULL;\r
859                                         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
860                                         szSubKey += _T("\\") + szApplicationName + _T("\\") + CString(MAKEINTRESOURCE(IDS_REG_ORIGINAL_PREFIX)) + CDotXkeymacs::GetFunctionSymbol(nFuncID);\r
861                                         if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
862                                                 // Use registry data\r
863                                                 TCHAR szKeyBind[128] = {'\0'};\r
864                                                 DWORD dwKeyBind = sizeof(szKeyBind);\r
865                                                 FILETIME ft = {'\0'};   // not use\r
866                                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS; ++dwIndex) {\r
867                                                         int nType, nKey;\r
868                                                         ReadKeyBind(nType, nKey, szKeyBind);\r
869                                                         SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFuncID), nType, nKey);\r
870 \r
871                                                         memset(szKeyBind, 0, sizeof(szKeyBind));\r
872                                                         dwKeyBind = sizeof(szKeyBind);\r
873                                                 }\r
874                                                 RegCloseKey(hKey);\r
875                                         }\r
876                                 }\r
877                         }\r
878                 }\r
879 //      case 4:\r
880 //              foo();\r
881 //      ...\r
882 //      case nLatestLevel-1:\r
883 //              bar();\r
884                 AfxGetApp()->WriteProfileInt(szSection, szEntry, nLatestLevel);\r
885                 break;\r
886         default:\r
887                 break;\r
888         }\r
889 }\r
890 \r
891 void CProfile::InitDllData()\r
892 {\r
893         LoadData();\r
894         SetDllData();\r
895 }\r
896 \r
897 void CProfile::ClearData(const CString szCurrentApplication)\r
898 {\r
899         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
900                 if (szCurrentApplication == m_Config.szSpecialApp[nAppID]) {\r
901                         ZeroMemory(m_Config.nCommandID[nAppID], sizeof(m_Config.nCommandID[nAppID]));\r
902                         ZeroMemory(m_Config.szSpecialApp[nAppID], CLASS_NAME_LENGTH);\r
903                         return;\r
904                 }\r
905 }\r
906 \r
907 // return count of saved settings\r
908 int CProfile::GetSavedSettingCount()\r
909 {\r
910         int nSavedSetting = 0;\r
911         for (int nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
912                 if (m_Config.szSpecialApp[nAppID][0])\r
913                         ++nSavedSetting;\r
914         return nSavedSetting;\r
915 }\r
916 \r
917 void CProfile::InitApplicationList(CComboBox *const cApplicationList)\r
918 {\r
919         cApplicationList->ResetContent();\r
920 \r
921         GetTaskList();\r
922 \r
923         EnumWindows(EnumWindowsProc, (LPARAM)cApplicationList);\r
924 \r
925         CString szListItem;\r
926         for (int i = 0; i < MAX_APP; ++i) {\r
927                 const LPCTSTR szAppName = m_Config.szSpecialApp[i];\r
928                 const LPCTSTR szAppTitle = m_szAppTitle[i];\r
929                 if (!szAppName[0] || !_tcscmp(szAppName, _T("IME")))\r
930                         continue;\r
931                 szListItem.Format(IDS_APPLICATION_LIST_ITEM, szAppTitle, szAppName);\r
932                 if (IsNotSameString(cApplicationList, szListItem) &&\r
933                                 !IsDefault(szAppName) && !IsDialog(szAppName))\r
934                         cApplicationList->AddString(szListItem);\r
935         }\r
936 \r
937         AddIMEInfo(cApplicationList);\r
938 \r
939         // Add Dialog\r
940         cApplicationList->InsertString(0, CString(MAKEINTRESOURCE(IDS_DIALOG_TITLE)));\r
941 \r
942         // Add Default\r
943         cApplicationList->InsertString( 0, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));\r
944         cApplicationList->SelectString(-1, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));\r
945 }\r
946 \r
947 void CProfile::AddIMEInfo(CComboBox *cApplicationList)\r
948 {\r
949         const UINT n = GetKeyboardLayoutList(0, NULL);\r
950         if (!n)\r
951                 return;\r
952         std::vector<HKL> hkls(n);\r
953         GetKeyboardLayoutList(n, &hkls[0]);\r
954         TCHAR szFileName[MAX_PATH];\r
955         TCHAR szDescription[WINDOW_TEXT_LENGTH];\r
956         for (std::vector<HKL>::const_iterator p = hkls.begin(); p != hkls.end(); ++p)\r
957                 if (ImmGetDescription(*p, szDescription, WINDOW_TEXT_LENGTH) &&\r
958                                 ImmGetIMEFileName(*p, szFileName, MAX_PATH)) {\r
959                         CString item;\r
960                         item.Format(IDS_APPLICATION_LIST_ITEM, szDescription, szFileName);\r
961                         if (IsNotSameString(cApplicationList, item))\r
962                                 cApplicationList->AddString(item);\r
963                 }\r
964 }\r
965 \r
966 void CProfile::GetTaskList()\r
967 {\r
968         ZeroMemory(m_TaskList, sizeof(m_TaskList));\r
969 \r
970         HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r
971         if (hProcessSnap == (HANDLE)-1)\r
972                 return;\r
973 \r
974         m_dwTasks = 0;\r
975         PROCESSENTRY32 processEntry32 = {sizeof(PROCESSENTRY32)};\r
976         if (Process32First(hProcessSnap, &processEntry32)) {\r
977                 do {\r
978                         lstrcpy(m_TaskList[m_dwTasks].ProcessName, processEntry32.szExeFile);\r
979                         m_TaskList[m_dwTasks++].dwProcessId = processEntry32.th32ProcessID;\r
980                 } while (m_dwTasks < MAX_TASKS && Process32Next(hProcessSnap, &processEntry32));\r
981         }\r
982 \r
983         CloseHandle(hProcessSnap);\r
984 }\r
985 \r
986 // return application index\r
987 // and update setting style\r
988 // if there is NOT the application in the data, this function takes care of it.\r
989 int CProfile::GetApplicationIndex(const CString szApplicationName, const BOOL bSaveAndValidate, int *const nSettingStyle)\r
990 {\r
991         if (!bSaveAndValidate) // SetDialogData\r
992                 *nSettingStyle = SETTING_UNDEFINED;\r
993         int nAppID = GetApplicationIndex(szApplicationName);\r
994         if (nAppID == MAX_APP) {\r
995                 if (bSaveAndValidate) { // GetDialogData\r
996                         for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
997                                 if (!m_Config.szSpecialApp[nAppID][0]) {\r
998                                         _tcsncpy_s(m_Config.szSpecialApp[nAppID], szApplicationName, _TRUNCATE);\r
999                                         break;\r
1000                                 }\r
1001                         if (nAppID == MAX_APP)\r
1002                                 return nAppID;\r
1003                 } else { // SetDialogData\r
1004                         for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
1005                                 if (IsDefault(m_Config.szSpecialApp[nAppID])) {\r
1006                                         *nSettingStyle = SETTING_DEFAULT;\r
1007                                         break;\r
1008                                 }\r
1009                         if (nAppID == MAX_APP)\r
1010                                 return nAppID;\r
1011                 }\r
1012         }\r
1013         if (bSaveAndValidate) // GetDialogData\r
1014                 m_Config.nSettingStyle[nAppID] = *nSettingStyle;\r
1015         else { // SetDialogData\r
1016                 if (*nSettingStyle == SETTING_UNDEFINED) // It means that *nSettingStyle != SETTING_DEFAULT.\r
1017                         *nSettingStyle = m_Config.nSettingStyle[nAppID];\r
1018         }\r
1019         return nAppID;\r
1020 }\r
1021 \r
1022 BOOL CProfile::Is106Keyboard()\r
1023 {\r
1024         static KEYBOARD_TYPE keyboard = UNKNOWN_KEYBOARD;\r
1025 \r
1026         if (keyboard == UNKNOWN_KEYBOARD) {\r
1027                 OSVERSIONINFO verInfo = {0};\r
1028                 verInfo.dwOSVersionInfoSize = sizeof (verInfo);\r
1029                 GetVersionEx(&verInfo);\r
1030 \r
1031                 DWORD subtype = 0;\r
1032                 DWORD cbData = sizeof(subtype);\r
1033 \r
1034                 if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {\r
1035                         HKEY hKey = NULL;\r
1036                         CString szSubKey(_T("SYSTEM\\CurrentControlSet\\Services\\i8042prt\\Parameters"));\r
1037                         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
1038                                 static const CString szValueName(_T("OverrideKeyboardSubtype"));\r
1039                                 if (RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE)&subtype, &cbData) != ERROR_SUCCESS) {\r
1040                                         subtype = 0;\r
1041                                 }\r
1042                                 RegCloseKey(hKey);\r
1043                         }\r
1044                 } else if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {\r
1045                         subtype = GetPrivateProfileInt(_T("keyboard"), _T("subtype"), 0, _T("system.ini"));\r
1046                 }\r
1047 \r
1048                 keyboard = (subtype & 0x02) ? JAPANESE_KEYBOARD : ENGLISH_KEYBOARD;\r
1049         }\r
1050 \r
1051         return keyboard == JAPANESE_KEYBOARD;\r
1052 }\r
1053 \r
1054 BOOL CProfile::IsTheString(const CString sz, const UINT nID)\r
1055 {\r
1056         return sz == CString(MAKEINTRESOURCE(nID));\r
1057 }\r
1058 \r
1059 // if sz is "Default", return TRUE\r
1060 BOOL CProfile::IsDefault(const CString sz)\r
1061 {\r
1062         return IsTheString(sz, IDS_DEFAULT);\r
1063 }\r
1064 \r
1065 // if sz is "Dialog", return TRUE\r
1066 BOOL CProfile::IsDialog(const CString sz)\r
1067 {\r
1068         return IsTheString(sz, IDS_DIALOG);\r
1069 }\r
1070 \r
1071 void CProfile::GetApplicationTitle(CComboBox *const cApplicationList, CString &rList, const int nIndex)\r
1072 {\r
1073         if (0 <= nIndex) {\r
1074                 cApplicationList->GetLBText(nIndex, rList);\r
1075         } else {\r
1076                 cApplicationList->GetWindowText(rList);\r
1077         }\r
1078 \r
1079         if (IsTheString(rList, IDS_DEFAULT_TITLE)) {\r
1080                 rList.LoadString(IDS_DEFAULT);\r
1081         }\r
1082 \r
1083         if (IsTheString(rList, IDS_DIALOG_TITLE)) {\r
1084                 rList.LoadString(IDS_DIALOG);\r
1085         }\r
1086 \r
1087         return;\r
1088 }\r
1089 \r
1090 void CProfile::UpdateApplicationTitle(CComboBox *const cApplicationList, const CString szCurrentApplication, const int nAppID, const BOOL bSaveAndValidate)\r
1091 {\r
1092         static CString szApplicationTitle;\r
1093         if (bSaveAndValidate) { // GetDialogData\r
1094                 if (!CProfile::IsDefault(szCurrentApplication))\r
1095                         _tcsncpy_s(m_szAppTitle[nAppID], szApplicationTitle, _TRUNCATE);\r
1096                 szApplicationTitle.Empty();\r
1097         } else { // SetDialogData\r
1098                 CString szListItem;\r
1099                 CProfile::GetApplicationTitle(cApplicationList, szListItem);\r
1100                 const int nEndTitle = szListItem.ReverseFind(_T('('));\r
1101                 if (nEndTitle > 0)\r
1102                         szApplicationTitle = szListItem.Left(nEndTitle);\r
1103         }\r
1104 }\r
1105 \r
1106 void CProfile::SetCommandID(const int nAppID, const int nType, const int nKey, int nComID)\r
1107 {\r
1108         if (nKey == 0xf0 && Commands[nComID].fCommand == CCommands::C_)\r
1109                 // Change CommandID C_Eisu\r
1110                 for (nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
1111                         if (Commands[nComID].fCommand == CCommands::C_Eisu)\r
1112                                 break;\r
1113         m_Config.nCommandID[nAppID][nType][nKey] = nComID;\r
1114 }\r
1115 \r
1116 int CProfile::GetCommandID(const int nAppID, const int nType, const int nKey)\r
1117 {\r
1118         int nComID = m_Config.nCommandID[nAppID][nType][nKey];\r
1119         if (nKey == 0xf0 && Commands[nComID].fCommand == CCommands::C_Eisu)\r
1120                 // Change CommandID C_\r
1121                 for (nComID = 1; nComID < MAX_COMMAND; nComID++)\r
1122                         if (Commands[nComID].fCommand == CCommands::C_)\r
1123                                 break;\r
1124         return nComID;\r
1125 }\r
1126 \r
1127 void CProfile::SetKillRingMax(const int nAppID, const int nKillRingMax)\r
1128 {\r
1129         m_Config.nKillRingMax[nAppID] = nKillRingMax;\r
1130 }\r
1131 \r
1132 int CProfile::GetKillRingMax(const int nAppID)\r
1133 {\r
1134         return m_Config.nKillRingMax[nAppID];\r
1135 }\r
1136 \r
1137 void CProfile::SetUseDialogSetting(const int nAppID, const BOOL bUseDialogSetting)\r
1138 {\r
1139         m_Config.bUseDialogSetting[nAppID] = bUseDialogSetting;\r
1140 }\r
1141 \r
1142 BOOL CProfile::GetUseDialogSetting(const int nAppID)\r
1143 {\r
1144         return m_Config.bUseDialogSetting[nAppID];\r
1145 }\r
1146 \r
1147 void CProfile::SetWindowText(const int nAppID, const CString szWindowText)\r
1148 {\r
1149         if (CUtils::GetWindowTextType(szWindowText) == IDS_WINDOW_TEXT_IGNORE)\r
1150                 _tcscpy_s(m_Config.szWindowText[nAppID], _T("*"));\r
1151         else\r
1152                 _tcsncpy_s(m_Config.szWindowText[nAppID], szWindowText, _TRUNCATE);\r
1153 }\r
1154 \r
1155 CString CProfile::GetWindowText(const int nAppID)\r
1156 {\r
1157         return m_Config.szWindowText[nAppID];\r
1158 }\r
1159 \r
1160 void CProfile::DeleteAllRegistryData()\r
1161 {\r
1162         HKEY hkey = NULL;\r
1163         if (RegOpenKeyEx(HKEY_CURRENT_USER, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)), 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) {\r
1164                 // I am sure that I have to do only one time, but...\r
1165                 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
1166                         DWORD dwIndex = 0;\r
1167                         TCHAR szName[SUB_KEY_NAME_LENGTH] = {'\0'};\r
1168                         DWORD dwName = sizeof(szName);\r
1169                         FILETIME filetime;\r
1170 \r
1171                         while (RegEnumKeyEx(hkey, dwIndex++, szName, &dwName, NULL, NULL, NULL, &filetime) == ERROR_SUCCESS) {\r
1172 //                              RegDeleteKey(hkey, szName);\r
1173                                 SHDeleteKey(hkey, szName);\r
1174                                 ZeroMemory(szName, sizeof(szName));\r
1175                                 dwName = sizeof(szName);\r
1176                         }\r
1177                 }\r
1178                 RegCloseKey(hkey);\r
1179         }\r
1180 }\r
1181 \r
1182 int CProfile::GetCurrentApplicationID(CComboBox *const cApplicationList, const CString szCurrentApplication)\r
1183 {\r
1184         int nCounter = cApplicationList->GetCount();\r
1185         CString szListItem;\r
1186         int nCurSel = cApplicationList->GetCurSel();\r
1187 \r
1188         for (int i = 0; i < nCounter; ++i) {\r
1189                 cApplicationList->SetCurSel(i);\r
1190                 CProfile::GetApplicationTitle(cApplicationList, szListItem);\r
1191                 if (szListItem.Find(szCurrentApplication) != -1) {\r
1192                         cApplicationList->SetCurSel(nCurSel);\r
1193                         return i;\r
1194                 }\r
1195         }\r
1196         return -1;\r
1197 }\r
1198 \r
1199 void CProfile::CopyData(const CString szDstApp, const CString szSrcApp)\r
1200 {\r
1201         int nSettingStyle = SETTING_SPECIFIC;\r
1202         const int nDstApp = GetApplicationIndex(szDstApp, TRUE, &nSettingStyle);\r
1203         const int nSrcApp = GetApplicationIndex(szSrcApp);\r
1204 \r
1205 #define CopyMember(member) CopyMemory(&m_Config. ## member ## [nDstApp], &m_Config. ## member ## [nSrcApp], sizeof(m_Config. ## member ## [nSrcApp]))\r
1206         CopyMember(b326Compatible);\r
1207         CopyMember(nFunctionID);\r
1208         CopyMember(bEnableCUA);\r
1209         CopyMember(bUseDialogSetting);\r
1210         CopyMember(bIgnoreUndefinedC_x);\r
1211         CopyMember(bIgnoreUndefinedMetaCtrl);\r
1212         CopyMember(nKillRingMax);\r
1213         CopyMember(nCommandID);\r
1214 #undef CopyMember\r
1215 }\r
1216 \r
1217 // return application index\r
1218 // if there is NOT the application in the data, return MAX_APP\r
1219 int CProfile::GetApplicationIndex(const CString szApplicationName)\r
1220 {\r
1221         int nAppID = 0;\r
1222         for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
1223                 if (szApplicationName == m_Config.szSpecialApp[nAppID])\r
1224                         break;\r
1225         return nAppID;\r
1226 }\r
1227 \r
1228 // Return True if Windows Vista or later.\r
1229 BOOL CProfile::IsVistaOrLater()\r
1230 {\r
1231         OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};\r
1232         GetVersionEx(&info);\r
1233 \r
1234         if (6 <= info.dwMajorVersion) {\r
1235                 return TRUE;\r
1236         }\r
1237         return FALSE;\r
1238 }\r
1239 \r
1240 void CProfile::RestartComputer()\r
1241 {\r
1242         if (!AdjustTokenPrivileges(SE_SHUTDOWN_NAME)) {\r
1243                 return;\r
1244         }\r
1245 \r
1246         ExitWindowsEx(EWX_REBOOT, 0);\r
1247 }\r
1248 \r
1249 BOOL CProfile::AdjustTokenPrivileges(LPCTSTR lpName)\r
1250 {\r
1251         BOOL rc = TRUE;\r
1252 \r
1253         HANDLE hToken;\r
1254         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
1255                 LUID luid;\r
1256                 if (LookupPrivilegeValue(NULL, lpName, &luid)) {\r
1257                         TOKEN_PRIVILEGES tp;\r
1258                         tp.PrivilegeCount = 1;\r
1259                         tp.Privileges[0].Luid = luid;\r
1260                         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\r
1261 \r
1262                         if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {\r
1263                                 rc = FALSE;\r
1264                         }\r
1265                 } else {\r
1266                         rc = FALSE;\r
1267                 }\r
1268                 CloseHandle(hToken);\r
1269         } else {\r
1270                 rc = FALSE;\r
1271         }\r
1272 \r
1273         return rc;\r
1274 }\r
1275 \r
1276 BOOL CProfile::DiableTokenPrivileges()\r
1277 {\r
1278         BOOL rc = TRUE;\r
1279 \r
1280         HANDLE hToken;\r
1281         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
1282                 if (!::AdjustTokenPrivileges(hToken, TRUE, NULL, NULL, NULL, NULL)) {\r
1283                         rc = FALSE;\r
1284                 }\r
1285                 CloseHandle(hToken);\r
1286         } else {\r
1287                 rc = FALSE;\r
1288         }\r
1289 \r
1290         return rc;\r
1291 }\r
1292 \r
1293 void CProfile::ExportProperties()\r
1294 {\r
1295         if (!AdjustTokenPrivileges(SE_BACKUP_NAME)) {\r
1296                 return;\r
1297         }\r
1298 \r
1299         CFileDialog oFileOpenDialog(FALSE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
1300         if (oFileOpenDialog.DoModal() == IDOK) {\r
1301                 CString szCommandLine;\r
1302                 szCommandLine.Format(_T("regedit /e \"%s\" HKEY_CURRENT_USER\\%s"), oFileOpenDialog.GetPathName(), CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)));\r
1303                 CUtils::Run(szCommandLine, TRUE);       // regedit /e "x:\xkeymacs.reg" HKEY_CURRENT_USER\Software\Oishi\XKeymacs2\r
1304         }\r
1305 \r
1306         DiableTokenPrivileges();\r
1307         return;\r
1308 }\r
1309 \r
1310 void CProfile::ImportProperties()\r
1311 {\r
1312         if (!AdjustTokenPrivileges(SE_RESTORE_NAME)) {\r
1313                 return;\r
1314         }\r
1315 \r
1316         CFileDialog oFileOpenDialog(TRUE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
1317         if (oFileOpenDialog.DoModal() == IDOK) {\r
1318                 CString szCommandLine;\r
1319                 szCommandLine.Format(_T("regedit \"%s\""), oFileOpenDialog.GetPathName());\r
1320                 CUtils::Run(szCommandLine, TRUE);       // regedit "x:\xkeymacs.reg"\r
1321         }\r
1322 \r
1323         DiableTokenPrivileges();\r
1324         return;\r
1325 }\r
1326 \r
1327 BOOL CProfile::GetEnableCUA(const int nAppID)\r
1328 {\r
1329         return m_Config.bEnableCUA[nAppID];\r
1330 }\r
1331 \r
1332 void CProfile::SetEnableCUA(const int nAppID, const BOOL bEnableCUA)\r
1333 {\r
1334         m_Config.bEnableCUA[nAppID] = bEnableCUA;\r
1335 }\r
1336 \r
1337 int CProfile::GetKeyboardSpeed()\r
1338 {\r
1339         int nKeyboardSpeed = 31; // default value of Windows\r
1340         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_KEYBOARD));\r
1341         CString szValueName(MAKEINTRESOURCE(IDS_KEYBOARD_SPEED));\r
1342 \r
1343         HKEY hKey = NULL;\r
1344         if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
1345                 // get data size\r
1346                 DWORD dwType = REG_SZ;\r
1347                 BYTE data[4] = {0};\r
1348                 DWORD dwcbData = sizeof(data)/sizeof(data[0]);\r
1349                 RegQueryValueEx(hKey, szValueName, NULL, &dwType, (LPBYTE)&data, &dwcbData);\r
1350                 RegCloseKey(hKey);\r
1351 \r
1352                 for (DWORD i = 0; i < dwcbData; ++i) {\r
1353                         if (data[i]) {\r
1354                                 if (i) {\r
1355                                         nKeyboardSpeed = nKeyboardSpeed * 10 + data[i] - _T('0');\r
1356                                 } else {\r
1357                                         nKeyboardSpeed = data[i] - _T('0');\r
1358                                 }\r
1359                         } else {\r
1360                                 break;\r
1361                         }\r
1362                 }\r
1363         }\r
1364 \r
1365         return nKeyboardSpeed;\r
1366 }\r