OSDN Git Service

Move member functions related to Commands in CXkeymacsData to CCommands.
[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 \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 nCommandType;\r
24         LPCTSTR szCommandTypeName;\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("")},\r
306 };\r
307 \r
308 CXkeymacsData CProfile::m_XkeymacsData[MAX_APP];\r
309 TASK_LIST CProfile::m_TaskList[MAX_TASKS];\r
310 DWORD CProfile::m_dwTasks;\r
311 \r
312 enum { INITIAL_SIZE     = 51200 };\r
313 enum { EXTEND_SIZE      = 25600 };\r
314 \r
315 void CProfile::Item2AppName(CString *const sz)\r
316 {\r
317         if (IsTheString(*sz, IDS_DEFAULT_TITLE)) {\r
318                 sz->LoadString(IDS_DEFAULT);\r
319         }\r
320 \r
321         if (IsTheString(*sz, IDS_DIALOG_TITLE)) {\r
322                 sz->LoadString(IDS_DIALOG);\r
323         }\r
324 \r
325         int nStart, nEnd, nCount;\r
326 \r
327         nStart  = sz->ReverseFind(_T('(')) + 1;\r
328         nEnd    = sz->Find(_T(')'), nStart) - 1;\r
329         nCount  = (nEnd + 1) - nStart;\r
330         *sz             = sz->Mid(nStart, nCount);\r
331 }\r
332 \r
333 int CProfile::IsNotSameString(CComboBox *const pApplication, const CString szListItem)\r
334 {\r
335         CString szItem, szList;\r
336         szList = szListItem;\r
337         Item2AppName(&szList);\r
338 \r
339         for (int i = 0; i < pApplication->GetCount(); ++i) {\r
340                 pApplication->GetLBText(i, szItem);\r
341                 Item2AppName(&szItem);\r
342                 if (!_tcsicmp(szItem, szList)) {\r
343                         return 0;\r
344                 }\r
345         }\r
346 \r
347         return 1;\r
348 }\r
349 \r
350 int CProfile::CountSeparator(const CString szMainString, const CString szSeparator)\r
351 {\r
352         int index       = 0;\r
353         int counter     = 0;\r
354 \r
355         while ((index = szMainString.Find(szSeparator, index)) != -1) {\r
356                 ++index;\r
357                 ++counter;\r
358         }\r
359 \r
360         return counter;\r
361 }\r
362 \r
363 void CProfile::GetNthString(CString *const szAppName, const CString szWindowName, const CString szSeparator, int n)\r
364 {\r
365         int index = -1;\r
366 \r
367         while (--n) {\r
368                 index = szWindowName.Find(szSeparator, index + 1);\r
369         }\r
370 \r
371         int nStart;\r
372         if (index != -1) {\r
373                 nStart = index + szSeparator.GetLength();\r
374         } else {\r
375                 nStart = 0;\r
376         }\r
377 \r
378         int nEnd = szWindowName.Find(szSeparator, nStart);\r
379         if (nEnd == -1) {\r
380                 nEnd = szWindowName.GetLength();\r
381         }\r
382 \r
383         *szAppName = szWindowName.Mid(nStart, nEnd - nStart);\r
384 }\r
385 \r
386 void CProfile::GetAppName(CString *const szAppName, LPCTSTR pWindowName)\r
387 {\r
388         CString szWindowName(pWindowName);\r
389         CString szSeparator(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE));\r
390         int nWord = CountSeparator(szWindowName, szSeparator) + 1;\r
391 \r
392         while (nWord) {\r
393                 GetNthString(szAppName, szWindowName, szSeparator, nWord);\r
394                 if (szAppName->GetAt(0) == _T('[')\r
395                  || szAppName->Find(_T('.'), 0) != -1           // for Microsoft Project\r
396                  || szAppName->Find(_T(']'), 0) != -1) {        // for the file name like [foo - bar]\r
397                         --nWord;\r
398                 } else {\r
399                         return;\r
400                 }\r
401         }\r
402 \r
403         *szAppName = szWindowName;\r
404 }\r
405 \r
406 BOOL CALLBACK CProfile::EnumWindowsProc(const HWND hWnd, const LPARAM lParam)\r
407 {\r
408         CComboBox               *pApplication   = (CComboBox*)lParam;\r
409         PTASK_LIST              pTask                   = CProfile::m_TaskList;\r
410         \r
411         TCHAR szWindowName[WINDOW_NAME_LENGTH];\r
412         TCHAR szClassName[CLASS_NAME_LENGTH];\r
413         WINDOWPLACEMENT wpl;\r
414         \r
415         wpl.length = sizeof(WINDOWPLACEMENT);\r
416         ::GetWindowText(hWnd, szWindowName, sizeof(szWindowName));\r
417         GetClassName(hWnd, szClassName, sizeof(szClassName));\r
418 \r
419         CString szAppName;\r
420         // Get Process Name\r
421         DWORD dwProcessId = 0;\r
422         GetWindowThreadProcessId(hWnd, &dwProcessId);\r
423         for (DWORD i = 0; i < CProfile::m_dwTasks; ++i) {\r
424                 if (pTask[i].dwProcessId == dwProcessId) {\r
425 \r
426                         // Get Application Name\r
427                         if (szWindowName[0] == '\0') {\r
428                                 continue;\r
429                         }\r
430                         if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_B2)), sizeof(pTask[i].ProcessName))) {\r
431                                 szAppName.LoadString(IDS_BECKY);\r
432                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXPLORER)), sizeof(pTask[i].ProcessName))) {\r
433                                 szAppName.LoadString(IDS_PROGRAM_MANAGER);\r
434                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSIMN)), sizeof(pTask[i].ProcessName))) {\r
435                                 szAppName.LoadString(IDS_OUTLOOK_EXPRESS);\r
436                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_PROJECT)), sizeof(pTask[i].ProcessName))\r
437                                         || !_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXCEL)), sizeof(pTask[i].ProcessName))\r
438                                         || !_tcsnicmp(pTask[i].ProcessName, _T("psp.exe"), sizeof(pTask[i].ProcessName))) {\r
439                                 GetNthString(&szAppName, szWindowName, CString(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE)), 1);\r
440                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sakura.exe"), sizeof(pTask[i].ProcessName))) {\r
441                                 GetNthString(&szAppName, szWindowName, CString(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE)), 2);  // '.' is included, so...\r
442                         } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSDN)), sizeof(pTask[i].ProcessName))) {\r
443                                 szAppName = szWindowName;\r
444                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("devenv.exe"), sizeof(pTask[i].ProcessName))) {\r
445                                 szAppName.Format(_T("Microsoft Visual Studio .NET"));\r
446                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vb6.exe"), sizeof(pTask[i].ProcessName))) {\r
447                                 szAppName.Format(_T("Microsoft Visual Basic"));\r
448                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("ssexp.exe"), sizeof(pTask[i].ProcessName))) {\r
449                                 szAppName.LoadString(IDS_VISUAL_SOURCESAFE_EXPLORER);\r
450                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sh.exe"), sizeof(pTask[i].ProcessName))) {\r
451                                 szAppName.Format(_T("MKS Korn Shell"));\r
452                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("csh.exe"), sizeof(pTask[i].ProcessName))) {\r
453                                 szAppName.Format(_T("C Shell"));\r
454                         } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vim.exe"), sizeof(pTask[i].ProcessName))) {\r
455                                 szAppName.Format(_T("VIM"));\r
456                         } else {\r
457                                 CUtils::SetCorrectApplicationName(pTask[i].ProcessName, sizeof(pTask[i].ProcessName), szWindowName, sizeof(szWindowName));\r
458                                 GetAppName(&szAppName, szWindowName);\r
459                         }\r
460                         break;\r
461                 }\r
462         }\r
463         \r
464         \r
465         if ((IsWindowVisible(hWnd))                                                                     // Is visible?\r
466          && (GetWindow(hWnd, GW_OWNER) == NULL)                                         // Is top level window?\r
467          && (lstrlen(szWindowName) > 0)                                                         // Have caption?\r
468          && (pApplication->FindString(-1, szClassName) == CB_ERR)) {// Is not same string?\r
469                 CString szListItem;\r
470                 szListItem.Format(IDS_APPLICATION_LIST_ITEM, szAppName, pTask[i].ProcessName);\r
471                 if (IsNotSameString(pApplication, szListItem)) {\r
472                         pApplication->AddString(szListItem);\r
473                 }\r
474         }\r
475         return TRUE;\r
476 }\r
477         \r
478 //////////////////////////////////////////////////////////////////////\r
479 // Construction/Destruction\r
480 //////////////////////////////////////////////////////////////////////\r
481 \r
482 CProfile::CProfile()\r
483 {\r
484 \r
485 }\r
486 \r
487 CProfile::~CProfile()\r
488 {\r
489 \r
490 }\r
491 \r
492 // This method initializes data in the registry, or retrieves and validates registry data.\r
493 // bSaveAndValidate specifies a flag that indicates \r
494 // whether registry data is being initialized (FALSE) or data is being retrieved (TRUE). \r
495 void CProfile::UpdateRegistryData(const BOOL bSaveAndValidate)\r
496 {\r
497         CString szEntry;\r
498         CString szApplicationName;\r
499         CString szApplicationTitle;\r
500         CString szWindowText;\r
501         CString szWindowTextType;\r
502 \r
503         BOOL bUseDialogSetting = FALSE;\r
504 \r
505         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
506                 // application name\r
507                 CString szSection(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));\r
508                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
509                 if (bSaveAndValidate) { // retrieve\r
510                         m_XkeymacsData[nApplicationID].ClearAll();\r
511                         szApplicationName = AfxGetApp()->GetProfileString(szSection, szEntry);\r
512                         if (szApplicationName.IsEmpty()) {\r
513                                 if (nApplicationID) {\r
514                                         if (!bUseDialogSetting) {\r
515                                                 szApplicationName.LoadString(IDS_DIALOG);\r
516                                                 bUseDialogSetting = TRUE;\r
517                                         } else {\r
518                                                 continue;\r
519                                         }\r
520                                 } else {\r
521                                         szApplicationName.LoadString(IDS_DEFAULT);\r
522                                 }\r
523                         } else {\r
524                                 if (szApplicationName == CString(MAKEINTRESOURCE(IDS_DIALOG))) {\r
525                                         bUseDialogSetting = TRUE;\r
526                                 }\r
527                         }\r
528                         m_XkeymacsData[nApplicationID].SetApplicationName(szApplicationName);\r
529                 } else {                                // initialize\r
530                         szApplicationName = m_XkeymacsData[nApplicationID].GetApplicationName();\r
531                         if (szApplicationName.IsEmpty()) {\r
532                                 continue;\r
533                         }\r
534                         AfxGetApp()->WriteProfileString(szSection, szEntry, szApplicationName);\r
535                 }\r
536 \r
537                 // application title\r
538                 szEntry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
539                 if (bSaveAndValidate) { // retrieve\r
540                         szApplicationTitle = AfxGetApp()->GetProfileString(szApplicationName, szEntry);\r
541                         m_XkeymacsData[nApplicationID].SetApplicationTitle(szApplicationTitle);\r
542                 } else {                                // initialize\r
543                         szApplicationTitle = m_XkeymacsData[nApplicationID].GetApplicationTitle();\r
544                         while (!szApplicationTitle.IsEmpty() && szApplicationTitle.GetAt(0) == _T(' ')) {\r
545                                 szApplicationTitle.Delete(0);\r
546                         }\r
547                         AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szApplicationTitle);\r
548                 }\r
549 \r
550                 // window text\r
551                 szEntry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
552                 if (bSaveAndValidate) { // retrieve\r
553                         szWindowText = AfxGetApp()->GetProfileString(szApplicationName, szEntry, _T("*"));\r
554                         if (szWindowText.IsEmpty()) {\r
555                                 szWindowText = _T('*');\r
556                         }\r
557                         m_XkeymacsData[nApplicationID].SetWindowText(szWindowText);\r
558                 } else {                                // initialize\r
559                         szWindowText = m_XkeymacsData[nApplicationID].GetWindowText();\r
560                         AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szWindowText);\r
561                 }\r
562 \r
563                 // window text type\r
564                 szEntry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT_TYPE);\r
565                 if (bSaveAndValidate) { // retrieve\r
566                         szWindowTextType = AfxGetApp()->GetProfileString(szApplicationName, szEntry);\r
567 \r
568                         int nWindowTextType = IDS_WINDOW_TEXT_IGNORE;\r
569                         if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH))) {\r
570                                 nWindowTextType = IDS_WINDOW_TEXT_MATCH;\r
571                         } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_FORWARD))) {\r
572                                 nWindowTextType = IDS_WINDOW_TEXT_MATCH_FORWARD;\r
573                         } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_BACKWARD))) {\r
574                                 nWindowTextType = IDS_WINDOW_TEXT_MATCH_BACKWARD;\r
575                         } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_FULL))) {\r
576                                 nWindowTextType = IDS_WINDOW_TEXT_MATCH_FULL;\r
577                         }\r
578 \r
579                         m_XkeymacsData[nApplicationID].SetWindowTextType(nWindowTextType);\r
580                 } else {                                // initialize\r
581                         szWindowTextType.LoadString(m_XkeymacsData[nApplicationID].GetWindowTextType());\r
582                         AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szWindowTextType);\r
583                 }\r
584 \r
585                 // on/off\r
586                 if (bSaveAndValidate) { // retrieve\r
587                         for (int nCommandID = 1; nCommandID < MAX_COMMAND; ++nCommandID) {\r
588                                 szEntry = CCommands::GetCommandName(nCommandID);\r
589                                 if (szEntry.IsEmpty()) {\r
590                                         break;\r
591                                 }\r
592 \r
593                                 HKEY hKey = NULL;\r
594                                 CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
595                                 szSubKey += _T("\\") + szApplicationName + _T("\\") + szEntry;\r
596                                 if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
597                                         // Use registry data\r
598                                         TCHAR szKeyBind[128] = {'\0'};\r
599                                         DWORD dwKeyBind = sizeof(szKeyBind);\r
600                                         FILETIME ft = {'\0'};   // not use\r
601                                         for (DWORD dwIndex = 0;\r
602                                                  RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS;\r
603                                                  ++dwIndex) {\r
604                                                 int nCommandType = 0;\r
605                                                 int nKey = 0;\r
606                                                 ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
607                                                 m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
608 \r
609 //                                              if (nCommandType == CONTROL && nKey == 'D') {\r
610 //                                                      CUtils::Log("GetProfileInt(at ibeam cursor only): %s, %s", szSubKey, szKeyBind);\r
611 //                                              }\r
612                                                 const CString szSection = szSubKey.Right(szSubKey.GetLength() - CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)).GetLength() - _tcslen(_T("\\"))) + _T("\\") + szKeyBind;\r
613                                                 const BOOL bAtIbeamCursorOnly = AfxGetApp()->GetProfileInt(szSection, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_AT_IBEAM_CURSOR_ONLY)), FALSE);\r
614                                                 m_XkeymacsData[nApplicationID].SetAtIbeamCursorOnly(nCommandType, nKey, bAtIbeamCursorOnly);\r
615 \r
616                                                 memset(szKeyBind, 0, sizeof(szKeyBind));\r
617                                                 dwKeyBind = sizeof(szKeyBind);\r
618                                         }\r
619                                         RegCloseKey(hKey);\r
620                                 } else {\r
621                                         // Use default setting\r
622                                         for (int i = 0; ; ++i) {\r
623                                                 if (CCommands::GetDefaultControlID(nCommandID, i) == IDC_CO2) {\r
624                                                         continue;\r
625                                                 }\r
626 \r
627                                                 int nCommandType = CCommands::GetDefaultCommandType(nCommandID, i);\r
628                                                 int nKey = CCommands::GetDefaultCommandKey(nCommandID, i);\r
629                                                 if (nKey == 0) {\r
630                                                         break;\r
631                                                 }\r
632                                                 m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
633                                                 m_XkeymacsData[nApplicationID].SetAtIbeamCursorOnly(nCommandType, nKey, FALSE);\r
634                                         }\r
635                                 }\r
636                         }\r
637                         for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
638                                 HKEY hKey = NULL;\r
639                                 CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
640                                 szSubKey += _T("\\") + szApplicationName + _T("\\") + CDotXkeymacs::GetFunctionSymbol(nFunctionID);\r
641                                 if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
642                                         // Use registry data\r
643                                         CDotXkeymacs::ClearKey(nFunctionID, nApplicationID);\r
644                                         TCHAR szKeyBind[128] = {'\0'};\r
645                                         DWORD dwKeyBind = sizeof(szKeyBind);\r
646                                         FILETIME ft = {'\0'};   // not use\r
647                                         for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS; ++dwIndex) {\r
648                                                 int nCommandType = 0;\r
649                                                 int nKey = 0;\r
650                                                 ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
651                                                 CDotXkeymacs::SetKey(nFunctionID, nApplicationID, nCommandType, nKey);\r
652 \r
653                                                 memset(szKeyBind, 0, sizeof(szKeyBind));\r
654                                                 dwKeyBind = sizeof(szKeyBind);\r
655                                         }\r
656                                         RegCloseKey(hKey);\r
657                                 }\r
658                         }\r
659                 } else {                                // initialize\r
660                         // create all commands\r
661                         for (int nCommandID = 1; nCommandID < MAX_COMMAND; ++nCommandID) {\r
662                                 szEntry = CCommands::GetCommandName(nCommandID);\r
663                                 if (szEntry.IsEmpty()) {\r
664                                         break;\r
665                                 }\r
666 \r
667                                 SaveCommand(szApplicationName, nCommandID);\r
668                         }\r
669                         for (int nCommandType = 0; nCommandType < MAX_COMMAND_TYPE; ++nCommandType) {\r
670                                 for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
671                                         int nCommandID = m_XkeymacsData[nApplicationID].GetCommandID(nCommandType, nKey);\r
672                                         SaveKeyBind(szApplicationName, nCommandID, nCommandType, nKey);\r
673                                 }\r
674                         }\r
675                         for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
676                                 for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFunctionID, nApplicationID); ++nKeyID) {\r
677                                         int nCommandType = 0;\r
678                                         int nKey = 0;\r
679                                         CDotXkeymacs::GetKey(nFunctionID, nApplicationID, nKeyID, &nCommandType, &nKey);\r
680                                         SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFunctionID), nCommandType, nKey);\r
681                                 }\r
682                         }\r
683                 }\r
684 \r
685                 // kill-ring-max\r
686                 szEntry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
687                 if (bSaveAndValidate) { // retrieve\r
688                         int nKillRingMax = AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 1);\r
689                         m_XkeymacsData[nApplicationID].SetKillRingMax(nKillRingMax);\r
690                 } else {                                // initialize\r
691                         int nKillRingMax = m_XkeymacsData[nApplicationID].GetKillRingMax();\r
692                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, nKillRingMax);\r
693                 }\r
694 \r
695                 // Use Dialog Setting\r
696                 szEntry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
697                 if (bSaveAndValidate) { // retrieve\r
698                         BOOL bUseDialogSetting = AfxGetApp()->GetProfileInt(szApplicationName,szEntry, 1);\r
699                         m_XkeymacsData[nApplicationID].SetUseDialogSetting(bUseDialogSetting);\r
700                 } else {                                // initialize\r
701                         BOOL bUseDialogSetting = m_XkeymacsData[nApplicationID].GetUseDialogSetting();\r
702                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, bUseDialogSetting);\r
703                 }\r
704 \r
705                 // Setting Style\r
706                 szEntry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
707                 if (bSaveAndValidate) { // retrieve\r
708                         int nSettingStyle = SETTING_SPECIFIC;\r
709                         if (AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0) != 0) {\r
710                                 nSettingStyle = SETTING_DISABLE;\r
711                         }\r
712                         m_XkeymacsData[nApplicationID].SetSettingStyle(nSettingStyle);\r
713                 } else {                                // initialize\r
714                         BOOL bDisableXkeymacs = FALSE;\r
715                         if (m_XkeymacsData[nApplicationID].GetSettingStyle() == SETTING_DISABLE) {\r
716                                 bDisableXkeymacs = TRUE;\r
717                         }\r
718                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, bDisableXkeymacs);\r
719                 }\r
720 \r
721                 // Ignore Meta Ctrl+? when it is undefined.\r
722                 szEntry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
723                 if (bSaveAndValidate) { // retrieve\r
724                         m_XkeymacsData[nApplicationID].SetIgnoreUndefinedMetaCtrl(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
725                 } else {                                // initialize\r
726                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_XkeymacsData[nApplicationID].GetIgnoreUndefinedMetaCtrl());\r
727                 }\r
728 \r
729                 // Ignore C-x ? when it is undefined.\r
730                 szEntry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
731                 if (bSaveAndValidate) { // retrieve\r
732                         m_XkeymacsData[nApplicationID].SetIgnoreUndefinedC_x(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
733                 } else {                                // initialize\r
734                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_XkeymacsData[nApplicationID].GetIgnoreUndefinedC_x());\r
735                 }\r
736 \r
737                 // Enable CUA-mode\r
738                 szEntry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
739                 if (bSaveAndValidate) { // retrieve\r
740                         m_XkeymacsData[nApplicationID].SetEnableCUA(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
741                 } else {                                // initialize\r
742                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_XkeymacsData[nApplicationID].GetEnableCUA());\r
743                 }\r
744 \r
745                 // Version 3.26 compatible mode\r
746                 szEntry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
747                 if (bSaveAndValidate) { // retrieve\r
748                         m_XkeymacsData[nApplicationID].Set326Compatible(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
749                 } else {                                // initialize\r
750                         AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_XkeymacsData[nApplicationID].Get326Compatible());\r
751                 }\r
752         }\r
753 }\r
754 \r
755 void CProfile::LoadRegistryData()\r
756 {\r
757         CDotXkeymacs::Load();\r
758         LevelUp();\r
759         UpdateRegistryData(TRUE);\r
760 }\r
761 \r
762 void CProfile::SaveRegistryData()\r
763 {\r
764         DeleteAllRegistryData();\r
765         UpdateRegistryData(FALSE);\r
766         SetDllData();\r
767 }\r
768 \r
769 void CProfile::SetDllData()\r
770 {\r
771         CMainFrame *pMainFrame = (CMainFrame*)AfxGetMainWnd();\r
772 \r
773         pMainFrame->m_pXkeymacsDll->ClearFunctionDefinition();\r
774         for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
775                 pMainFrame->m_pXkeymacsDll->SetFunctionDefinition(nFunctionID, CDotXkeymacs::GetFunctionDefinition(nFunctionID));\r
776         }\r
777 \r
778         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
779 \r
780                 CString szApplicationName = m_XkeymacsData[nApplicationID].GetApplicationName();\r
781 \r
782                 if (szApplicationName.IsEmpty()) {\r
783                         pMainFrame->m_pXkeymacsDll->Clear(nApplicationID);\r
784                         continue;\r
785                 }\r
786 \r
787                 pMainFrame->m_pXkeymacsDll->SetApplicationName(nApplicationID, szApplicationName);\r
788                 pMainFrame->m_pXkeymacsDll->SetWindowText(nApplicationID, m_XkeymacsData[nApplicationID].GetWindowText());\r
789                 pMainFrame->m_pXkeymacsDll->SetCommandID(nApplicationID, CONTROL, 'X', 0);\r
790                 pMainFrame->m_pXkeymacsDll->SetAtIbeamCursorOnly(nApplicationID, CONTROL, 'X', FALSE);\r
791 \r
792                 for (int nCommandType = 0; nCommandType < MAX_COMMAND_TYPE; ++nCommandType) {\r
793                         for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
794                                 const int nCommandID = m_XkeymacsData[nApplicationID].GetCommandID(nCommandType, nKey);\r
795                                 pMainFrame->m_pXkeymacsDll->SetCommandID(nApplicationID, nCommandType, nKey, nCommandID);\r
796                                 const BOOL bAtIbeamCursorOnly = m_XkeymacsData[nApplicationID].GetAtIbeamCursorOnly(nCommandType, nKey);\r
797                                 pMainFrame->m_pXkeymacsDll->SetAtIbeamCursorOnly(nApplicationID, nCommandType, nKey, bAtIbeamCursorOnly);\r
798                                 if ((nCommandType & CONTROLX) && nCommandID) {\r
799                                         pMainFrame->m_pXkeymacsDll->SetCommandID(nApplicationID, CONTROL, 'X', 1);                      // Commands[1] is C-x\r
800                                         pMainFrame->m_pXkeymacsDll->SetAtIbeamCursorOnly(nApplicationID, CONTROL, 'X', bAtIbeamCursorOnly);\r
801                                 }\r
802                         }\r
803                 }\r
804 \r
805                 for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
806                         for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFunctionID, nApplicationID); ++nKeyID) {\r
807                                 int nCommandType = 0;\r
808                                 int nKey = 0;\r
809                                 CDotXkeymacs::GetKey(nFunctionID, nApplicationID, nKeyID, &nCommandType, &nKey);\r
810                                 pMainFrame->m_pXkeymacsDll->SetFunctionKey(nFunctionID, nApplicationID, nCommandType, nKey);\r
811                                 if (nCommandType & CONTROLX) {\r
812                                         pMainFrame->m_pXkeymacsDll->SetCommandID(nApplicationID, CONTROL, 'X', 1);                      // Commands[1] is C-x\r
813                                         const BOOL bAtIbeamCursorOnly = m_XkeymacsData[nApplicationID].GetAtIbeamCursorOnly(nCommandType, nKey);\r
814                                         pMainFrame->m_pXkeymacsDll->SetAtIbeamCursorOnly(nApplicationID, CONTROL, 'X', bAtIbeamCursorOnly);\r
815                                 }\r
816                         }\r
817                 }\r
818 \r
819                 pMainFrame->m_pXkeymacsDll->SetKillRingMax(nApplicationID, m_XkeymacsData[nApplicationID].GetKillRingMax());\r
820                 pMainFrame->m_pXkeymacsDll->SetUseDialogSetting(nApplicationID, m_XkeymacsData[nApplicationID].GetUseDialogSetting());\r
821                 pMainFrame->m_pXkeymacsDll->SetSettingStyle(nApplicationID, m_XkeymacsData[nApplicationID].GetSettingStyle());\r
822                 pMainFrame->m_pXkeymacsDll->SetIgnoreUndefinedMetaCtrl(nApplicationID, m_XkeymacsData[nApplicationID].GetIgnoreUndefinedMetaCtrl());\r
823                 pMainFrame->m_pXkeymacsDll->SetIgnoreUndefinedC_x(nApplicationID, m_XkeymacsData[nApplicationID].GetIgnoreUndefinedC_x());\r
824                 pMainFrame->m_pXkeymacsDll->SetEnableCUA(nApplicationID, m_XkeymacsData[nApplicationID].GetEnableCUA());\r
825                 pMainFrame->m_pXkeymacsDll->Set326Compatible(nApplicationID, m_XkeymacsData[nApplicationID].Get326Compatible());\r
826         }\r
827 }\r
828 \r
829 void CProfile::ReadKeyBind(int *const pnCommandType, int *const pnKey, LPCTSTR szKeyBind)\r
830 {\r
831         *pnCommandType = KeyBind2CommandType(szKeyBind);\r
832         *pnKey = KeyBind2Key(szKeyBind + _tcslen(CommandType2String(*pnCommandType)));\r
833 }\r
834 \r
835 CString CProfile::WriteKeyBind(const int nCommandType, const int nKey)\r
836 {\r
837         CString szKeyBind;\r
838         szKeyBind.Format(_T("%s%s"), CommandType2String(nCommandType), Key2String(nKey));\r
839         return szKeyBind;\r
840 }\r
841 \r
842 int CProfile::KeyBind2CommandType(LPCTSTR szKeyBind)\r
843 {\r
844         for (int nCommandType = MAX_COMMAND_TYPE - 1; nCommandType; --nCommandType) {\r
845                 if (IsCommandType(nCommandType, szKeyBind)) {\r
846                         return nCommandType;\r
847                 }\r
848         }\r
849         return NONE;\r
850 }\r
851 \r
852 int CProfile::KeyBind2Key(LPCTSTR szKey)\r
853 {\r
854         for (int nKey = 1; nKey < 0xff; ++nKey) {\r
855                 if (!_tcscmp(szKey, Key2String(nKey))) {\r
856                         return nKey;\r
857                 }\r
858         }\r
859         return 0;\r
860 }\r
861 \r
862 LPCTSTR CProfile::CommandType2String(int nCommandType)\r
863 {\r
864         if (nCommandType < 0 || sizeof(CommandTypes) / sizeof(CommandTypes[0]) <= nCommandType) {\r
865                 ASSERT(0);\r
866                 nCommandType = NONE;\r
867         }\r
868         return CommandTypes[nCommandType].szCommandTypeName;\r
869 }\r
870 \r
871 LPCTSTR CProfile::Key2String(int nKey)\r
872 {\r
873         if (CProfile::Is106Keyboard()) {\r
874                 switch (nKey) {\r
875                 case 0xBA:\r
876                         return _T(":");\r
877                 case 0xBB:\r
878                         return _T(";");\r
879                 case 0xC0:\r
880                         return _T("@");\r
881                 case 0xDE:\r
882                         return _T("^");\r
883                 default:\r
884                         break;\r
885                 }\r
886         }\r
887 \r
888         if (nKey < 0 || sizeof(KeyNames) / sizeof(KeyNames[0]) <= nKey) {\r
889                 ASSERT(0);\r
890                 nKey = 0;\r
891         }\r
892         return KeyNames[nKey].name;\r
893 }\r
894 \r
895 BOOL CProfile::IsCommandType(const int nCommandType, LPCTSTR szKeyBind)\r
896 {\r
897         LPCTSTR szCommandType = CommandType2String(nCommandType);\r
898 \r
899         if (!_tcsnicmp(szKeyBind, szCommandType, _tcslen(szCommandType))) {\r
900                 return TRUE;\r
901         }\r
902 \r
903         return FALSE;\r
904 }\r
905 \r
906 void CProfile::SaveKeyBind(const CString szApplicationName, const int nCommandID, const int nCommandType, const int nKey)\r
907 {\r
908         if (!nCommandID) {\r
909                 return;\r
910         }\r
911 \r
912         CString szCommandName = CCommands::GetCommandName(nCommandID);\r
913         if (szCommandName.IsEmpty()) {\r
914                 return;\r
915         }\r
916 \r
917         SaveKeyBind(szApplicationName, szCommandName, nCommandType, nKey);\r
918 }\r
919 \r
920 void CProfile::SaveKeyBind(const CString szApplicationName, const CString szCommandName, const int nCommandType, const int nKey)\r
921 {\r
922         CString szKeyBind = WriteKeyBind(nCommandType, nKey);\r
923         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
924         szSubKey += _T("\\") + szApplicationName + _T("\\") + szCommandName;\r
925         if (!szKeyBind.IsEmpty()) {\r
926                 szSubKey += _T("\\") + szKeyBind;\r
927         }\r
928 \r
929         HKEY hKey = NULL;\r
930         if (RegCreateKeyEx(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS) {\r
931                 RegCloseKey(hKey);\r
932         }\r
933 }\r
934 \r
935 void CProfile::SaveCommand(const CString szApplicationName, const int nCommandID)\r
936 {\r
937         SaveKeyBind(szApplicationName, nCommandID, 0, 0);\r
938 }\r
939 \r
940 void CProfile::AddKeyBind2C_(const CString szApplicationName, const BYTE bVk)\r
941 {\r
942         for (int nCommandID = 0; nCommandID < MAX_COMMAND; ++nCommandID) {\r
943                 if (Commands[nCommandID].fCommand == CCommands::C_) {\r
944                         break;\r
945                 }\r
946         }\r
947 \r
948         SaveKeyBind(szApplicationName, nCommandID, NONE, bVk);\r
949 }\r
950 \r
951 void CProfile::LevelUp()\r
952 {\r
953         const int nDefalutLevel = 0;\r
954         const int nLatestLevel = 4;\r
955 \r
956         CString szSection;\r
957         CString szEntry;\r
958         szEntry.Format(_T("Level"));\r
959 \r
960         switch (AfxGetApp()->GetProfileInt(szSection, szEntry, nDefalutLevel)) {\r
961         case nDefalutLevel:\r
962                 {\r
963                         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
964                                 CString szEntry;\r
965                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
966 \r
967                                 CString szApplicationName;\r
968                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
969                                 if (szApplicationName.IsEmpty()) {\r
970                                         continue;\r
971                                 }\r
972 \r
973                                 AddKeyBind2C_(szApplicationName, VK_LCONTROL);\r
974                                 AddKeyBind2C_(szApplicationName, VK_RCONTROL);\r
975                         }\r
976                 }\r
977                 // Do NOT write break; here.\r
978         case 1:\r
979                 {\r
980                         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
981                                 CString szEntry;\r
982                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
983 \r
984                                 CString szApplicationName;\r
985                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
986                                 if (szApplicationName.IsEmpty()) {\r
987                                         continue;\r
988                                 }\r
989 \r
990                                 // Set kill-ring-max 1 if it is 0.\r
991                                 if (!AfxGetApp()->GetProfileInt(szApplicationName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 0)) {\r
992                                         AfxGetApp()->WriteProfileInt(szApplicationName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 1);\r
993                                 }\r
994                         }\r
995                 }\r
996                 // Do NOT write break; here.\r
997         case 2:\r
998                 {\r
999                         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1000                                 CString szEntry;\r
1001                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
1002 \r
1003                                 CString szApplicationName;\r
1004                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
1005                                 if (szApplicationName.IsEmpty()) {\r
1006                                         continue;\r
1007                                 }\r
1008 \r
1009                                 // Chaged a label from Enter to newline.\r
1010                                 CString szSrcSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
1011                                 szSrcSubKey += _T("\\") + szApplicationName + _T("\\") + _T("Enter");\r
1012                                 CString szDestSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
1013                                 szDestSubKey += _T("\\") + szApplicationName + _T("\\") + _T("newline");\r
1014                                 HKEY hKeyDest = NULL;\r
1015                                 if (RegCreateKeyEx(HKEY_CURRENT_USER, szDestSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyDest, NULL) == ERROR_SUCCESS) {\r
1016                                         SHCopyKey(HKEY_CURRENT_USER, szSrcSubKey, hKeyDest, NULL);\r
1017                                         SHDeleteKey(HKEY_CURRENT_USER, szSrcSubKey);\r
1018                                         RegCloseKey(hKeyDest);\r
1019                                 }\r
1020                         }\r
1021                 }\r
1022                 // Do NOT write break; here.\r
1023         case 3:\r
1024                 {\r
1025                         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1026                                 CString szEntry;\r
1027                                 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
1028 \r
1029                                 CString szApplicationName;\r
1030                                 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
1031                                 if (szApplicationName.IsEmpty()) {\r
1032                                         continue;\r
1033                                 }\r
1034 \r
1035                                 // rename original function to remove IDS_REG_ORIGINAL_PREFIX\r
1036                                 for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
1037                                         HKEY hKey = NULL;\r
1038                                         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
1039                                         szSubKey += _T("\\") + szApplicationName + _T("\\") + CString(MAKEINTRESOURCE(IDS_REG_ORIGINAL_PREFIX)) + CDotXkeymacs::GetFunctionSymbol(nFunctionID);\r
1040                                         if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
1041                                                 // Use registry data\r
1042                                                 TCHAR szKeyBind[128] = {'\0'};\r
1043                                                 DWORD dwKeyBind = sizeof(szKeyBind);\r
1044                                                 FILETIME ft = {'\0'};   // not use\r
1045                                                 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS; ++dwIndex) {\r
1046                                                         int nCommandType = 0;\r
1047                                                         int nKey = 0;\r
1048                                                         ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
1049                                                         SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFunctionID), nCommandType, nKey);\r
1050 \r
1051                                                         memset(szKeyBind, 0, sizeof(szKeyBind));\r
1052                                                         dwKeyBind = sizeof(szKeyBind);\r
1053                                                 }\r
1054                                                 RegCloseKey(hKey);\r
1055                                         }\r
1056                                 }\r
1057                         }\r
1058                 }\r
1059 //      case 4:\r
1060 //              foo();\r
1061 //      ...\r
1062 //      case nLatestLevel-1:\r
1063 //              bar();\r
1064                 AfxGetApp()->WriteProfileInt(szSection, szEntry, nLatestLevel);\r
1065                 break;\r
1066         default:\r
1067                 break;\r
1068         }\r
1069 }\r
1070 \r
1071 void CProfile::InitDllData()\r
1072 {\r
1073         LoadRegistryData();\r
1074         SetDllData();\r
1075 }\r
1076 \r
1077 void CProfile::ClearData(const CString szCurrentApplication)\r
1078 {\r
1079         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1080                 if (m_XkeymacsData[nApplicationID].GetApplicationName() == szCurrentApplication) {\r
1081                         break;\r
1082                 }\r
1083         }\r
1084         if (nApplicationID < MAX_APP) {\r
1085                 m_XkeymacsData[nApplicationID].ClearAll();\r
1086         }\r
1087 }\r
1088 \r
1089 // return count of saved settings\r
1090 int CProfile::GetSavedSettingCount()\r
1091 {\r
1092         int nSavedSetting = 0;\r
1093 \r
1094         for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1095                 CString szApplicationName;\r
1096                 szApplicationName = m_XkeymacsData[nApplicationID].GetApplicationName();\r
1097                 if (!szApplicationName.IsEmpty()) {\r
1098                         ++nSavedSetting;\r
1099                 }\r
1100         }\r
1101 \r
1102         return nSavedSetting;\r
1103 }\r
1104 \r
1105 void CProfile::InitApplicationList(CComboBox *const cApplicationList)\r
1106 {\r
1107         cApplicationList->ResetContent();\r
1108 \r
1109         GetTaskList();\r
1110 \r
1111         EnumWindows(EnumWindowsProc, (LPARAM)cApplicationList);\r
1112 \r
1113         for (int i = 0; i < MAX_APP; ++i) {\r
1114                 CString szApplicationName       = m_XkeymacsData[i].GetApplicationName();\r
1115                 CString szApplicationTitle      = m_XkeymacsData[i].GetApplicationTitle();\r
1116 \r
1117                 CString szListItem;\r
1118                 szListItem.Format(IDS_APPLICATION_LIST_ITEM, szApplicationTitle, szApplicationName);\r
1119                 if (IsNotSameString(cApplicationList, szListItem)\r
1120                  && !IsDefault(szApplicationName)\r
1121                  && !IsDialog(szApplicationName)\r
1122                  && !szApplicationName.IsEmpty()) {\r
1123                         cApplicationList->AddString(szListItem);\r
1124                 }\r
1125         }\r
1126 \r
1127         // Add IME\r
1128         HKL hKL = GetKeyboardLayout(0);\r
1129         if (ImmIsIME(hKL)) {\r
1130                 LPTSTR szIMEDescription = NULL;\r
1131                 UINT nIMEDescription = ImmGetDescription(hKL, NULL, 0);\r
1132                 if (nIMEDescription) {\r
1133                         nIMEDescription += sizeof(TCHAR);       // for NULL\r
1134                         if ((szIMEDescription = new TCHAR[nIMEDescription]) != NULL) {\r
1135                                 ImmGetDescription(hKL, szIMEDescription, nIMEDescription);\r
1136                         }\r
1137 //                      CUtils::Log(_T("nIMEDescription = %d, szIMEDescription = _%s_"), nIMEDescription, szIMEDescription);\r
1138                 }\r
1139 \r
1140                 LPTSTR szIMEFileName = NULL;\r
1141                 UINT nIMEFileName = ImmGetIMEFileName(hKL, NULL, 0);\r
1142                 if (nIMEFileName) {\r
1143                         nIMEFileName += sizeof(TCHAR);\r
1144                         if ((szIMEFileName = new TCHAR[nIMEFileName]) != NULL) {\r
1145                                 ImmGetIMEFileName(hKL, szIMEFileName, nIMEFileName);\r
1146                         }\r
1147 //                      CUtils::Log(_T("nIMEFileName = %d, szIMEFileName = _%s_"), nIMEFileName, szIMEFileName);\r
1148                 }\r
1149 \r
1150                 CString szIMETitle;\r
1151                 CString szIME(MAKEINTRESOURCE(IDS_IME_FILE_NAME));\r
1152                 szIMETitle.Format(IDS_APPLICATION_LIST_ITEM, szIMEDescription ? szIMEDescription : szIME, szIMEFileName ? szIMEFileName : szIME);\r
1153 //              CUtils::Log(_T("szIMETitle = _%s_, szIMEDescription = _%s_, szIMEFileName = _%s_"), szIMETitle, szIMEDescription, szIMEFileName);\r
1154                 if (IsNotSameString(cApplicationList, szIMETitle)) {\r
1155                         cApplicationList->AddString(szIMETitle);\r
1156                 }\r
1157 \r
1158                 delete[] szIMEDescription;\r
1159                 szIMEDescription = NULL;\r
1160                 delete[] szIMEFileName;\r
1161                 szIMEFileName = NULL;\r
1162         }\r
1163 \r
1164         // Add Dialog\r
1165         cApplicationList->InsertString(0, CString(MAKEINTRESOURCE(IDS_DIALOG_TITLE)));\r
1166 \r
1167         // Add Default\r
1168         cApplicationList->InsertString( 0, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));\r
1169         cApplicationList->SelectString(-1, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));\r
1170 }\r
1171 \r
1172 void CProfile::GetTaskList()\r
1173 {\r
1174         ZeroMemory(m_TaskList, sizeof(m_TaskList));\r
1175 \r
1176         HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\r
1177         if (hProcessSnap == (HANDLE)-1)\r
1178                 return;\r
1179 \r
1180         m_dwTasks = 0;\r
1181         PROCESSENTRY32 processEntry32 = {sizeof(PROCESSENTRY32)};\r
1182         if (Process32First(hProcessSnap, &processEntry32)) {\r
1183                 do {\r
1184                         lstrcpy(m_TaskList[m_dwTasks].ProcessName, processEntry32.szExeFile);\r
1185                         m_TaskList[m_dwTasks++].dwProcessId = processEntry32.th32ProcessID;\r
1186                 } while (m_dwTasks < MAX_TASKS && Process32Next(hProcessSnap, &processEntry32));\r
1187         }\r
1188 \r
1189         CloseHandle(hProcessSnap);\r
1190 }\r
1191 \r
1192 // return application index\r
1193 // and update setting style\r
1194 // if there is NOT the application in the data, this function takes care of it.\r
1195 int CProfile::GetApplicationIndex(const CString szApplicationName, const BOOL bSaveAndValidate, int *const nSettingStyle)\r
1196 {\r
1197         if (!bSaveAndValidate) {        // SetDialogData\r
1198                 *nSettingStyle = SETTING_UNDEFINED;\r
1199         }\r
1200 \r
1201         int nApplicationID = GetApplicationIndex(szApplicationName);\r
1202 \r
1203         if (nApplicationID == MAX_APP) {\r
1204                 if (bSaveAndValidate) { // GetDialogData\r
1205                         for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1206                                 CString sz = m_XkeymacsData[nApplicationID].GetApplicationName();\r
1207                                 if (sz.IsEmpty()) {\r
1208                                         m_XkeymacsData[nApplicationID].SetApplicationName(szApplicationName);\r
1209                                         break;\r
1210                                 }\r
1211                         }\r
1212                         if (nApplicationID == MAX_APP) {\r
1213                                 return nApplicationID;\r
1214                         }\r
1215                 } else {                                // SetDialogData\r
1216                         for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1217                                 if (IsDefault(m_XkeymacsData[nApplicationID].GetApplicationName())) {\r
1218                                         *nSettingStyle = SETTING_DEFAULT;\r
1219                                         break;\r
1220                                 }\r
1221                         }\r
1222                         if (nApplicationID == MAX_APP) {\r
1223                                 return nApplicationID;\r
1224                         }\r
1225                 }\r
1226         }\r
1227 \r
1228         if (bSaveAndValidate) { // GetDialogData\r
1229                 m_XkeymacsData[nApplicationID].SetSettingStyle(*nSettingStyle);\r
1230         } else {                                // SetDialogData\r
1231                 if (*nSettingStyle == SETTING_UNDEFINED) {      // It means that *nSettingStyle != SETTING_DEFAULT.\r
1232                         *nSettingStyle = m_XkeymacsData[nApplicationID].GetSettingStyle();\r
1233                 }\r
1234         }\r
1235 \r
1236         return nApplicationID;\r
1237 }\r
1238 \r
1239 BOOL CProfile::Is106Keyboard()\r
1240 {\r
1241         static KEYBOARD_TYPE keyboard = UNKNOWN_KEYBOARD;\r
1242 \r
1243         if (keyboard == UNKNOWN_KEYBOARD) {\r
1244                 OSVERSIONINFO verInfo = {0};\r
1245                 verInfo.dwOSVersionInfoSize = sizeof (verInfo);\r
1246                 GetVersionEx(&verInfo);\r
1247 \r
1248                 DWORD subtype = 0;\r
1249                 DWORD cbData = sizeof(subtype);\r
1250 \r
1251                 if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {\r
1252                         HKEY hKey = NULL;\r
1253                         CString szSubKey(_T("SYSTEM\\CurrentControlSet\\Services\\i8042prt\\Parameters"));\r
1254                         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
1255                                 static const CString szValueName(_T("OverrideKeyboardSubtype"));\r
1256                                 if (RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE)&subtype, &cbData) != ERROR_SUCCESS) {\r
1257                                         subtype = 0;\r
1258                                 }\r
1259                                 RegCloseKey(hKey);\r
1260                         }\r
1261                 } else if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {\r
1262                         subtype = GetPrivateProfileInt(_T("keyboard"), _T("subtype"), 0, _T("system.ini"));\r
1263                 }\r
1264 \r
1265                 keyboard = (subtype & 0x02) ? JAPANESE_KEYBOARD : ENGLISH_KEYBOARD;\r
1266         }\r
1267 \r
1268         return keyboard == JAPANESE_KEYBOARD;\r
1269 }\r
1270 \r
1271 BOOL CProfile::IsTheString(const CString sz, const UINT nID)\r
1272 {\r
1273         return sz == CString(MAKEINTRESOURCE(nID));\r
1274 }\r
1275 \r
1276 // if sz is "Default", return TRUE\r
1277 BOOL CProfile::IsDefault(const CString sz)\r
1278 {\r
1279         return IsTheString(sz, IDS_DEFAULT);\r
1280 }\r
1281 \r
1282 // if sz is "Dialog", return TRUE\r
1283 BOOL CProfile::IsDialog(const CString sz)\r
1284 {\r
1285         return IsTheString(sz, IDS_DIALOG);\r
1286 }\r
1287 \r
1288 void CProfile::GetApplicationTitle(CComboBox *const cApplicationList, CString &rList, const int nIndex)\r
1289 {\r
1290         if (0 <= nIndex) {\r
1291                 cApplicationList->GetLBText(nIndex, rList);\r
1292         } else {\r
1293                 cApplicationList->GetWindowText(rList);\r
1294         }\r
1295 \r
1296         if (IsTheString(rList, IDS_DEFAULT_TITLE)) {\r
1297                 rList.LoadString(IDS_DEFAULT);\r
1298         }\r
1299 \r
1300         if (IsTheString(rList, IDS_DIALOG_TITLE)) {\r
1301                 rList.LoadString(IDS_DIALOG);\r
1302         }\r
1303 \r
1304         return;\r
1305 }\r
1306 \r
1307 void CProfile::UpdateApplicationTitle(CComboBox *const cApplicationList, const CString szCurrentApplication, const int nApplicationID, const BOOL bSaveAndValidate)\r
1308 {\r
1309         static CString szApplicationTitle;\r
1310         if (bSaveAndValidate) { // GetDialogData\r
1311                 if (!CProfile::IsDefault(szCurrentApplication)) {\r
1312                         m_XkeymacsData[nApplicationID].SetApplicationTitle(szApplicationTitle);\r
1313                 }\r
1314                 szApplicationTitle.Empty();\r
1315         } else {                                // SetDialogData\r
1316                 CString szListItem;\r
1317                 CProfile::GetApplicationTitle(cApplicationList, szListItem);\r
1318                 int nEndTitle = szListItem.ReverseFind(_T('('));\r
1319                 if (nEndTitle > 0) {\r
1320                         szApplicationTitle = szListItem.Left(nEndTitle);\r
1321                 }\r
1322         }\r
1323 }\r
1324 \r
1325 void CProfile::SetCommandID(const int nApplicationID, const int nCommandType, const int nKey, int nCommandID)\r
1326 {\r
1327         if (nKey == 0xf0 && Commands[nCommandID].fCommand == CCommands::C_) {\r
1328                 // Change CommandID C_Eisu\r
1329                 for (nCommandID = 1; nCommandID < MAX_COMMAND; ++nCommandID) {\r
1330                         if (Commands[nCommandID].fCommand == CCommands::C_Eisu) {\r
1331                                 break;\r
1332                         }\r
1333                 }\r
1334         }\r
1335         m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
1336 }\r
1337 \r
1338 int CProfile::GetCommandID(const int nApplicationID, const int nCommandType, const int nKey)\r
1339 {\r
1340         int nCommandID = m_XkeymacsData[nApplicationID].GetCommandID(nCommandType, nKey);\r
1341         if (nKey == 0xf0 && Commands[nCommandID].fCommand == CCommands::C_Eisu) {\r
1342                 // Change CommandID C_\r
1343                 for (nCommandID = 1; nCommandID < MAX_COMMAND; ++nCommandID) {\r
1344                         if (Commands[nCommandID].fCommand == CCommands::C_) {\r
1345                                 break;\r
1346                         }\r
1347                 }\r
1348         }\r
1349         return nCommandID;\r
1350 }\r
1351 \r
1352 void CProfile::SetKillRingMax(const int nApplicationID, const int nKillRingMax)\r
1353 {\r
1354         m_XkeymacsData[nApplicationID].SetKillRingMax(nKillRingMax);\r
1355 }\r
1356 \r
1357 int CProfile::GetKillRingMax(const int nApplicationID)\r
1358 {\r
1359         return m_XkeymacsData[nApplicationID].GetKillRingMax();\r
1360 }\r
1361 \r
1362 void CProfile::SetUseDialogSetting(const int nApplicationID, const BOOL bUseDialogSetting)\r
1363 {\r
1364         m_XkeymacsData[nApplicationID].SetUseDialogSetting(bUseDialogSetting);\r
1365 }\r
1366 \r
1367 BOOL CProfile::GetUseDialogSetting(const int nApplicationID)\r
1368 {\r
1369         return m_XkeymacsData[nApplicationID].GetUseDialogSetting();\r
1370 }\r
1371 \r
1372 void CProfile::SetWindowText(const int nApplicationID, const CString szWindowText)\r
1373 {\r
1374         m_XkeymacsData[nApplicationID].SetWindowText(szWindowText);\r
1375 }\r
1376 \r
1377 CString CProfile::GetWindowText(const int nApplicationID)\r
1378 {\r
1379         return m_XkeymacsData[nApplicationID].GetWindowText();\r
1380 }\r
1381 \r
1382 void CProfile::DeleteAllRegistryData()\r
1383 {\r
1384         HKEY hkey = NULL;\r
1385         if (RegOpenKeyEx(HKEY_CURRENT_USER, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)), 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) {\r
1386                 // I am sure that I have to do only one time, but...\r
1387                 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1388                         DWORD dwIndex = 0;\r
1389                         TCHAR szName[SUB_KEY_NAME_LENGTH] = {'\0'};\r
1390                         DWORD dwName = sizeof(szName);\r
1391                         FILETIME filetime;\r
1392 \r
1393                         while (RegEnumKeyEx(hkey, dwIndex++, szName, &dwName, NULL, NULL, NULL, &filetime) == ERROR_SUCCESS) {\r
1394 //                              RegDeleteKey(hkey, szName);\r
1395                                 SHDeleteKey(hkey, szName);\r
1396                                 ZeroMemory(szName, sizeof(szName));\r
1397                                 dwName = sizeof(szName);\r
1398                         }\r
1399                 }\r
1400                 RegCloseKey(hkey);\r
1401         }\r
1402 }\r
1403 \r
1404 int CProfile::GetCurrentApplicationID(CComboBox *const cApplicationList, const CString szCurrentApplication)\r
1405 {\r
1406         int nCounter = cApplicationList->GetCount();\r
1407         CString szListItem;\r
1408         int nCurSel = cApplicationList->GetCurSel();\r
1409 \r
1410         for (int i = 0; i < nCounter; ++i) {\r
1411                 cApplicationList->SetCurSel(i);\r
1412                 CProfile::GetApplicationTitle(cApplicationList, szListItem);\r
1413                 if (szListItem.Find(szCurrentApplication) != -1) {\r
1414                         cApplicationList->SetCurSel(nCurSel);\r
1415                         return i;\r
1416                 }\r
1417         }\r
1418         return -1;\r
1419 }\r
1420 \r
1421 void CProfile::CopyData(const CString szDestinationApplication, const CString szSourceApplication)\r
1422 {\r
1423         int nSettingStyle = SETTING_SPECIFIC;\r
1424         int nDestinationApplication = GetApplicationIndex(szDestinationApplication, TRUE, &nSettingStyle);\r
1425         int nSourceApplication = GetApplicationIndex(szSourceApplication);\r
1426 \r
1427         CString szApplicationName = m_XkeymacsData[nDestinationApplication].GetApplicationName();\r
1428         CString szApplicationTitle = m_XkeymacsData[nDestinationApplication].GetApplicationTitle();\r
1429         CString szWindowText = m_XkeymacsData[nDestinationApplication].GetWindowText();\r
1430         int nWindowTextType = m_XkeymacsData[nDestinationApplication].GetWindowTextType();\r
1431 \r
1432         m_XkeymacsData[nDestinationApplication] = m_XkeymacsData[nSourceApplication];\r
1433 \r
1434         m_XkeymacsData[nDestinationApplication].SetApplicationName(szApplicationName);\r
1435         m_XkeymacsData[nDestinationApplication].SetApplicationTitle(szApplicationTitle);\r
1436         m_XkeymacsData[nDestinationApplication].SetWindowText(szWindowText);\r
1437         m_XkeymacsData[nDestinationApplication].SetWindowTextType(nWindowTextType);\r
1438 }\r
1439 \r
1440 // return application index\r
1441 // if there is NOT the application in the data, return MAX_APP\r
1442 int CProfile::GetApplicationIndex(const CString szApplicationName)\r
1443 {\r
1444         int nApplicationID = 0;\r
1445         for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
1446                 if (m_XkeymacsData[nApplicationID].GetApplicationName() == szApplicationName) {\r
1447                         break;\r
1448                 }\r
1449         }\r
1450         return nApplicationID;\r
1451 }\r
1452 \r
1453 // Return True if Windows Vista or later.\r
1454 BOOL CProfile::IsVistaOrLater()\r
1455 {\r
1456         OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};\r
1457         GetVersionEx(&info);\r
1458 \r
1459         if (6 <= info.dwMajorVersion) {\r
1460                 return TRUE;\r
1461         }\r
1462         return FALSE;\r
1463 }\r
1464 \r
1465 void CProfile::RestartComputer()\r
1466 {\r
1467         if (!AdjustTokenPrivileges(SE_SHUTDOWN_NAME)) {\r
1468                 return;\r
1469         }\r
1470 \r
1471         ExitWindowsEx(EWX_REBOOT, 0);\r
1472 }\r
1473 \r
1474 BOOL CProfile::AdjustTokenPrivileges(LPCTSTR lpName)\r
1475 {\r
1476         BOOL rc = TRUE;\r
1477 \r
1478         HANDLE hToken;\r
1479         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
1480                 LUID luid;\r
1481                 if (LookupPrivilegeValue(NULL, lpName, &luid)) {\r
1482                         TOKEN_PRIVILEGES tp;\r
1483                         tp.PrivilegeCount = 1;\r
1484                         tp.Privileges[0].Luid = luid;\r
1485                         tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;\r
1486 \r
1487                         if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {\r
1488                                 rc = FALSE;\r
1489                         }\r
1490                 } else {\r
1491                         rc = FALSE;\r
1492                 }\r
1493                 CloseHandle(hToken);\r
1494         } else {\r
1495                 rc = FALSE;\r
1496         }\r
1497 \r
1498         return rc;\r
1499 }\r
1500 \r
1501 BOOL CProfile::DiableTokenPrivileges()\r
1502 {\r
1503         BOOL rc = TRUE;\r
1504 \r
1505         HANDLE hToken;\r
1506         if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {\r
1507                 if (!::AdjustTokenPrivileges(hToken, TRUE, NULL, NULL, NULL, NULL)) {\r
1508                         rc = FALSE;\r
1509                 }\r
1510                 CloseHandle(hToken);\r
1511         } else {\r
1512                 rc = FALSE;\r
1513         }\r
1514 \r
1515         return rc;\r
1516 }\r
1517 \r
1518 void CProfile::ExportProperties()\r
1519 {\r
1520         if (!AdjustTokenPrivileges(SE_BACKUP_NAME)) {\r
1521                 return;\r
1522         }\r
1523 \r
1524         CFileDialog oFileOpenDialog(FALSE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
1525         if (oFileOpenDialog.DoModal() == IDOK) {\r
1526                 CString szCommandLine;\r
1527                 szCommandLine.Format(_T("regedit /e \"%s\" HKEY_CURRENT_USER\\%s"), oFileOpenDialog.GetPathName(), CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)));\r
1528                 CUtils::Run(szCommandLine, TRUE);       // regedit /e "x:\xkeymacs.reg" HKEY_CURRENT_USER\Software\Oishi\XKeymacs2\r
1529         }\r
1530 \r
1531         DiableTokenPrivileges();\r
1532         return;\r
1533 }\r
1534 \r
1535 void CProfile::ImportProperties()\r
1536 {\r
1537         if (!AdjustTokenPrivileges(SE_RESTORE_NAME)) {\r
1538                 return;\r
1539         }\r
1540 \r
1541         CFileDialog oFileOpenDialog(TRUE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));\r
1542         if (oFileOpenDialog.DoModal() == IDOK) {\r
1543                 CString szCommandLine;\r
1544                 szCommandLine.Format(_T("regedit \"%s\""), oFileOpenDialog.GetPathName());\r
1545                 CUtils::Run(szCommandLine, TRUE);       // regedit "x:\xkeymacs.reg"\r
1546         }\r
1547 \r
1548         DiableTokenPrivileges();\r
1549         return;\r
1550 }\r
1551 \r
1552 BOOL CProfile::GetEnableCUA(const int nApplicationID)\r
1553 {\r
1554         return m_XkeymacsData[nApplicationID].GetEnableCUA();\r
1555 }\r
1556 \r
1557 void CProfile::SetEnableCUA(const int nApplicationID, const BOOL bEnableCUA)\r
1558 {\r
1559         m_XkeymacsData[nApplicationID].SetEnableCUA(bEnableCUA);\r
1560 }\r
1561 \r
1562 int CProfile::GetKeyboardSpeed()\r
1563 {\r
1564         int nKeyboardSpeed = 31; // default value of Windows\r
1565         CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_KEYBOARD));\r
1566         CString szValueName(MAKEINTRESOURCE(IDS_KEYBOARD_SPEED));\r
1567 \r
1568         HKEY hKey = NULL;\r
1569         if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {\r
1570                 // get data size\r
1571                 DWORD dwType = REG_SZ;\r
1572                 BYTE data[4] = {0};\r
1573                 DWORD dwcbData = sizeof(data)/sizeof(data[0]);\r
1574                 RegQueryValueEx(hKey, szValueName, NULL, &dwType, (LPBYTE)&data, &dwcbData);\r
1575                 RegCloseKey(hKey);\r
1576 \r
1577                 for (DWORD i = 0; i < dwcbData; ++i) {\r
1578                         if (data[i]) {\r
1579                                 if (i) {\r
1580                                         nKeyboardSpeed = nKeyboardSpeed * 10 + data[i] - _T('0');\r
1581                                 } else {\r
1582                                         nKeyboardSpeed = data[i] - _T('0');\r
1583                                 }\r
1584                         } else {\r
1585                                 break;\r
1586                         }\r
1587                 }\r
1588         }\r
1589 \r
1590         return nKeyboardSpeed;\r
1591 }\r