OSDN Git Service

Use LPCSTR instead of CString in arguments of SaveKeyBind,
[xkeymacs/xkeymacs.git] / xkeymacs / profile.cpp
index 44677e7..923ff43 100644 (file)
@@ -10,7 +10,7 @@
 #include <Imm.h>\r
 #include <Shlwapi.h>\r
 #include <TlHelp32.h>\r
-\r
+#include <vector>\r
 \r
 #ifdef _DEBUG\r
 #undef THIS_FILE\r
@@ -20,8 +20,8 @@ static char THIS_FILE[]=__FILE__;
 \r
 struct CommandTypeName\r
 {\r
-       int nCommandType;\r
-       LPCTSTR szCommandTypeName;\r
+       int nType;\r
+       LPCTSTR szName;\r
 };\r
 \r
 static const CommandTypeName CommandTypes[] = {\r
@@ -305,7 +305,8 @@ static const KeyName KeyNames[] = {
        {0xff,                  _T("Fn")},\r
 };\r
 \r
-CData CProfile::m_Data[MAX_APP];\r
+CONFIG CProfile::m_Config;\r
+TCHAR CProfile::m_szAppTitle[MAX_APP][WINDOW_TEXT_LENGTH];\r
 TASK_LIST CProfile::m_TaskList[MAX_TASKS];\r
 DWORD CProfile::m_dwTasks;\r
 \r
@@ -420,7 +421,8 @@ BOOL CALLBACK CProfile::EnumWindowsProc(const HWND hWnd, const LPARAM lParam)
        // Get Process Name\r
        DWORD dwProcessId = 0;\r
        GetWindowThreadProcessId(hWnd, &dwProcessId);\r
-       for (DWORD i = 0; i < CProfile::m_dwTasks; ++i) {\r
+       DWORD i;\r
+       for (i = 0; i < CProfile::m_dwTasks; ++i) {\r
                if (pTask[i].dwProcessId == dwProcessId) {\r
 \r
                        // Get Application Name\r
@@ -475,274 +477,138 @@ BOOL CALLBACK CProfile::EnumWindowsProc(const HWND hWnd, const LPARAM lParam)
        return TRUE;\r
 }\r
 \r
-//////////////////////////////////////////////////////////////////////\r
-// Construction/Destruction\r
-//////////////////////////////////////////////////////////////////////\r
-\r
-CProfile::CProfile()\r
-{\r
-\r
-}\r
-\r
-CProfile::~CProfile()\r
+void CProfile::LoadRegistry()\r
 {\r
-\r
-}\r
-\r
-// This method initializes data in the registry, or retrieves and validates registry data.\r
-// bSaveAndValidate specifies a flag that indicates \r
-// whether registry data is being initialized (FALSE) or data is being retrieved (TRUE). \r
-void CProfile::UpdateRegistryData(const BOOL bSaveAndValidate)\r
-{\r
-       CString szEntry;\r
-       CString szApplicationName;\r
-       CString szApplicationTitle;\r
-       CString szWindowText;\r
-       CString szWindowTextType;\r
-\r
-       BOOL bUseDialogSetting = FALSE;\r
-\r
-       for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
-               // application name\r
-               CString szSection(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));\r
-               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       m_Data[nApplicationID].ClearAll();\r
-                       szApplicationName = AfxGetApp()->GetProfileString(szSection, szEntry);\r
-                       if (szApplicationName.IsEmpty()) {\r
-                               if (nApplicationID) {\r
-                                       if (!bUseDialogSetting) {\r
-                                               szApplicationName.LoadString(IDS_DIALOG);\r
-                                               bUseDialogSetting = TRUE;\r
-                                       } else {\r
-                                               continue;\r
-                                       }\r
-                               } else {\r
-                                       szApplicationName.LoadString(IDS_DEFAULT);\r
+       bool bDialog = false;\r
+       const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));    \r
+       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
+               CString entry;\r
+               entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
+               CString appName = AfxGetApp()->GetProfileString(section, entry);\r
+               if (appName.IsEmpty())  {\r
+                       if (nAppID) {\r
+                               if (bDialog)\r
+                                       continue;\r
+                               appName.LoadString(IDS_DIALOG);\r
+                               bDialog = true;\r
+                       } else\r
+                               appName.LoadString(IDS_DEFAULT);\r
+               } else if (appName == CString(MAKEINTRESOURCE(IDS_DIALOG)))\r
+                       bDialog = true;\r
+               _tcsncpy_s(m_Config.szSpecialApp[nAppID], appName, _TRUNCATE);\r
+               entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
+               _tcsncpy_s(m_szAppTitle[nAppID], AfxGetApp()->GetProfileString(appName, entry), _TRUNCATE);\r
+               entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
+               _tcsncpy_s(m_Config.szWindowText[nAppID], AfxGetApp()->GetProfileString(appName, entry, _T("*")), _TRUNCATE);\r
+\r
+               const CString regApp = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + appName;\r
+               for (int nComID = 1; nComID < MAX_COMMAND; ++nComID) {\r
+                       entry = CCommands::GetCommandName(nComID);\r
+                       HKEY hKey;\r
+                       const CString regKey = regApp + _T("\\") + entry;\r
+                       if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
+                               TCHAR szKeyBind[128];\r
+                               DWORD dwKeyBind = _countof(szKeyBind);\r
+                               for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
+                                       int nType, nKey;\r
+                                       ReadKeyBind(&nType, &nKey, szKeyBind);\r
+                                       m_Config.nCommandID[nAppID][nType][nKey] = nComID;\r
+                                       dwKeyBind = _countof(szKeyBind);\r
                                }\r
+                               RegCloseKey(hKey);\r
                        } else {\r
-                               if (szApplicationName == CString(MAKEINTRESOURCE(IDS_DIALOG))) {\r
-                                       bUseDialogSetting = TRUE;\r
-                               }\r
-                       }\r
-                       m_Data[nApplicationID].SetApplicationName(szApplicationName);\r
-               } else {                                // initialize\r
-                       szApplicationName = m_Data[nApplicationID].GetApplicationName();\r
-                       if (szApplicationName.IsEmpty()) {\r
-                               continue;\r
-                       }\r
-                       AfxGetApp()->WriteProfileString(szSection, szEntry, szApplicationName);\r
-               }\r
-\r
-               // application title\r
-               szEntry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       szApplicationTitle = AfxGetApp()->GetProfileString(szApplicationName, szEntry);\r
-                       m_Data[nApplicationID].SetApplicationTitle(szApplicationTitle);\r
-               } else {                                // initialize\r
-                       szApplicationTitle = m_Data[nApplicationID].GetApplicationTitle();\r
-                       while (!szApplicationTitle.IsEmpty() && szApplicationTitle.GetAt(0) == _T(' ')) {\r
-                               szApplicationTitle.Delete(0);\r
-                       }\r
-                       AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szApplicationTitle);\r
-               }\r
-\r
-               // window text\r
-               szEntry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       szWindowText = AfxGetApp()->GetProfileString(szApplicationName, szEntry, _T("*"));\r
-                       if (szWindowText.IsEmpty()) {\r
-                               szWindowText = _T('*');\r
-                       }\r
-                       m_Data[nApplicationID].SetWindowText(szWindowText);\r
-               } else {                                // initialize\r
-                       szWindowText = m_Data[nApplicationID].GetWindowText();\r
-                       AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szWindowText);\r
-               }\r
-\r
-               // window text type\r
-               szEntry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT_TYPE);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       szWindowTextType = AfxGetApp()->GetProfileString(szApplicationName, szEntry);\r
-\r
-                       int nWindowTextType = IDS_WINDOW_TEXT_IGNORE;\r
-                       if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH))) {\r
-                               nWindowTextType = IDS_WINDOW_TEXT_MATCH;\r
-                       } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_FORWARD))) {\r
-                               nWindowTextType = IDS_WINDOW_TEXT_MATCH_FORWARD;\r
-                       } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_BACKWARD))) {\r
-                               nWindowTextType = IDS_WINDOW_TEXT_MATCH_BACKWARD;\r
-                       } else if (szWindowTextType == CString(MAKEINTRESOURCE(IDS_WINDOW_TEXT_MATCH_FULL))) {\r
-                               nWindowTextType = IDS_WINDOW_TEXT_MATCH_FULL;\r
-                       }\r
-\r
-                       m_Data[nApplicationID].SetWindowTextType(nWindowTextType);\r
-               } else {                                // initialize\r
-                       szWindowTextType.LoadString(m_Data[nApplicationID].GetWindowTextType());\r
-                       AfxGetApp()->WriteProfileString(szApplicationName, szEntry, szWindowTextType);\r
-               }\r
-\r
-               CString regApp(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
-               regApp += _T("\\") + szApplicationName;\r
-               // on/off\r
-               if (bSaveAndValidate) { // retrieve\r
-                       for (int nCommandID = 1; nCommandID < MAX_COMMAND; ++nCommandID) {\r
-                               szEntry = CCommands::GetCommandName(nCommandID);\r
-                               if (szEntry.IsEmpty()) {\r
-                                       break;\r
-                               }\r
-                               HKEY hKey = NULL;\r
-                               CString regKey = regApp + _T("\\") + szEntry;\r
-                               if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
-                                       // Use registry data\r
-                                       TCHAR szKeyBind[128] = {'\0'};\r
-                                       DWORD dwKeyBind = sizeof(szKeyBind);\r
-                                       FILETIME ft = {'\0'};   // not use\r
-                                       for (DWORD dwIndex = 0;\r
-                                                RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS;\r
-                                                ++dwIndex) {\r
-                                               int nCommandType = 0;\r
-                                               int nKey = 0;\r
-                                               ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
-                                               m_Data[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
-                                               memset(szKeyBind, 0, sizeof(szKeyBind));\r
-                                               dwKeyBind = sizeof(szKeyBind);\r
-                                       }\r
-                                       RegCloseKey(hKey);\r
-                               } else {\r
-                                       // Use default setting\r
-                                       for (int i = 0; ; ++i) {\r
-                                               if (CCommands::GetDefaultControlID(nCommandID, i) == IDC_CO2) {\r
-                                                       continue;\r
-                                               }\r
-\r
-                                               int nCommandType = CCommands::GetDefaultCommandType(nCommandID, i);\r
-                                               int nKey = CCommands::GetDefaultCommandKey(nCommandID, i);\r
-                                               if (nKey == 0) {\r
-                                                       break;\r
-                                               }\r
-                                               m_Data[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
-                                       }\r
-                               }\r
-                       }\r
-                       for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
-                               HKEY hKey = NULL;\r
-                               CString regKey = regApp + _T("\\") + CDotXkeymacs::GetFunctionSymbol(nFunctionID);\r
-                               if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
-                                       // Use registry data\r
-                                       CDotXkeymacs::ClearKey(nFunctionID, nApplicationID);\r
-                                       TCHAR szKeyBind[128] = {'\0'};\r
-                                       DWORD dwKeyBind = sizeof(szKeyBind);\r
-                                       FILETIME ft = {'\0'};   // not use\r
-                                       for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS; ++dwIndex) {\r
-                                               int nCommandType = 0;\r
-                                               int nKey = 0;\r
-                                               ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
-                                               CDotXkeymacs::SetKey(nFunctionID, nApplicationID, nCommandType, nKey);\r
-\r
-                                               memset(szKeyBind, 0, sizeof(szKeyBind));\r
-                                               dwKeyBind = sizeof(szKeyBind);\r
-                                       }\r
-                                       RegCloseKey(hKey);\r
-                               }\r
-                       }\r
-               } else {                                // initialize\r
-                       // create all commands\r
-                       for (int nCommandID = 1; nCommandID < MAX_COMMAND; ++nCommandID) {\r
-                               szEntry = CCommands::GetCommandName(nCommandID);\r
-                               if (szEntry.IsEmpty()) {\r
-                                       break;\r
-                               }\r
-\r
-                               SaveCommand(szApplicationName, nCommandID);\r
-                       }\r
-                       for (int nCommandType = 0; nCommandType < MAX_COMMAND_TYPE; ++nCommandType) {\r
-                               for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
-                                       int nCommandID = m_Data[nApplicationID].GetCommandID(nCommandType, nKey);\r
-                                       SaveKeyBind(szApplicationName, nCommandID, nCommandType, nKey);\r
-                               }\r
-                       }\r
-                       for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
-                               for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFunctionID, nApplicationID); ++nKeyID) {\r
-                                       int nCommandType = 0;\r
-                                       int nKey = 0;\r
-                                       CDotXkeymacs::GetKey(nFunctionID, nApplicationID, nKeyID, &nCommandType, &nKey);\r
-                                       SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFunctionID), nCommandType, nKey);\r
+                               // Set the default assignment\r
+                               for (int i = 0; const int nKey = CCommands::GetDefaultCommandKey(nComID, i); ++i) {\r
+                                       if (CCommands::GetDefaultControlID(nComID, i) == IDC_CO2)\r
+                                               continue;\r
+                                       const int nType = CCommands::GetDefaultCommandType(nComID, i);\r
+                                       m_Config.nCommandID[nAppID][nType][nKey] = nComID;\r
                                }\r
                        }\r
                }\r
