todolist.cpp

来自「管理项目进度工具的原代码」· C++ 代码 · 共 855 行 · 第 1/2 页

CPP
855
字号
        bUseIni = FileMisc::FileExists(sIniPath);

		// if we found one then make sure it does not have single 
		// instance specified
		if (bUseIni)
			AfxGetApp()->WriteProfileInt("Preferences", "MultiInstance", TRUE);
	}

    // else try for an ini file having the same name as the executable
	if (!bUseIni)    {        // then try current working dir followed by app folder
		FileMisc::MakePath(sIniPath, NULL, FileMisc::GetCwd(), sAppName, ".ini");		bUseIni = FileMisc::FileExists(sIniPath);

		// followed by app folder
        if (!bUseIni)
		{
			FileMisc::MakePath(sIniPath, sDrive, sFolder, sAppName, ".ini");
    		bUseIni = FileMisc::FileExists(sIniPath);
		}
   }	// then try registry	if (!bUseIni)	{      BOOL bFirstTime = !CRegKey::KeyExists(HKEY_CURRENT_USER, "Software\\Abstractspoon\\ToDoList");		if (bFirstTime) // first time		{			// don't bother the user if we're being run off removeable media			if (CDriveInfo::IsRemovablePath(sIniPath))				bUseIni = TRUE;			else			{				CWelcomeDialog dialog;				if (dialog.DoModal() == IDOK)					bUseIni = dialog.GetUseIniFile();				else					return FALSE;			}		}	}	// finally make the choice	if (bUseIni)	{		free((void*)m_pszProfileName);		m_pszProfileName = _strdup(sIniPath);	}	else		SetRegistryKey(_T(REGKEY));    UpgradePreferences(bUseIni);	return TRUE;}
void CToDoListApp::UpgradePreferences(BOOL bUseIni)
{
	// put later upgrades at top
	// HERE
	
	// unification of file states
	// do splits separately because it uses the unmodified filespec as the
	// value names whereas the others replace backslashes with underscores
	// for use as the key name
	// and as an optimization, if the splitpos key does not exist then 
	// assume we've already done the upgrade
	CTDLPrefMigrationDlg feedbackDlg;
	
	if (RelocateSplitPosSettings(bUseIni, &feedbackDlg))
	{
		CWaitCursor cursor;
		RelocateFileStateSettings("Filter", bUseIni);
		RelocateFileStateSettings("ExpandedState", bUseIni);
		RelocateFileStateSettings("SortState", bUseIni);
	}
}

BOOL CToDoListApp::RelocateSplitPosSettings(BOOL bUseIni, CTDLPrefMigrationDlg* pFeedbackDlg)
{
	if (bUseIni)
	{
		CIni ini(m_pszProfileName);

		if (!ini.IsSectionExist("SplitPos"))
			return FALSE;

		// at this point notify the user that
		// it can take some time to transfer all their settings
		AfxMessageBox(IDS_WARN_CONVERT_INI);

		if (pFeedbackDlg)
			pFeedbackDlg->Create(NULL);

		CStringArray aFileKeys;
		ini.GetKeyNames("SplitPos", &aFileKeys);

		for (int nItem = 0; nItem < aFileKeys.GetSize(); nItem++)
		{
			Misc::ProcessMsgLoop(); // for feedback dialog

			CString sItem = aFileKeys[nItem];
			
			int nSplit = ini.GetInt("SplitPos", sItem, -1);
			
			if (nSplit != -1)
			{
				CString sNewKey, sValueName("SplitPos");
				
				// handle 'Shared' differently
				if (sItem.CompareNoCase("Shared") == 0)
				{
					sNewKey = "FileStates";
					sValueName = "SharedSplitPos";
				}
				else
				{
					sItem.Replace('\\', '_');
					sNewKey.Format("FileStates\\%s", sItem);
				}

				ini.WriteInt(sNewKey, sValueName, nSplit);
			}
		}
		
		// delete old key
		ini.DeleteSection("SplitPos");
	}
	else // registry
	{
		CString sAppKey = CRegKey::GetAppRegPath(), sOldKey;
		sOldKey.Format("%sSplitPos", sAppKey);
		
		if (!CRegKey::KeyExists(HKEY_CURRENT_USER, sOldKey))
			return FALSE;

		CRegKey regOld;
		CStringArray aFileKeys;
		
		regOld.Open(HKEY_CURRENT_USER, sOldKey);
		regOld.GetValueNames(aFileKeys);
		
		for (int nItem = 0; nItem < aFileKeys.GetSize(); nItem++)
		{
			CString sItem = aFileKeys[nItem];
			
			int nSplit = -1;
			regOld.Read(sItem, (DWORD&)nSplit);
			
			if (nSplit != -1)
			{
				CString sNewKey, sValueName("SplitPos");
				
				// handle 'Shared' differently
				if (sItem.CompareNoCase("Shared") == 0)
				{
					sNewKey.Format("%sFileStates", sAppKey);
					sValueName = "SharedSplitPos";
				}
				else
				{
					sItem.Replace('\\', '_');
					sNewKey.Format("%sFileStates\\%s", sAppKey, sItem);
				}
				
				CRegKey regNew;
				
				regNew.Open(HKEY_CURRENT_USER, sNewKey);
				regNew.Write(sValueName, (DWORD)nSplit);
				regNew.Close();
			}
		}
		
		// delete old key
		CRegKey::Delete(HKEY_CURRENT_USER, sOldKey);
	}

	return TRUE;
}

