docmulti.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #ifdef AFX_CORE2_SEG
  12. #pragma code_seg(AFX_CORE2_SEG)
  13. #endif
  14. #ifdef _DEBUG
  15. #undef THIS_FILE
  16. static char THIS_FILE[] = __FILE__;
  17. #endif
  18. #define new DEBUG_NEW
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CMultiDocTemplate construction/destruction
  21. CMultiDocTemplate::CMultiDocTemplate(UINT nIDResource, CRuntimeClass* pDocClass,
  22. CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass)
  23. : CDocTemplate(nIDResource, pDocClass, pFrameClass, pViewClass)
  24. {
  25. ASSERT(m_docList.IsEmpty());
  26. m_hMenuShared = NULL;
  27. m_hAccelTable = NULL;
  28. m_nUntitledCount = 0; // start at 1
  29. // load resources in constructor if not statically allocated
  30. if (!CDocManager::bStaticInit)
  31. LoadTemplate();
  32. }
  33. void CMultiDocTemplate::LoadTemplate()
  34. {
  35. CDocTemplate::LoadTemplate();
  36. if (m_nIDResource != 0 && m_hMenuShared == NULL)
  37. {
  38. HINSTANCE hInst = AfxFindResourceHandle(
  39. MAKEINTRESOURCE(m_nIDResource), RT_MENU);
  40. m_hMenuShared = ::LoadMenu(hInst, MAKEINTRESOURCE(m_nIDResource));
  41. m_hAccelTable =
  42. ::LoadAccelerators(hInst, MAKEINTRESOURCE(m_nIDResource));
  43. }
  44. #ifdef _DEBUG
  45. // warnings about missing components (don't bother with accelerators)
  46. if (m_hMenuShared == NULL)
  47. TRACE1("Warning: no shared menu for document template #%d.\n",
  48. m_nIDResource);
  49. #endif //_DEBUG
  50. }
  51. CMultiDocTemplate::~CMultiDocTemplate()
  52. {
  53. #ifdef _DEBUG
  54. if (!m_docList.IsEmpty())
  55. TRACE1("Warning: destroying CMultiDocTemplate with %d documents alive.\n",
  56. m_docList.GetCount());
  57. #endif
  58. // delete shared components
  59. if (m_hMenuShared != NULL)
  60. ::DestroyMenu(m_hMenuShared);
  61. if (m_hAccelTable != NULL)
  62. ::FreeResource((HGLOBAL)m_hAccelTable);
  63. }
  64. /////////////////////////////////////////////////////////////////////////////
  65. // CMultiDocTemplate attributes
  66. POSITION CMultiDocTemplate::GetFirstDocPosition() const
  67. {
  68. return m_docList.GetHeadPosition();
  69. }
  70. CDocument* CMultiDocTemplate::GetNextDoc(POSITION& rPos) const
  71. {
  72. return (CDocument*)m_docList.GetNext(rPos);
  73. }
  74. /////////////////////////////////////////////////////////////////////////////
  75. // CMultiDocTemplate document management (a list of currently open documents)
  76. void CMultiDocTemplate::AddDocument(CDocument* pDoc)
  77. {
  78. ASSERT_VALID(pDoc);
  79. CDocTemplate::AddDocument(pDoc);
  80. ASSERT(m_docList.Find(pDoc, NULL) == NULL); // must not be in list
  81. m_docList.AddTail(pDoc);
  82. }
  83. void CMultiDocTemplate::RemoveDocument(CDocument* pDoc)
  84. {
  85. ASSERT_VALID(pDoc);
  86. CDocTemplate::RemoveDocument(pDoc);
  87. m_docList.RemoveAt(m_docList.Find(pDoc));
  88. }
  89. /////////////////////////////////////////////////////////////////////////////
  90. // CMultiDocTemplate commands
  91. CDocument* CMultiDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName,
  92. BOOL bMakeVisible)
  93. {
  94. CDocument* pDocument = CreateNewDocument();
  95. if (pDocument == NULL)
  96. {
  97. TRACE0("CDocTemplate::CreateNewDocument returned NULL.\n");
  98. AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
  99. return NULL;
  100. }
  101. ASSERT_VALID(pDocument);
  102. BOOL bAutoDelete = pDocument->m_bAutoDelete;
  103. pDocument->m_bAutoDelete = FALSE; // don't destroy if something goes wrong
  104. CFrameWnd* pFrame = CreateNewFrame(pDocument, NULL);
  105. pDocument->m_bAutoDelete = bAutoDelete;
  106. if (pFrame == NULL)
  107. {
  108. AfxMessageBox(AFX_IDP_FAILED_TO_CREATE_DOC);
  109. delete pDocument; // explicit delete on error
  110. return NULL;
  111. }
  112. ASSERT_VALID(pFrame);
  113. if (lpszPathName == NULL)
  114. {
  115. // create a new document - with default document name
  116. SetDefaultTitle(pDocument);
  117. // avoid creating temporary compound file when starting up invisible
  118. if (!bMakeVisible)
  119. pDocument->m_bEmbedded = TRUE;
  120. if (!pDocument->OnNewDocument())
  121. {
  122. // user has be alerted to what failed in OnNewDocument
  123. TRACE0("CDocument::OnNewDocument returned FALSE.\n");
  124. pFrame->DestroyWindow();
  125. return NULL;
  126. }
  127. // it worked, now bump untitled count
  128. m_nUntitledCount++;
  129. }
  130. else
  131. {
  132. // open an existing document
  133. CWaitCursor wait;
  134. if (!pDocument->OnOpenDocument(lpszPathName))
  135. {
  136. // user has be alerted to what failed in OnOpenDocument
  137. TRACE0("CDocument::OnOpenDocument returned FALSE.\n");
  138. pFrame->DestroyWindow();
  139. return NULL;
  140. }
  141. pDocument->SetPathName(lpszPathName);
  142. }
  143. InitialUpdateFrame(pFrame, pDocument, bMakeVisible);
  144. return pDocument;
  145. }
  146. void CMultiDocTemplate::SetDefaultTitle(CDocument* pDocument)
  147. {
  148. CString strDocName;
  149. if (GetDocString(strDocName, CDocTemplate::docName) &&
  150. !strDocName.IsEmpty())
  151. {
  152. TCHAR szNum[8];
  153. wsprintf(szNum, _T("%d"), m_nUntitledCount+1);
  154. strDocName += szNum;
  155. }
  156. else
  157. {
  158. // use generic 'untitled' - ignore untitled count
  159. VERIFY(strDocName.LoadString(AFX_IDS_UNTITLED));
  160. }
  161. pDocument->SetTitle(strDocName);
  162. }
  163. /////////////////////////////////////////////////////////////////////////////
  164. // CMultiDocTemplate diagnostics
  165. #ifdef _DEBUG
  166. void CMultiDocTemplate::Dump(CDumpContext& dc) const
  167. {
  168. CDocTemplate::Dump(dc);
  169. dc << "m_hMenuShared = " << (UINT)m_hMenuShared;
  170. dc << "\nm_hAccelTable = " << (UINT)m_hAccelTable;
  171. dc << "\nm_nUntitledCount = " << m_nUntitledCount;
  172. dc << "\nwith " << m_docList.GetCount() << " open documents";
  173. POSITION pos = GetFirstDocPosition();
  174. while (pos != NULL)
  175. {
  176. CDocument* pDoc = GetNextDoc(pos);
  177. dc << "\nwith document " << (void*)pDoc;
  178. }
  179. dc << "\n";
  180. }
  181. void CMultiDocTemplate::AssertValid() const
  182. {
  183. CDocTemplate::AssertValid();
  184. POSITION pos = GetFirstDocPosition();
  185. while (pos != NULL)
  186. {
  187. CDocument* pDoc = GetNextDoc(pos);
  188. ASSERT_VALID(pDoc);
  189. }
  190. }
  191. #endif //_DEBUG
  192. #ifdef AFX_INIT_SEG
  193. #pragma code_seg(AFX_INIT_SEG)
  194. #endif
  195. IMPLEMENT_DYNAMIC(CMultiDocTemplate, CDocTemplate)
  196. /////////////////////////////////////////////////////////////////////////////