FileChangeDoc.cpp
上传用户:lqt88888
上传日期:2009-12-14
资源大小:905k
文件大小:5k
源码类别:

书籍源码

开发平台:

Visual C++

  1. // FileChangeDoc.cpp : implementation of the CFileChangeDoc class
  2. //
  3. #include "stdafx.h"
  4. #include "FileChange.h"
  5. #include "MainFrm.h"
  6. #include "FileChangeDoc.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CFileChangeDoc
  14. IMPLEMENT_DYNCREATE(CFileChangeDoc, CDocument)
  15. BEGIN_MESSAGE_MAP(CFileChangeDoc, CDocument)
  16. //{{AFX_MSG_MAP(CFileChangeDoc)
  17. // NOTE - the ClassWizard will add and remove mapping macros here.
  18. //    DO NOT EDIT what you see in these blocks of generated code!
  19. //}}AFX_MSG_MAP
  20. END_MESSAGE_MAP()
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CFileChangeDoc construction/destruction
  23. CFileChangeDoc::CFileChangeDoc()
  24. {
  25. // TODO: add one-time construction code here
  26. }
  27. CFileChangeDoc::~CFileChangeDoc()
  28. {
  29. }
  30. BOOL CFileChangeDoc::OnNewDocument()
  31. {
  32. if (!CDocument::OnNewDocument())
  33. return FALSE;
  34. // TODO: add reinitialization code here
  35. // (SDI documents will reuse this document)
  36. return TRUE;
  37. }
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CFileChangeDoc serialization
  40. void CFileChangeDoc::Serialize(CArchive& ar)
  41. {
  42. // CEditView contains an edit control which handles all serialization
  43. ((CEditView*)m_viewList.GetHead())->SerializeRaw(ar);
  44. }
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CFileChangeDoc diagnostics
  47. #ifdef _DEBUG
  48. void CFileChangeDoc::AssertValid() const
  49. {
  50. CDocument::AssertValid();
  51. }
  52. void CFileChangeDoc::Dump(CDumpContext& dc) const
  53. {
  54. CDocument::Dump(dc);
  55. }
  56. #endif //_DEBUG
  57. /////////////////////////////////////////////////////////////////////////////
  58. // CFileChangeDoc commands
  59. BOOL CFileChangeDoc::OnSaveDocument(LPCTSTR lpszPathName) 
  60. {
  61. WatchStop();
  62. BOOL bRet=CDocument::OnSaveDocument(lpszPathName);
  63. WatchStart();
  64. return bRet;
  65. }
  66. void CFileChangeDoc::OnCloseDocument() 
  67. {
  68. WatchStop();
  69. CDocument::OnCloseDocument();
  70. }
  71. BOOL CFileChangeDoc::OnOpenDocument(LPCTSTR lpszPathName) 
  72. {
  73. if (!CDocument::OnOpenDocument(lpszPathName))
  74. return FALSE;
  75. //save the filename
  76. m_strPathName=lpszPathName;
  77. //start the watch
  78. WatchStart();
  79. return TRUE;
  80. }
  81. void CFileChangeDoc::OnFileAlarm(short nCause)
  82. {
  83. MessageBeep(MB_ICONEXCLAMATION);
  84. CMainFrame* pwndMain=(CMainFrame*)AfxGetApp()->GetMainWnd();
  85. ASSERT(pwndMain);
  86. CView* pView=(CView*)m_viewList.GetHead();
  87. pwndMain->MDIActivate(pView->GetParent());
  88. CString sMsg;
  89. switch(nCause)
  90. {
  91. case FA_WRITTEN:
  92. sMsg.Format("文件 %s 已被改变!",m_strPathName);
  93. AfxMessageBox(sMsg);
  94. break;
  95. case FA_FILELOST:
  96. sMsg.Format("文件 %s 已被删除或移动!",m_strPathName);
  97. AfxMessageBox("file deleted/moved");
  98. break;
  99. }
  100. }
  101. //Start the watching thread
  102. void CFileChangeDoc::WatchStart()
  103. {
  104. m_evStopWatch.ResetEvent();
  105. AfxBeginThread(FileChangeWatch,(LPVOID)this);
  106. }
  107. //Stop the watching thread
  108. void CFileChangeDoc::WatchStop()
  109. {
  110. m_evStopWatch.SetEvent();
  111. }
  112. UINT CFileChangeDoc::FileChangeWatch(LPVOID lpParam)
  113. {
  114. CFileChangeDoc* pDoc=(CFileChangeDoc*)lpParam;
  115. ASSERT(pDoc);
  116. CFile* pFile = pDoc->GetFile(pDoc->GetPathName(),
  117. CFile::modeRead|CFile::shareDenyWrite,NULL);
  118. ASSERT(pFile);
  119. if(pFile)
  120. {
  121. // 保存上次写文件的时间
  122. FILETIME ftLastWriteTime;
  123. BY_HANDLE_FILE_INFORMATION fileinfo;
  124. if(!GetFileInformationByHandle((HANDLE)pFile->m_hFile,&fileinfo))
  125. return 0;
  126. ftLastWriteTime=fileinfo.ftLastWriteTime;
  127. pDoc->ReleaseFile(pFile,FALSE);
  128. // 分离文件路径
  129. char path[_MAX_PATH];
  130. _splitpath(pDoc->GetPathName(), NULL, path, NULL, NULL);
  131. while(1)
  132. {
  133. // 获取文件更改通知句柄
  134. HANDLE hFileChanged=FindFirstChangeNotification(path,FALSE,
  135. FILE_NOTIFY_CHANGE_LAST_WRITE|
  136. FILE_NOTIFY_CHANGE_SIZE|
  137. FILE_NOTIFY_CHANGE_FILE_NAME);
  138. HANDLE hWaitEvents[]={pDoc->m_evStopWatch,hFileChanged};
  139. // 等待文件更改通知或停止监视事件
  140. DWORD dwResult=
  141. WaitForMultipleObjects(2,hWaitEvents,FALSE,INFINITE);
  142. FindCloseChangeNotification(hFileChanged);
  143. if(dwResult==WAIT_OBJECT_0+1)
  144. {
  145. // 获取文件的保存时间
  146. pFile = pDoc->GetFile(pDoc->GetPathName(),
  147. CFile::modeRead|CFile::shareDenyWrite,NULL);
  148. if(pFile)
  149. {
  150. if(GetFileInformationByHandle((HANDLE)pFile->m_hFile,
  151. &fileinfo))
  152. {
  153. // 判断文件是否已更改
  154. if((ftLastWriteTime.dwHighDateTime+
  155. ftLastWriteTime.dwLowDateTime)!=
  156. (fileinfo.ftLastWriteTime.dwHighDateTime+
  157. fileinfo.ftLastWriteTime.dwLowDateTime))
  158. pDoc->OnFileAlarm(FA_WRITTEN);
  159. // 保存修改时间
  160. ftLastWriteTime=fileinfo.ftLastWriteTime;
  161. }
  162. pDoc->ReleaseFile(pFile,FALSE);
  163. }
  164. else // 文件不存在,已被删除或移动
  165. {
  166. pDoc->OnFileAlarm(FA_FILELOST);
  167. }
  168. }
  169. else
  170. break;
  171. }
  172. }
  173. return 0;
  174. }