⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 doccore.cpp

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		if (afxData.bMarked4)
			AfxGetFileTitle(lpszPathName, szTitle, _countof(szTitle));
		else
			lstrcpyn(szTitle, lpszPathName, _countof(szTitle));
		AfxFormatString1(prompt, nIDP, szTitle);
	}

	AfxMessageBox(prompt, MB_ICONEXCLAMATION, nHelpContext);
}

/////////////////////////////////////////////////////////////////////////////
// File operations (default uses CDocument::Serialize)

CString CMirrorFile::GetTempName(LPCTSTR lpszOriginalFile, BOOL bCreate)
{
	CString str;

	// get the directory for the file

	TCHAR szPath[_MAX_PATH];
	LPTSTR lpszName;
	GetFullPathName(lpszOriginalFile, _MAX_PATH, szPath, &lpszName);
	*lpszName = NULL;

	// let's create a temporary file name, and create
	// a file too!

	GetTempFileName(szPath, _T("MFC"), 0,
		str.GetBuffer(_MAX_PATH+1));
	str.ReleaseBuffer();

	// delete the file if the user just wants a name

	if (!bCreate)
		CFile::Remove(str);

	return str;
}

BOOL CMirrorFile::Open(LPCTSTR lpszFileName, UINT nOpenFlags,
	CFileException* pError)
{
	ASSERT(lpszFileName != NULL);
	m_strMirrorName.Empty();

	CFileStatus status;
	if (nOpenFlags & CFile::modeCreate) //opened for writing
	{
		if (CFile::GetStatus(lpszFileName, status))
		{
			CString strRoot;
			AfxGetRoot(lpszFileName, strRoot);

			DWORD dwSecPerClus, dwBytesPerSec, dwFreeClus, dwTotalClus;
			DWORD nBytes = 0;
			if (GetDiskFreeSpace(strRoot, &dwSecPerClus, &dwBytesPerSec, &dwFreeClus,
				&dwTotalClus))
			{
				nBytes = dwFreeClus * dwSecPerClus * dwBytesPerSec;
			}
			if (nBytes > 2 * DWORD(status.m_size)) // at least 2x free space avail
			{
				m_strMirrorName = GetTempName(lpszFileName, TRUE);
			}
		}
	}

	if (!m_strMirrorName.IsEmpty() &&
		CFile::Open(m_strMirrorName, nOpenFlags, pError))
	{
		m_strFileName = lpszFileName;
		FILETIME ftCreate, ftAccess, ftModify;
		if (::GetFileTime((HANDLE)m_hFile, &ftCreate, &ftAccess, &ftModify))
		{
			AfxTimeToFileTime(status.m_ctime, &ftCreate);
			SetFileTime((HANDLE)m_hFile, &ftCreate, &ftAccess, &ftModify);
		}

		DWORD dwLength = 0;
		PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
		if (GetFileSecurity(lpszFileName, DACL_SECURITY_INFORMATION,
			NULL, dwLength, &dwLength))
		{
			pSecurityDescriptor = (PSECURITY_DESCRIPTOR) new BYTE[dwLength];
			if (::GetFileSecurity(lpszFileName, DACL_SECURITY_INFORMATION,
				pSecurityDescriptor, dwLength, &dwLength))
			{
				SetFileSecurity(m_strMirrorName, DACL_SECURITY_INFORMATION, pSecurityDescriptor);
			}
			delete[] (BYTE*)pSecurityDescriptor;
		}
		return TRUE;
	}
	m_strMirrorName.Empty();
	return CFile::Open(lpszFileName, nOpenFlags, pError);
}

void CMirrorFile::Abort()
{
	CFile::Abort();
	if (!m_strMirrorName.IsEmpty())
		CFile::Remove(m_strMirrorName);
}

//WINBUG: these will be in a public header, some day.

typedef BOOL (WINAPI* ReplaceAPIPtr)(LPCWSTR, LPCWSTR, LPCWSTR,
						DWORD, LPVOID, LPVOID);
#ifndef REPLACEFILE_WRITE_THROUGH
#define REPLACEFILE_WRITE_THROUGH 0x00000001
#endif
#ifndef REPLACEFILE_IGNORE_MERGE_ERRORS
#define REPLACEFILE_IGNORE_MERGE_ERRORS 0x00000002
#endif

#ifndef ERROR_UNABLE_TO_MOVE_REPLACEMENT
#define ERROR_UNABLE_TO_MOVE_REPLACEMENT 1176L
#endif
#ifndef ERROR_UNABLE_TO_MOVE_REPLACEMENT_2
#define ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 1177L
#endif

