You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1114 lines
39 KiB
1114 lines
39 KiB
// Document.cpp : Implementation of CTriEditDocument
|
|
// Copyright (c)1997-1999 Microsoft Corporation, All Rights Reserved
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include "triedit.h"
|
|
#include "Document.h"
|
|
#include "util.h"
|
|
|
|
#ifdef IE5_SPACING
|
|
#include "dispatch.h"
|
|
#include <mshtmdid.h>
|
|
#include <mshtmcid.h>
|
|
#endif //IE5_SPACING
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTriEditDocument
|
|
|
|
CTriEditDocument::CTriEditDocument()
|
|
{
|
|
m_pUnkTrident = NULL;
|
|
m_pOleObjTrident = NULL;
|
|
m_pCmdTgtTrident = NULL;
|
|
m_pDropTgtTrident = NULL;
|
|
#ifdef IE5_SPACING
|
|
m_pTridentPersistStreamInit = NULL;
|
|
m_pMapArray = NULL;
|
|
m_hgMap = NULL;
|
|
m_pspNonDSP = NULL;
|
|
m_hgSpacingNonDSP = NULL;
|
|
m_ichspNonDSPMax = 0;
|
|
m_ichspNonDSP = 0;
|
|
#endif //IE5_SPACING
|
|
|
|
m_pClientSiteHost = NULL;
|
|
m_pUIHandlerHost = NULL;
|
|
m_pDragDropHandlerHost = NULL;
|
|
|
|
m_pUIHandler = NULL;
|
|
|
|
m_pTokenizer = NULL;
|
|
m_hwndTrident = NULL;
|
|
|
|
m_fUIHandlerSet = FALSE;
|
|
m_fInContextMenu = FALSE;
|
|
|
|
m_fDragRectVisible = FALSE;
|
|
m_fConstrain = FALSE;
|
|
m_f2dDropMode = FALSE;
|
|
m_eDirection = CONSTRAIN_NONE;
|
|
m_ptAlign.x = 1;
|
|
m_ptAlign.y = 1;
|
|
m_pihtmlElement = NULL;
|
|
m_pihtmlStyle = NULL;
|
|
m_hbrDragRect = NULL;
|
|
m_fLocked = FALSE;
|
|
m_hgDocRestore = NULL;
|
|
}
|
|
|
|
HRESULT CTriEditDocument::FinalConstruct()
|
|
{
|
|
HRESULT hr;
|
|
IUnknown *pUnk = GetControllingUnknown();
|
|
|
|
hr = CoCreateInstance(CLSID_HTMLDocument, pUnk, CLSCTX_INPROC_SERVER,
|
|
IID_IUnknown, (void**)&m_pUnkTrident);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
_ASSERTE(NULL != m_pUnkTrident);
|
|
|
|
// When we cache Trident pointers, we do a GetControllingUnknown()->Release()
|
|
// since the addref will increment our outer unknown pointer and not Trident
|
|
// We compensate for this by doing a corresponding GetControllingUnknown()->AddRef()
|
|
// in our FinalRelease. Though these cancel out, it is necessary to do this in order
|
|
// to ensure that our FinalRelease will get called.
|
|
|
|
// Cache Trident's IOleObject pointer
|
|
|
|
hr = m_pUnkTrident->QueryInterface(IID_IOleObject, (void **)&m_pOleObjTrident);
|
|
_ASSERTE(S_OK == hr && NULL != m_pOleObjTrident);
|
|
pUnk->Release();
|
|
|
|
// Cache Trident's IOleCommandTarget pointer
|
|
|
|
hr = m_pUnkTrident->QueryInterface(IID_IOleCommandTarget, (void **)&m_pCmdTgtTrident);
|
|
_ASSERTE(S_OK == hr && NULL != m_pCmdTgtTrident);
|
|
pUnk->Release();
|
|
|
|
// Allocate UI handler sub-object
|
|
m_pUIHandler = new CTriEditUIHandler(this);
|
|
if (NULL == m_pUIHandler)
|
|
hr = E_OUTOFMEMORY;
|
|
|
|
#ifdef IE5_SPACING
|
|
// Get IPersistStreamInit
|
|
hr = m_pUnkTrident->QueryInterface(IID_IPersistStreamInit, (void **) &m_pTridentPersistStreamInit);
|
|
_ASSERTE(S_OK == hr && NULL != m_pTridentPersistStreamInit);
|
|
pUnk->Release(); // PuruK - REVIEW Why do we need to do this?
|
|
SetFilterInDone(FALSE);
|
|
#endif //IE5_SPACING
|
|
|
|
// Allocate buffer for saving document's contents before <BODY> tag
|
|
// Trident replaces all content before <BODY> tag by its own header
|
|
m_hgDocRestore = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, cbHeader);
|
|
if (NULL == m_hgDocRestore)
|
|
{
|
|
delete m_pUIHandler;
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
}
|
|
|
|
_ASSERTE(SUCCEEDED(hr));
|
|
|
|
return hr;
|
|
}
|
|
|
|
void CTriEditDocument::FinalRelease()
|
|
{
|
|
IUnknown *pUnk = GetControllingUnknown();
|
|
|
|
// Release host interface pointers
|
|
SAFERELEASE(m_pClientSiteHost);
|
|
SAFERELEASE(m_pUIHandlerHost);
|
|
SAFERELEASE(m_pDragDropHandlerHost);
|
|
|
|
// Release internal interface pointers
|
|
SAFERELEASE(m_pTokenizer);
|
|
|
|
// Release 2d drop related pointers
|
|
ReleaseElement();
|
|
|
|
// Release Trident interface pointers
|
|
SAFERELEASE(m_pDropTgtTrident);
|
|
|
|
pUnk->AddRef();
|
|
SAFERELEASE(m_pOleObjTrident);
|
|
pUnk->AddRef();
|
|
SAFERELEASE(m_pCmdTgtTrident);
|
|
#ifdef IE5_SPACING
|
|
pUnk->AddRef(); // REVIEW - PuruK - Why do we need to do this?
|
|
SAFERELEASE(m_pTridentPersistStreamInit);
|
|
#endif //IE5_SPACING
|
|
|
|
SAFERELEASE(m_pUnkTrident);
|
|
|
|
// Delete UI handler sub-object
|
|
if (m_pUIHandler != NULL)
|
|
{
|
|
// Assert that the ref count on the sub-object is 1
|
|
// If this isn't 1, then Trident is holding on to this pointer
|
|
_ASSERTE(m_pUIHandler->m_cRef == 1);
|
|
delete m_pUIHandler;
|
|
}
|
|
|
|
if (m_hgDocRestore != NULL)
|
|
{
|
|
GlobalUnlock(m_hgDocRestore);
|
|
GlobalFree(m_hgDocRestore);
|
|
}
|
|
|
|
#ifdef IE5_SPACING
|
|
if (m_hgMap != NULL)
|
|
{
|
|
GlobalUnlock(m_hgMap);
|
|
GlobalFree(m_hgMap);
|
|
m_hgMap = NULL;
|
|
}
|
|
if (m_hgSpacingNonDSP != NULL)
|
|
{
|
|
GlobalUnlock(m_hgSpacingNonDSP);
|
|
GlobalFree(m_hgSpacingNonDSP);
|
|
m_hgSpacingNonDSP = NULL;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#ifdef IE5_SPACING
|
|
void CTriEditDocument::FillUniqueID(BSTR bstrUniqueID, BSTR bstrDspVal, int ichNonDSP, MAPSTRUCT *pMap, int iMapCur, BOOL fLowerCase, int iType)
|
|
{
|
|
memcpy((BYTE *)pMap[iMapCur].szUniqueID, (BYTE *)bstrUniqueID, min(wcslen(bstrUniqueID), cchID)*sizeof(WCHAR));
|
|
if (iType == INDEX_DSP)
|
|
{
|
|
memcpy((BYTE *)pMap[iMapCur].szDspID, (BYTE *)bstrDspVal, min(wcslen(bstrDspVal), cchID)*sizeof(WCHAR));
|
|
_ASSERTE(ichNonDSP == -1);
|
|
pMap[iMapCur].ichNonDSP = ichNonDSP;
|
|
}
|
|
else if (iType == INDEX_COMMENT)
|
|
{
|
|
pMap[iMapCur].ichNonDSP = ichNonDSP;
|
|
}
|
|
else if (iType == INDEX_AIMGLINK)
|
|
{
|
|
memcpy((BYTE *)pMap[iMapCur].szDspID, (BYTE *)bstrDspVal, min(wcslen(bstrDspVal), cchID)*sizeof(WCHAR));
|
|
pMap[iMapCur].ichNonDSP = ichNonDSP;
|
|
}
|
|
else if (iType == INDEX_OBJ_COMMENT)
|
|
{
|
|
pMap[iMapCur].ichNonDSP = ichNonDSP;
|
|
}
|
|
else
|
|
_ASSERTE(FALSE);
|
|
pMap[iMapCur].fLowerCase = fLowerCase;
|
|
_ASSERTE(iType >= INDEX_NIL && iType < INDEX_MAX);
|
|
pMap[iMapCur].iType = iType;
|
|
}
|
|
|
|
BOOL CTriEditDocument::FGetSavedDSP(BSTR bstrUniqueID, BSTR *pbstrDspVal, int *pichNonDSP, MAPSTRUCT *pMap, BOOL *pfLowerCase, int *pIndex)
|
|
{
|
|
BOOL fRet = FALSE;
|
|
int i;
|
|
|
|
// TODO - find a faster way than this linear search...
|
|
for (i = 0; i < m_iMapCur; i++)
|
|
{
|
|
if (0 == _wcsnicmp(pMap[i].szUniqueID, bstrUniqueID, wcslen(bstrUniqueID)))
|
|
{
|
|
fRet = TRUE;
|
|
if (pMap[i].iType == INDEX_DSP)
|
|
{
|
|
*pbstrDspVal = SysAllocString(pMap[i].szDspID);
|
|
*pichNonDSP = -1;
|
|
}
|
|
else if (pMap[i].iType == INDEX_COMMENT)
|
|
{
|
|
*pbstrDspVal = (BSTR)NULL;
|
|
*pichNonDSP = pMap[i].ichNonDSP;
|
|
}
|
|
else if (pMap[i].iType == INDEX_AIMGLINK)
|
|
{
|
|
*pbstrDspVal = SysAllocString(pMap[i].szDspID);
|
|
*pichNonDSP = pMap[i].ichNonDSP;
|
|
_ASSERTE(*pichNonDSP != -1);
|
|
}
|
|
else if (pMap[i].iType == INDEX_OBJ_COMMENT)
|
|
{
|
|
*pbstrDspVal = (BSTR)NULL;
|
|
*pichNonDSP = pMap[i].ichNonDSP;
|
|
_ASSERTE(*pichNonDSP != -1);
|
|
}
|
|
*pfLowerCase = pMap[i].fLowerCase;
|
|
*pIndex = pMap[i].iType;
|
|
|
|
goto LRet;
|
|
}
|
|
}
|
|
|
|
LRet:
|
|
return(fRet);
|
|
}
|
|
|
|
void
|
|
CTriEditDocument::FillNonDSPData(BSTR pOuterTag)
|
|
{
|
|
int len = 0;
|
|
|
|
_ASSERTE(m_ichspNonDSPMax != -1);
|
|
_ASSERTE(m_ichspNonDSP != -1);
|
|
_ASSERTE(m_hgSpacingNonDSP != NULL);
|
|
_ASSERTE(m_pspNonDSP != NULL);
|
|
|
|
// even if pOuterTag is NULL, we still need to store the fact that we have
|
|
// zero bytes of data.
|
|
if (pOuterTag != NULL)
|
|
len = wcslen(pOuterTag);
|
|
|
|
if ((int)(m_ichspNonDSP + len + sizeof(int)) > m_ichspNonDSPMax)
|
|
{
|
|
HGLOBAL hgSpacingNonDSP;
|
|
|
|
//reallocate & set m_ichspNonDSPMax
|
|
GlobalUnlock(m_hgSpacingNonDSP);
|
|
hgSpacingNonDSP = m_hgSpacingNonDSP;
|
|
#pragma prefast(suppress: 308, "noise")
|
|
m_hgSpacingNonDSP = GlobalReAlloc(m_hgSpacingNonDSP, (m_ichspNonDSP + len + sizeof(int)+MIN_SP_NONDSP)*sizeof(WCHAR), GMEM_MOVEABLE|GMEM_ZEROINIT);
|
|
// if this alloc failed, we may still want to continue
|
|
if (m_hgSpacingNonDSP == NULL)
|
|
{
|
|
GlobalFree(hgSpacingNonDSP);
|
|
goto LRet;
|
|
}
|
|
else
|
|
{
|
|
m_pspNonDSP = (WCHAR *)GlobalLock(m_hgSpacingNonDSP);
|
|
_ASSERTE(m_pspNonDSP != NULL);
|
|
m_ichspNonDSPMax = (m_ichspNonDSP + len + sizeof(int)+MIN_SP_NONDSP);
|
|
}
|
|
_ASSERTE(m_ichspNonDSP < m_ichspNonDSPMax);
|
|
}
|
|
|
|
memcpy((BYTE *)(m_pspNonDSP+m_ichspNonDSP), (BYTE *)&len, sizeof(int));
|
|
m_ichspNonDSP += sizeof(int)/sizeof(WCHAR);
|
|
memcpy((BYTE *)(m_pspNonDSP+m_ichspNonDSP), (BYTE *)pOuterTag, len*sizeof(WCHAR));
|
|
m_ichspNonDSP += len;
|
|
|
|
LRet:
|
|
return;
|
|
|
|
}
|
|
|
|
void
|
|
CTriEditDocument::ReSetinnerHTMLComment(IHTMLCommentElement *pCommentElement, IHTMLElement* /*pElement*/, int ichspNonDSP)
|
|
{
|
|
WCHAR *pStrComment = NULL;
|
|
//#ifdef DEBUG
|
|
// CComBSTR bstrOuter, bstrOuterBefore;
|
|
//#endif //DEBUG
|
|
int cchComment = 0;
|
|
|
|
// get the ich, get the saved comment, set it
|
|
memcpy((BYTE *)&cchComment, (BYTE *)(m_pspNonDSP+ichspNonDSP), sizeof(int));
|
|
_ASSERTE(cchComment > 0);
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&bstrOuterBefore);
|
|
//#endif //DEBUG
|
|
pStrComment = new WCHAR[cchComment + 1];
|
|
if (pStrComment == NULL)
|
|
return;
|
|
|
|
memcpy((BYTE *)pStrComment, (BYTE *)(m_pspNonDSP+ichspNonDSP+sizeof(int)/sizeof(WCHAR)), cchComment*sizeof(WCHAR));
|
|
pStrComment[cchComment] = '\0';
|
|
pCommentElement->put_text((BSTR)pStrComment);
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&bstrOuter);
|
|
//#endif //DEBUG
|
|
if (pStrComment)
|
|
delete pStrComment;
|
|
//#ifdef DEBUG
|
|
// bstrOuter.Empty();
|
|
// bstrOuterBefore.Empty();
|
|
//#endif //DEBUG
|
|
|
|
}
|
|
|
|
void
|
|
CTriEditDocument::SetinnerHTMLComment(IHTMLCommentElement *pCommentElement, IHTMLElement* /*pElement*/, BSTR pOuterTag)
|
|
{
|
|
WCHAR *pStr = NULL;
|
|
WCHAR *pStrComment = NULL;
|
|
LPCWSTR rgComment[] =
|
|
{
|
|
L"TRIEDITPRECOMMENT-",
|
|
L"-->",
|
|
L"<!--",
|
|
};
|
|
//#ifdef DEBUG
|
|
// CComBSTR bstrOuter, bstrInnerBefore, bstrInnerAfter, bstrOuterBefore;
|
|
//#endif //DEBUG
|
|
|
|
// special case -
|
|
// send pOuterTag as NULL, if we want to get rid of the comment completely
|
|
if (pOuterTag == NULL)
|
|
{
|
|
pCommentElement->put_text((BSTR)pOuterTag);
|
|
goto LRet;
|
|
}
|
|
|
|
//remove the TRIEDITCOMMENT stuff from pOuterTag and set the outerHTML properly
|
|
pStr = wcsstr(pOuterTag, rgComment[0]);
|
|
if (pStr != NULL)
|
|
{
|
|
pStrComment = new WCHAR[wcslen(pOuterTag)-(SAFE_PTR_DIFF_TO_INT(pStr-pOuterTag)+wcslen(rgComment[0]))+wcslen(rgComment[1])+wcslen(rgComment[2])+1];
|
|
if (pStrComment != NULL)
|
|
{
|
|
memcpy( (BYTE *)pStrComment,
|
|
(BYTE *)(rgComment[2]),
|
|
(wcslen(rgComment[2]))*sizeof(WCHAR)
|
|
);
|
|
memcpy( (BYTE *)(pStrComment+wcslen(rgComment[2])),
|
|
(BYTE *)(pStr+wcslen(rgComment[0])),
|
|
(wcslen(pOuterTag)-(SAFE_PTR_DIFF_TO_INT(pStr-pOuterTag)+wcslen(rgComment[0]))-wcslen(rgComment[1]))*sizeof(WCHAR)
|
|
);
|
|
memcpy( (BYTE *)(pStrComment+wcslen(rgComment[2])+wcslen(pOuterTag)-(pStr-pOuterTag+wcslen(rgComment[0]))-wcslen(rgComment[1])),
|
|
(BYTE *)(rgComment[1]),
|
|
(wcslen(rgComment[1]))*sizeof(WCHAR)
|
|
);
|
|
pStrComment[wcslen(pOuterTag)-(pStr-pOuterTag+wcslen(rgComment[0]))-wcslen(rgComment[1])+wcslen(rgComment[1])+wcslen(rgComment[2])] = '\0';
|
|
//#ifdef DEBUG
|
|
// pElement->get_innerHTML(&bstrInnerBefore);
|
|
// pElement->get_outerHTML(&bstrOuterBefore);
|
|
//#endif //DEBUG
|
|
pCommentElement->put_text((BSTR)pStrComment);
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&bstrOuter);
|
|
// pElement->get_innerHTML(&bstrInnerAfter);
|
|
//#endif //DEBUG
|
|
delete pStrComment;
|
|
}
|
|
}
|
|
LRet:
|
|
//#ifdef DEBUG
|
|
// bstrOuter.Empty();
|
|
// bstrInnerBefore.Empty();
|
|
// bstrInnerAfter.Empty();
|
|
// bstrOuterBefore.Empty();
|
|
//#endif //DEBUG
|
|
return;
|
|
}
|
|
|
|
void
|
|
CTriEditDocument::RemoveEPComment(IHTMLObjectElement *pObjectElement, BSTR bstrAlt,
|
|
int cch, BSTR *pbstrAltComment, BSTR *pbstrAltNew)
|
|
{
|
|
int ich = 0;
|
|
WCHAR *pAltNew = NULL;
|
|
WCHAR *pStrAlt = bstrAlt;
|
|
WCHAR *pStr = NULL;
|
|
WCHAR *pStrEnd = NULL;
|
|
WCHAR *pStrComment = NULL;
|
|
LPCWSTR rgComment[] =
|
|
{
|
|
L"<!--ERRORPARAM",
|
|
L"ERRORPARAM-->",
|
|
};
|
|
|
|
if (bstrAlt == (BSTR)NULL || pObjectElement == NULL)
|
|
return;
|
|
|
|
// look for ERRORPARAM
|
|
pStr = wcsstr(bstrAlt, rgComment[0]);
|
|
pStrEnd = wcsstr(bstrAlt, rgComment[1]);
|
|
if (pStr != NULL && pStrEnd != NULL)
|
|
{
|
|
pStrEnd += wcslen(rgComment[1]);
|
|
pStrComment = new WCHAR[SAFE_PTR_DIFF_TO_INT(pStrEnd-pStr)+1];
|
|
if (pStrComment == NULL)
|
|
goto LRetNull;
|
|
memcpy((BYTE *)pStrComment, (BYTE *)pStr, SAFE_PTR_DIFF_TO_INT(pStrEnd-pStr)*sizeof(WCHAR));
|
|
pStrComment[pStrEnd-pStr] = '\0';
|
|
*pbstrAltComment = SysAllocString(pStrComment);
|
|
delete pStrComment;
|
|
|
|
pAltNew = new WCHAR[cch+1]; // max size
|
|
if (pAltNew == NULL)
|
|
goto LRetNull;
|
|
// remove stuff from pStr till pStrEnd & copy into *pbstrAltNew
|
|
if (pStr > pStrAlt)
|
|
{
|
|
memcpy((BYTE *)pAltNew, (BYTE *)pStrAlt, SAFE_PTR_DIFF_TO_INT(pStr-pStrAlt)*sizeof(WCHAR));
|
|
ich += SAFE_PTR_DIFF_TO_INT(pStr-pStrAlt);
|
|
}
|
|
if ((pStrAlt+cch)-pStrEnd > 0)
|
|
{
|
|
memcpy((BYTE *)(pAltNew+ich), (BYTE *)pStrEnd, SAFE_PTR_DIFF_TO_INT((pStrAlt+cch)-pStrEnd)*sizeof(WCHAR));
|
|
ich += SAFE_PTR_DIFF_TO_INT((pStrAlt+cch)-pStrEnd);
|
|
}
|
|
pAltNew[ich] = '\0';
|
|
*pbstrAltNew = SysAllocString(pAltNew);
|
|
delete pAltNew;
|
|
}
|
|
else
|
|
{
|
|
LRetNull:
|
|
*pbstrAltNew = (bstrAlt) ? SysAllocString(bstrAlt) : (BSTR)NULL;
|
|
*pbstrAltComment = (BSTR)NULL;
|
|
}
|
|
|
|
} /* CTriEditDocument::RemoveEPComment() */
|
|
|
|
HRESULT
|
|
CTriEditDocument::SetObjectComment(IHTMLObjectElement *pObjectElement, BSTR bstrAltNew)
|
|
{
|
|
HRESULT hr;
|
|
|
|
_ASSERTE(pObjectElement != NULL);
|
|
hr = pObjectElement->put_altHtml(bstrAltNew);
|
|
return(hr);
|
|
|
|
} /* CTriEditDocument::SetObjectComment() */
|
|
|
|
void
|
|
CTriEditDocument::AppendEPComment(IHTMLObjectElement *pObjectElement, int ichspNonDSP)
|
|
{
|
|
CComBSTR bstrAltNew;
|
|
int cch;
|
|
WCHAR *pStrSaved = NULL;
|
|
HRESULT hr;
|
|
|
|
// get current altHtml from the tree
|
|
hr = pObjectElement->get_altHtml(&bstrAltNew);
|
|
if (hr != S_OK || bstrAltNew == (BSTR)NULL)
|
|
goto LRet;
|
|
|
|
// get saved altHtml in m_pspNonDSP
|
|
memcpy((BYTE *)&cch, (BYTE *)(m_pspNonDSP+ichspNonDSP), sizeof(int));
|
|
if (cch <= 0)
|
|
goto LRet;
|
|
pStrSaved = new WCHAR[cch + 1];
|
|
if (pStrSaved == NULL)
|
|
goto LRet;
|
|
memcpy((BYTE *)pStrSaved, (BYTE *)(m_pspNonDSP+ichspNonDSP+sizeof(int)/sizeof(WCHAR)), cch*sizeof(WCHAR));
|
|
pStrSaved[cch] = '\0';
|
|
|
|
// append saved altHtml
|
|
bstrAltNew += pStrSaved;
|
|
|
|
// save it back in the tree
|
|
hr = pObjectElement->put_altHtml(bstrAltNew);
|
|
if (pStrSaved)
|
|
delete pStrSaved;
|
|
|
|
LRet:
|
|
return;
|
|
} /* CTriEditDocument::AppendEPComment() */
|
|
|
|
|
|
void
|
|
CTriEditDocument::MapUniqueID(BOOL fGet)
|
|
{
|
|
CComPtr<IHTMLDocument2> pHTMLDoc;
|
|
CComPtr<IHTMLElementCollection> pHTMLCollection;
|
|
CComPtr<IDispatch> pDispControl;
|
|
CComPtr<IHTMLElement> pElement;
|
|
CComPtr<IHTMLUniqueName> pUniqueName;
|
|
CComPtr<IHTMLCommentElement> pCommentElement;
|
|
CComPtr<IHTMLObjectElement> pObjectElement;
|
|
|
|
HRESULT hr;
|
|
//CComBSTR bstrUniqueID;
|
|
WCHAR *pAttr = NULL;
|
|
WCHAR *pAttrL = NULL;
|
|
WCHAR *pAttrDSU = NULL;
|
|
long len;
|
|
int i;
|
|
LPCWSTR szDSP[] =
|
|
{
|
|
L"DESIGNTIMESP",
|
|
L"designtimesp",
|
|
L"DESIGNTIMEURL",
|
|
};
|
|
LPCWSTR szComment[] =
|
|
{
|
|
L"<!--TRIEDITCOMMENT",
|
|
L"<!--ERRORPARAM",
|
|
L"<!--ERROROBJECT",
|
|
};
|
|
VARIANT var, vaName, vaIndex;
|
|
|
|
if (!IsIE5OrBetterInstalled())
|
|
goto LRet;
|
|
|
|
pHTMLDoc = NULL;
|
|
hr = m_pUnkTrident->QueryInterface(IID_IHTMLDocument2, (void **) &pHTMLDoc);
|
|
if (hr != S_OK)
|
|
goto LRet;
|
|
|
|
|
|
pHTMLDoc->get_all(&pHTMLCollection);
|
|
if (hr != S_OK)
|
|
goto LRet;
|
|
|
|
pAttr = new WCHAR[wcslen(szDSP[0])+1];
|
|
memcpy((BYTE *)pAttr, (BYTE *)szDSP[0], wcslen(szDSP[0])*sizeof(WCHAR));
|
|
pAttr[wcslen(szDSP[0])] = '\0';
|
|
pAttrL = new WCHAR[wcslen(szDSP[1])+1];
|
|
memcpy((BYTE *)pAttrL, (BYTE *)szDSP[1], wcslen(szDSP[1])*sizeof(WCHAR));
|
|
pAttrL[wcslen(szDSP[1])] = '\0';
|
|
pAttrDSU = new WCHAR[wcslen(szDSP[2])+1];
|
|
memcpy((BYTE *)pAttrDSU, (BYTE *)szDSP[2], wcslen(szDSP[2])*sizeof(WCHAR));
|
|
pAttrDSU[wcslen(szDSP[2])] = '\0';
|
|
|
|
pHTMLCollection->get_length(&len);
|
|
|
|
if (len == 0)
|
|
goto LRet;
|
|
|
|
if (!fGet)
|
|
{
|
|
// now we know that we atleast have one element, lets allocate space for saving
|
|
// UniqueID's & designtimesp's
|
|
if (m_pMapArray == NULL) // this is the first time we are here
|
|
{
|
|
_ASSERTE(m_hgMap == NULL);
|
|
m_hgMap = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, MIN_MAP*sizeof(MAPSTRUCT));
|
|
if (m_hgMap == NULL)
|
|
goto LRet;
|
|
m_cMapMax = MIN_MAP;
|
|
}
|
|
_ASSERTE(m_hgMap != NULL);
|
|
m_pMapArray = (MAPSTRUCT *) GlobalLock(m_hgMap);
|
|
_ASSERTE(m_pMapArray != NULL);
|
|
// even if we allocate the space for m_hgMap here or not, we should start from 0
|
|
m_iMapCur = 0;
|
|
// zeroise the array
|
|
memset((BYTE *)m_pMapArray, 0, m_cMapMax*sizeof(MAPSTRUCT));
|
|
|
|
if (m_pspNonDSP == NULL) // this is the first time we are here
|
|
{
|
|
_ASSERTE(m_hgSpacingNonDSP == NULL);
|
|
m_hgSpacingNonDSP = GlobalAlloc(GMEM_MOVEABLE|GMEM_ZEROINIT, MIN_SP_NONDSP*sizeof(WCHAR));
|
|
if (m_hgSpacingNonDSP == NULL)
|
|
goto LRet;
|
|
m_ichspNonDSPMax = MIN_SP_NONDSP;
|
|
}
|
|
_ASSERTE(m_hgSpacingNonDSP != NULL);
|
|
m_pspNonDSP = (WCHAR *) GlobalLock(m_hgSpacingNonDSP);
|
|
_ASSERTE(m_pspNonDSP != NULL);
|
|
// even if we allocate the space for m_hgSpacingNonDSP here or not, we should start from 0
|
|
m_ichspNonDSP = 0;
|
|
// zeroise the array
|
|
memset((BYTE *)m_pspNonDSP, 0, m_ichspNonDSPMax*sizeof(WCHAR));
|
|
}
|
|
else // if (fGet)
|
|
{
|
|
if (m_iMapCur < 1) // we don't have any mappings saved
|
|
goto LRet;
|
|
m_pMapArray = (MAPSTRUCT *)GlobalLock(m_hgMap);
|
|
_ASSERTE(m_pMapArray != NULL);
|
|
|
|
m_pspNonDSP = (WCHAR *)GlobalLock(m_hgSpacingNonDSP);
|
|
_ASSERTE(m_pspNonDSP != NULL);
|
|
}
|
|
|
|
// loop through all the elemets and fill m_pMapArray
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
VARIANT_BOOL fSuccess;
|
|
|
|
if (!fGet)
|
|
{
|
|
// reallocate m_hgMap if needed
|
|
if (m_iMapCur == m_cMapMax - 1)
|
|
{
|
|
HGLOBAL hgMap;
|
|
GlobalUnlock(m_hgMap);
|
|
hgMap = m_hgMap;
|
|
#pragma prefast(suppress:308, "noise")
|
|
m_hgMap = GlobalReAlloc(m_hgMap, (m_cMapMax+MIN_MAP)*sizeof(MAPSTRUCT), GMEM_MOVEABLE|GMEM_ZEROINIT);
|
|
// if this alloc failed, we may still want to continue
|
|
if (m_hgMap == NULL)
|
|
{
|
|
GlobalFree(hgMap);
|
|
goto LRet;
|
|
}
|
|
else
|
|
{
|
|
m_pMapArray = (MAPSTRUCT *)GlobalLock(m_hgMap);
|
|
_ASSERTE(m_pMapArray != NULL);
|
|
m_cMapMax += MIN_MAP;
|
|
}
|
|
}
|
|
_ASSERTE(m_iMapCur < m_cMapMax);
|
|
}
|
|
|
|
VariantInit(&vaName);
|
|
VariantInit(&vaIndex);
|
|
|
|
V_VT(&vaName) = VT_ERROR;
|
|
V_ERROR(&vaName) = DISP_E_PARAMNOTFOUND;
|
|
|
|
V_VT(&vaIndex) = VT_I4;
|
|
V_I4(&vaIndex) = i;
|
|
|
|
pDispControl = NULL;
|
|
hr = pHTMLCollection->item(vaIndex, vaName, &pDispControl);
|
|
VariantClear(&vaName);
|
|
VariantClear(&vaIndex);
|
|
// Trident has a bug that if the object was nested inside <scripts> tags,
|
|
// it returns S_OK with pDispControl as NULL. (See VID BUG 11303)
|
|
if (hr == S_OK && pDispControl != NULL)
|
|
{
|
|
pElement = NULL;
|
|
hr = pDispControl->QueryInterface(IID_IHTMLElement, (void **) &pElement);
|
|
if (hr == S_OK && pElement != NULL)
|
|
{
|
|
//#ifdef DEBUG
|
|
// CComBSTR bstrTagName, bstrClsName;
|
|
//
|
|
// hr = pElement->get_className(&bstrClsName);
|
|
// hr = pElement->get_tagName(&bstrTagName);
|
|
//#endif //DEBUG
|
|
if (!fGet) // saving the data
|
|
{
|
|
BOOL fLowerCase = FALSE;
|
|
|
|
VariantInit(&var);
|
|
// KNOWN (and postponed) TRIDENT BUG - ideally, we should be able to look for hr's value here,
|
|
// but trident returns S_OK even if it can't get the attribute!!!
|
|
hr = pElement->getAttribute(pAttr, 0, &var); // look for DESIGNTIMESP (upper or lower case'd)
|
|
if (var.vt == VT_BSTR)
|
|
{
|
|
CComVariant varT;
|
|
|
|
hr = pElement->getAttribute(pAttrL, 1, &varT); // look for lowercase designtimesp
|
|
if (varT.vt == VT_BSTR)
|
|
fLowerCase = TRUE;
|
|
}
|
|
if (var.vt == VT_BSTR && var.bstrVal != NULL)
|
|
{
|
|
CComBSTR bstrUniqueID;
|
|
CComVariant varDSU;
|
|
int iType = INDEX_DSP; // initial value
|
|
int ich = -1; // initial value;
|
|
//#ifdef DEBUG
|
|
// CComBSTR pOuterTag;
|
|
//#endif //DEBUG
|
|
|
|
pUniqueName = NULL;
|
|
hr = pDispControl->QueryInterface(IID_IHTMLUniqueName, (void **) &pUniqueName);
|
|
if (hr == S_OK && pUniqueName != NULL)
|
|
hr = pUniqueName->get_uniqueID(&bstrUniqueID);
|
|
if (pUniqueName)
|
|
pUniqueName.Release();
|
|
//pHTMLDoc3->get_uniqueID(&bstrUniqueID);
|
|
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&pOuterTag);
|
|
// pOuterTag.Empty();
|
|
//#endif //DEBUG
|
|
// at this point, we know that this tag had designtimesp.
|
|
// It may also have additional triedit attributes like designtimeurl
|
|
// lets check for those as well
|
|
hr = pElement->getAttribute(pAttrDSU, 0, &varDSU); // look for DESIGNTIMEURL (upper or lower case'd)
|
|
if ( hr == S_OK
|
|
&& varDSU.vt == VT_BSTR
|
|
&& varDSU.bstrVal != NULL
|
|
)
|
|
{
|
|
// we found 'designtimeurl'
|
|
iType = INDEX_AIMGLINK;
|
|
ich = m_ichspNonDSP;
|
|
|
|
FillNonDSPData(varDSU.bstrVal);
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&pOuterTag);
|
|
// pOuterTag.Empty();
|
|
//#endif //DEBUG
|
|
// now remove designtimeurl & its value
|
|
hr = pElement->removeAttribute(pAttrDSU, 0, &fSuccess);
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&pOuterTag);
|
|
// pOuterTag.Empty();
|
|
//#endif //DEBUG
|
|
}
|
|
|
|
// fill ID mapping structure
|
|
FillUniqueID(bstrUniqueID, var.bstrVal, ich, m_pMapArray, m_iMapCur, fLowerCase, iType);
|
|
bstrUniqueID.Empty();
|
|
m_iMapCur++;
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&pOuterTag);
|
|
// pOuterTag.Empty();
|
|
//#endif //DEBUG
|
|
// Now, remove designtimesp and its value
|
|
hr = pElement->removeAttribute(pAttr, 0, &fSuccess);
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&pOuterTag);
|
|
// pOuterTag.Empty();
|
|
//#endif //DEBUG
|
|
bstrUniqueID.Empty();
|
|
}
|
|
else if (var.vt == VT_NULL)
|
|
{
|
|
CComBSTR bstrUniqueID;
|
|
CComBSTR pOuterTag;
|
|
//#ifdef DEBUG
|
|
// CComBSTR pOuter;
|
|
//#endif // DEBUG
|
|
|
|
// see if this is a comment and save it
|
|
pElement->get_outerHTML(&pOuterTag);
|
|
if ( pOuterTag != NULL
|
|
&& 0 == _wcsnicmp(pOuterTag, szComment[0], wcslen(szComment[0]))
|
|
)
|
|
{
|
|
pUniqueName = NULL;
|
|
hr = pDispControl->QueryInterface(IID_IHTMLUniqueName, (void **) &pUniqueName);
|
|
if (hr == S_OK && pUniqueName != NULL)
|
|
hr = pUniqueName->get_uniqueID(&bstrUniqueID);
|
|
if (pUniqueName)
|
|
pUniqueName.Release();
|
|
|
|
// fill ID mapping structure
|
|
FillUniqueID(bstrUniqueID, NULL, m_ichspNonDSP, m_pMapArray, m_iMapCur, fLowerCase, INDEX_COMMENT);
|
|
bstrUniqueID.Empty();
|
|
m_iMapCur++;
|
|
|
|
FillNonDSPData(pOuterTag);
|
|
// now, remove the comment spacing stuff and set_outerHTML
|
|
hr = pDispControl->QueryInterface(IID_IHTMLCommentElement, (void **) &pCommentElement);
|
|
if (hr == S_OK && pCommentElement != NULL)
|
|
SetinnerHTMLComment(pCommentElement, pElement, pOuterTag);
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&pOuter);
|
|
// pOuter.Empty();
|
|
//#endif //DEBUG
|
|
if (pCommentElement)
|
|
pCommentElement.Release();
|
|
}
|
|
else if ( S_OK == pDispControl->QueryInterface(IID_IHTMLObjectElement, (void **) &pObjectElement)
|
|
&& pObjectElement != NULL
|
|
)
|
|
{
|
|
BSTR bstrAlt, bstrAltNew, bstrAltComment;
|
|
|
|
bstrAlt = bstrAltNew = bstrAltComment = NULL;
|
|
pUniqueName = NULL;
|
|
hr = pDispControl->QueryInterface(IID_IHTMLUniqueName, (void **) &pUniqueName);
|
|
if (hr == S_OK && pUniqueName != NULL)
|
|
hr = pUniqueName->get_uniqueID(&bstrUniqueID);
|
|
if (pUniqueName)
|
|
pUniqueName.Release();
|
|
|
|
// fill ID mapping structure
|
|
FillUniqueID(bstrUniqueID, NULL, m_ichspNonDSP, m_pMapArray, m_iMapCur, FALSE, INDEX_OBJ_COMMENT);
|
|
bstrUniqueID.Empty();
|
|
m_iMapCur++;
|
|
|
|
pObjectElement->get_altHtml(&bstrAlt);
|
|
// remove <!--ERRORPARAM ...ERRORPARAM-->
|
|
// ASSUME (FOR NOW) that we won't see TRIEDITCOMMENT or others here
|
|
RemoveEPComment(pObjectElement, bstrAlt, SysStringLen(bstrAlt), &bstrAltComment, &bstrAltNew);
|
|
|
|
FillNonDSPData(bstrAltComment);
|
|
SysFreeString(bstrAltComment);
|
|
|
|
hr = SetObjectComment(pObjectElement, bstrAltNew);
|
|
SysFreeString(bstrAltNew);
|
|
|
|
SysFreeString(bstrAlt);
|
|
//#ifdef DEBUG
|
|
// pObjectElement->get_altHtml(&bstrAlt);
|
|
// bstrAlt.Empty();
|
|
//#endif //DEBUG
|
|
}
|
|
if (pObjectElement)
|
|
pObjectElement.Release();
|
|
|
|
bstrUniqueID.Empty();
|
|
pOuterTag.Empty();
|
|
}
|
|
VariantClear(&var);
|
|
}
|
|
else // if (fGet)
|
|
{
|
|
BOOL fLowerCase = FALSE;
|
|
int index, ichNonDSP;
|
|
CComBSTR bstrUniqueID;
|
|
|
|
pUniqueName = NULL;
|
|
hr = pDispControl->QueryInterface(IID_IHTMLUniqueName, (void **) &pUniqueName);
|
|
if (hr == S_OK && pUniqueName != NULL)
|
|
hr = pUniqueName->get_uniqueID(&bstrUniqueID);
|
|
if (pUniqueName)
|
|
pUniqueName.Release();
|
|
|
|
// get the uniqueID
|
|
//pHTMLDoc3->get_uniqueID(&bstrUniqueID);
|
|
// see if we have it in m_hgMap, if we do, get corresponding designtimesp ID
|
|
// if we don't have a DSP for this uniqueID, this is newly inserted element
|
|
VariantInit(&var);
|
|
if (FGetSavedDSP(bstrUniqueID, &(var.bstrVal), &ichNonDSP, m_pMapArray, &fLowerCase, &index))
|
|
{
|
|
//#ifdef DEBUG
|
|
// CComBSTR pOuterTag;
|
|
//#endif //DEBUG
|
|
// insert (correct case) "designtimesp = xxxx" in the tag by setting attribute/value
|
|
var.vt = VT_BSTR;
|
|
#ifdef DEBUG
|
|
if (index == INDEX_DSP)
|
|
_ASSERTE(var.bstrVal != NULL && ichNonDSP == -1);
|
|
else if (index == INDEX_COMMENT)
|
|
_ASSERTE(var.bstrVal == (BSTR)NULL && ichNonDSP != -1);
|
|
else if (index == INDEX_AIMGLINK)
|
|
_ASSERTE(var.bstrVal != NULL && ichNonDSP != -1);
|
|
// pElement->get_outerHTML(&pOuterTag);
|
|
// pOuterTag.Empty();
|
|
#endif //DEBUG
|
|
if (index == INDEX_DSP)
|
|
{
|
|
if (fLowerCase)
|
|
hr = pElement->setAttribute(pAttrL, var, 1);
|
|
else
|
|
hr = pElement->setAttribute(pAttr, var, 1);
|
|
}
|
|
else if (index == INDEX_COMMENT)
|
|
{
|
|
hr = pDispControl->QueryInterface(IID_IHTMLCommentElement, (void **) &pCommentElement);
|
|
if (hr == S_OK && pCommentElement != NULL)
|
|
ReSetinnerHTMLComment(pCommentElement, pElement, ichNonDSP);
|
|
if (pCommentElement)
|
|
pCommentElement.Release();
|
|
}
|
|
else if (index == INDEX_AIMGLINK)
|
|
{
|
|
CComVariant varDSU;
|
|
WCHAR *pchDSU;
|
|
int cchDSU = 0;
|
|
|
|
if (fLowerCase)
|
|
hr = pElement->setAttribute(pAttrL, var, 1);
|
|
else
|
|
hr = pElement->setAttribute(pAttr, var, 1);
|
|
|
|
// put designtimeurl as well
|
|
// get the data from ichNonDSP and setAttribute
|
|
_ASSERTE(ichNonDSP != -1);
|
|
memcpy((BYTE *)&cchDSU, (BYTE *)(m_pspNonDSP+ichNonDSP), sizeof(INT));
|
|
_ASSERTE(cchDSU > 0);
|
|
pchDSU = new WCHAR[cchDSU+1];
|
|
memcpy((BYTE *)pchDSU, (BYTE *)(m_pspNonDSP+ichNonDSP+sizeof(int)/sizeof(WCHAR)), cchDSU*sizeof(WCHAR));
|
|
pchDSU[cchDSU] = '\0';
|
|
varDSU.bstrVal = SysAllocString(pchDSU);
|
|
varDSU.vt = VT_BSTR;
|
|
hr = pElement->setAttribute(pAttrDSU, varDSU, 1);
|
|
delete pchDSU;
|
|
} //else if (index == INDEX_AIMGLINK)
|
|
else if (index == INDEX_OBJ_COMMENT)
|
|
{
|
|
hr = pDispControl->QueryInterface(IID_IHTMLObjectElement, (void **) &pObjectElement);
|
|
if (pObjectElement != NULL)
|
|
{
|
|
AppendEPComment(pObjectElement, ichNonDSP);
|
|
}
|
|
else // something is not right, just ignore
|
|
{
|
|
_ASSERTE(FALSE);
|
|
}
|
|
if (pObjectElement)
|
|
pObjectElement.Release();
|
|
}
|
|
//#ifdef DEBUG
|
|
// pElement->get_outerHTML(&pOuterTag);
|
|
// pOuterTag.Empty();
|
|
//#endif //DEBUG
|
|
} // if (FGetSavedDSP())
|
|
VariantClear(&var);
|
|
bstrUniqueID.Empty();
|
|
} // end of else case of 'if (!fGet)'
|
|
//#ifdef DEBUG
|
|
// bstrTagName.Empty();
|
|
// bstrClsName.Empty();
|
|
//#endif //DEBUG
|
|
} // if (hr == S_OK && pElement != NULL)
|
|
if (pElement)
|
|
pElement.Release();
|
|
} // if (hr == S_OK && pDispControl != NULL)
|
|
if (pDispControl)
|
|
pDispControl.Release();
|
|
} // for (i ...)
|
|
|
|
LRet:
|
|
if (pAttr != NULL)
|
|
delete pAttr;
|
|
if (pAttrL != NULL)
|
|
delete pAttrL;
|
|
if (pAttrDSU != NULL)
|
|
delete pAttrDSU;
|
|
if (pHTMLCollection)
|
|
pHTMLCollection.Release();
|
|
if (pHTMLDoc)
|
|
pHTMLDoc.Release();
|
|
if (m_hgMap != NULL)
|
|
GlobalUnlock(m_hgMap);
|
|
if (m_hgSpacingNonDSP != NULL)
|
|
GlobalUnlock(m_hgSpacingNonDSP);
|
|
|
|
|
|
return;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
STDMETHODIMP
|
|
CTridentEventSink::Invoke(DISPID dispid, REFIID, LCID, USHORT, DISPPARAMS*, VARIANT*, EXCEPINFO*, UINT*)
|
|
{
|
|
switch(dispid)
|
|
{
|
|
case DISPID_HTMLDOCUMENTEVENTS_ONREADYSTATECHANGE:
|
|
{
|
|
CComBSTR p;
|
|
HRESULT hr;
|
|
LPCWSTR szComplete[] =
|
|
{
|
|
L"complete",
|
|
};
|
|
|
|
//look for READYSTATE_COMPLETE)
|
|
hr = m_pHTMLDocument2->get_readyState(&p);
|
|
if ( hr == S_OK
|
|
&& (p != NULL)
|
|
&& 0 == _wcsnicmp(p, szComplete[0], wcslen(szComplete[0]))
|
|
&& m_pTriEditDocument->FIsFilterInDone()
|
|
)
|
|
{
|
|
CComVariant varDirty;
|
|
|
|
// we know that the document is loaded.
|
|
// get pointer to DOM and access all tags
|
|
// create a table that holds mapping from designtimespID to uniqueID
|
|
// save the mapping and remove designtimesp attribute
|
|
|
|
// at the time of save, fill in the designtimesp's for each uniqueID
|
|
|
|
m_pTriEditDocument->MapUniqueID(/*fGet*/FALSE);
|
|
m_pTriEditDocument->SetFilterInDone(FALSE);
|
|
// set the document to be CLEAN (non-DIRTY), we don't care about hr
|
|
varDirty.bVal = FALSE;
|
|
varDirty.vt = VT_BOOL;
|
|
hr = m_pTriEditDocument->Exec(&CGID_MSHTML, IDM_SETDIRTY, MSOCMDEXECOPT_DODEFAULT, &varDirty, NULL);
|
|
}
|
|
p.Empty();
|
|
}
|
|
break;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
HRESULT
|
|
CBaseTridentEventSink::Advise(IUnknown* pUnkSource, REFIID riidEventInterface)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if(NULL == pUnkSource)
|
|
{
|
|
_ASSERTE(FALSE);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
if(m_dwCookie > 0)
|
|
{
|
|
_ASSERTE(FALSE);
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
hr = AtlAdvise(pUnkSource, static_cast<IUnknown*>(this), riidEventInterface, &m_dwCookie);
|
|
if(SUCCEEDED(hr) && m_dwCookie > 0)
|
|
{
|
|
m_iidEventInterface = riidEventInterface;
|
|
|
|
m_pUnkSource = pUnkSource; // no addref. Advise already addref'ed it
|
|
return S_OK;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
//
|
|
void
|
|
CBaseTridentEventSink::Unadvise(void)
|
|
{
|
|
if(0 == m_dwCookie)
|
|
return;
|
|
|
|
AtlUnadvise(m_pUnkSource, m_iidEventInterface, m_dwCookie);
|
|
m_dwCookie = 0;
|
|
m_pUnkSource = NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
// IPersistStreamInit
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
STDMETHODIMP CTriEditDocument::Load(LPSTREAM pStm)
|
|
{
|
|
ATLTRACE(_T("CTriEditDocument::IPersistStreamInit::Load"));
|
|
_ASSERTE(m_pTridentPersistStreamInit != NULL);
|
|
return m_pTridentPersistStreamInit->Load(pStm);
|
|
}
|
|
|
|
STDMETHODIMP CTriEditDocument::Save(LPSTREAM pStm, BOOL fClearDirty)
|
|
{
|
|
ATLTRACE(_T("CTriEditDocument::IPersistStreamInit::Save"));
|
|
_ASSERTE(m_pTridentPersistStreamInit != NULL);
|
|
|
|
// before we deligate Save to Trident, do the preFiltering stuff
|
|
if (m_hgMap != NULL)
|
|
{
|
|
MapUniqueID(/*fGet*/TRUE);
|
|
}
|
|
|
|
return m_pTridentPersistStreamInit->Save(pStm, fClearDirty);
|
|
}
|
|
|
|
STDMETHODIMP CTriEditDocument::GetSizeMax(ULARGE_INTEGER *pcbSize)
|
|
{
|
|
ATLTRACE(_T("CTriEditDocument::IPersistStreamInit::GetSizeMax"));
|
|
_ASSERTE(m_pTridentPersistStreamInit != NULL);
|
|
return m_pTridentPersistStreamInit->GetSizeMax(pcbSize);
|
|
}
|
|
|
|
STDMETHODIMP CTriEditDocument::IsDirty()
|
|
{
|
|
//ATLTRACE(_T("CTriEditDocument::IPersistStreamInit::IsDirty\n"));
|
|
_ASSERTE(m_pTridentPersistStreamInit != NULL);
|
|
return m_pTridentPersistStreamInit->IsDirty();
|
|
}
|
|
|
|
STDMETHODIMP CTriEditDocument::InitNew()
|
|
{
|
|
ATLTRACE(_T("CTriEditDocument::IPersistStreamInit::InitNew\n"));
|
|
_ASSERTE(m_pTridentPersistStreamInit != NULL);
|
|
return(m_pTridentPersistStreamInit->InitNew());
|
|
}
|
|
|
|
STDMETHODIMP CTriEditDocument::GetClassID(CLSID *pClassID)
|
|
{
|
|
ATLTRACE(_T("CTriEditDocument::IPersistStreamInit::GetClassID\n"));
|
|
_ASSERTE(m_pTridentPersistStreamInit != NULL);
|
|
*pClassID = GetObjectCLSID();
|
|
return S_OK;
|
|
}
|
|
#endif //IE5_SPACING
|