-\r
-               // kill-ring-max\r
-               szEntry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       int nKillRingMax = AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 1);\r
-                       m_Data[nApplicationID].SetKillRingMax(nKillRingMax);\r
-               } else {                                // initialize\r
-                       int nKillRingMax = m_Data[nApplicationID].GetKillRingMax();\r
-                       AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, nKillRingMax);\r
-               }\r
-\r
-               // Use Dialog Setting\r
-               szEntry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       BOOL bUseDialogSetting = AfxGetApp()->GetProfileInt(szApplicationName,szEntry, 1);\r
-                       m_Data[nApplicationID].SetUseDialogSetting(bUseDialogSetting);\r
-               } else {                                // initialize\r
-                       BOOL bUseDialogSetting = m_Data[nApplicationID].GetUseDialogSetting();\r
-                       AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, bUseDialogSetting);\r
-               }\r
-\r
-               // Setting Style\r
-               szEntry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       int nSettingStyle = SETTING_DEFAULT;\r
+               for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {\r
                        HKEY hKey;\r
-                       if (AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0) != 0) {\r
-                               nSettingStyle = SETTING_DISABLE;\r
-                       } else if (RegOpenKeyEx(HKEY_CURRENT_USER, regApp, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
+                       const CString regKey = regApp + _T("\\") + CDotXkeymacs::GetFunctionSymbol(nFuncID);\r
+                       if (RegOpenKeyEx(HKEY_CURRENT_USER, regKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
+                               CDotXkeymacs::ClearKey(nFuncID, nAppID);\r
+                               TCHAR szKeyBind[128];\r
+                               DWORD dwKeyBind = _countof(szKeyBind);\r
+                               for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++dwIndex) {\r
+                                       int nType, nKey;\r
+                                       ReadKeyBind(&nType, &nKey, szKeyBind);\r
+                                       CDotXkeymacs::SetKey(nFuncID, nAppID, nType, nKey);\r
+                                       dwKeyBind = _countof(szKeyBind);\r
+                               }\r
                                RegCloseKey(hKey);\r
-                               nSettingStyle = SETTING_SPECIFIC;\r
                        }\r
-                       m_Data[nApplicationID].SetSettingStyle(nSettingStyle);\r
-               } else {                                // initialize\r
-                       BOOL bDisableXkeymacs = FALSE;\r
-                       if (m_Data[nApplicationID].GetSettingStyle() == SETTING_DISABLE) {\r
-                               bDisableXkeymacs = TRUE;\r
-                       }\r
-                       AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, bDisableXkeymacs);\r
-               }\r
-\r
-               // Ignore Meta Ctrl+? when it is undefined.\r
-               szEntry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       m_Data[nApplicationID].SetIgnoreUndefinedMetaCtrl(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
-               } else {                                // initialize\r
-                       AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_Data[nApplicationID].GetIgnoreUndefinedMetaCtrl());\r
                }\r
 \r