BOOL CToDoListApp::RelocateFileStateSettings(const CString& sSection, BOOL bUseIni)
{
	if (bUseIni)
	{
		CIni ini(m_pszProfileName);

		CString sNewFileKey, sOldFileKey;
		CStringArray aSections;
		ini.GetSectionNames(&aSections);

		for (int nItem = 0; nItem < aSections.GetSize(); nItem++)
		{
			Misc::ProcessMsgLoop(); // for feedback dialog
			
			CString sItem = aSections[nItem];

			// look for match at start of section name
			if (sItem.Find(sSection) == 0 && sItem.GetLength() > sSection.GetLength())
			{
				CString sFileKey = sItem.Mid(sSection.GetLength() + 1); // name + backslash

				if (!sFileKey.IsEmpty())
				{
					sNewFileKey.Format("FileStates\\%s\\%s", sFileKey, sSection);
					
					ini.CopySection(sItem, sNewFileKey, TRUE); // copy over

					Misc::ProcessMsgLoop(); // for feedback dialog

					ini.DeleteSection(sItem); // and delete
				}
			}
		}
		
		// delete old key
		ini.DeleteSection(sSection);
	}
	else // registry
	{
		// check for existence of old key
		CString sAppKey = CRegKey::GetAppRegPath(), sOldKey;
		sOldKey.Format("%s%s", sAppKey, sSection);
		
		if (!CRegKey::KeyExists(HKEY_CURRENT_USER, sOldKey))
			return FALSE;

		CRegKey regOld;
		CString sNewFileKey, sOldFileKey;
		CStringArray aFileKeys;
		
		regOld.Open(HKEY_CURRENT_USER, sOldKey);
		regOld.GetSubkeyNames(aFileKeys);
		regOld.Close();
		
		// copy values to new location
		for (int nItem = 0; nItem < aFileKeys.GetSize(); nItem++)
		{
			CString sItem = aFileKeys[nItem];
			sItem.Replace('\\', '_');
			
			sOldFileKey.Format("%s\\%s", sOldKey, sItem);
			sNewFileKey.Format("%sFileStates\\%s\\%s", sAppKey, sItem, sSection);
			
			CRegKey::CopyKey(HKEY_CURRENT_USER, sOldFileKey, HKEY_CURRENT_USER, sNewFileKey);
		}
		
		// then delete old key
		CRegKey::Delete(HKEY_CURRENT_USER, sOldKey);
	}

	return TRUE;
}

int CToDoListApp::DoMessageBox(LPCTSTR lpszPrompt, UINT nType, UINT nIDPrompt) 
{
	// make sure app window is visible
	if (m_pMainWnd && !m_pMainWnd->IsWindowVisible())
		m_pMainWnd->SendMessage(WM_TDL_SHOWWINDOW, 0, 0);
	
	return CWinApp::DoMessageBox(lpszPrompt, nType, nIDPrompt);
}

