Using ATL to Automate an MFC Application
Posted
by Bart De Lathouwer
on August 12th, 2000
- Lets start first to make the application visible. Add a property 'Visible' as a VARIANT_BOOL.
The code should look like this:
//----------------------------------------------- // get & put_Visible //----------------------------------------------- // STDMETHODIMP CAutoATLApp::get_Visible(VARIANT_BOOL *pVal) { METHOD_PROLOGUE_ATL CWnd* pMainWnd = AfxGetMainWnd(); ASSERT(pMainWnd); *pVal = pMainWnd->IsWindowVisible(); return S_OK; } STDMETHODIMP CAutoATLApp::put_Visible(VARIANT_BOOL newVal) { METHOD_PROLOGUE_ATL CWnd* pMainWnd = AfxGetMainWnd(); ASSERT(pMainWnd); pMainWnd->ShowWindow(SW_SHOW); pMainWnd->UpdateWindow(); return S_OK; }
- When i document i created by a client no frame or views are created. To be able to do so we must override CreateNewDocument in CMultiDocTemplate. CreateNewDocument is called from OpenDocumentFile to create a new document. But the document already exists. CrateNewDocument should therefor be altered NOT to create a document.
Create a new class that inherites from CMultiDocTemplate and override CreateNewDocument and add a member variable CDocument* m_pDocument. CreateNewDocument should look like this:
CDocument* CAnotherMultiDocTemplate::CreateNewDocument() { // default implementation constructs one from CRuntimeClass if (m_pDocClass == NULL) { TRACE0("Error: you must override " "CDocTemplate::CreateNewDocument.\n"); ASSERT(FALSE); return NULL; } //----------------------------------------------- // BdL; Document has already been created! // // CDocument* pDocument = // (CDocument*)m_pDocClass->CreateObject(); //----------------------------------------------- if (m_pDocument == NULL) { TRACE1("Warning: Dynamic create of document " "type %hs failed.\n", m_pDocClass->m_lpszClassName); return NULL; } ASSERT_KINDOF(CDocument, m_pDocument); AddDocument(m_pDocument); return m_pDocument; }To make your life a bit more easy, add the header file (AnotherMultiDocTemplate.h) of the new class to stdafx.h
- Alter in InitInstance of the application the DocumentTemplate:
// CMultiDocTemplate* pDocTemplate; // pDocTemplate = new CMultiDocTemplate( to CAnotherMultiDocTemplate* pDocTemplate; pDocTemplate = new CAnotherMultiDocTemplate(
- Add FinalConstruct and FinalRelease to CAutoATLDoc. FinalConstruct will continue to create Frame and View. FinalRelease will the necessary cleanup.
Add the following lines to CAutoAtlDoc.h
HRESULT FinalConstruct(); void FinalRelease();
Add the following lines to CAutoAtlDoc.cpp
HRESULT CAutoATLDoc::FinalConstruct() { METHOD_PROLOGUE_ATL CAutoATLApp* pApp = (CAutoATLApp*)AfxGetApp(); ASSERT_VALID(pApp); // Find document template POSITION pos = pApp->GetFirstDocTemplatePosition(); CAnotherMultiDocTemplate* pDocClass = (CAnotherMultiDocTemplate*)pApp->GetNextDocTemplate(pos); ASSERT_VALID(pDocClass); // Create view and frame pDocClass->m_pDocument = this; pDocClass->OpenDocumentFile(NULL, true); return S_OK; } void CAutoATLDoc::FinalRelease() { // Do will still have a View connected? // (The frame will no longer exist if the document // has been closed manually, because the OnClose // message is passed BEFORE deleting the document) POSITION pos = GetFirstViewPosition(); if (pos != NULL) { // Prevent the document from deleting itself already. m_bAutoDelete = false; OnCloseDocument(); m_bAutoDelete = true; } } - In the application override OnFileOpen, OnFileNew and OpenDocumentFile. Normally OnFileOpen and OnFileNew create a document AND the frame and view. Now the frame and view are now created in the FinalConstruct of CAutoAtlDoc.
//----------------------------------------------- // //----------------------------------------------- // void CAutoATLApp::OnFileNew() { // Dynamically create a new CFuchiaDocument. // The document will continue to create itself // in the constructor. IMPLEMENT_CREATE_DOCUMENT; } void CAutoATLApp::OnFileOpen() { // prompt the user (with all document templates) CString _lpszPathName; if (!DoPromptFileName(_lpszPathName, AFX_IDS_OPENFILE, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, TRUE, NULL)) return; // open cancelled OpenDocumentFile(_lpszPathName); } CDocument* CAutoATLApp::OpenDocumentFile(LPCTSTR lpszFileName) { // Dynamically create a new CFuchiaDocument. // The document will continue to create itself // in the constructor. IMPLEMENT_CREATE_DOCUMENT; // Open an existing document CWaitCursor wait; if ( !pDoc->OnOpenDocument( lpszFileName ) ) { // Unable to open the document. TRACE( "Unable to open the document \ in %s at %d.\n", THIS_FILE, __LINE__ ); // We must delete the document instance. pDoc->Release(); return NULL; } // Set the document file path and name. pDoc->SetPathName(lpszFileName); return pDoc; }
- IMPLEMENT_CREATE_DOCUMENT is a macro you can put on top in the document header file.
//----------------------------------------------- // Call this MACRO when you need to create a new Document. // The document will construct itself further inside // FinalConstruct. #define IMPLEMENT_CREATE_DOCUMENT \ CComObject
* pDoc; \ HRESULT hr = CComObject ::CreateInstance(&pDoc); \ ASSERT(SUCCEEDED(hr)); \ pDoc->InternalAddRef(); //-----------------------------------------------

Comments
There are no comments yet. Be the first to comment!