-               // Ignore C-x ? when it is undefined.\r
-               szEntry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       m_Data[nApplicationID].SetIgnoreUndefinedC_x(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
-               } else {                                // initialize\r
-                       AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_Data[nApplicationID].GetIgnoreUndefinedC_x());\r
-               }\r
+               entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
+               m_Config.nKillRingMax[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 1);\r
+               entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
+               m_Config.bUseDialogSetting[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 1);\r
+               entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
+               m_Config.nSettingStyle[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0) ? SETTING_DISABLE : SETTING_SPECIFIC;\r
+               entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
+               m_Config.bIgnoreUndefinedMetaCtrl[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0);\r
+               entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
+               m_Config.bIgnoreUndefinedC_x[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0);\r
+               entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
+               m_Config.bEnableCUA[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0);\r
+               entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
+               m_Config.b326Compatible[nAppID] = AfxGetApp()->GetProfileInt(appName, entry, 0);\r
+       }\r
+}\r
 \r
-               // Enable CUA-mode\r
-               szEntry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       m_Data[nApplicationID].SetEnableCUA(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
-               } else {                                // initialize\r
-                       AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_Data[nApplicationID].GetEnableCUA());\r
+void CProfile::SaveRegistry()\r
+{\r
+       const CString section(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION));    \r
+       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
+               const LPCTSTR szAppName = m_Config.szSpecialApp[nAppID];\r
+               CString entry;\r
+               entry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
+               if (!szAppName[0]) {\r
+                       if (!AfxGetApp()->GetProfileString(section, entry).IsEmpty())\r
+                               AfxGetApp()->WriteProfileString(section, entry, _T(""));\r
+                       continue;\r
                }\r
+               AfxGetApp()->WriteProfileString(section, entry, szAppName);\r
+\r
+               entry.LoadString(IDS_REG_ENTRY_APPLICATOIN_TITLE);\r
+               CString appTitle = m_szAppTitle[nAppID];\r
+               appTitle.TrimLeft(_T(' '));\r
+               AfxGetApp()->WriteProfileString(szAppName, entry, appTitle);\r
+               entry.LoadString(IDS_REG_ENTRY_WINDOW_TEXT);\r
+               AfxGetApp()->WriteProfileString(szAppName, entry, m_Config.szWindowText[nAppID]);\r
+\r
+               const CString regApp = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + szAppName;\r
+               // Create all commands\r
+               for (int nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
+                       SaveCommand(szAppName, nComID);\r
+               for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)\r
+                       for (int nKey = 0; nKey < MAX_KEY; ++nKey)\r
+                               SaveKeyBind(szAppName, m_Config.nCommandID[nAppID][nType][nKey], nType, nKey);\r
+               for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
+                       for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFuncID, nAppID); ++nKeyID) {\r
+                               int nType, nKey;\r
+                               CDotXkeymacs::GetKey(nFuncID, nAppID, nKeyID, &nType, &nKey);\r
+                               SaveKeyBind(szAppName, CDotXkeymacs::GetFunctionSymbol(nFuncID), nType, nKey);\r
+                       }\r
 \r
-               // Version 3.26 compatible mode\r
-               szEntry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
-               if (bSaveAndValidate) { // retrieve\r
-                       m_Data[nApplicationID].Set326Compatible(AfxGetApp()->GetProfileInt(szApplicationName, szEntry, 0));\r
-               } else {                                // initialize\r
-                       AfxGetApp()->WriteProfileInt(szApplicationName, szEntry, m_Data[nApplicationID].Get326Compatible());\r
-               }\r
+               entry.LoadString(IDS_REG_ENTRY_KILL_RING_MAX);\r
+               AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.nKillRingMax[nAppID]);\r
+               entry.LoadString(IDS_REG_ENTRY_USE_DIALOG_SETTING);\r
+               AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bUseDialogSetting[nAppID]);\r
+               entry.LoadString(IDS_REG_ENTRY_DISABLE_XKEYMACS);\r
+               AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.nSettingStyle[nAppID] == SETTING_DISABLE);\r
+               entry.LoadString(IDC_REG_ENTRY_IGNORE_META_CTRL);\r
+               AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bIgnoreUndefinedMetaCtrl[nAppID]);\r
+               entry.LoadString(IDC_REG_ENTRY_IGNORE_C_X);\r
+               AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bIgnoreUndefinedC_x[nAppID]);\r
+               entry.LoadString(IDC_REG_ENTRY_ENABLE_CUA);\r
+               AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.bEnableCUA[nAppID]);\r
+               entry.LoadString(IDS_REG_ENTRY_326_COMPATIBLE);\r
+               AfxGetApp()->WriteProfileInt(szAppName, entry, m_Config.b326Compatible[nAppID]);\r
        }\r
 }\r
 \r