void CToDoListApp::OnImportPrefs() 
{
	// default location is always app folder
	CString sIniPath = FileMisc::GetModuleFileName();
	sIniPath.MakeLower();
	sIniPath.Replace("exe", "ini");
	
	CEnFileDialog dialog(TRUE, "ini", sIniPath, 
						OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, 
						CEnString(IDS_INIFILEFILTER));
	
	if (dialog.DoModal() == IDOK)
	{
		CRegKey reg;
		
		if (reg.Open(HKEY_CURRENT_USER, APPREGKEY) == ERROR_SUCCESS)
		{
			sIniPath = dialog.GetPathName();
			
			if (reg.ImportFromIni(sIniPath)) // => import ini to registry
			{
				// use them now?
				// only ask if we're not already using the registry
				BOOL bUsingIni = (m_pszRegistryKey == NULL);

				if (bUsingIni)
				{
					if (AfxMessageBox(IDS_POSTIMPORTPREFS, MB_YESNO | MB_ICONQUESTION) == IDYES)
					{
						// renames existing prefs file
						CString sNewName(sIniPath);
						sNewName += ".bak";
						
						if (GetFileAttributes(sNewName) != 0xffffffff)
							DeleteFile(sNewName);
						
						if (MoveFile(sIniPath, sNewName))
						{
							// and initialize the registry 
							SetRegistryKey(_T(REGKEY));
							
							// reset prefs
							m_pMainWnd->SendMessage(WM_TDL_REFRESHPREFS);
						}
					}
				}
				else // reset prefs
					m_pMainWnd->SendMessage(WM_TDL_REFRESHPREFS);
			}
			else // notify user
			{
				CEnString sMessage(IDS_INVALIDPREFFILE, dialog.GetFileName());
				AfxMessageBox(sMessage, MB_OK | MB_ICONEXCLAMATION);
			}
		}
	}
}

void CToDoListApp::OnUpdateImportPrefs(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(TRUE);
}

void CToDoListApp::OnExportPrefs() 
{
	ASSERT (m_pszRegistryKey != NULL);

	CRegKey reg;

	if (reg.Open(HKEY_CURRENT_USER, APPREGKEY) == ERROR_SUCCESS)
	{
		// default location is always app folder
		CString sAppPath = FileMisc::GetModuleFileName();

		CString sIniPath(sAppPath);
		sIniPath.MakeLower();
		sIniPath.Replace("exe", "ini");
		
		CEnFileDialog dialog(FALSE, "ini", sIniPath, OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY, 
							CEnString(IDS_INIFILEFILTER));
		
		if (dialog.DoModal() == IDOK)
		{
			BOOL bUsingReg = (m_pszRegistryKey != NULL);
			sIniPath = dialog.GetPathName();

			if (bUsingReg && reg.ExportToIni(sIniPath))
			{
				// use them now? 
				CString sAppFolder, sIniFolder;
				
				FileMisc::SplitPath(sAppPath, NULL, &sAppFolder);
				FileMisc::SplitPath(sIniPath, NULL, &sIniFolder);
				
				// only if they're in the same folder as the exe
				if (sIniFolder.CompareNoCase(sAppFolder) == 0)
				{
					if (AfxMessageBox(IDS_POSTEXPORTPREFS, MB_YESNO | MB_ICONQUESTION) == IDYES)
					{
						free((void*)m_pszRegistryKey);
						m_pszRegistryKey = NULL;
						
						free((void*)m_pszProfileName);
						m_pszProfileName = _strdup(sIniPath);
						
						// reset prefs
						m_pMainWnd->SendMessage(WM_TDL_REFRESHPREFS);
					}
				}
			}
		}
	}
}

void CToDoListApp::OnUpdateExportPrefs(CCmdUI* pCmdUI) 
{
	BOOL bUsingReg = (m_pszRegistryKey != NULL);
	pCmdUI->Enable(bUsingReg);
}

void CToDoListApp::OnHelpContactus() 
{
	::ShellExecute(*m_pMainWnd, NULL, CONTACTUS, NULL, NULL, SW_SHOWNORMAL);
}

void CToDoListApp::OnHelpFeedbackandsupport() 
{
	::ShellExecute(*m_pMainWnd, NULL, FEEDBACKANDSUPPORT, NULL, NULL, SW_SHOWNORMAL);
}

void CToDoListApp::OnHelpLicense() 
{
	::ShellExecute(*m_pMainWnd, NULL, LICENSE, NULL, NULL, SW_SHOWNORMAL);
}

void CToDoListApp::OnHelpOnline() 
{
	::ShellExecute(*m_pMainWnd, NULL, ONLINE, NULL, NULL, SW_SHOWNORMAL);
}

void CToDoListApp::OnHelpWiki() 
{
	::ShellExecute(*m_pMainWnd, NULL, WIKI, NULL, NULL, SW_SHOWNORMAL);
}

void CToDoListApp::OnHelpCommandline() 
{
	AfxMessageBox(IDS_COMMANDLINEOPTIONS, MB_OK | MB_ICONINFORMATION);
}

void CToDoListApp::OnHelpDonate() 
{
	::ShellExecute(*m_pMainWnd, NULL, DONATE, NULL, NULL, SW_SHOWNORMAL);
}

int CToDoListApp::ExitInstance() 
{
	// TODO: Add your specialized code here and/or call the base class
	
	return CWinApp::ExitInstance();
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?