void CMirrorFile::Close()
{
	CString m_strName = m_strFileName; //file close empties string
	CFile::Close();
	if (!m_strMirrorName.IsEmpty())
	{
		BOOL bWorked = FALSE;
		DWORD dwResult = 0;
      ReplaceAPIPtr pfn = NULL;
		CString strBackupName;

		if (!afxData.bWin95)
		{
			HMODULE hModule = GetModuleHandleA("KERNEL32");
			ASSERT(hModule != NULL);

	      pfn = (ReplaceAPIPtr) GetProcAddress(hModule, "ReplaceFile");

			if (pfn != NULL)
			{
				USES_CONVERSION;

				strBackupName = GetTempName(m_strMirrorName, FALSE);

				// this NT API handles copying all attributes for us

				bWorked = (pfn)(T2W((LPTSTR)(LPCTSTR)m_strName),
                            T2W((LPTSTR)(LPCTSTR)m_strMirrorName),
                            T2W((LPTSTR)(LPCTSTR)strBackupName),
					REPLACEFILE_WRITE_THROUGH | REPLACEFILE_IGNORE_MERGE_ERRORS,
					NULL, NULL);

				if (!bWorked)
				   dwResult = GetLastError();
			}
		}

		if (!bWorked)
		{
			if (dwResult == ERROR_UNABLE_TO_MOVE_REPLACEMENT || dwResult == 0)
				CFile::Remove(m_strName);

			if (dwResult == ERROR_UNABLE_TO_MOVE_REPLACEMENT_2)
			   CFile::Remove(strBackupName);

			CFile::Rename(m_strMirrorName, m_strName);
		}
      else if (pfn != NULL)
      {
         CFile::Remove(strBackupName);
      }
	}
}

CFile* CDocument::GetFile(LPCTSTR lpszFileName, UINT nOpenFlags,
	CFileException* pError)
{
	CMirrorFile* pFile = new CMirrorFile;
	ASSERT(pFile != NULL);
	if (!pFile->Open(lpszFileName, nOpenFlags, pError))
	{
		delete pFile;
		pFile = NULL;
	}
	return pFile;
}

void CDocument::ReleaseFile(CFile* pFile, BOOL bAbort)
{
	ASSERT_KINDOF(CFile, pFile);
	if (bAbort)
		pFile->Abort(); // will not throw an exception
	else
		pFile->Close();
	delete pFile;
}

BOOL CDocument::OnNewDocument()
{
	if (IsModified())
		TRACE0("Warning: OnNewDocument replaces an unsaved document.\n");

	DeleteContents();
	m_strPathName.Empty();      // no path name yet
	SetModifiedFlag(FALSE);     // make clean

	return TRUE;
}

