MSDIDocManager.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:7k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // MSDIDocManager.cpp
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. /*********************************************************
  21. * Multithreaded SDI Application
  22. * Version: 1.4
  23. * Date: January 3, 2002
  24. * Autor: Michal Mecinski
  25. * E-mail: mimec@mimec.w.pl
  26. * WWW: http://www.mimec.w.pl
  27. *
  28. * Copyright (C) 2002-03 by Michal Mecinski
  29. *********************************************************/
  30. #include "stdafx.h"
  31. #include "MSDIDocManager.h"
  32. #include "MSDIThread.h"
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CMSDIDocManager
  40. CMSDIDocManager::CMSDIDocManager()
  41. {
  42. m_nDocCnt = 1;
  43. }
  44. CMSDIDocManager::~CMSDIDocManager()
  45. {
  46. }
  47. /////////////////////////////////////////////////////////////////////////////
  48. // CMSDIDocManager diagnostics
  49. #ifdef _DEBUG
  50. void CMSDIDocManager::AssertValid() const
  51. {
  52. CDocManager::AssertValid();
  53. }
  54. void CMSDIDocManager::Dump(CDumpContext& dc) const
  55. {
  56. CDocManager::Dump(dc);
  57. }
  58. #endif //_DEBUG
  59. /////////////////////////////////////////////////////////////////////////////
  60. // CMSDIDocManager implementation
  61. void CMSDIDocManager::OnExitThread(CMSDIThread* pThread)
  62. {
  63. m_CriticalSection.Lock();
  64. // remove the thread from the list
  65. POSITION pos = m_ThreadList.Find(pThread);
  66. ASSERT(pos != NULL);
  67. m_ThreadList.RemoveAt(pos);
  68. // check if no more threads
  69. if (m_ThreadList.IsEmpty())
  70. PostQuitMessage(0);
  71. HANDLE hThread = pThread->m_hThread;
  72. // prevent from CWndThread from closing the handle
  73. pThread->m_hThread = NULL;
  74. // let the thread exit
  75. pThread->m_eventTerminate.SetEvent();
  76. // wait until it terminates
  77. WaitForSingleObject(hThread, INFINITE);
  78. // free the thread
  79. CloseHandle(hThread);
  80. m_CriticalSection.Unlock();
  81. PostUpdateNotify(MSDIN_EXIT_THREAD);
  82. }
  83. void CMSDIDocManager::OnFileNew()
  84. {
  85. OpenDocumentFile(NULL);
  86. return;
  87. }
  88. void CMSDIDocManager::OnFileOpen()
  89. {
  90. CString newName;
  91. // allow selecting multiple files
  92. if (!DoPromptFileName(newName, AFX_IDS_OPENFILE,
  93. OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT, TRUE, NULL))
  94. return;
  95. CString strPath, strFile;
  96. // extract path part
  97. AfxExtractSubString(strPath, newName, 0, '');
  98. CString strLast = strPath.Right(1);
  99. if (strLast != '\' && strLast != '/')
  100. strPath += '\';
  101. for (int i=1; ; i++)
  102. {
  103. AfxExtractSubString(strFile, newName, i, '');
  104. if (strFile.IsEmpty())
  105. {
  106. if (i == 1) // no multiselect
  107. AfxGetApp()->OpenDocumentFile(newName);
  108. break;
  109. }
  110. // build full file path
  111. strFile = strPath + strFile;
  112. AfxGetApp()->OpenDocumentFile(strFile);
  113. }
  114. }
  115. CDocument* CMSDIDocManager::OpenDocumentFile(LPCTSTR lpszFileName)
  116. {
  117. CMSDIThread* pThread = (CMSDIThread*)AfxGetThread();
  118. if (lpszFileName && pThread->IsKindOf(RUNTIME_CLASS(CMSDIThread)))
  119. {
  120. // get current thread's main window
  121. CFrameWnd* pWnd = (CFrameWnd*)pThread->GetMainWnd();
  122. if (pWnd)
  123. {
  124. CDocument* pDoc = pWnd->GetActiveDocument();
  125. // is the document empty?
  126. if (pDoc && pDoc->GetPathName().IsEmpty() && !pDoc->IsModified())
  127. {
  128. // replace it instead of creating a new one
  129. return pThread->m_pDocManager->OpenDocumentFile(lpszFileName);
  130. }
  131. }
  132. }
  133. CMSDIThread* pNewThread = (CMSDIThread*)RUNTIME_CLASS(CMSDIThread)->CreateObject();
  134. if (lpszFileName)   // pass file path to the new thread
  135. pNewThread->m_strFileOpen = lpszFileName;
  136. else                // number of the new document
  137. pNewThread->m_nDocCnt = m_nDocCnt++;
  138. m_CriticalSection.Lock();
  139. if (pNewThread->CreateThread())
  140. m_ThreadList.AddTail(pNewThread);
  141. m_CriticalSection.Unlock();
  142. PostUpdateNotify(MSDIN_NEW_THREAD);
  143. return NULL;
  144. }
  145. BOOL CMSDIDocManager::DoPromptFileName(CString& fileName, UINT nIDSTitle,
  146. DWORD lFlags, BOOL bOpenFileDialog, CDocTemplate* pTemplate)
  147. {
  148. CMSDIThread* pThread = (CMSDIThread*)AfxGetThread();
  149. ASSERT_KINDOF(CMSDIThread, pThread);
  150. CDocManager* pDocMgr = pThread->m_pDocManager;
  151. ASSERT_KINDOF(CDocManager, pDocMgr);
  152. return pDocMgr->DoPromptFileName(fileName, nIDSTitle, lFlags, bOpenFileDialog, pTemplate);
  153. }
  154. BOOL CMSDIDocManager::OnDDECommand(LPTSTR lpszCommand)
  155. {
  156. CString strCommand = lpszCommand;
  157. if (strCommand.Left(7) == _T("[open(""))
  158. strCommand = strCommand.Mid(7);
  159. else
  160. return FALSE;
  161. int i = strCommand.Find('"');
  162. if (i<0)
  163. return FALSE;
  164. strCommand.ReleaseBuffer(i);
  165. OpenDocumentFile(strCommand);
  166. return TRUE;
  167. }
  168. void CMSDIDocManager::KillAllThreads()
  169. {
  170. m_CriticalSection.Lock();
  171. while (!m_ThreadList.IsEmpty())
  172. {
  173. HANDLE hArray[MAXIMUM_WAIT_OBJECTS];
  174. int nCnt = 0;
  175. POSITION pos = m_ThreadList.GetHeadPosition();
  176. while (pos && nCnt < MAXIMUM_WAIT_OBJECTS)
  177. {
  178. POSITION posPrev = pos;
  179. CMSDIThread* pThread = m_ThreadList.GetNext(pos);
  180. m_ThreadList.RemoveAt(posPrev);
  181. hArray[nCnt++] = pThread->m_hThread;
  182. pThread->m_hThread = NULL;
  183. pThread->m_eventTerminate.SetEvent();
  184. PostThreadMessage(pThread->m_nThreadID, WM_QUIT, 0, 0);
  185. }
  186. // unlock now to prevent deadlock
  187. m_CriticalSection.Unlock();
  188. // wait until all remaining threads terminate
  189. WaitForMultipleObjects(nCnt, hArray, TRUE, INFINITE);
  190. for (int i=0; i<nCnt; i++)
  191. CloseHandle(hArray[i]);
  192. // check once again if there are no threads remaining
  193. // or created in the meantime
  194. m_CriticalSection.Lock();
  195. }
  196. // there are no remaining threads now, we can safely exit
  197. m_CriticalSection.Unlock();
  198. }
  199. void CMSDIDocManager::CloseAllFrames()
  200. {
  201. POSITION pos = m_ThreadList.GetHeadPosition();
  202. while (pos)
  203. {
  204. CWinThread* pThread = m_ThreadList.GetNext(pos);
  205. pThread->GetMainWnd()->PostMessage(WM_CLOSE);
  206. }
  207. }
  208. void CMSDIDocManager::PostMessageToAll(UINT message, WPARAM wParam, LPARAM lParam)
  209. {
  210. m_CriticalSection.Lock();
  211. POSITION pos = m_ThreadList.GetHeadPosition();
  212. while (pos)
  213. {
  214. CWinThread* pThread = m_ThreadList.GetNext(pos);
  215. pThread->PostThreadMessage(message, wParam, lParam);
  216. }
  217. m_CriticalSection.Unlock();
  218. }