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

📄 filechangemonitordoc.cpp

📁 有关文件读写的各种典型操作例程VC源代码实现
💻 CPP
字号:
// FileChangeMonitorDoc.cpp :  CFileChangeMonitorDoc 类的实现
//

#include "stdafx.h"
#include "FileChangeMonitor.h"

#include "FileChangeMonitorDoc.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CFileChangeMonitorDoc

IMPLEMENT_DYNCREATE(CFileChangeMonitorDoc, CDocument)

BEGIN_MESSAGE_MAP(CFileChangeMonitorDoc, CDocument)
END_MESSAGE_MAP()


// CFileChangeMonitorDoc 构造/销毁

CFileChangeMonitorDoc::CFileChangeMonitorDoc()
{
	// TODO:在此添加一次性构造代码

}

CFileChangeMonitorDoc::~CFileChangeMonitorDoc()
{
}

BOOL CFileChangeMonitorDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO:在此添加重新初始化代码
	// (SDI 文档将重用该文档)

	return TRUE;
}




// CFileChangeMonitorDoc 序列化

void CFileChangeMonitorDoc::Serialize(CArchive& ar)
{
	// CEditView 包含一个处理所有序列化的编辑控件
	reinterpret_cast<CEditView*>(m_viewList.GetHead())->SerializeRaw(ar);
}


// CFileChangeMonitorDoc 诊断

#ifdef _DEBUG
void CFileChangeMonitorDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CFileChangeMonitorDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG


// CFileChangeMonitorDoc 命令

UINT CFileChangeMonitorDoc::FileChangeMonitor(LPVOID lpParam)
{
	CFileChangeMonitorDoc* pDoc=(CFileChangeMonitorDoc*)lpParam;
	CFile* pMonitorFile = pDoc->GetFile(pDoc->GetPathName(),
		CFile::modeRead|CFile::shareDenyWrite,NULL);	
	if(pMonitorFile)
	{	// 保存上次写文件的时间
		FILETIME FileLastWriteTime;
		BY_HANDLE_FILE_INFORMATION FileInfo;
		if(!GetFileInformationByHandle((HANDLE)pMonitorFile->m_hFile,&FileInfo))
			return 0;
		FileLastWriteTime=FileInfo.ftLastWriteTime;
		pDoc->ReleaseFile(pMonitorFile,FALSE);			
		// 分离文件路径
		char path[_MAX_PATH];
		_splitpath(pDoc->GetPathName(), NULL, path, NULL, NULL);
		while(1)
		{
			// 获取文件更改通知句柄
			HANDLE hFileChanged=FindFirstChangeNotification(path,FALSE,
				FILE_NOTIFY_CHANGE_LAST_WRITE|
				FILE_NOTIFY_CHANGE_SIZE|
				FILE_NOTIFY_CHANGE_FILE_NAME);			
			HANDLE hWaitEvents[]={pDoc->m_EventStopMonitor,hFileChanged};
			// 等待文件更改通知或停止监视事件
			DWORD dwResult=WaitForMultipleObjects(2,hWaitEvents,FALSE,INFINITE);
			FindCloseChangeNotification(hFileChanged);				
			if(dwResult==WAIT_OBJECT_0+1)
			{  // 获取文件的保存时间
				pMonitorFile = pDoc->GetFile(pDoc->GetPathName(),
					CFile::modeRead|CFile::shareDenyWrite,NULL);	
				if(pMonitorFile)
				{
					if(GetFileInformationByHandle((HANDLE)pMonitorFile->m_hFile,
						&FileInfo))
					{
						// 判断文件是否已更改
						if((FileLastWriteTime.dwHighDateTime+
							FileLastWriteTime.dwLowDateTime)!=
							(FileInfo.ftLastWriteTime.dwHighDateTime+
							FileInfo.ftLastWriteTime.dwLowDateTime))
							pDoc->OnFileChangeNotify(1);
						// 保存修改时间
						FileLastWriteTime=FileInfo.ftLastWriteTime;
					}
					pDoc->ReleaseFile(pMonitorFile,FALSE);
				}
				else	
				{  // 文件不存在,已被删除或移动
					pDoc->OnFileChangeNotify(2);
				}
			}
			else
				break;
		}
	}
	return 0;
}
void CFileChangeMonitorDoc::OnFileChangeNotify(short nCause)
{
	MessageBeep(MB_ICONEXCLAMATION);	
	CMainFrame* pWnd=(CMainFrame*)AfxGetApp()->GetMainWnd();	
	CView* pView=(CView*)m_viewList.GetHead();
	pWnd->MDIActivate(pView->GetParent());	
	CString StrTip;
	switch(nCause)
	{
	case 1:
		StrTip.Format("文件 %s 内容可能已被改变!",m_strPathName);
		MessageBox(pView->m_hWnd,StrTip,"信息提示",MB_OK);	
		break;
	case 2:
		StrTip.Format("文件 %s 可能已经被进行更名、删除、移动等操作!",m_strPathName);
		MessageBox(pView->m_hWnd,StrTip,"信息提示",MB_OK);
		break;
	}
}
void CFileChangeMonitorDoc::StartMonitorThread(void)
{
	m_EventStopMonitor.ResetEvent();
	AfxBeginThread(FileChangeMonitor,(LPVOID)this);	
}
void CFileChangeMonitorDoc::StopMonitorThread(void)
{
	m_EventStopMonitor.SetEvent();
}
BOOL CFileChangeMonitorDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	m_strPathName=lpszPathName;
	this->StartMonitorThread();	
	return TRUE;
}
void CFileChangeMonitorDoc::OnCloseDocument()
{
	this->StopMonitorThread();
	CDocument::OnCloseDocument();
}
BOOL CFileChangeMonitorDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
	this->StopMonitorThread();
	BOOL bReturn=CDocument::OnSaveDocument(lpszPathName);
	this->StartMonitorThread();
	return bReturn;
}

⌨️ 快捷键说明

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