todolist.cpp

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

CPP
855
字号
// ToDoList.cpp : Defines the class behaviors for the application.//#include "stdafx.h"#include "ToDoList.h"#include "ToDoListWnd.h"#include "PreferencesGenPage.h"#include "welcomedialog.h"#include "tdcmsg.h"
#include "tdlprefmigrationdlg.h"
#include "..\shared\LimitSingleInstance.h"#include "..\shared\encommandlineinfo.h"#include "..\shared\driveinfo.h"
#include "..\shared\enfiledialog.h"
#include "..\shared\enstring.h"
#include "..\shared\regkey.h"
#include "..\shared\filemisc.h"
#include "..\shared\autoflag.h"

#include "..\3rdparty\xmlnodewrapper.h"
#include "..\3rdparty\ini.h"

#include <afxpriv.h>#include <shlwapi.h>#pragma comment(lib, "shlwapi.lib")#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endifCLimitSingleInstance g_SingleInstanceObj(_T("{3A4EFC98-9BA9-473D-A3CF-6B0FE644470D}")); BOOL CALLBACK FindOtherInstance(HWND hwnd, LPARAM lParam);

const LPCTSTR REGKEY = "AbstractSpoon";const LPCTSTR APPREGKEY = "Software\\AbstractSpoon\\ToDoList";

const LPCTSTR CONTACTUS = "mailto:abstractspoon2@optusnet.com.au"; 
const LPCTSTR FEEDBACKANDSUPPORT = "http://www.codeproject.com/tools/todolist2.asp"; 
const LPCTSTR LICENSE = "http://creativecommons.org/licenses/by-sa/2.5/"; 
const LPCTSTR ONLINE = "http://www.abstractspoon.com/tdl_resources.html"; 
const LPCTSTR WIKI = "http://abstractspoon.pbwiki.com/"; 
const LPCTSTR DONATE = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=abstractspoon2%40optusnet%2ecom%2eau&item_name=Software"; 
/////////////////////////////////////////////////////////////////////////////// CToDoListAppBEGIN_MESSAGE_MAP(CToDoListApp, CWinApp)	//{{AFX_MSG_MAP(CToDoListApp)	ON_COMMAND(ID_HELP_CONTACTUS, OnHelpContactus)
	ON_COMMAND(ID_HELP_FEEDBACKANDSUPPORT, OnHelpFeedbackandsupport)
	ON_COMMAND(ID_HELP_LICENSE, OnHelpLicense)
	ON_COMMAND(ID_HELP_ONLINE, OnHelpOnline)
	ON_COMMAND(ID_HELP_WIKI, OnHelpWiki)
	ON_COMMAND(ID_HELP_COMMANDLINE, OnHelpCommandline)
	ON_COMMAND(ID_HELP_DONATE, OnHelpDonate)
	//}}AFX_MSG_MAP
	ON_COMMAND(ID_HELP, OnHelp)	ON_COMMAND(ID_TOOLS_IMPORTPREFS, OnImportPrefs)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_IMPORTPREFS, OnUpdateImportPrefs)
	ON_COMMAND(ID_TOOLS_EXPORTPREFS, OnExportPrefs)
	ON_UPDATE_COMMAND_UI(ID_TOOLS_EXPORTPREFS, OnUpdateExportPrefs)