@@ -750,66 +616,39 @@ void CProfile::LoadData()
 {\r
        CDotXkeymacs::Load();\r
        LevelUp();\r
-       UpdateRegistryData(TRUE);\r
+       LoadRegistry();\r
 }\r
 \r
 void CProfile::SaveData()\r
 {\r
        DeleteAllRegistryData();\r
-       UpdateRegistryData(FALSE);\r
+       SaveRegistry();\r
        SetDllData();\r
 }\r
 \r
 void CProfile::SetDllData()\r
 {\r
-       CXkeymacsDll::ClearFunctionDefinition();\r
-       for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
-               CXkeymacsDll::SetFunctionDefinition(nFunctionID, CDotXkeymacs::GetFunctionDefinition(nFunctionID));\r
-       }\r
-\r
-       for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
-\r
-               CString szApplicationName = m_Data[nApplicationID].GetApplicationName();\r
-\r
-               if (szApplicationName.IsEmpty()) {\r
-                       CXkeymacsDll::Clear(nApplicationID);\r
-                       continue;\r
-               }\r
-\r
-               CXkeymacsDll::SetApplicationName(nApplicationID, szApplicationName);\r
-               CXkeymacsDll::SetWindowText(nApplicationID, m_Data[nApplicationID].GetWindowText());\r
-               CXkeymacsDll::SetCommandID(nApplicationID, CONTROL, 'X', 0);\r
-\r
-               for (int nCommandType = 0; nCommandType < MAX_COMMAND_TYPE; ++nCommandType) {\r
-                       for (int nKey = 0; nKey < MAX_KEY; ++nKey) {\r
-                               const int nCommandID = m_Data[nApplicationID].GetCommandID(nCommandType, nKey);\r
-                               CXkeymacsDll::SetCommandID(nApplicationID, nCommandType, nKey, nCommandID);\r
-                               if ((nCommandType & CONTROLX) && nCommandID) {\r
-                                       CXkeymacsDll::SetCommandID(nApplicationID, CONTROL, 'X', 1);                    // Commands[1] is C-x\r
-                               }\r
-                       }\r
-               }\r
-\r
-               for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
-                       for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFunctionID, nApplicationID); ++nKeyID) {\r
-                               int nCommandType = 0;\r
-                               int nKey = 0;\r
-                               CDotXkeymacs::GetKey(nFunctionID, nApplicationID, nKeyID, &nCommandType, &nKey);\r
-                               CXkeymacsDll::SetFunctionKey(nFunctionID, nApplicationID, nCommandType, nKey);\r
-                               if (nCommandType & CONTROLX) {\r
-                                       CXkeymacsDll::SetCommandID(nApplicationID, CONTROL, 'X', 1);                    // Commands[1] is C-x\r
-                               }\r
+       memset(m_Config.nFunctionID, -1, sizeof(m_Config.nFunctionID));\r
+       for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
+               _tcscpy_s(m_Config.szFunctionDefinition[nFuncID], CDotXkeymacs::GetFunctionDefinition(nFuncID));\r
+\r
+       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
+               m_Config.nCommandID[nAppID][CONTROL]['X'] = 0; // C-x is unassigned.\r
+               for (int nType = 0; nType < MAX_COMMAND_TYPE; ++nType)\r
+                       for (int nKey = 0; nKey < MAX_KEY; ++nKey)\r
+                               if ((nType & CONTROLX) && m_Config.nCommandID[nAppID][nType][nKey])\r
+                                       m_Config.nCommandID[nAppID][CONTROL]['X'] = 1; // C-x is available.\r
+               for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID)\r
+                       for (int nKeyID = 0; nKeyID < CDotXkeymacs::GetKeyNumber(nFuncID, nAppID); ++nKeyID) {\r
+                               int nType, nKey;\r
+                               CDotXkeymacs::GetKey(nFuncID, nAppID, nKeyID, &nType, &nKey);\r
+                               m_Config.nFunctionID[nAppID][nType][nKey] = nFuncID;\r
+                               if (nType & CONTROLX)\r
+                                       m_Config.nCommandID[nAppID][CONTROL]['X'] = 1; // C-x is available.\r
                        }\r
-               }\r
-\r
-               CXkeymacsDll::SetKillRingMax(nApplicationID, m_Data[nApplicationID].GetKillRingMax());\r
-               CXkeymacsDll::SetUseDialogSetting(nApplicationID, m_Data[nApplicationID].GetUseDialogSetting());\r
-               CXkeymacsDll::SetSettingStyle(nApplicationID, m_Data[nApplicationID].GetSettingStyle());\r
-               CXkeymacsDll::SetIgnoreUndefinedMetaCtrl(nApplicationID, m_Data[nApplicationID].GetIgnoreUndefinedMetaCtrl());\r
-               CXkeymacsDll::SetIgnoreUndefinedC_x(nApplicationID, m_Data[nApplicationID].GetIgnoreUndefinedC_x());\r
-               CXkeymacsDll::SetEnableCUA(nApplicationID, m_Data[nApplicationID].GetEnableCUA());\r
-               CXkeymacsDll::Set326Compatible(nApplicationID, m_Data[nApplicationID].Get326Compatible());\r
        }\r
+       m_Config.b106Keyboard = Is106Keyboard();\r
+       CXkeymacsDll::SetConfig(m_Config);\r
        CXkeymacsApp *pApp = static_cast<CXkeymacsApp *>(AfxGetApp());\r
        if (!pApp->IsWow64())\r
                return;\r
@@ -824,18 +663,18 @@ void CProfile::ReadKeyBind(int *const pnCommandType, int *const pnKey, LPCTSTR s
        *pnKey = KeyBind2Key(szKeyBind + _tcslen(CommandType2String(*pnCommandType)));\r
 }\r
 \r
