1 // Profile.cpp: implementation of the CProfile class
\r
3 //////////////////////////////////////////////////////////////////////
\r
6 #include "xkeymacs.h"
\r
9 #include "DotXkeymacs.h"
\r
11 #include <Shlwapi.h>
\r
12 #include <TlHelp32.h>
\r
17 static char THIS_FILE[]=__FILE__;
\r
18 #define new DEBUG_NEW
\r
21 struct CommandTypeName
\r
24 LPCTSTR szCommandTypeName;
\r
27 static const CommandTypeName CommandTypes[] = {
\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
46 static const KeyName KeyNames[] = {
\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
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
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
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
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
308 CXkeymacsData CProfile::m_XkeymacsData[MAX_APP];
\r
309 TASK_LIST CProfile::m_TaskList[MAX_TASKS];
\r
310 DWORD CProfile::m_dwTasks;
\r
312 enum { INITIAL_SIZE = 51200 };
\r
313 enum { EXTEND_SIZE = 25600 };
\r
315 void CProfile::Item2AppName(CString *const sz)
\r
317 if (IsTheString(*sz, IDS_DEFAULT_TITLE)) {
\r
318 sz->LoadString(IDS_DEFAULT);
\r
321 if (IsTheString(*sz, IDS_DIALOG_TITLE)) {
\r
322 sz->LoadString(IDS_DIALOG);
\r
325 int nStart, nEnd, nCount;
\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
333 int CProfile::IsNotSameString(CComboBox *const pApplication, const CString szListItem)
\r
335 CString szItem, szList;
\r
336 szList = szListItem;
\r
337 Item2AppName(&szList);
\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
350 int CProfile::CountSeparator(const CString szMainString, const CString szSeparator)
\r
355 while ((index = szMainString.Find(szSeparator, index)) != -1) {
\r
363 void CProfile::GetNthString(CString *const szAppName, const CString szWindowName, const CString szSeparator, int n)
\r
368 index = szWindowName.Find(szSeparator, index + 1);
\r
373 nStart = index + szSeparator.GetLength();
\r
378 int nEnd = szWindowName.Find(szSeparator, nStart);
\r
380 nEnd = szWindowName.GetLength();
\r
383 *szAppName = szWindowName.Mid(nStart, nEnd - nStart);
\r
386 void CProfile::GetAppName(CString *const szAppName, LPCTSTR pWindowName)
\r
388 CString szWindowName(pWindowName);
\r
389 CString szSeparator(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE));
\r
390 int nWord = CountSeparator(szWindowName, szSeparator) + 1;
\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
403 *szAppName = szWindowName;
\r
406 BOOL CALLBACK CProfile::EnumWindowsProc(const HWND hWnd, const LPARAM lParam)
\r
408 CComboBox *pApplication = (CComboBox*)lParam;
\r
409 PTASK_LIST pTask = CProfile::m_TaskList;
\r
411 TCHAR szWindowName[WINDOW_NAME_LENGTH];
\r
412 TCHAR szClassName[CLASS_NAME_LENGTH];
\r
413 WINDOWPLACEMENT wpl;
\r
415 wpl.length = sizeof(WINDOWPLACEMENT);
\r
416 ::GetWindowText(hWnd, szWindowName, sizeof(szWindowName));
\r
417 GetClassName(hWnd, szClassName, sizeof(szClassName));
\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
426 // Get Application Name
\r
427 if (szWindowName[0] == '\0') {
\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
457 CUtils::SetCorrectApplicationName(pTask[i].ProcessName, sizeof(pTask[i].ProcessName), szWindowName, sizeof(szWindowName));
\r
458 GetAppName(&szAppName, szWindowName);
\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
478 //////////////////////////////////////////////////////////////////////
\r
479 // Construction/Destruction
\r
480 //////////////////////////////////////////////////////////////////////
\r
482 CProfile::CProfile()
\r
487 CProfile::~CProfile()
\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
498 CString szApplicationName;
\r
499 CString szApplicationTitle;
\r
500 CString szWindowText;
\r
501 CString szWindowTextType;
\r
503 BOOL bUseDialogSetting = FALSE;
\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
521 szApplicationName.LoadString(IDS_DEFAULT);
\r
524 if (szApplicationName == CString(MAKEINTRESOURCE(IDS_DIALOG))) {
\r
525 bUseDialogSetting = TRUE;
\r
528 m_XkeymacsData[nApplicationID].SetApplicationName(szApplicationName);
\r
529 } else { // initialize
\r
530 szApplicationName = m_XkeymacsData[nApplicationID].GetApplicationName();
\r
531 if (szApplicationName.IsEmpty()) {
\r
534 AfxGetApp()->WriteProfileString(szSection, szEntry, szApplicationName);
\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
547 AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szApplicationTitle);
\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
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
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
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
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
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
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
604 int nCommandType = 0;
\r
606 ReadKeyBind(&nCommandType, &nKey, szKeyBind);
\r
607 m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);
\r
609 // if (nCommandType == CONTROL && nKey == 'D') {
\r
610 // CUtils::Log("GetProfileInt(at ibeam cursor only): %s, %s", szSubKey, szKeyBind);
\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
616 memset(szKeyBind, 0, sizeof(szKeyBind));
\r
617 dwKeyBind = sizeof(szKeyBind);
\r
621 // Use default setting
\r
622 for (int i = 0; ; ++i) {
\r
623 if (CCommands::GetDefaultControlID(nCommandID, i) == IDC_CO2) {
\r
627 int nCommandType = CCommands::GetDefaultCommandType(nCommandID, i);
\r
628 int nKey = CCommands::GetDefaultCommandKey(nCommandID, i);
\r
632 m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);
\r
633 m_XkeymacsData[nApplicationID].SetAtIbeamCursorOnly(nCommandType, nKey, FALSE);
\r
637 for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {
\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
650 ReadKeyBind(&nCommandType, &nKey, szKeyBind);
\r
651 CDotXkeymacs::SetKey(nFunctionID, nApplicationID, nCommandType, nKey);
\r
653 memset(szKeyBind, 0, sizeof(szKeyBind));
\r
654 dwKeyBind = sizeof(szKeyBind);
\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
667 SaveCommand(szApplicationName, nCommandID);
\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
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
679 CDotXkeymacs::GetKey(nFunctionID, nApplicationID, nKeyID, &nCommandType, &nKey);
\r
680 SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFunctionID), nCommandType, nKey);
\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
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
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
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
718 AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, bDisableXkeymacs);
\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
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
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
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
755 void CProfile::LoadRegistryData()
\r
757 CDotXkeymacs::Load();
\r
759 UpdateRegistryData(TRUE);
\r
762 void CProfile::SaveRegistryData()
\r
764 DeleteAllRegistryData();
\r
765 UpdateRegistryData(FALSE);
\r
769 void CProfile::SetDllData()
\r
771 CMainFrame *pMainFrame = (CMainFrame*)AfxGetMainWnd();
\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
778 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
780 CString szApplicationName = m_XkeymacsData[nApplicationID].GetApplicationName();
\r
782 if (szApplicationName.IsEmpty()) {
\r
783 pMainFrame->m_pXkeymacsDll->Clear(nApplicationID);
\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
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
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
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
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
829 void CProfile::ReadKeyBind(int *const pnCommandType, int *const pnKey, LPCTSTR szKeyBind)
\r
831 *pnCommandType = KeyBind2CommandType(szKeyBind);
\r
832 *pnKey = KeyBind2Key(szKeyBind + _tcslen(CommandType2String(*pnCommandType)));
\r
835 CString CProfile::WriteKeyBind(const int nCommandType, const int nKey)
\r
838 szKeyBind.Format(_T("%s%s"), CommandType2String(nCommandType), Key2String(nKey));
\r
842 int CProfile::KeyBind2CommandType(LPCTSTR szKeyBind)
\r
844 for (int nCommandType = MAX_COMMAND_TYPE - 1; nCommandType; --nCommandType) {
\r
845 if (IsCommandType(nCommandType, szKeyBind)) {
\r
846 return nCommandType;
\r
852 int CProfile::KeyBind2Key(LPCTSTR szKey)
\r
854 for (int nKey = 1; nKey < 0xff; ++nKey) {
\r
855 if (!_tcscmp(szKey, Key2String(nKey))) {
\r
862 LPCTSTR CProfile::CommandType2String(int nCommandType)
\r
864 if (nCommandType < 0 || sizeof(CommandTypes) / sizeof(CommandTypes[0]) <= nCommandType) {
\r
866 nCommandType = NONE;
\r
868 return CommandTypes[nCommandType].szCommandTypeName;
\r
871 LPCTSTR CProfile::Key2String(int nKey)
\r
873 if (CProfile::Is106Keyboard()) {
\r
888 if (nKey < 0 || sizeof(KeyNames) / sizeof(KeyNames[0]) <= nKey) {
\r
892 return KeyNames[nKey].name;
\r
895 BOOL CProfile::IsCommandType(const int nCommandType, LPCTSTR szKeyBind)
\r
897 LPCTSTR szCommandType = CommandType2String(nCommandType);
\r
899 if (!_tcsnicmp(szKeyBind, szCommandType, _tcslen(szCommandType))) {
\r
906 void CProfile::SaveKeyBind(const CString szApplicationName, const int nCommandID, const int nCommandType, const int nKey)
\r
912 CString szCommandName = CCommands::GetCommandName(nCommandID);
\r
913 if (szCommandName.IsEmpty()) {
\r
917 SaveKeyBind(szApplicationName, szCommandName, nCommandType, nKey);
\r
920 void CProfile::SaveKeyBind(const CString szApplicationName, const CString szCommandName, const int nCommandType, const int nKey)
\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
930 if (RegCreateKeyEx(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS) {
\r
935 void CProfile::SaveCommand(const CString szApplicationName, const int nCommandID)
\r
937 SaveKeyBind(szApplicationName, nCommandID, 0, 0);
\r
940 void CProfile::AddKeyBind2C_(const CString szApplicationName, const BYTE bVk)
\r
942 for (int nCommandID = 0; nCommandID < MAX_COMMAND; ++nCommandID) {
\r
943 if (Commands[nCommandID].fCommand == CCommands::C_) {
\r
948 SaveKeyBind(szApplicationName, nCommandID, NONE, bVk);
\r
951 void CProfile::LevelUp()
\r
953 const int nDefalutLevel = 0;
\r
954 const int nLatestLevel = 4;
\r
958 szEntry.Format(_T("Level"));
\r
960 switch (AfxGetApp()->GetProfileInt(szSection, szEntry, nDefalutLevel)) {
\r
961 case nDefalutLevel:
\r
963 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
965 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);
\r
967 CString szApplicationName;
\r
968 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);
\r
969 if (szApplicationName.IsEmpty()) {
\r
973 AddKeyBind2C_(szApplicationName, VK_LCONTROL);
\r
974 AddKeyBind2C_(szApplicationName, VK_RCONTROL);
\r
977 // Do NOT write break; here.
\r
980 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
982 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);
\r
984 CString szApplicationName;
\r
985 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);
\r
986 if (szApplicationName.IsEmpty()) {
\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
996 // Do NOT write break; here.
\r
999 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
1001 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);
\r
1003 CString szApplicationName;
\r
1004 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);
\r
1005 if (szApplicationName.IsEmpty()) {
\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
1022 // Do NOT write break; here.
\r
1025 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
1027 szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);
\r
1029 CString szApplicationName;
\r
1030 szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);
\r
1031 if (szApplicationName.IsEmpty()) {
\r
1035 // rename original function to remove IDS_REG_ORIGINAL_PREFIX
\r
1036 for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {
\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
1048 ReadKeyBind(&nCommandType, &nKey, szKeyBind);
\r
1049 SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFunctionID), nCommandType, nKey);
\r
1051 memset(szKeyBind, 0, sizeof(szKeyBind));
\r
1052 dwKeyBind = sizeof(szKeyBind);
\r
1054 RegCloseKey(hKey);
\r
1062 // case nLatestLevel-1:
\r
1064 AfxGetApp()->WriteProfileInt(szSection, szEntry, nLatestLevel);
\r
1071 void CProfile::InitDllData()
\r
1073 LoadRegistryData();
\r
1077 void CProfile::ClearData(const CString szCurrentApplication)
\r
1079 for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
1080 if (m_XkeymacsData[nApplicationID].GetApplicationName() == szCurrentApplication) {
\r
1084 if (nApplicationID < MAX_APP) {
\r
1085 m_XkeymacsData[nApplicationID].ClearAll();
\r
1089 // return count of saved settings
\r
1090 int CProfile::GetSavedSettingCount()
\r
1092 int nSavedSetting = 0;
\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
1102 return nSavedSetting;
\r
1105 void CProfile::InitApplicationList(CComboBox *const cApplicationList)
\r
1107 cApplicationList->ResetContent();
\r
1111 EnumWindows(EnumWindowsProc, (LPARAM)cApplicationList);
\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
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
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
1137 // CUtils::Log(_T("nIMEDescription = %d, szIMEDescription = _%s_"), nIMEDescription, szIMEDescription);
\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
1147 // CUtils::Log(_T("nIMEFileName = %d, szIMEFileName = _%s_"), nIMEFileName, szIMEFileName);
\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
1158 delete[] szIMEDescription;
\r
1159 szIMEDescription = NULL;
\r
1160 delete[] szIMEFileName;
\r
1161 szIMEFileName = NULL;
\r
1165 cApplicationList->InsertString(0, CString(MAKEINTRESOURCE(IDS_DIALOG_TITLE)));
\r
1168 cApplicationList->InsertString( 0, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));
\r
1169 cApplicationList->SelectString(-1, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));
\r
1172 void CProfile::GetTaskList()
\r
1174 ZeroMemory(m_TaskList, sizeof(m_TaskList));
\r
1176 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
\r
1177 if (hProcessSnap == (HANDLE)-1)
\r
1181 PROCESSENTRY32 processEntry32 = {sizeof(PROCESSENTRY32)};
\r
1182 if (Process32First(hProcessSnap, &processEntry32)) {
\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
1189 CloseHandle(hProcessSnap);
\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
1197 if (!bSaveAndValidate) { // SetDialogData
\r
1198 *nSettingStyle = SETTING_UNDEFINED;
\r
1201 int nApplicationID = GetApplicationIndex(szApplicationName);
\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
1212 if (nApplicationID == MAX_APP) {
\r
1213 return nApplicationID;
\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
1222 if (nApplicationID == MAX_APP) {
\r
1223 return nApplicationID;
\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
1236 return nApplicationID;
\r
1239 BOOL CProfile::Is106Keyboard()
\r
1241 static KEYBOARD_TYPE keyboard = UNKNOWN_KEYBOARD;
\r
1243 if (keyboard == UNKNOWN_KEYBOARD) {
\r
1244 OSVERSIONINFO verInfo = {0};
\r
1245 verInfo.dwOSVersionInfoSize = sizeof (verInfo);
\r
1246 GetVersionEx(&verInfo);
\r
1248 DWORD subtype = 0;
\r
1249 DWORD cbData = sizeof(subtype);
\r
1251 if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
\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
1259 RegCloseKey(hKey);
\r
1261 } else if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
\r
1262 subtype = GetPrivateProfileInt(_T("keyboard"), _T("subtype"), 0, _T("system.ini"));
\r
1265 keyboard = (subtype & 0x02) ? JAPANESE_KEYBOARD : ENGLISH_KEYBOARD;
\r
1268 return keyboard == JAPANESE_KEYBOARD;
\r
1271 BOOL CProfile::IsTheString(const CString sz, const UINT nID)
\r
1273 return sz == CString(MAKEINTRESOURCE(nID));
\r
1276 // if sz is "Default", return TRUE
\r
1277 BOOL CProfile::IsDefault(const CString sz)
\r
1279 return IsTheString(sz, IDS_DEFAULT);
\r
1282 // if sz is "Dialog", return TRUE
\r
1283 BOOL CProfile::IsDialog(const CString sz)
\r
1285 return IsTheString(sz, IDS_DIALOG);
\r
1288 void CProfile::GetApplicationTitle(CComboBox *const cApplicationList, CString &rList, const int nIndex)
\r
1290 if (0 <= nIndex) {
\r
1291 cApplicationList->GetLBText(nIndex, rList);
\r
1293 cApplicationList->GetWindowText(rList);
\r
1296 if (IsTheString(rList, IDS_DEFAULT_TITLE)) {
\r
1297 rList.LoadString(IDS_DEFAULT);
\r
1300 if (IsTheString(rList, IDS_DIALOG_TITLE)) {
\r
1301 rList.LoadString(IDS_DIALOG);
\r
1307 void CProfile::UpdateApplicationTitle(CComboBox *const cApplicationList, const CString szCurrentApplication, const int nApplicationID, const BOOL bSaveAndValidate)
\r
1309 static CString szApplicationTitle;
\r
1310 if (bSaveAndValidate) { // GetDialogData
\r
1311 if (!CProfile::IsDefault(szCurrentApplication)) {
\r
1312 m_XkeymacsData[nApplicationID].SetApplicationTitle(szApplicationTitle);
\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
1325 void CProfile::SetCommandID(const int nApplicationID, const int nCommandType, const int nKey, int nCommandID)
\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
1335 m_XkeymacsData[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);
\r
1338 int CProfile::GetCommandID(const int nApplicationID, const int nCommandType, const int nKey)
\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
1349 return nCommandID;
\r
1352 void CProfile::SetKillRingMax(const int nApplicationID, const int nKillRingMax)
\r
1354 m_XkeymacsData[nApplicationID].SetKillRingMax(nKillRingMax);
\r
1357 int CProfile::GetKillRingMax(const int nApplicationID)
\r
1359 return m_XkeymacsData[nApplicationID].GetKillRingMax();
\r
1362 void CProfile::SetUseDialogSetting(const int nApplicationID, const BOOL bUseDialogSetting)
\r
1364 m_XkeymacsData[nApplicationID].SetUseDialogSetting(bUseDialogSetting);
\r
1367 BOOL CProfile::GetUseDialogSetting(const int nApplicationID)
\r
1369 return m_XkeymacsData[nApplicationID].GetUseDialogSetting();
\r
1372 void CProfile::SetWindowText(const int nApplicationID, const CString szWindowText)
\r
1374 m_XkeymacsData[nApplicationID].SetWindowText(szWindowText);
\r
1377 CString CProfile::GetWindowText(const int nApplicationID)
\r
1379 return m_XkeymacsData[nApplicationID].GetWindowText();
\r
1382 void CProfile::DeleteAllRegistryData()
\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
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
1400 RegCloseKey(hkey);
\r
1404 int CProfile::GetCurrentApplicationID(CComboBox *const cApplicationList, const CString szCurrentApplication)
\r
1406 int nCounter = cApplicationList->GetCount();
\r
1407 CString szListItem;
\r
1408 int nCurSel = cApplicationList->GetCurSel();
\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
1421 void CProfile::CopyData(const CString szDestinationApplication, const CString szSourceApplication)
\r
1423 int nSettingStyle = SETTING_SPECIFIC;
\r
1424 int nDestinationApplication = GetApplicationIndex(szDestinationApplication, TRUE, &nSettingStyle);
\r
1425 int nSourceApplication = GetApplicationIndex(szSourceApplication);
\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
1432 m_XkeymacsData[nDestinationApplication] = m_XkeymacsData[nSourceApplication];
\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
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
1444 int nApplicationID = 0;
\r
1445 for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {
\r
1446 if (m_XkeymacsData[nApplicationID].GetApplicationName() == szApplicationName) {
\r
1450 return nApplicationID;
\r
1453 // Return True if Windows Vista or later.
\r
1454 BOOL CProfile::IsVistaOrLater()
\r
1456 OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};
\r
1457 GetVersionEx(&info);
\r
1459 if (6 <= info.dwMajorVersion) {
\r
1465 void CProfile::RestartComputer()
\r
1467 if (!AdjustTokenPrivileges(SE_SHUTDOWN_NAME)) {
\r
1471 ExitWindowsEx(EWX_REBOOT, 0);
\r
1474 BOOL CProfile::AdjustTokenPrivileges(LPCTSTR lpName)
\r
1479 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
\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
1487 if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
\r
1493 CloseHandle(hToken);
\r
1501 BOOL CProfile::DiableTokenPrivileges()
\r
1506 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
\r
1507 if (!::AdjustTokenPrivileges(hToken, TRUE, NULL, NULL, NULL, NULL)) {
\r
1510 CloseHandle(hToken);
\r
1518 void CProfile::ExportProperties()
\r
1520 if (!AdjustTokenPrivileges(SE_BACKUP_NAME)) {
\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
1531 DiableTokenPrivileges();
\r
1535 void CProfile::ImportProperties()
\r
1537 if (!AdjustTokenPrivileges(SE_RESTORE_NAME)) {
\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
1548 DiableTokenPrivileges();
\r
1552 BOOL CProfile::GetEnableCUA(const int nApplicationID)
\r
1554 return m_XkeymacsData[nApplicationID].GetEnableCUA();
\r
1557 void CProfile::SetEnableCUA(const int nApplicationID, const BOOL bEnableCUA)
\r
1559 m_XkeymacsData[nApplicationID].SetEnableCUA(bEnableCUA);
\r
1562 int CProfile::GetKeyboardSpeed()
\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
1569 if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
\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
1577 for (DWORD i = 0; i < dwcbData; ++i) {
\r
1580 nKeyboardSpeed = nKeyboardSpeed * 10 + data[i] - _T('0');
\r
1582 nKeyboardSpeed = data[i] - _T('0');
\r
1590 return nKeyboardSpeed;
\r