// TangramLittle Library - version 1.0
// Author: Sunhui
// Modified by:
// Created: 2005-04-06
// Copyright: (c) Sunhui
// Licence: wxWindows licence
//
// This source code is a part of Tangram library.
// The use and distribution terms for this software are covered by the
// The wxWindows Library Licence (http://opensource.org/licenses/wxwindows.php)
// which can be found in the file licence.txt at the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by
// the terms of this license. You must not remove this notice, or
// any other, from this software.
// XDocument.cpp : implementation file
//
#include "stdafx.h"
#include "dotnetextimpl.h"
#include "XDocument.h"
/*#include "TangramCntrItem.h"
BEGIN_INTERFACE_MAP(CAXDocContFrameHook, COleFrameHook)
INTERFACE_PART(CAXDocContFrameHook, IID_IOleCommandTarget, OleCommandTarget)
END_INTERFACE_MAP()
STDMETHODIMP_(ULONG) CAXDocContFrameHook::XOleCommandTarget::AddRef()
{
METHOD_PROLOGUE_EX_(CAXDocContFrameHook, OleCommandTarget)
ULONG nResult = (ULONG)pThis->ExternalAddRef();
return nResult;
}
STDMETHODIMP_(ULONG) CAXDocContFrameHook::XOleCommandTarget::Release()
{
METHOD_PROLOGUE_EX_(CAXDocContFrameHook, OleCommandTarget)
ULONG nResult = (ULONG)pThis->ExternalRelease();
return nResult;
}
STDMETHODIMP CAXDocContFrameHook::XOleCommandTarget::QueryInterface(
REFIID iid, LPVOID* ppvObj)
{
METHOD_PROLOGUE_EX_(CAXDocContFrameHook, OleCommandTarget)
HRESULT hr = (HRESULT)pThis->ExternalQueryInterface(&iid, ppvObj);
return hr;
}
/*
* IOleCommandTarget methods, provided to make PowerPoint happy
* with this frame.
*/
/*STDMETHODIMP CAXDocContFrameHook::XOleCommandTarget::QueryStatus( const GUID* pguidCmdGroup, ULONG cCmds, OLECMD rgCmds[],
OLECMDTEXT* pcmdtext)
{
METHOD_PROLOGUE_EX_(CAXDocContFrameHook, OleCommandTarget)
HRESULT hr=NOERROR;
COleCmdUI state(rgCmds, cCmds, pguidCmdGroup);
if (pcmdtext == NULL)
state.m_nCmdTextFlag = 0;
else
state.m_nCmdTextFlag = pcmdtext->cmdtextf;
for (state.m_nIndex = 0; state.m_nIndex < cCmds; state.m_nIndex++)
{
state.m_nID = rgCmds[state.m_nIndex].cmdID;
state.DoUpdate(g_pDotNetExtImpl->m_pCurDoc->m_pFrame->GetParentFrame(), TRUE);
}
if (pcmdtext != NULL && pcmdtext->rgwz != NULL &&
(pcmdtext->cmdtextf != OLECMDTEXTF_NONE))
{
USES_CONVERSION;
ASSERT(cCmds == 1);
state.m_strText = state.m_strText.Right(pcmdtext->cwBuf-1);
pcmdtext->cwActual = state.m_strText.GetLength();
#ifdef _UNICODE
lstrcpyW(pcmdtext->rgwz, (LPCTSTR) state.m_strText);
#elif defined(OLE2ANSI)
lstrcpy(pcmdtext->rgwz, state.m_strText);
#else
lstrcpyW(pcmdtext->rgwz, T2W((LPCTSTR) state.m_strText));
#endif
}
return hr;
}
STDMETHODIMP CAXDocContFrameHook::XOleCommandTarget::Exec(const GUID* pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt,
VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
{
METHOD_PROLOGUE_EX_(CAXDocContFrameHook, OleCommandTarget);
HRESULT hr=NOERROR;
OLECMD cmd;
COleCmdUI state(&cmd, 1, pguidCmdGroup);
state.m_nIndex = 0;
cmd.cmdf = 0;
cmd.cmdID = nCmdID;
state.m_nID = nCmdID;
// help via Doc Object targeting is not supported
if (nCmdExecOpt == OLECMDEXECOPT_SHOWHELP)
hr = OLECMDERR_E_DISABLED;
else
{
// is the command supported?
if (!state.DoUpdate(g_pDotNetExtImpl->m_pCurDoc->m_pFrame->GetParentFrame(), TRUE))
hr = OLECMDERR_E_NOTSUPPORTED;
else
{
if (cmd.cmdf & OLECMDF_ENABLED)
{
if (g_pDotNetExtImpl->m_pCurDoc->m_pFrame->GetParentFrame()->OnCmdMsg(state.m_nID, CN_COMMAND, NULL, NULL))
hr = S_OK;
else
hr = E_FAIL;
}
else
hr = OLECMDERR_E_DISABLED;
}
}
return hr;
}
BOOL CAXDocContFrameHook::OnDocActivate(BOOL bActive)
{
ASSERT_VALID(this);
if (m_lpActiveObject == NULL)
return TRUE;
// allow server to do document activation related actions
m_lpActiveObject->OnDocWindowActivate(bActive);
// make sure window caption gets updated later
COleFrameHook* pNotifyHook = m_pActiveItem->m_pInPlaceFrame;
if(pNotifyHook==NULL)return TRUE;
pNotifyHook->m_pFrameWnd->DelayUpdateFrameTitle();
if (!bActive)
{
// clear border space
pNotifyHook->m_xOleInPlaceFrame.SetBorderSpace(NULL);
if (m_pActiveItem->m_pInPlaceDoc != NULL)
m_pActiveItem->m_pInPlaceDoc->m_xOleInPlaceFrame.SetBorderSpace(NULL);
// remove the menu hook when the doc is not active
pNotifyHook->m_xOleInPlaceFrame.SetMenu(NULL, NULL, NULL);
// unhook top-level frame if not needed
if (pNotifyHook != this)pNotifyHook->m_pFrameWnd->m_pNotifyHook = NULL;
}
else
pNotifyHook->m_pFrameWnd->m_pNotifyHook = pNotifyHook;
// don't do default if activating
return bActive;
}
*/
// CXDocument
IMPLEMENT_DYNCREATE(CXDocument, COleDocument)
CXDocument::CXDocument()
{
EnableCompoundFile(TRUE);
g_pDotNetExtImpl->m_nDocCount++;
m_nVbaObjID = -1;
m_bMainDoc = false;
m_bVBAPrj = false;
m_pVbaConnector = NULL;
m_pFrame = NULL;
if(g_pDotNetExtImpl)
{
g_pDotNetExtImpl->m_pCurDoc = this;
//Support VBA:
if(g_pDotNetExtImpl->m_pVbaProjectRuntimeClass)
{
m_pVbaConnector = (CVbaProjectConnector*)g_pDotNetExtImpl->m_pVbaProjectRuntimeClass->CreateObject();
m_pVbaConnector->m_pDoc=this;
}
}
}
BOOL CXDocument::OnNewDocument()
{
if (!COleDocument::OnNewDocument())
return FALSE;
//Support VBA:
if(m_pVbaConnector)
{
BOOL bRet=false;
bRet = m_pVbaConnector->OnNewDocument();
m_pVbaConnector->SetupReference();
return bRet;
}
SetModifiedFlag(FALSE);
UpdateAllViews(NULL);
return TRUE;
}
CXDocument::~CXDocument()
{
//Support VBA:
if(m_pVbaConnector)
delete m_pVbaConnector;
}
BEGIN_MESSAGE_MAP(CXDocument, COleDocument)
END_MESSAGE_MAP()
void CXDocument::LoadFromStorage()
{
if(m_pVbaConnector)
m_pVbaConnector->LoadFromStorage();
else
COleDocument::LoadFromStorage();
}
void CXDocument::SaveToStorage(CObject* pObject)
{
if(m_pVbaConnector)
m_pVbaConnector->SaveToStorage(pObject);
else
COleDocument::SaveToStorage(pObject);
}
IStorage* CXDocument::GetStorage()
{
return m_lpRootStg;
}
BOOL CXDocument::GetRemember()
{
return m_bRemember;
}
BOOL CXDocument::GetSaveState()
{
return m_bSameAsLoad;
}
// CXDocument diagnostics
#ifdef _DEBUG
void CXDocument::AssertValid() const
{
COleDocument::AssertValid();
}
void CXDocument::Dump(CDumpContext& dc) const
{
COleDocument::Dump(dc);
}
#endif //_DEBUG
// CXDocument serialization
void CXDocument::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
ar << m_nVbaObjID;
}
else
{
// TODO: add loading code here
ar >> m_nVbaObjID;
}
COleDocument::Serialize(ar);
}
// CXDocument commands
IDispatch* CXDocument::GetDocDisp(void)
{
return NULL;
}
void CXDocument::OnExternalCommand(LPCTSTR command, LPCTSTR args)
{
TRACE(_T("Call CXDocument OnExternalCommand: %s, %s\r\n"),command,args);
// TODO: Add your message handler code here
}
BOOL CXDocument::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!COleDocument::OnOpenDocument(lpszPathName))
return FALSE;
if(m_pVbaConnector)
{
m_pVbaConnector->m_pDoc->m_bVBAPrj = true;
m_pVbaConnector->SetupReference();
}
// TODO: Add your specialized creation code here
return TRUE;
}
BOOL CXDocument::OnSaveDocument(LPCTSTR lpszPathName)
{
USES_CONVERSION;
if(!m_bMainDoc)
{
if (!COleDocument::OnSaveDocument(lpszPathName))
return FALSE;
}
else
{
// use helper to save to root storage
LPSTORAGE lpOrigStg = NULL;
BOOL bResult = FALSE;
// open new root storage if necessary
m_bSameAsLoad=false;
if (lpszPathName != NULL && !m_bSameAsLoad)
{
// temporarily detach current storage|STGM_SHARE_DENY_WRITE
lpOrigStg = m_lpRootStg;
m_lpRootStg = NULL;
LPSTORAGE lpStorage;
SCODE sc = ::StgCreateDocfile(T2COLE(lpszPathName),
STGM_READWRITE|STGM_TRANSACTED|STGM_CREATE,
0, &lpStorage);
if (sc != S_OK)
AfxThrowOleException(sc);
ASSERT(lpStorage != NULL);
m_lpRootStg = lpStorage;
lpOrigStg->CopyTo(0,NULL,NULL,m_lpRootStg);
sc = m_lpRootStg->Commit(STGC_DEFAULT);
if (sc != S_OK)
AfxThrowOleException(sc);
}
ASSERT(m_lpRootStg != NULL);
// create Contents stream
COleStreamFile file;
CFileException fe;
if (!file.CreateStream(m_lpRootStg, _T("Contents"),
CFile::modeReadWrite|CFile::shareExclusive|CFile::modeCreate, &fe))
{
if (fe.m_cause == CFileException::fileNotFound)
AfxThrowArchiveException(CArchiveException::badSchema);
else
AfxThrowFileException(fe.m_cause, fe.m_lOsError);
}
// save to Contents stream
CArchive saveArchive(&file, CArchive::store | CArchive::bNoFlushOnDelete);
saveArchive.m_pDocument = this;
saveArchive.m_bForceFlat = FALSE;
BOOL fNeedSaveCompleted = FALSE;
TRY
{
if(m_pVbaConnector)
fNeedSaveCompleted=m_pVbaConnector->SaveMainDoc(&saveArchive,true);
else
{
// save the contents
Serialize(saveArchive);
}
saveArchive.Close();
file.Close();
// commit the root storage
SCODE sc = m_lpRootStg->Commit(STGC_DEFAULT);
if (sc != S_OK)
AfxThrowOleException(sc);
}
CATCH_ALL(e)
{
if(m_pVbaConnector&&fNeedSaveCompleted)
m_pVbaConnector->SaveMainDoc(&saveArchive,false);
file.Abort(); // will not throw an exception
CommitItems(FALSE); // abort save in progress
//NO_CPP_EXCEPTION(saveArchive.Abort());
THROW_LAST();
}
END_CATCH_ALL
if (lpszPathName != NULL)
{
// commit each of the items
CommitItems(m_bRemember && !m_bSameAsLoad);
// mark document as clean if remembering the storage
if (m_bRemember)
SetModifiedFlag(FALSE);
// remember correct storage or release save copy as storage
if (!m_bSameAsLoad)
{
if (m_bRemember)
{
// Save As case -- m_stgRoot is new storage, forget old storage
lpOrigStg->Release();
}
else
{
// Save Copy As case -- m_stgRoot should hook up to m_stgOrig.
m_lpRootStg->Release();
m_lpRootStg = lpOrigStg;
}
}
}
}
SetModifiedFlag(FALSE);
return TRUE;
}
void CXDocument::DeleteContents()
{
//Support VBA :
if(m_pVbaConnector)
m_pVbaConnector->Close();
COleDocument::DeleteContents();
}