-CString CProfile::WriteKeyBind(const int nCommandType, const int nKey)\r
+CString CProfile::WriteKeyBind(const int nType, const int nKey)\r
 {\r
        CString szKeyBind;\r
-       szKeyBind.Format(_T("%s%s"), CommandType2String(nCommandType), Key2String(nKey));\r
+       szKeyBind.Format(_T("%s%s"), CommandType2String(nType), Key2String(nKey));\r
        return szKeyBind;\r
 }\r
 \r
 int CProfile::KeyBind2CommandType(LPCTSTR szKeyBind)\r
 {\r
-       for (int nCommandType = MAX_COMMAND_TYPE - 1; nCommandType; --nCommandType) {\r
-               if (IsCommandType(nCommandType, szKeyBind)) {\r
-                       return nCommandType;\r
+       for (int nType = MAX_COMMAND_TYPE - 1; nType; --nType) {\r
+               if (IsCommandType(nType, szKeyBind)) {\r
+                       return nType;\r
                }\r
        }\r
        return NONE;\r
@@ -851,13 +690,13 @@ int CProfile::KeyBind2Key(LPCTSTR szKey)
        return 0;\r
 }\r
 \r
-LPCTSTR CProfile::CommandType2String(int nCommandType)\r
+LPCTSTR CProfile::CommandType2String(int nType)\r
 {\r
-       if (nCommandType < 0 || sizeof(CommandTypes) / sizeof(CommandTypes[0]) <= nCommandType) {\r
+       if (nType < 0 || sizeof(CommandTypes) / sizeof(CommandTypes[0]) <= nType) {\r
                ASSERT(0);\r
-               nCommandType = NONE;\r
+               nType = NONE;\r
        }\r
-       return CommandTypes[nCommandType].szCommandTypeName;\r
+       return CommandTypes[nType].szName;\r
 }\r
 \r
 LPCTSTR CProfile::Key2String(int nKey)\r
@@ -884,9 +723,9 @@ LPCTSTR CProfile::Key2String(int nKey)
        return KeyNames[nKey].name;\r
 }\r
 \r
-BOOL CProfile::IsCommandType(const int nCommandType, LPCTSTR szKeyBind)\r
+BOOL CProfile::IsCommandType(const int nType, LPCTSTR szKeyBind)\r
 {\r
-       LPCTSTR szCommandType = CommandType2String(nCommandType);\r
+       LPCTSTR szCommandType = CommandType2String(nType);\r
 \r
        if (!_tcsnicmp(szKeyBind, szCommandType, _tcslen(szCommandType))) {\r
                return TRUE;\r
@@ -895,49 +734,39 @@ BOOL CProfile::IsCommandType(const int nCommandType, LPCTSTR szKeyBind)
        return FALSE;\r
 }\r
 \r
-void CProfile::SaveKeyBind(const CString szApplicationName, const int nCommandID, const int nCommandType, const int nKey)\r
+void CProfile::SaveKeyBind(const LPCSTR szAppName, const int nComID, const int nType, const int nKey)\r
 {\r
-       if (!nCommandID) {\r
+       if (!nComID)\r
                return;\r
-       }\r
-\r
-       CString szCommandName = CCommands::GetCommandName(nCommandID);\r
-       if (szCommandName.IsEmpty()) {\r
+       const LPCSTR szComName = CCommands::GetCommandName(nComID);\r
+       if (!szComName[0])\r
                return;\r
-       }\r
-\r
-       SaveKeyBind(szApplicationName, szCommandName, nCommandType, nKey);\r
+       SaveKeyBind(szAppName, szComName, nType, nKey);\r
 }\r
 \r
-void CProfile::SaveKeyBind(const CString szApplicationName, const CString szCommandName, const int nCommandType, const int nKey)\r
+void CProfile::SaveKeyBind(const LPCSTR szAppName, const LPCSTR szComName, const int nType, const int nKey)\r
 {\r
-       CString szKeyBind = WriteKeyBind(nCommandType, nKey);\r
-       CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
-       szSubKey += _T("\\") + szApplicationName + _T("\\") + szCommandName;\r
-       if (!szKeyBind.IsEmpty()) {\r
+       const CString szKeyBind = WriteKeyBind(nType, nKey);\r
+       CString szSubKey = CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)) + _T("\\") + szAppName + _T("\\") + szComName;\r
+       if (!szKeyBind.IsEmpty())\r
                szSubKey += _T("\\") + szKeyBind;\r
-       }\r
-\r
        HKEY hKey = NULL;\r
-       if (RegCreateKeyEx(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS) {\r
+       if (RegCreateKeyEx(HKEY_CURRENT_USER, szSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) == ERROR_SUCCESS)\r
                RegCloseKey(hKey);\r
-       }\r
 }\r
 \r
-void CProfile::SaveCommand(const CString szApplicationName, const int nCommandID)\r
+void CProfile::SaveCommand(const LPCSTR szAppName, const int nComID)\r
 {\r
-       SaveKeyBind(szApplicationName, nCommandID, 0, 0);\r
+       SaveKeyBind(szAppName, nComID, 0, 0);\r
 }\r
 \r
-void CProfile::AddKeyBind2C_(const CString szApplicationName, const BYTE bVk)\r
+void CProfile::AddKeyBind2C_(const LPCSTR szAppName, const BYTE bVk)\r
 {\r
-       for (int nCommandID = 0; nCommandID < MAX_COMMAND; ++nCommandID) {\r
-               if (Commands[nCommandID].fCommand == CCommands::C_) {\r
+       int nComID;\r
+       for (nComID = 0; nComID < MAX_COMMAND; ++nComID)\r
+               if (Commands[nComID].fCommand == CCommands::C_)\r
                        break;\r
-               }\r
-       }\r
-\r
-       SaveKeyBind(szApplicationName, nCommandID, NONE, bVk);\r
+       SaveKeyBind(szAppName, nComID, NONE, bVk);\r
 }\r
 \r
 void CProfile::LevelUp()\r
@@ -952,9 +781,9 @@ void CProfile::LevelUp()
        switch (AfxGetApp()->GetProfileInt(szSection, szEntry, nDefalutLevel)) {\r
        case nDefalutLevel:\r
                {\r
-                       for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
+                       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
                                CString szEntry;\r
-                               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
+                               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
 \r
                                CString szApplicationName;\r
                                szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
@@ -969,9 +798,9 @@ void CProfile::LevelUp()
                // Do NOT write break; here.\r
        case 1:\r
                {\r
-                       for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
+                       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
                                CString szEntry;\r
-                               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
+                               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
 \r
                                CString szApplicationName;\r
                                szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
@@ -988,9 +817,9 @@ void CProfile::LevelUp()
                // Do NOT write break; here.\r
        case 2:\r
                {\r
-                       for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
+                       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
                                CString szEntry;\r
-                               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
+                               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
 \r
                                CString szApplicationName;\r
                                szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
@@ -1014,9 +843,9 @@ void CProfile::LevelUp()
                // Do NOT write break; here.\r
        case 3:\r
                {\r
-                       for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
+                       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
                                CString szEntry;\r
-                               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nApplicationID);\r
+                               szEntry.Format(IDS_REG_ENTRY_APPLICATION, nAppID);\r
 \r
                                CString szApplicationName;\r
                                szApplicationName = AfxGetApp()->GetProfileString(CString(MAKEINTRESOURCE(IDS_REG_SECTION_APPLICATION)), szEntry);\r
@@ -1025,20 +854,20 @@ void CProfile::LevelUp()
                                }\r
 \r
                                // rename original function to remove IDS_REG_ORIGINAL_PREFIX\r
-                               for (int nFunctionID = 0; nFunctionID < CDotXkeymacs::GetFunctionNumber(); ++nFunctionID) {\r
+                               for (int nFuncID = 0; nFuncID < CDotXkeymacs::GetFunctionNumber(); ++nFuncID) {\r
                                        HKEY hKey = NULL;\r
                                        CString szSubKey(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA));\r
-                                       szSubKey += _T("\\") + szApplicationName + _T("\\") + CString(MAKEINTRESOURCE(IDS_REG_ORIGINAL_PREFIX)) + CDotXkeymacs::GetFunctionSymbol(nFunctionID);\r
+                                       szSubKey += _T("\\") + szApplicationName + _T("\\") + CString(MAKEINTRESOURCE(IDS_REG_ORIGINAL_PREFIX)) + CDotXkeymacs::GetFunctionSymbol(nFuncID);\r
                                        if (RegOpenKeyEx(HKEY_CURRENT_USER, szSubKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS) {\r
                                                // Use registry data\r
                                                TCHAR szKeyBind[128] = {'\0'};\r
                                                DWORD dwKeyBind = sizeof(szKeyBind);\r
                                                FILETIME ft = {'\0'};   // not use\r
                                                for (DWORD dwIndex = 0; RegEnumKeyEx(hKey, dwIndex, szKeyBind, &dwKeyBind, NULL, NULL, NULL, &ft) == ERROR_SUCCESS; ++dwIndex) {\r
-                                                       int nCommandType = 0;\r
+                                                       int nType = 0;\r
                                                        int nKey = 0;\r
-                                                       ReadKeyBind(&nCommandType, &nKey, szKeyBind);\r
-                                                       SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFunctionID), nCommandType, nKey);\r
+                                                       ReadKeyBind(&nType, &nKey, szKeyBind);\r
+                                                       SaveKeyBind(szApplicationName, CDotXkeymacs::GetFunctionSymbol(nFuncID), nType, nKey);\r
 \r
                                                        memset(szKeyBind, 0, sizeof(szKeyBind));\r
                                                        dwKeyBind = sizeof(szKeyBind);\r
@@ -1068,29 +897,21 @@ void CProfile::InitDllData()
 \r
 void CProfile::ClearData(const CString szCurrentApplication)\r
 {\r
-       for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
-               if (m_Data[nApplicationID].GetApplicationName() == szCurrentApplication) {\r
-                       break;\r
+       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
+               if (szCurrentApplication == m_Config.szSpecialApp[nAppID]) {\r
+                       ZeroMemory(m_Config.nCommandID[nAppID], sizeof(m_Config.nCommandID[nAppID]));\r
+                       ZeroMemory(m_Config.szSpecialApp[nAppID], CLASS_NAME_LENGTH);\r
+                       return;\r
                }\r
-       }\r
-       if (nApplicationID < MAX_APP) {\r
-               m_Data[nApplicationID].ClearAll();\r
-       }\r
 }\r
 \r
 // return count of saved settings\r
 int CProfile::GetSavedSettingCount()\r
 {\r
        int nSavedSetting = 0;\r
-\r
-       for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
-               CString szApplicationName;\r
-               szApplicationName = m_Data[nApplicationID].GetApplicationName();\r
-               if (!szApplicationName.IsEmpty()) {\r
+       for (int nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
+               if (m_Config.szSpecialApp[nAppID][0])\r
                        ++nSavedSetting;\r
-               }\r
-       }\r
-\r
        return nSavedSetting;\r
 }\r
 \r
@@ -1102,56 +923,19 @@ void CProfile::InitApplicationList(CComboBox *const cApplicationList)
 \r
        EnumWindows(EnumWindowsProc, (LPARAM)cApplicationList);\r
 \r
+       CString szListItem;\r
        for (int i = 0; i < MAX_APP; ++i) {\r
-               CString szApplicationName       = m_Data[i].GetApplicationName();\r
-               CString szApplicationTitle      = m_Data[i].GetApplicationTitle();\r
-\r
-               CString szListItem;\r
-               szListItem.Format(IDS_APPLICATION_LIST_ITEM, szApplicationTitle, szApplicationName);\r
-               if (IsNotSameString(cApplicationList, szListItem)\r
-                && !IsDefault(szApplicationName)\r
-                && !IsDialog(szApplicationName)\r
-                && !szApplicationName.IsEmpty()) {\r
+               const LPCTSTR szAppName = m_Config.szSpecialApp[i];\r
+               const LPCTSTR szAppTitle = m_szAppTitle[i];\r
+               if (!szAppName[0] || !_tcscmp(szAppName, _T("IME")))\r
+                       continue;\r
+               szListItem.Format(IDS_APPLICATION_LIST_ITEM, szAppTitle, szAppName);\r
+               if (IsNotSameString(cApplicationList, szListItem) &&\r
+                               !IsDefault(szAppName) && !IsDialog(szAppName))\r
                        cApplicationList->AddString(szListItem);\r
-               }\r
        }\r
 \r
-       // Add IME\r
-       HKL hKL = GetKeyboardLayout(0);\r
-       if (ImmIsIME(hKL)) {\r
-               LPTSTR szIMEDescription = NULL;\r
-               UINT nIMEDescription = ImmGetDescription(hKL, NULL, 0);\r
-               if (nIMEDescription) {\r
-                       nIMEDescription += sizeof(TCHAR);       // for NULL\r
-                       if ((szIMEDescription = new TCHAR[nIMEDescription]) != NULL) {\r
-                               ImmGetDescription(hKL, szIMEDescription, nIMEDescription);\r
-                       }\r
-//                     CUtils::Log(_T("nIMEDescription = %d, szIMEDescription = _%s_"), nIMEDescription, szIMEDescription);\r
-               }\r
-\r
-               LPTSTR szIMEFileName = NULL;\r
-               UINT nIMEFileName = ImmGetIMEFileName(hKL, NULL, 0);\r
-               if (nIMEFileName) {\r
-                       nIMEFileName += sizeof(TCHAR);\r
-                       if ((szIMEFileName = new TCHAR[nIMEFileName]) != NULL) {\r
-                               ImmGetIMEFileName(hKL, szIMEFileName, nIMEFileName);\r
-                       }\r
-//                     CUtils::Log(_T("nIMEFileName = %d, szIMEFileName = _%s_"), nIMEFileName, szIMEFileName);\r
-               }\r
-\r
-               CString szIMETitle;\r
-               CString szIME(MAKEINTRESOURCE(IDS_IME_FILE_NAME));\r
-               szIMETitle.Format(IDS_APPLICATION_LIST_ITEM, szIMEDescription ? szIMEDescription : szIME, szIMEFileName ? szIMEFileName : szIME);\r
-//             CUtils::Log(_T("szIMETitle = _%s_, szIMEDescription = _%s_, szIMEFileName = _%s_"), szIMETitle, szIMEDescription, szIMEFileName);\r
-               if (IsNotSameString(cApplicationList, szIMETitle)) {\r
-                       cApplicationList->AddString(szIMETitle);\r
-               }\r
-\r
-               delete[] szIMEDescription;\r
-               szIMEDescription = NULL;\r
-               delete[] szIMEFileName;\r
-               szIMEFileName = NULL;\r
-       }\r
+       AddIMEInfo(cApplicationList);\r
 \r
        // Add Dialog\r
        cApplicationList->InsertString(0, CString(MAKEINTRESOURCE(IDS_DIALOG_TITLE)));\r
@@ -1161,6 +945,25 @@ void CProfile::InitApplicationList(CComboBox *const cApplicationList)
        cApplicationList->SelectString(-1, CString(MAKEINTRESOURCE(IDS_DEFAULT_TITLE)));\r
 }\r
 \r
+void CProfile::AddIMEInfo(CComboBox *cApplicationList)\r
+{\r
+       const UINT n = GetKeyboardLayoutList(0, NULL);\r
+       if (!n)\r
+               return;\r
+       std::vector<HKL> hkls(n);\r
+       GetKeyboardLayoutList(n, &hkls[0]);\r
+       TCHAR szFileName[MAX_PATH];\r
+       TCHAR szDescription[WINDOW_TEXT_LENGTH];\r
+       for (std::vector<HKL>::const_iterator p = hkls.begin(); p != hkls.end(); ++p)\r
+               if (ImmGetDescription(*p, szDescription, WINDOW_TEXT_LENGTH) &&\r
+                               ImmGetIMEFileName(*p, szFileName, MAX_PATH)) {\r
+                       CString item;\r
+                       item.Format(IDS_APPLICATION_LIST_ITEM, szDescription, szFileName);\r
+                       if (IsNotSameString(cApplicationList, item))\r
+                               cApplicationList->AddString(item);\r
+               }\r
+}\r
+\r
 void CProfile::GetTaskList()\r
 {\r
        ZeroMemory(m_TaskList, sizeof(m_TaskList));\r
@@ -1186,46 +989,35 @@ void CProfile::GetTaskList()
 // if there is NOT the application in the data, this function takes care of it.\r
 int CProfile::GetApplicationIndex(const CString szApplicationName, const BOOL bSaveAndValidate, int *const nSettingStyle)\r
 {\r
-       if (!bSaveAndValidate) {        // SetDialogData\r
+       if (!bSaveAndValidate) // SetDialogData\r
                *nSettingStyle = SETTING_UNDEFINED;\r
-       }\r
-\r
-       int nApplicationID = GetApplicationIndex(szApplicationName);\r
-\r
-       if (nApplicationID == MAX_APP) {\r
-               if (bSaveAndValidate) { // GetDialogData\r
-                       for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
-                               CString sz = m_Data[nApplicationID].GetApplicationName();\r
-                               if (sz.IsEmpty()) {\r
-                                       m_Data[nApplicationID].SetApplicationName(szApplicationName);\r
+       int nAppID = GetApplicationIndex(szApplicationName);\r
+       if (nAppID == MAX_APP) {\r
+               if (bSaveAndValidate) { // GetDialogData\r
+                       for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
+                               if (!m_Config.szSpecialApp[nAppID][0]) {\r
+                                       _tcsncpy_s(m_Config.szSpecialApp[nAppID], szApplicationName, _TRUNCATE);\r
                                        break;\r
                                }\r
-                       }\r
-                       if (nApplicationID == MAX_APP) {\r
-                               return nApplicationID;\r
-                       }\r
-               } else {                                // SetDialogData\r
-                       for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
-                               if (IsDefault(m_Data[nApplicationID].GetApplicationName())) {\r
+                       if (nAppID == MAX_APP)\r
+                               return nAppID;\r
+               } else { // SetDialogData\r
+                       for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
+                               if (IsDefault(m_Config.szSpecialApp[nAppID])) {\r
                                        *nSettingStyle = SETTING_DEFAULT;\r
                                        break;\r
                                }\r
-                       }\r
-                       if (nApplicationID == MAX_APP) {\r
-                               return nApplicationID;\r
-                       }\r
+                       if (nAppID == MAX_APP)\r
+                               return nAppID;\r
                }\r
        }\r
-\r
-       if (bSaveAndValidate) { // GetDialogData\r
-               m_Data[nApplicationID].SetSettingStyle(*nSettingStyle);\r
-       } else {                                // SetDialogData\r
-               if (*nSettingStyle == SETTING_UNDEFINED) {      // It means that *nSettingStyle != SETTING_DEFAULT.\r
-                       *nSettingStyle = m_Data[nApplicationID].GetSettingStyle();\r
-               }\r
+       if (bSaveAndValidate) // GetDialogData\r
+               m_Config.nSettingStyle[nAppID] = *nSettingStyle;\r
+       else { // SetDialogData\r
+               if (*nSettingStyle == SETTING_UNDEFINED) // It means that *nSettingStyle != SETTING_DEFAULT.\r
+                       *nSettingStyle = m_Config.nSettingStyle[nAppID];\r
        }\r
-\r
-       return nApplicationID;\r
+       return nAppID;\r
 }\r
 \r
 BOOL CProfile::Is106Keyboard()\r
@@ -1296,79 +1088,74 @@ void CProfile::GetApplicationTitle(CComboBox *const cApplicationList, CString &r
        return;\r
 }\r
 \r
-void CProfile::UpdateApplicationTitle(CComboBox *const cApplicationList, const CString szCurrentApplication, const int nApplicationID, const BOOL bSaveAndValidate)\r
+void CProfile::UpdateApplicationTitle(CComboBox *const cApplicationList, const CString szCurrentApplication, const int nAppID, const BOOL bSaveAndValidate)\r
 {\r
        static CString szApplicationTitle;\r
        if (bSaveAndValidate) { // GetDialogData\r
-               if (!CProfile::IsDefault(szCurrentApplication)) {\r
-                       m_Data[nApplicationID].SetApplicationTitle(szApplicationTitle);\r
-               }\r
+               if (!CProfile::IsDefault(szCurrentApplication))\r
+                       _tcsncpy_s(m_szAppTitle[nAppID], szApplicationTitle, _TRUNCATE);\r
                szApplicationTitle.Empty();\r
-       } else {                                // SetDialogData\r
+       } else { // SetDialogData\r
                CString szListItem;\r
                CProfile::GetApplicationTitle(cApplicationList, szListItem);\r
-               int nEndTitle = szListItem.ReverseFind(_T('('));\r
-               if (nEndTitle > 0) {\r
+               const int nEndTitle = szListItem.ReverseFind(_T('('));\r
+               if (nEndTitle > 0)\r
                        szApplicationTitle = szListItem.Left(nEndTitle);\r
-               }\r
        }\r
 }\r
 \r
-void CProfile::SetCommandID(const int nApplicationID, const int nCommandType, const int nKey, int nCommandID)\r
+void CProfile::SetCommandID(const int nAppID, const int nType, const int nKey, int nComID)\r
 {\r
-       if (nKey == 0xf0 && Commands[nCommandID].fCommand == CCommands::C_) {\r
+       if (nKey == 0xf0 && Commands[nComID].fCommand == CCommands::C_)\r
                // Change CommandID C_Eisu\r
-               for (nCommandID = 1; nCommandID < MAX_COMMAND; ++nCommandID) {\r
-                       if (Commands[nCommandID].fCommand == CCommands::C_Eisu) {\r
+               for (nComID = 1; nComID < MAX_COMMAND; ++nComID)\r
+                       if (Commands[nComID].fCommand == CCommands::C_Eisu)\r
                                break;\r
-                       }\r
-               }\r
-       }\r
-       m_Data[nApplicationID].SetCommandID(nCommandType, nKey, nCommandID);\r
+       m_Config.nCommandID[nAppID][nType][nKey] = nComID;\r
 }\r
 \r
-int CProfile::GetCommandID(const int nApplicationID, const int nCommandType, const int nKey)\r
+int CProfile::GetCommandID(const int nAppID, const int nType, const int nKey)\r
 {\r
-       int nCommandID = m_Data[nApplicationID].GetCommandID(nCommandType, nKey);\r
-       if (nKey == 0xf0 && Commands[nCommandID].fCommand == CCommands::C_Eisu) {\r
+       int nComID = m_Config.nCommandID[nAppID][nType][nKey];\r
+       if (nKey == 0xf0 && Commands[nComID].fCommand == CCommands::C_Eisu)\r
                // Change CommandID C_\r
-               for (nCommandID = 1; nCommandID < MAX_COMMAND; ++nCommandID) {\r
-                       if (Commands[nCommandID].fCommand == CCommands::C_) {\r
+               for (nComID = 1; nComID < MAX_COMMAND; nComID++)\r
+                       if (Commands[nComID].fCommand == CCommands::C_)\r
                                break;\r
-                       }\r
-               }\r
-       }\r
-       return nCommandID;\r
+       return nComID;\r
 }\r
 \r
-void CProfile::SetKillRingMax(const int nApplicationID, const int nKillRingMax)\r
+void CProfile::SetKillRingMax(const int nAppID, const int nKillRingMax)\r
 {\r
-       m_Data[nApplicationID].SetKillRingMax(nKillRingMax);\r
+       m_Config.nKillRingMax[nAppID] = nKillRingMax;\r
 }\r
 \r
-int CProfile::GetKillRingMax(const int nApplicationID)\r
+int CProfile::GetKillRingMax(const int nAppID)\r
 {\r
-       return m_Data[nApplicationID].GetKillRingMax();\r
+       return m_Config.nKillRingMax[nAppID];\r
 }\r
 \r
-void CProfile::SetUseDialogSetting(const int nApplicationID, const BOOL bUseDialogSetting)\r
+void CProfile::SetUseDialogSetting(const int nAppID, const BOOL bUseDialogSetting)\r
 {\r
-       m_Data[nApplicationID].SetUseDialogSetting(bUseDialogSetting);\r
+       m_Config.bUseDialogSetting[nAppID] = bUseDialogSetting;\r
 }\r
 \r
-BOOL CProfile::GetUseDialogSetting(const int nApplicationID)\r
+BOOL CProfile::GetUseDialogSetting(const int nAppID)\r
 {\r
-       return m_Data[nApplicationID].GetUseDialogSetting();\r
+       return m_Config.bUseDialogSetting[nAppID];\r
 }\r
 \r
-void CProfile::SetWindowText(const int nApplicationID, const CString szWindowText)\r
+void CProfile::SetWindowText(const int nAppID, const CString szWindowText)\r
 {\r
-       m_Data[nApplicationID].SetWindowText(szWindowText);\r
+       if (CUtils::GetWindowTextType(szWindowText) == IDS_WINDOW_TEXT_IGNORE)\r
+               _tcscpy_s(m_Config.szWindowText[nAppID], _T("*"));\r
+       else\r
+               _tcsncpy_s(m_Config.szWindowText[nAppID], szWindowText, _TRUNCATE);\r
 }\r
 \r
-CString CProfile::GetWindowText(const int nApplicationID)\r
+CString CProfile::GetWindowText(const int nAppID)\r
 {\r
-       return m_Data[nApplicationID].GetWindowText();\r
+       return m_Config.szWindowText[nAppID];\r
 }\r
 \r
 void CProfile::DeleteAllRegistryData()\r
@@ -1376,7 +1163,7 @@ void CProfile::DeleteAllRegistryData()
        HKEY hkey = NULL;\r
        if (RegOpenKeyEx(HKEY_CURRENT_USER, CString(MAKEINTRESOURCE(IDS_REGSUBKEY_DATA)), 0, KEY_ALL_ACCESS, &hkey) == ERROR_SUCCESS) {\r
                // I am sure that I have to do only one time, but...\r
-               for (int nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
+               for (int nAppID = 0; nAppID < MAX_APP; ++nAppID) {\r
                        DWORD dwIndex = 0;\r
                        TCHAR szName[SUB_KEY_NAME_LENGTH] = {'\0'};\r
                        DWORD dwName = sizeof(szName);\r
@@ -1410,36 +1197,33 @@ int CProfile::GetCurrentApplicationID(CComboBox *const cApplicationList, const C
        return -1;\r
 }\r
 \r
-void CProfile::CopyData(const CString szDestinationApplication, const CString szSourceApplication)\r
+void CProfile::CopyData(const CString szDstApp, const CString szSrcApp)\r
 {\r
        int nSettingStyle = SETTING_SPECIFIC;\r
-       int nDestinationApplication = GetApplicationIndex(szDestinationApplication, TRUE, &nSettingStyle);\r
-       int nSourceApplication = GetApplicationIndex(szSourceApplication);\r
-\r
-       CString szApplicationName = m_Data[nDestinationApplication].GetApplicationName();\r
-       CString szApplicationTitle = m_Data[nDestinationApplication].GetApplicationTitle();\r
-       CString szWindowText = m_Data[nDestinationApplication].GetWindowText();\r
-       int nWindowTextType = m_Data[nDestinationApplication].GetWindowTextType();\r
-\r
-       m_Data[nDestinationApplication] = m_Data[nSourceApplication];\r
-\r
-       m_Data[nDestinationApplication].SetApplicationName(szApplicationName);\r
-       m_Data[nDestinationApplication].SetApplicationTitle(szApplicationTitle);\r
-       m_Data[nDestinationApplication].SetWindowText(szWindowText);\r
-       m_Data[nDestinationApplication].SetWindowTextType(nWindowTextType);\r
+       const int nDstApp = GetApplicationIndex(szDstApp, TRUE, &nSettingStyle);\r
+       const int nSrcApp = GetApplicationIndex(szSrcApp);\r
+\r
+#define CopyMember(member) CopyMemory(&m_Config. ## member ## [nDstApp], &m_Config. ## member ## [nSrcApp], sizeof(m_Config. ## member ## [nSrcApp]))\r
+       CopyMember(b326Compatible);\r
+       CopyMember(nFunctionID);\r
+       CopyMember(bEnableCUA);\r
+       CopyMember(bUseDialogSetting);\r
+       CopyMember(bIgnoreUndefinedC_x);\r
+       CopyMember(bIgnoreUndefinedMetaCtrl);\r
+       CopyMember(nKillRingMax);\r
+       CopyMember(nCommandID);\r
+#undef CopyMember\r
 }\r
 \r
 // return application index\r
 // if there is NOT the application in the data, return MAX_APP\r
 int CProfile::GetApplicationIndex(const CString szApplicationName)\r
 {\r
-       int nApplicationID = 0;\r
-       for (nApplicationID = 0; nApplicationID < MAX_APP; ++nApplicationID) {\r
-               if (m_Data[nApplicationID].GetApplicationName() == szApplicationName) {\r
+       int nAppID = 0;\r
+       for (nAppID = 0; nAppID < MAX_APP; ++nAppID)\r
+               if (szApplicationName == m_Config.szSpecialApp[nAppID])\r
                        break;\r
-               }\r
-       }\r
-       return nApplicationID;\r
+       return nAppID;\r
 }\r
 \r
 // Return True if Windows Vista or later.\r
@@ -1541,14 +1325,14 @@ void CProfile::ImportProperties()
        return;\r
 }\r
 \r
-BOOL CProfile::GetEnableCUA(const int nApplicationID)\r
+BOOL CProfile::GetEnableCUA(const int nAppID)\r
 {\r
-       return m_Data[nApplicationID].GetEnableCUA();\r
+       return m_Config.bEnableCUA[nAppID];\r
 }\r
 \r
-void CProfile::SetEnableCUA(const int nApplicationID, const BOOL bEnableCUA)\r
+void CProfile::SetEnableCUA(const int nAppID, const BOOL bEnableCUA)\r
 {\r
-       m_Data[nApplicationID].SetEnableCUA(bEnableCUA);\r
+       m_Config.bEnableCUA[nAppID] = bEnableCUA;\r
 }\r
 \r
 int CProfile::GetKeyboardSpeed()\r