END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CToDoListApp constructionCToDoListApp::CToDoListApp(){	// TODO: add construction code here,	// Place all significant initialization in InitInstance
}/////////////////////////////////////////////////////////////////////////////// The one and only CToDoListApp objectCToDoListApp theApp;/////////////////////////////////////////////////////////////////////////////// CToDoListApp initializationBOOL CToDoListApp::InitInstance(){	AfxOleInit(); // for initializing COM and handling drag and drop via explorer
	AfxEnableControlContainer(); // embedding IE

	// load localized resources
	CEnString sResVersion(IDS_RES_VERSION);
	HINSTANCE hResDll = AfxLoadLibrary("ToDoListLOC.dll");

	if (hResDll)
	{
		// check resource version
		TCHAR szResVer[10];
		::LoadString(hResDll, IDS_RES_VERSION, szResVer, sizeof(szResVer) - 1);

		if (atoi(sResVersion) == atoi(szResVer))
			AfxSetResourceHandle(hResDll);
		else
			AfxMessageBox(IDS_MISMATCHEDRESOURCES);
	}

	CEnCommandLineInfo cmdInfo;
	
	if (!ParseCommandLine(&cmdInfo))
		return FALSE;

	// see if the user just wants to see the commandline options
	if (cmdInfo.HasOption("h") || cmdInfo.HasOption("help") || 
		cmdInfo.HasOption("?"))
	{
		AfxMessageBox(IDS_COMMANDLINEOPTIONS, MB_OK | MB_ICONINFORMATION);
		return FALSE;
	}

	// before anything else make sure we've got MSXML3 installed
	if (!CXmlDocumentWrapper::IsVersion3orGreater())
	{
		AfxMessageBox(IDS_BADMSXML);
		return FALSE;
	}

	if (!InitPreferences(&cmdInfo))		return FALSE;

	// does the user want single instance only	BOOL bSingleInstance = !CPreferencesDlg().GetMultiInstance();	if (bSingleInstance && g_SingleInstanceObj.IsAnotherInstanceRunning())	{		HWND hWnd = NULL;		EnumWindows(FindOtherInstance, (LPARAM)&hWnd);				// make sure its not closing
		if (hWnd && !::SendMessage(hWnd, WM_TDL_ISCLOSING, 0, 0))		{
			// check version			int nVer = ::SendMessage(hWnd, WM_TDL_GETVERSION, 0, 0);						if (nVer < CToDoListWnd::GetVersion())				MessageBox(NULL, CEnString(IDS_EARLIERVERRUNNING), CEnString(IDS_COPYRIGHT), MB_OK);						::SendMessage(hWnd, WM_TDL_SHOWWINDOW, 0, 0);
			// pass on file to open
			if (!cmdInfo.m_strFileName.IsEmpty())				SendDataMessage(hWnd, OPENTASKLIST, cmdInfo.m_strFileName);
						::SetForegroundWindow(hWnd);
			
			// new task?
			CString sValue;
			
			if (cmdInfo.GetOption("nt", sValue))
			{
				SendDataMessage(hWnd, ADDNEWTASK, sValue);
				
				if (cmdInfo.GetOption("cm", sValue))
				{
					// replace [\][n] with [\n]
					sValue.Replace("\\n", "\n");
					SendDataMessage(hWnd, SETCOMMENTS, sValue);
				}
			}
			// or select task
			else if (cmdInfo.GetOption("tid", sValue))
			{
				DWORD dwID = atoi(sValue);

				if (dwID)
					SendDataMessage(hWnd, SELECTTASK, dwID);
			}
			// or merge/import
			else if (cmdInfo.GetOption("m", sValue))
			{
				if (!sValue.IsEmpty())
					SendDataMessage(hWnd, IMPORTFILE, sValue);
			}
						return FALSE;
		}	}	BOOL bForceVisible = cmdInfo.HasOption("v");
	BOOL bPasswordPrompting = !cmdInfo.HasOption("x");

	DWORD dwFlags = (bForceVisible ? TLD_FORCEVISIBLE : 0) |
					(bPasswordPrompting ? TLD_PASSWORDPROMPTING : 0);	CToDoListWnd* pTDL = new CToDoListWnd;		if (pTDL && pTDL->Create(dwFlags, cmdInfo.m_strFileName))	{		HWND hWnd = pTDL->GetSafeHwnd();
		m_pMainWnd = pTDL;
		
		// new task?
		CString sValue;
		
		if (cmdInfo.GetOption("nt", sValue))
		{
			SendDataMessage(hWnd, ADDNEWTASK, sValue);

			if (cmdInfo.GetOption("cm", sValue))
			{
				// replace [\][n] with [\n]
				sValue.Replace("\\n", "\n");
				SendDataMessage(hWnd, SETCOMMENTS, sValue);
			}
		}
		// or select task
		else if (cmdInfo.GetOption("tid", sValue))
		{
			DWORD dwID = atoi(sValue);
			
			if (dwID)
				SendDataMessage(hWnd, SELECTTASK, dwID);
		}
		// or merge/import
		else if (cmdInfo.GetOption("m", sValue))
		{
			if (!sValue.IsEmpty())
				SendDataMessage(hWnd, IMPORTFILE, sValue);
		}

		return TRUE;	}
	// else	return FALSE;}

BOOL CToDoListApp::ParseCommandLine(CEnCommandLineInfo* pInfo)
{
	ASSERT (pInfo);

	CWinApp::ParseCommandLine(*pInfo); // default

	// check for task link
	CString sLink;

	if (pInfo->GetOption("l", sLink) && sLink.Find(TDL_PROTOCOL) != -1)
	{
		CString sFilePath;
		DWORD dwID = 0;

		CToDoCtrl::ParseTaskLink(sLink, dwID, sFilePath);

		if (!sFilePath.IsEmpty() && dwID)
		{
			// remove possible trailing slash on file path
			sFilePath.TrimRight('\\');

			// replace possible %20 by spaces
			sFilePath.Replace("%20", " ");

			// verify the file existence unless the path is relative
			if (/*PathIsRelative(sFilePath) || */FileMisc::FileExists(sFilePath))
			{
				pInfo->m_strFileName = sFilePath;
				pInfo->SetOption("tid", dwID);
			}
			else
			{
				pInfo->m_strFileName.Empty();
				pInfo->DeleteOption("tid");
				AfxMessageBox(CEnString(IDS_TDLLINKLOADFAILED, sFilePath));

				return FALSE;
			}
		}
	}
	// else validate file path
	else if (!FileMisc::FileExists(pInfo->m_strFileName))
		pInfo->m_strFileName.Empty();

	return TRUE;
}

