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 + -
显示快捷键?