📄 filechangemonitordoc.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 + -