1 // Profile.cpp: implementation of the CProfile class
\r
3 //////////////////////////////////////////////////////////////////////
\r
7 #include "xkeymacs.h"
\r
8 #include "dotxkeymacs.h"
\r
10 #include "../xkeymacsdll/xkeymacsdll.h"
\r
11 #include "../xkeymacsdll/AppName.h"
\r
12 #include "../xkeymacsdll/Utils.h"
\r
13 #include <TlHelp32.h>
\r
17 static char THIS_FILE[]=__FILE__;
\r
18 #define new DEBUG_NEW
\r
21 Config CProfile::m_Config;
\r
22 TCHAR CProfile::m_szAppTitle[MAX_APP][WINDOW_TEXT_LENGTH];
\r
23 TASK_LIST CProfile::m_TaskList[MAX_TASKS];
\r
24 DWORD CProfile::m_dwTasks;
\r
25 KeyString CProfile::m_KeyString(CProfile::Is106Keyboard() != FALSE);
\r
27 // This function returns the nth string in a window name separated by " - ".
\r
28 // If there aren't a sufficient number of strings, it returns the last string
\r
29 // appropriate for the title.
\r
30 bool CProfile::GetAppTitle(CString& appTitle, const CString& windowName, int nth)
\r
32 const CString sep(MAKEINTRESOURCE(IDS_SEPARATE_WINDOWTITLE));
\r
33 const int nSep = windowName.Find(sep);
\r
35 appTitle = windowName;
\r
38 if (GetAppTitle(appTitle, windowName.Right(windowName.GetLength() - nSep - sep.GetLength()), --nth) ||
\r
39 !nth || nth > 0 && appTitle.GetAt(0) != _T('[') && appTitle.FindOneOf(_T(".]")) == -1)
\r
41 appTitle = windowName.Left(nSep);
\r
45 BOOL CALLBACK CProfile::EnumWindowsProc(const HWND hWnd, const LPARAM lParam)
\r
47 CProperties *pProperties = reinterpret_cast<CProperties*>(lParam);
\r
48 PTASK_LIST pTask = CProfile::m_TaskList;
\r
50 TCHAR szWindowName[WINDOW_TEXT_LENGTH];
\r
51 TCHAR szClassName[CLASS_NAME_LENGTH];
\r
52 WINDOWPLACEMENT wpl;
\r
54 wpl.length = sizeof(WINDOWPLACEMENT);
\r
55 ::GetWindowText(hWnd, szWindowName, sizeof(szWindowName));
\r
56 GetClassName(hWnd, szClassName, sizeof(szClassName));
\r
60 DWORD dwProcessId = 0;
\r
61 GetWindowThreadProcessId(hWnd, &dwProcessId);
\r
63 for (i = 0; i < CProfile::m_dwTasks; ++i) {
\r
64 if (pTask[i].dwProcessId == dwProcessId) {
\r
66 // Get Application Name
\r
67 if (szWindowName[0] == '\0') {
\r
70 if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_B2)), sizeof(pTask[i].ProcessName))) {
\r
71 appTitle.LoadString(IDS_BECKY);
\r
72 } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXPLORER)), sizeof(pTask[i].ProcessName))) {
\r
73 appTitle.LoadString(IDS_PROGRAM_MANAGER);
\r
74 } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSIMN)), sizeof(pTask[i].ProcessName))) {
\r
75 appTitle.LoadString(IDS_OUTLOOK_EXPRESS);
\r
76 } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_PROJECT)), sizeof(pTask[i].ProcessName))
\r
77 || !_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_EXCEL)), sizeof(pTask[i].ProcessName))
\r
78 || !_tcsnicmp(pTask[i].ProcessName, _T("psp.exe"), sizeof(pTask[i].ProcessName))) {
\r
79 GetAppTitle(appTitle, szWindowName, 1);
\r
80 } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sakura.exe"), sizeof(pTask[i].ProcessName))) {
\r
81 GetAppTitle(appTitle, szWindowName, 2); // '.' is included, so...
\r
82 } else if (!_tcsnicmp(pTask[i].ProcessName, CString(MAKEINTRESOURCE(IDS_MSDN)), sizeof(pTask[i].ProcessName))) {
\r
83 appTitle = szWindowName;
\r
84 } else if (!_tcsnicmp(pTask[i].ProcessName, _T("devenv.exe"), sizeof(pTask[i].ProcessName))) {
\r
85 appTitle.Format(_T("Microsoft Visual Studio .NET"));
\r
86 } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vb6.exe"), sizeof(pTask[i].ProcessName))) {
\r
87 appTitle.Format(_T("Microsoft Visual Basic"));
\r
88 } else if (!_tcsnicmp(pTask[i].ProcessName, _T("ssexp.exe"), sizeof(pTask[i].ProcessName))) {
\r
89 appTitle.LoadString(IDS_VISUAL_SOURCESAFE_EXPLORER);
\r
90 } else if (!_tcsnicmp(pTask[i].ProcessName, _T("sh.exe"), sizeof(pTask[i].ProcessName))) {
\r
91 appTitle.Format(_T("MKS Korn Shell"));
\r
92 } else if (!_tcsnicmp(pTask[i].ProcessName, _T("csh.exe"), sizeof(pTask[i].ProcessName))) {
\r
93 appTitle.Format(_T("C Shell"));
\r
94 } else if (!_tcsnicmp(pTask[i].ProcessName, _T("vim.exe"), sizeof(pTask[i].ProcessName))) {
\r
95 appTitle.Format(_T("VIM"));
\r
97 AppName::CorrectAppName(szWindowName, pTask[i].ProcessName);
\r
98 GetAppTitle(appTitle, szWindowName);
\r
104 if (IsWindowVisible(hWnd) && // Is visible?
\r
105 GetWindow(hWnd, GW_OWNER) == NULL && // Is top level window?
\r
106 lstrlen(szWindowName) > 0) { // Have caption?
\r
107 pProperties->AddItem(appTitle, pTask[i].ProcessName);
\r
112 void CProfile::LoadRegistry()
\r
114 bool bDialog = false;
\r
115 const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));
\r
116 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {
\r
118 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);
\r
119 CString appName = AfxGetApp()->GetProfileString(section, entry);
\r
120 if (appName.IsEmpty()) {
\r
124 appName.LoadString(IDS_DIALOG);
\r
127 appName.LoadString(IDS_DEFAULT);
\r
128 } else if (appName == CString(MAKEINTRESOURCE(IDS_DIALOG)))
\r
130 _tcsncpy_s(m_Config.szSpecialApp[nAppID], appName, _TRUNCATE);
\r
131 entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);
\r
132 _tcsncpy_s(m_szAppTitle[nAppID], AfxGetApp()->GetProfileString(appName, entry), _TRUNCATE);
\r
133 entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);
\r
134 _tcsncpy_s(m_Config.szWindowText[nAppID], AfxGetApp()->GetProfileString(appName, entry, _T("*")), _TRUNCATE);
\r
136 const CString regApp = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName;
\r
137 for (BYTE nComID = 1; nComID < MAX_COMMAND; ++nComID) {
\r
138 entry = CCommands::GetCommandName(nComID);
\r
140 const CString regKey = regApp + _T("\\") + entry;
\r
141 if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
\r
142 TCHAR szKeyBind[128];
\r
143 DWORD dwKeyBind = _countof(szKeyBind);
\r
144 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {
\r
146 StringToKey(szKeyBind, nType, nKey);
\r
147 m_Config.nCommandID[nAppID][nType][nKey] = nComID;
\r
148 dwKeyBind = _countof(szKeyBind);
\r
152 // Set the default assignment
\r
153 for (int i = 0; const int nKey = CCommands::GetDefaultCommandKey(nComID, i); ++i) {
\r
154 if (CCommands::GetDefaultControlID(nComID, i) == IDC_CO2)
\r
156 const int nType = CCommands::GetDefaultCommandType(nComID, i);
\r
157 m_Config.nCommandID[nAppID][nType][nKey] = nComID;
\r
161 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {
\r
163 const CString regKey = regApp + _T("\\") + CDotXkeymacs::GetFunctionSymbol(nFuncID);
\r
164 if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
\r
165 CDotXkeymacs::ClearKey(nFuncID, nAppID);
\r
166 TCHAR szKeyBind[128];
\r
167 DWORD dwKeyBind = _countof(szKeyBind);
\r
168 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {
\r
170 StringToKey(szKeyBind, nType, nKey);
\r
171 CDotXkeymacs::SetKey(nFuncID, nAppID, nType, nKey);
\r
172 dwKeyBind = _countof(szKeyBind);
\r
178 entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);
\r
179 int n = AfxGetApp()->GetProfileInt(appName, entry, 1);
\r
180 m_Config.nKillRingMax[nAppID] = static_cast<BYTE>(n > 255 ? 255 : n);
\r
181 entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);
\r
182 m_Config.bUseDialogSetting[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 1));
\r
183 entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);
\r
184 m_Config.nSettingStyle[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0) ? SETTING_DISABLE : SETTING_SPECIFIC);
\r
185 entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);
\r
186 m_Config.bIgnoreUndefinedMetaCtrl[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0));
\r
187 entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);
\r
188 m_Config.bIgnoreUndefinedC_x[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0));
\r
189 entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);
\r
190 m_Config.bEnableCUA[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0));
\r
191 entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);
\r
192 m_Config.b326Compatible[nAppID] = static_cast<BYTE>(AfxGetApp()->GetProfileInt(appName, entry, 0));
\r
196 void CProfile::SaveRegistry()
\r
198 const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));
\r
199 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {
\r
200 const LPCTSTR szAppName = m_Config.szSpecialApp[nAppID];
\r
202 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);
\r
203 if (!szAppName[0]) {
\r
204 if (!AfxGetApp()->GetProfileString(section, entry).IsEmpty())
\r
205 AfxGetApp()->WriteProfileString(section, entry, _T(""));
\r
208 AfxGetApp()->WriteProfileString(section, entry, szAppName);
\r
210 entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);
\r
211 CString appTitle = m_szAppTitle[nAppID];
\r
212 appTitle.TrimLeft(_T(' '));
\r
213 AfxGetApp()->WriteProfileString(szAppName, entry, appTitle);
\r
214 entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);
\r
215 AfxGetApp()->WriteProfileString(szAppName, entry, m_Config.szWindowText[nAppID]);
\r
217 // Create all commands
\r
218 for (int nComID = 1; nComID < MAX_COMMAND; ++nComID)
\r
219 SaveKeyBind(szAppName, nComID, 0, 0);
\r
220 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)
\r
221 for (int nKey = 0; nKey < MAX_KEY; ++nKey)
\r
222 SaveKeyBind(szAppName, m_Config.nCommandID[nAppID][nType][nKey], nType, nKey);
\r
223 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)
\r
224 for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFuncID, nAppID); ++nKeyID) {
\r
226 CDotXkeymacs::GetKey(nFuncID, nAppID, nKeyID, &nType, &nKey);
\r
227 SaveKeyBind(szAppName, CDotXkeymacs::GetFunctionSymbol(nFuncID), nType, nKey);
\r
230 entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);
\r
231 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.nKillRingMax[nAppID]);
\r
232 entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);
\r
233 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bUseDialogSetting[nAppID]);
\r
234 entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);
\r
235 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.nSettingStyle[nAppID] == SETTING_DISABLE);
\r
236 entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);
\r
237 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bIgnoreUndefinedMetaCtrl[nAppID]);
\r
238 entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);
\r
239 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bIgnoreUndefinedC_x[nAppID]);
\r
240 entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);
\r
241 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bEnableCUA[nAppID]);
\r
242 entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);
\r
243 AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.b326Compatible[nAppID]);
\r
247 void CProfile::LoadData()
\r
249 CDotXkeymacs::Load();
\r
254 void CProfile::SaveData()
\r
256 DeleteAllRegistryData();
\r
261 void CProfile::SetDllData()
\r
263 memset(m_Config.nFunctionID, -1, sizeof(m_Config.nFunctionID));
\r
264 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)
\r
265 _tcscpy_s(m_Config.szFunctionDefinition[nFuncID], CDotXkeymacs::GetFunctionDefinition(nFuncID));
\r
267 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {
\r
268 m_Config.nCommandID[nAppID][CONTROL]['X'] = 0; // C-x is unassigned.
\r
269 for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)
\r
270 for (int nKey = 0; nKey < MAX_KEY; ++nKey)
\r
271 if ((nType & CONTROLX) && m_Config.nCommandID[nAppID][nType][nKey])
\r
272 m_Config.nCommandID[nAppID][CONTROL]['X'] = 1; // C-x is available.
\r
273 for (BYTE nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)
\r
274 for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFuncID, nAppID); ++nKeyID) {
\r
276 CDotXkeymacs::GetKey(nFuncID, nAppID, nKeyID, &nType, &nKey);
\r
277 m_Config.nFunctionID[nAppID][nType][nKey] = nFuncID;
\r
278 if (nType & CONTROLX)
\r
279 m_Config.nCommandID[nAppID][CONTROL]['X'] = 1; // C-x is available.
\r
282 m_Config.b106Keyboard = static_cast<BYTE>(Is106Keyboard());
\r
283 CXkeymacsDll::SetConfig(m_Config);
\r
284 CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());
\r
285 if (!pApp->IsWow64())
\r
287 if (!CXkeymacsDll::SaveConfig())
\r
289 pApp->SendIPCMessage(XKEYMACS_RELOAD);
\r
292 void CProfile::SaveKeyBind(const LPCTSTR appName, int comID, int type, int key)
\r
296 LPCTSTR comName = CCommands::GetCommandName(comID);
\r
299 SaveKeyBind(appName, comName, type, key);
\r
302 void CProfile::SaveKeyBind(const LPCTSTR appName, const LPCTSTR comName, int type, int key)
\r
304 CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName + _T("\\") + comName;
\r
305 CString s = KeyToString(type, key);
\r
307 subKey = subKey + _T("\\") + s;
\r
309 if (RegCreateKeyEx(HKEY_CURRENT_USER, subKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)
\r
313 void CProfile::StringToKey(const LPCTSTR str, int& type, int& key)
\r
315 m_KeyString.ToKey(str, type, key);
\r
318 CString CProfile::KeyToString(int type, int key)
\r
320 return m_KeyString.ToString(type, key);
\r
323 void CProfile::AddKeyBind2C_(const LPCSTR szAppName, const BYTE bVk)
\r
326 for (nComID = 0; nComID < MAX_COMMAND; ++nComID)
\r
327 if (Commands[nComID].fCommand == CCommands::C_)
\r
329 SaveKeyBind(szAppName, nComID, NONE, bVk);
\r
332 void CProfile::LevelUp()
\r
334 const int nCurrentLevel = AfxGetApp()->GetProfileInt(_T(""), _T("Level"), 0);
\r
335 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {
\r
337 entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);
\r
338 const CString appName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), entry);
\r
339 if (appName.IsEmpty())
\r
341 switch (nCurrentLevel) {
\r
343 AddKeyBind2C_(appName, VK_LCONTROL);
\r
344 AddKeyBind2C_(appName, VK_RCONTROL);
\r
347 // Set kill-ring-max 1 if it is 0.
\r
348 if (!AfxGetApp()->GetProfileInt(appName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 0))
\r
349 AfxGetApp()->WriteProfileInt(appName, CString(MAKEINTRESOURCE(IDS_REG_ENTRY_KILL_RING_MAX)), 1);
\r
353 // Chaged a label from Enter to newline.
\r
354 const CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName;
\r
355 const CString srcKey = subKey + _T("\\") + _T("Enter");
\r
356 const CString dstKey = subKey + _T("\\") + _T("newline");
\r
357 HKEY hDstKey = NULL;
\r
358 if (RegCreateKeyEx(HKEY_CURRENT_USER, dstKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hDstKey, NULL) == ERROR_SUCCESS) {
\r
359 SHCopyKey(HKEY_CURRENT_USER, srcKey, hDstKey, NULL);
\r
360 SHDeleteKey(HKEY_CURRENT_USER, srcKey);
\r
361 RegCloseKey(hDstKey);
\r
366 // rename original function to remove IDS_REG_ORIGINAL_PREFIX
\r
367 for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {
\r
369 const CString subKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName + _T("\\") + CString(MAKEINTRESOURCE(IDS_REG_ORIGINAL_PREFIX)) + CDotXkeymacs::GetFunctionSymbol(nFuncID);
\r
370 if (RegOpenKeyEx(HKEY_CURRENT_USER, subKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
\r
371 // Use registry data
\r
372 TCHAR szKeyBind[128];
\r
373 DWORD dwKeyBind = sizeof(szKeyBind);
\r
374 for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {
\r
376 StringToKey(szKeyBind, nType, nKey);
\r
377 SaveKeyBind(appName, CDotXkeymacs::GetFunctionSymbol(nFuncID), nType, nKey);
\r
378 dwKeyBind = sizeof(szKeyBind);
\r
385 AfxGetApp()->WriteProfileInt(_T(""), _T("Level"), 4);
\r
388 void CProfile::InitDllData()
\r
394 void CProfile::ClearData(const CString szCurrentApplication)
\r
396 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID)
\r
397 if (szCurrentApplication == m_Config.szSpecialApp[nAppID]) {
\r
398 ZeroMemory(m_Config.nCommandID[nAppID], sizeof(m_Config.nCommandID[nAppID]));
\r
399 ZeroMemory(m_Config.szSpecialApp[nAppID], CLASS_NAME_LENGTH);
\r
404 // return count of saved settings
\r
405 int CProfile::GetSavedSettingCount()
\r
407 int nSavedSetting = 0;
\r
408 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID)
\r
409 if (m_Config.szSpecialApp[nAppID][0])
\r
411 return nSavedSetting;
\r
414 void CProfile::InitAppList(CProperties& cProperties)
\r
418 EnumWindows(EnumWindowsProc, reinterpret_cast<LPARAM>(&cProperties));
\r
420 for (int i = 0; i < MAX_APP; ++i) {
\r
421 const LPCTSTR szAppName = m_Config.szSpecialApp[i];
\r
422 const LPCTSTR szAppTitle = m_szAppTitle[i];
\r
423 if (!szAppName[0] || !_tcscmp(szAppName, _T("IME")))
\r
425 if (CString(MAKEINTRESOURCE(IDS_DEFAULT)) == szAppName ||
\r
426 CString(MAKEINTRESOURCE(IDS_DIALOG)) == szAppName)
\r
428 cProperties.AddItem(szAppTitle, szAppName);
\r
430 AddIMEInfo(cProperties);
\r
433 void CProfile::AddIMEInfo(CProperties& cProperties)
\r
436 for (IMEListIterator p = imeList.begin(); p != imeList.end(); ++p)
\r
437 cProperties.AddItem(p->szDescription, p->szFileName);
\r
440 void CProfile::GetTaskList()
\r
442 ZeroMemory(m_TaskList, sizeof(m_TaskList));
\r
444 HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
\r
445 if (hProcessSnap == (HANDLE)-1)
\r
449 PROCESSENTRY32 processEntry32 = {sizeof(PROCESSENTRY32)};
\r
450 if (Process32First(hProcessSnap, &processEntry32)) {
\r
452 lstrcpy(m_TaskList[m_dwTasks].ProcessName, processEntry32.szExeFile);
\r
453 m_TaskList[m_dwTasks++].dwProcessId = processEntry32.th32ProcessID;
\r
454 } while (m_dwTasks < MAX_TASKS && Process32Next(hProcessSnap, &processEntry32));
\r
457 CloseHandle(hProcessSnap);
\r
460 int CProfile::DefaultAppID()
\r
462 const CString name(MAKEINTRESOURCE(IDS_DEFAULT));
\r
463 for(int nAppID = 0; nAppID < MAX_APP; ++nAppID)
\r
464 if (name == m_Config.szSpecialApp[nAppID])
\r
469 int CProfile::AssignAppID(const LPCSTR szAppName)
\r
471 int nAppID = GetAppID(szAppName);
\r
472 if (nAppID != MAX_APP)
\r
474 for (nAppID = 0; nAppID < MAX_APP; ++nAppID)
\r
475 if (!m_Config.szSpecialApp[nAppID][0]) {
\r
476 _tcsncpy_s(m_Config.szSpecialApp[nAppID], szAppName, _TRUNCATE);
\r
482 int CProfile::GetSettingStyle(const int nAppID)
\r
484 if (nAppID == MAX_APP)
\r
485 return SETTING_DEFAULT;
\r
486 return m_Config.nSettingStyle[nAppID];
\r
489 void CProfile::SetSettingStyle(int nAppID, int nSettingStyle)
\r
491 if (nAppID == MAX_APP)
\r
493 m_Config.nSettingStyle[nAppID] = static_cast<BYTE>(nSettingStyle);
\r
496 BOOL CProfile::Is106Keyboard()
\r
498 static KEYBOARD_TYPE keyboard = UNKNOWN_KEYBOARD;
\r
500 if (keyboard == UNKNOWN_KEYBOARD) {
\r
501 OSVERSIONINFO verInfo = {0};
\r
502 verInfo.dwOSVersionInfoSize = sizeof (verInfo);
\r
503 GetVersionEx(&verInfo);
\r
506 DWORD cbData = sizeof(subtype);
\r
508 if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
\r
510 CString szSubKey(_T("SYSTEM\\CurrentControlSet\\Services\\i8042prt\\Parameters"));
\r
511 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
\r
512 static const CString szValueName(_T("OverrideKeyboardSubtype"));
\r
513 if (RegQueryValueEx(hKey, szValueName, NULL, NULL, (LPBYTE)&subtype, &cbData) != ERROR_SUCCESS) {
\r
518 } else if (verInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) {
\r
519 subtype = GetPrivateProfileInt(_T("keyboard"), _T("subtype"), 0, _T("system.ini"));
\r
522 keyboard = (subtype & 0x02) ? JAPANESE_KEYBOARD : ENGLISH_KEYBOARD;
\r
525 return keyboard == JAPANESE_KEYBOARD;
\r
528 void CProfile::SetAppTitle(const int nAppID, const CString& appTitle)
\r
530 _tcsncpy_s(m_szAppTitle[nAppID], appTitle, _TRUNCATE);
\r
533 void CProfile::SetCommandID(const int nAppID, const int nType, const int nKey, int nComID)
\r
535 if (nKey == 0xf0 && Commands[nComID].fCommand == CCommands::C_)
\r
536 // Change CommandID C_Eisu
\r
537 for (nComID = 1; nComID < MAX_COMMAND; ++nComID)
\r
538 if (Commands[nComID].fCommand == CCommands::C_Eisu)
\r
540 m_Config.nCommandID[nAppID][nType][nKey] = static_cast<BYTE>(nComID);
\r
543 int CProfile::GetCommandID(const int nAppID, const int nType, const int nKey)
\r
545 int nComID = m_Config.nCommandID[nAppID][nType][nKey];
\r
546 if (nKey == 0xf0 && Commands[nComID].fCommand == CCommands::C_Eisu)
\r
547 // Change CommandID C_
\r
548 for (nComID = 1; nComID < MAX_COMMAND; nComID++)
\r
549 if (Commands[nComID].fCommand == CCommands::C_)
\r
554 void CProfile::SetKillRingMax(const int nAppID, const int nKillRingMax)
\r
556 m_Config.nKillRingMax[nAppID] = static_cast<BYTE>(nKillRingMax > 255 ? 255 : nKillRingMax);
\r
559 int CProfile::GetKillRingMax(const int nAppID)
\r
561 return m_Config.nKillRingMax[nAppID];
\r
564 void CProfile::SetUseDialogSetting(const int nAppID, const BOOL bUseDialogSetting)
\r
566 m_Config.bUseDialogSetting[nAppID] = static_cast<BYTE>(bUseDialogSetting);
\r
569 BOOL CProfile::GetUseDialogSetting(const int nAppID)
\r
571 return m_Config.bUseDialogSetting[nAppID];
\r
574 void CProfile::SetWindowText(const int nAppID, const CString szWindowText)
\r
576 if (CUtils::GetWindowTextType(szWindowText) == IDS_WINDOW_TEXT_IGNORE)
\r
577 _tcscpy_s(m_Config.szWindowText[nAppID], _T("*"));
\r
579 _tcsncpy_s(m_Config.szWindowText[nAppID], szWindowText, _TRUNCATE);
\r
582 CString CProfile::GetWindowText(const int nAppID)
\r
584 return m_Config.szWindowText[nAppID];
\r
587 void CProfile::DeleteAllRegistryData()
\r
590 if (RegOpenKeyEx(HKEY_CURRENT_USER, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)), 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) {
\r
591 // I am sure that I have to do only one time, but...
\r
592 for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {
\r
594 TCHAR szName[SUB_KEY_NAME_LENGTH] = {'\0'};
\r
595 DWORD dwName = sizeof(szName);
\r
598 while (RegEnumKeyEx(hkey, dwIndex++, szName, &dwName, NULL, NULL, NULL, &filetime) == ERROR_SUCCESS) {
\r
599 // RegDeleteKey(hkey, szName);
\r
600 SHDeleteKey(hkey, szName);
\r
601 ZeroMemory(szName, sizeof(szName));
\r
602 dwName = sizeof(szName);
\r
609 void CProfile::CopyData(const CString szDstApp, const CString szSrcApp)
\r
611 const int nDstApp = AssignAppID(szDstApp);
\r
612 const int nSrcApp = GetAppID(szSrcApp);
\r
613 if (nDstApp == MAX_APP || nSrcApp == MAX_APP)
\r
615 SetSettingStyle(nDstApp, SETTING_SPECIFIC);
\r
617 #define CopyMember(member) CopyMemory(&m_Config. ## member ## [nDstApp], &m_Config. ## member ## [nSrcApp], sizeof(m_Config. ## member ## [nSrcApp]))
\r
618 CopyMember(b326Compatible);
\r
619 CopyMember(nFunctionID);
\r
620 CopyMember(bEnableCUA);
\r
621 CopyMember(bUseDialogSetting);
\r
622 CopyMember(bIgnoreUndefinedC_x);
\r
623 CopyMember(bIgnoreUndefinedMetaCtrl);
\r
624 CopyMember(nKillRingMax);
\r
625 CopyMember(nCommandID);
\r
629 // return application index
\r
630 // if there is NOT the application in the data, return MAX_APP
\r
631 int CProfile::GetAppID(const LPCSTR szAppName)
\r
634 for (nAppID = 0; nAppID < MAX_APP; ++nAppID)
\r
635 if (!_tcscmp(szAppName, m_Config.szSpecialApp[nAppID]))
\r
640 // Return True if Windows Vista or later.
\r
641 BOOL CProfile::IsVistaOrLater()
\r
643 OSVERSIONINFO info = {sizeof(OSVERSIONINFO)};
\r
644 GetVersionEx(&info);
\r
646 if (6 <= info.dwMajorVersion) {
\r
652 void CProfile::RestartComputer()
\r
654 if (!AdjustTokenPrivileges(SE_SHUTDOWN_NAME)) {
\r
658 ExitWindowsEx(EWX_REBOOT, 0);
\r
661 BOOL CProfile::AdjustTokenPrivileges(LPCTSTR lpName)
\r
666 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
\r
668 if (LookupPrivilegeValue(NULL, lpName, &luid)) {
\r
669 TOKEN_PRIVILEGES tp;
\r
670 tp.PrivilegeCount = 1;
\r
671 tp.Privileges[0].Luid = luid;
\r
672 tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
\r
674 if (!::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
\r
680 CloseHandle(hToken);
\r
688 BOOL CProfile::DiableTokenPrivileges()
\r
693 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
\r
694 if (!::AdjustTokenPrivileges(hToken, TRUE, NULL, NULL, NULL, NULL)) {
\r
697 CloseHandle(hToken);
\r
705 void CProfile::ExportProperties()
\r
707 if (!AdjustTokenPrivileges(SE_BACKUP_NAME)) {
\r
711 CFileDialog oFileOpenDialog(FALSE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));
\r
712 if (oFileOpenDialog.DoModal() == IDOK) {
\r
713 CString szCommandLine;
\r
714 szCommandLine.Format(_T("regedit /e \"%s\" HKEY_CURRENT_USER\\%s"), oFileOpenDialog.GetPathName(), CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)));
\r
715 CUtils::Run(szCommandLine, TRUE); // regedit /e "x:\xkeymacs.reg" HKEY_CURRENT_USER\Software\Oishi\XKeymacs2
\r
718 DiableTokenPrivileges();
\r
722 void CProfile::ImportProperties()
\r
724 if (!AdjustTokenPrivileges(SE_RESTORE_NAME)) {
\r
728 CFileDialog oFileOpenDialog(TRUE, _T("reg"), _T("xkeymacs"), OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, CString(MAKEINTRESOURCE(IDS_REGISTRATION_FILTER)));
\r
729 if (oFileOpenDialog.DoModal() == IDOK) {
\r
730 CString szCommandLine;
\r
731 szCommandLine.Format(_T("regedit \"%s\""), oFileOpenDialog.GetPathName());
\r
732 CUtils::Run(szCommandLine, TRUE); // regedit "x:\xkeymacs.reg"
\r
735 DiableTokenPrivileges();
\r
739 BOOL CProfile::GetEnableCUA(const int nAppID)
\r
741 return m_Config.bEnableCUA[nAppID];
\r
744 void CProfile::SetEnableCUA(const int nAppID, const BOOL bEnableCUA)
\r
746 m_Config.bEnableCUA[nAppID] = static_cast<BYTE>(bEnableCUA);
\r
749 int CProfile::GetKeyboardSpeed()
\r
751 int nKeyboardSpeed = 31; // default value of Windows
\r
752 CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_KEYBOARD));
\r
753 CString szValueName(MAKEINTRESOURCE(IDS_KEYBOARD_SPEED));
\r
756 if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) {
\r
758 DWORD dwType = REG_SZ;
\r
759 BYTE data[4] = {0};
\r
760 DWORD dwcbData = sizeof(data)/sizeof(data[0]);
\r
761 RegQueryValueEx(hKey, szValueName, NULL, &dwType, (LPBYTE)&data, &dwcbData);
\r
764 for (DWORD i = 0; i < dwcbData; ++i) {
\r
767 nKeyboardSpeed = nKeyboardSpeed * 10 + data[i] - _T('0');
\r
769 nKeyboardSpeed = data[i] - _T('0');
\r
777 return nKeyboardSpeed;
\r