BOOL CToDoListApp::SendDataMessage(HWND hWnd, int nType, int nSize, void* pData)
{
   COPYDATASTRUCT cds;
   
   cds.dwData = nType;
   cds.cbData = nSize;
   cds.lpData = pData;
   
   return SendMessage(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds);
}

BOOL CToDoListApp::SendDataMessage(HWND hwnd, int nType, DWORD dwData)
{
   return SendDataMessage(hwnd, nType, sizeof(dwData), (LPVOID)&dwData);
}

BOOL CToDoListApp::SendDataMessage(HWND hwnd, int nType, LPCTSTR szData)
{
   return SendDataMessage(hwnd, nType, strlen(szData) + 1, (LPVOID)szData);
}
BOOL CALLBACK FindOtherInstance(HWND hwnd, LPARAM lParam){	CString sCaption;	int nLen = ::GetWindowTextLength(hwnd);	::GetWindowText(hwnd, sCaption.GetBuffer(nLen + 1), nLen + 1);	sCaption.ReleaseBuffer();	if (sCaption.Find(CEnString(IDS_COPYRIGHT)) != -1)	{		HWND* pWnd = (HWND*)lParam;		*pWnd = hwnd;		return FALSE;	}	return TRUE;}BOOL CToDoListApp::PreTranslateMessage(MSG* pMsg) {
	// give first chance to main window for handling accelerators	if (m_pMainWnd && m_pMainWnd->PreTranslateMessage(pMsg))		return TRUE;	return CWinApp::PreTranslateMessage(pMsg);}void CToDoListApp::OnHelp() { 	DoHelp();}void CToDoListApp::WinHelp(DWORD dwData, UINT nCmd) {	if (nCmd == HELP_CONTEXT)		DoHelp((LPCTSTR)dwData);}void CToDoListApp::DoHelp(const CString& /*sHelpRef*/){
	// prevent reentrancy
	static BOOL bAlreadyHere = FALSE;

	if (bAlreadyHere)
		return;

	CAutoFlag af(bAlreadyHere, TRUE);
	// 1. look for todolist_help.tdl in the registry	CString sHelpTopic, sHelpFile = GetProfileString("Help", "TDLFile");	if (!FileMisc::FileExists(sHelpFile))	{		// 2. try exe folder		CString sFolder, sDrive, sHelpPath = FileMisc::GetModuleFileName();

		FileMisc::SplitPath(sHelpPath, &sDrive, &sFolder);
		FileMisc::MakePath(sHelpPath, sDrive, sFolder, "ToDoListDocumentation.tdl");
		// try again		if (!FileMisc::FileExists(sHelpFile))		{
			// 3. ask the user
			CEnString sMsg(IDS_LOCATEHELP), sTitle(IDS_LOCATEHELP_TITLE);
			if (MessageBox(*m_pMainWnd, sMsg, sTitle, MB_OKCANCEL) == IDOK)			{
				CEnString sFilter(IDS_HELPFILEFILTER);				//fabio_2005
				CEnFileDialog dialog(TRUE, "tdl", sHelpFile, OFN_PATHMUSTEXIST, "Help Files (*.tdl)|*.tdl||");				dialog.m_ofn.lpstrTitle = (LPCSTR)(LPCTSTR)sTitle;				if (dialog.DoModal() == IDOK)					sHelpFile = dialog.GetPathName();				else					return;			}			else				return;		}	}	ASSERT (!sHelpFile.IsEmpty());	if (32 < (int)ShellExecute(*m_pMainWnd, NULL, sHelpFile, NULL, NULL, SW_SHOWNORMAL))		WriteProfileString("Help", "TDLFile", sHelpFile);
/*
    CString sHelpFile = sHelpRef.IsEmpty() ? 
						"http://www.abstractspoon.com/help.html" :
						"http://www.abstractspoon.com/help_prefs.html";

	ShellExecute(*m_pMainWnd, NULL, sHelpFile, NULL, NULL, SW_SHOWNORMAL);
*/
}BOOL CToDoListApp::InitPreferences(const CEnCommandLineInfo* pInfo){
	BOOL bUseIni = FALSE;

	// get the app file path
	CString sTemp = FileMisc::GetModuleFileName(), sDrive, sFolder, sAppName;
	FileMisc::SplitPath(sTemp, &sDrive, &sFolder, &sAppName);

    // try command line first    CString sIniPath;

    if (pInfo->GetOption("i", sIniPath) && !sIniPath.IsEmpty())    {
		// prefix application path if path is relative
		if (PathIsRelative(sIniPath))
			FileMisc::MakePath(sIniPath, sDrive, sFolder, sIniPath);

        bUseIni = FileMisc::FileExists(sIniPath);
    }

	// else if there is a tasklist on the commandline then try for an
	// ini file of the same name
	if (!bUseIni && !pInfo->m_strFileName.IsEmpty())
	{
	    sIniPath = pInfo->m_strFileName;
		FileMisc::ReplaceExtension(sIniPath, "ini");

⌨️ 快捷键说明

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