OSDN Git Service

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