BOOL CDocument::OnOpenDocument(LPCTSTR lpszPathName)
{
	if (IsModified())
		TRACE0("Warning: OnOpenDocument replaces an unsaved document.\n");

	CFileException fe;
	CFile* pFile = GetFile(lpszPathName,
		CFile::modeRead|CFile::shareDenyWrite, &fe);
	if (pFile == NULL)
	{
		ReportSaveLoadException(lpszPathName, &fe,
			FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
		return FALSE;
	}

	DeleteContents();
	SetModifiedFlag();  // dirty during de-serialize

	CArchive loadArchive(pFile, CArchive::load | CArchive::bNoFlushOnDelete);
	loadArchive.m_pDocument = this;
	loadArchive.m_bForceFlat = FALSE;
	TRY
	{
		CWaitCursor wait;
		if (pFile->GetLength() != 0)
			Serialize(loadArchive);     // load me
		loadArchive.Close();
		ReleaseFile(pFile, FALSE);
	}
	CATCH_ALL(e)
	{
		ReleaseFile(pFile, TRUE);
		DeleteContents();   // remove failed contents

		TRY
		{
			ReportSaveLoadException(lpszPathName, e,
				FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
		}
		END_TRY
		DELETE_EXCEPTION(e);
		return FALSE;
	}
	END_CATCH_ALL

	SetModifiedFlag(FALSE);     // start off with unmodified

	return TRUE;
}

BOOL CDocument::OnSaveDocument(LPCTSTR lpszPathName)
{
	CFileException fe;
	CFile* pFile = NULL;
	pFile = GetFile(lpszPathName, CFile::modeCreate |
		CFile::modeReadWrite | CFile::shareExclusive, &fe);

	if (pFile == NULL)
	{
		ReportSaveLoadException(lpszPathName, &fe,
			TRUE, AFX_IDP_INVALID_FILENAME);
		return FALSE;
	}

	CArchive saveArchive(pFile, CArchive::store | CArchive::bNoFlushOnDelete);
	saveArchive.m_pDocument = this;
	saveArchive.m_bForceFlat = FALSE;
	TRY
	{
		CWaitCursor wait;
		Serialize(saveArchive);     // save me
		saveArchive.Close();
		ReleaseFile(pFile, FALSE);
	}
	CATCH_ALL(e)
	{
		ReleaseFile(pFile, TRUE);

		TRY
		{
			ReportSaveLoadException(lpszPathName, e,
				TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
		}
		END_TRY
		DELETE_EXCEPTION(e);
		return FALSE;
	}
	END_CATCH_ALL

	SetModifiedFlag(FALSE);     // back to unmodified

	return TRUE;        // success
}

void CDocument::OnCloseDocument()
	// must close all views now (no prompting) - usually destroys this
{
	// destroy all frames viewing this document
	// the last destroy may destroy us
	BOOL bAutoDelete = m_bAutoDelete;
	m_bAutoDelete = FALSE;  // don't destroy document while closing views
	while (!m_viewList.IsEmpty())
	{
		// get frame attached to the view
		CView* pView = (CView*)m_viewList.GetHead();
		ASSERT_VALID(pView);
		CFrameWnd* pFrame = pView->GetParentFrame();
		ASSERT_VALID(pFrame);

		// and close it
		PreCloseFrame(pFrame);
		pFrame->DestroyWindow();
			// will destroy the view as well
	}
	m_bAutoDelete = bAutoDelete;

	// clean up contents of document before destroying the document itself
	DeleteContents();

	// delete the document if necessary
	if (m_bAutoDelete)
		delete this;
}

void CDocument::OnIdle()
{
	// default does nothing
}

/////////////////////////////////////////////////////////////////////////////
// View operations

void CDocument::AddView(CView* pView)
{
	ASSERT_VALID(pView);
	ASSERT(pView->m_pDocument == NULL); // must not be already attached
	ASSERT(m_viewList.Find(pView, NULL) == NULL);   // must not be in list

	m_viewList.AddTail(pView);
	ASSERT(pView->m_pDocument == NULL); // must be un-attached
	pView->m_pDocument = this;

	OnChangedViewList();    // must be the last thing done to the document
}

void CDocument::RemoveView(CView* pView)
{
	ASSERT_VALID(pView);
	ASSERT(pView->m_pDocument == this); // must be attached to us

	m_viewList.RemoveAt(m_viewList.Find(pView));
	pView->m_pDocument = NULL;

	OnChangedViewList();    // must be the last thing done to the document
}

POSITION CDocument::GetFirstViewPosition() const
{
	return m_viewList.GetHeadPosition();
}

CView* CDocument::GetNextView(POSITION& rPosition) const
{
	ASSERT(rPosition != BEFORE_START_POSITION);
		// use CDocument::GetFirstViewPosition instead !
	if (rPosition == NULL)
		return NULL;    // nothing left
	CView* pView = (CView*)m_viewList.GetNext(rPosition);
	ASSERT_KINDOF(CView, pView);
	return pView;
}

void CDocument::UpdateAllViews(CView* pSender, LPARAM lHint, CObject* pHint)
	// walk through all views
{
	ASSERT(pSender == NULL || !m_viewList.IsEmpty());
		// must have views if sent by one of them

	POSITION pos = GetFirstViewPosition();
	while (pos != NULL)
	{
		CView* pView = GetNextView(pos);
		ASSERT_VALID(pView);
		if (pView != pSender)
			pView->OnUpdate(pSender, lHint, pHint);
	}
}

void CDocument::SendInitialUpdate()
	// walk through all views and call OnInitialUpdate
{
	POSITION pos = GetFirstViewPosition();
	while (pos != NULL)
	{
		CView* pView = GetNextView(pos);
		ASSERT_VALID(pView);
		pView->OnInitialUpdate();
	}
}

/////////////////////////////////////////////////////////////////////////////
// command routing

BOOL CDocument::OnCmdMsg(UINT nID, int nCode, void* pExtra,
	AFX_CMDHANDLERINFO* pHandlerInfo)
{
	if (CCmdTarget::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;

	// otherwise check template
	if (m_pDocTemplate != NULL &&
	  m_pDocTemplate->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;

	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////
// CDocument diagnostics

#ifdef _DEBUG
void CDocument::Dump(CDumpContext& dc) const
{
	CObject::Dump(dc);

	dc << "m_strTitle = " << m_strTitle;
	dc << "\nm_strPathName = " << m_strPathName;
	dc << "\nm_bModified = " << m_bModified;
	dc << "\nm_pDocTemplate = " << (void*)m_pDocTemplate;

	if (dc.GetDepth() > 0)
	{
		POSITION pos = GetFirstViewPosition();
		while (pos != NULL)
		{
			CView* pView = GetNextView(pos);
			dc << "\nwith view " << (void*)pView;
		}
	}

	dc << "\n";
}

void CDocument::AssertValid() const
{
	CObject::AssertValid();

	POSITION pos = GetFirstViewPosition();
	while (pos != NULL)
	{
		CView* pView = GetNextView(pos);
		ASSERT_VALID(pView);
	}
}
#endif //_DEBUG

#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif

IMPLEMENT_DYNAMIC(CDocument, CCmdTarget)

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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