// //************************************************************************** // // BOleIPS.cpp -- Implements the Bolero half of the OLE2 in-process // server object. // // BOleIps objects impersonate the client application // from the point of view of the Bolero customer who's // writing a server object (IPart) // // Copyright (c) 1993,94 by Borland International, Inc. All rights reserved // //************************************************************************** #include "BOleIPS.h" #include "BOleCMan.h" //************************************************************************** // // BOleInProcHandler implementation // //************************************************************************** BOleInProcHandler::BOleInProcHandler(BOleClassManager *pFact, IBUnknownMain * pOuter, BOleService *pSvc ) : BOleComponent(pFact, pOuter) { pService = pSvc; pDefHandler = NULL; pDefIPAO = NULL; pDefSite = NULL; pAdviseView = NULL; dwAdviseFlags = 0L; dwAdviseAspects = 0L; } BOleInProcHandler::~BOleInProcHandler () { if (pDefHandler) pDefHandler->Release(); } HRESULT _IFUNC BOleInProcHandler::QueryInterfaceMain(REFIID iid, LPVOID FAR *ppv) { HRESULT hr = ResultFromScode(E_NOINTERFACE); *ppv = NULL; // interfaces if (SUCCEEDED(hr = IViewObject2_QueryInterface(this, iid, ppv))) { } else if (SUCCEEDED(hr = IOleInPlaceActiveObject_QueryInterface(this, iid, ppv))) { } else if (SUCCEEDED(hr = IBSite_QueryInterface(this, iid, ppv))) { } // base classes else if (SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(iid, ppv))) { } // helpers else if (pDefHandler && SUCCEEDED(hr = pDefHandler->QueryInterface(iid, ppv))) { } return hr; } //************************************************************************** // // IViewObject implementation // //************************************************************************** HRESULT _IFUNC BOleInProcHandler::Draw (DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL(CALLBACK * pfnContinue)(DWORD), DWORD dwContinue) { HRESULT hr = ResultFromScode(VIEW_E_DRAW); // Let provider Draw // unless its iconic which the handler does for us // if (dwDrawAspect != DVASPECT_ICON) { if (SUCCEEDED(pProvider->Draw(hdcDraw, lprcBounds, // lprcWBounds is NULL unless this is a metafile // lprcWBounds ? lprcWBounds : lprcBounds, (BOleAspect) dwDrawAspect))) { hr = NOERROR; } } // If this failed let the default handler render the Metafile // if (!SUCCEEDED(hr)) { IViewObject *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject, &(LPVOID)pVO))) { hr = pVO->Draw(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue); pVO->Release(); } } return hr; } HRESULT _IFUNC BOleInProcHandler::GetColorSet ( DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, LPLOGPALETTE FAR* ppColorSet) { // what color pallete will the object use when rendering return pPart->GetPalette (ppColorSet); } HRESULT _IFUNC BOleInProcHandler::Freeze ( DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DWORD FAR* pdwFreeze) { HRESULT hr; IViewObject *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject, &(LPVOID)pVO))) { hr = pVO->Freeze(dwDrawAspect, lindex, pvAspect, pdwFreeze); pVO->Release(); return hr; } // the object shouldn't change the rendering return ResultFromScode (E_FAIL); } HRESULT _IFUNC BOleInProcHandler::Unfreeze (DWORD dwFreeze) { HRESULT hr; IViewObject *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject, &(LPVOID)pVO))) { hr = pVO->Unfreeze(dwFreeze); pVO->Release(); return hr; } // ok it can change again return NOERROR; } HRESULT _IFUNC BOleInProcHandler::SetAdvise (DWORD aspects, DWORD advf, LPADVISESINK pAdvSink) { dwAdviseAspects = aspects; dwAdviseFlags = advf; if (pAdviseView) pAdviseView->Release(); pAdviseView = pAdvSink; // // // // // // // if (advf | ADVF_PRIMEFIRST) // Cause advises now // Invalidate(BOLE_INVAL_DATA | BOLE_INVAL_VIEW); return NOERROR; } HRESULT _IFUNC BOleInProcHandler::GetAdvise (DWORD FAR* pAspects, DWORD FAR* pAdvf, LPADVISESINK FAR* ppAdvSink) { pAdviseView->AddRef(); *ppAdvSink = pAdviseView; *pAspects = dwAdviseAspects; *pAdvf = dwAdviseFlags; return NOERROR; } HRESULT _IFUNC BOleInProcHandler::GetExtent(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE FAR *ptd, LPSIZEL lpsizel) { if (dwDrawAspect != DVASPECT_CONTENT) return ResultFromScode (E_FAIL); if (!lpsizel) return ResultFromScode (E_INVALIDARG); SIZE s; HRESULT hr = pProvider->GetPartSize (&s); lpsizel->cx = MAP_PIX_TO_LOGHIM (s.cx, BOleService::pixPerIn.x); lpsizel->cy = MAP_PIX_TO_LOGHIM (s.cy, BOleService::pixPerIn.y); return hr; } //************************************************************************** // // IBSite methods (override this interface on aggregated BOleIPSServer // to implement Invalidate). // //************************************************************************** HRESULT _IFUNC BOleInProcHandler::Init(PIBDataProvider pDP, PIBPart pP, LPCOLESTR szProgId, BOOL fHatchWnd) { HRESULT hr; // Initialize back pointers // pProvider = pDP; pPart = pP; CLSID cid; if (SUCCEEDED(hr = CLSIDFromProgID(szProgId, &cid))) { // create the default handler, which will launch the exe server // OleCreateEmbeddingHelper(cid, AsPIUnknown(pObjOuter), EMBDHLP_INPROC_HANDLER | EMBDHLP_DELAYCREATE, NULL, IID_IUnknown, &(LPVOID)pDefHandler); // initialize default IPS // hr = pDefHandler->QueryInterface(IID_IBSite, &(LPVOID)pDefSite); if (SUCCEEDED(hr)) { pDefSite->Release(); // prevent aggregation deadlock // hr = pDefSite->Init(pDP, pP, szProgId, fHatchWnd); } } return hr; } HRESULT _IFUNC BOleInProcHandler::SiteShow(BOOL b) { return pDefSite->SiteShow(b); } HRESULT _IFUNC BOleInProcHandler::DiscardUndo() { return pDefSite->DiscardUndo(); } HRESULT _IFUNC BOleInProcHandler::GetSiteRect(LPRECT r1, LPRECT r2) { return pDefSite->GetSiteRect(r1,r2); } HRESULT _IFUNC BOleInProcHandler::SetSiteRect(LPCRECT r) { return pDefSite->SetSiteRect(r); } HRESULT _IFUNC BOleInProcHandler::SetSiteExtent(LPCSIZE s) { return pDefSite->SetSiteExtent(s); } void _IFUNC BOleInProcHandler::OnSetFocus(BOOL b) { pDefSite->OnSetFocus(b); } void _IFUNC BOleInProcHandler::Disconnect () { pDefSite->Disconnect (); } HRESULT _IFUNC BOleInProcHandler::GetZoom( BOleScaleFactor *pScale) { return pDefSite->GetZoom(pScale); } void _IFUNC BOleInProcHandler::Invalidate( BOleInvalidate b) { if ((b & BOLE_INVAL_VIEW) && pAdviseView) { pAdviseView->OnViewChange(dwAdviseAspects, -1); if (dwAdviseFlags == ADVF_ONLYONCE) { pAdviseView->Release(); pAdviseView = NULL; dwAdviseAspects = 0L; dwAdviseFlags = 0L; // } } if (b) // VIEW or DATA or PERSIST remains invalid pDefSite->Invalidate(b); } //************************************************************************** // // IOleInPlaceActiveObject // // This interface is overridden to pre-process translator and other messages // from the container's message loop. // //************************************************************************** IOleInPlaceActiveObject * BOleInProcHandler::DefaultIPAO() { if (!pDefIPAO) { // Initialize pointer to default in place active object implementation // if (SUCCEEDED(pDefHandler->QueryInterface(IID_IOleInPlaceActiveObject, &(LPVOID) pDefIPAO))) { pDefIPAO->Release(); // prevent aggregation deadlock } } return pDefIPAO; } HRESULT _IFUNC BOleInProcHandler::GetWindow(HWND FAR *phwnd) { return DefaultIPAO()->GetWindow (phwnd); } HRESULT _IFUNC BOleInProcHandler::ContextSensitiveHelp(BOOL fEnterMode) { return DefaultIPAO()->ContextSensitiveHelp (fEnterMode); } // Allow DLL Server to translate accelerators // HRESULT _IFUNC BOleInProcHandler::TranslateAccelerator (LPMSG lpmsg) { return pService->GetApplication()->Accelerator(lpmsg); // } HRESULT _IFUNC BOleInProcHandler::OnFrameWindowActivate (BOOL fActivate) { return DefaultIPAO()->OnFrameWindowActivate (fActivate); } HRESULT _IFUNC BOleInProcHandler::OnDocWindowActivate (BOOL fActivate) { return DefaultIPAO()->OnDocWindowActivate (fActivate); } HRESULT _IFUNC BOleInProcHandler::ResizeBorder (LPCRECT lprectBorder, LPOLEINPLACEUIWINDOW lpUIWindow, BOOL fFrameWindow) { return DefaultIPAO()->ResizeBorder (lprectBorder, lpUIWindow, fFrameWindow); } HRESULT _IFUNC BOleInProcHandler::EnableModeless (BOOL fEnable) { return DefaultIPAO()->EnableModeless (fEnable); } //************************************************************************** // // BOleInProcServer implementation // //************************************************************************** BOleInProcServer::BOleInProcServer(BOleClassManager *pFact, IBUnknownMain * pOuter, BOleService *pSvc ) : BOleSite(pFact, pOuter, pSvc) { pService = pSvc; pDefHandler = NULL; pAdviseView = NULL; dwAdviseFlags = 0L; dwAdviseAspects = 0L; exCon = 0L; fRunningMode = FALSE; } BOleInProcServer::~BOleInProcServer () { if (pDefHandler) pDefHandler->Release(); } HRESULT _IFUNC BOleInProcServer::QueryInterfaceMain(REFIID iid, LPVOID FAR *ppv) { HRESULT hr = ResultFromScode(E_NOINTERFACE); *ppv = NULL; // interfaces if (SUCCEEDED(hr = IViewObject2_QueryInterface(this, iid, ppv))) { } else if (SUCCEEDED(hr = IRunnableObject_QueryInterface(this, iid, ppv))) { } else if (SUCCEEDED(hr = IExternalConnection_QueryInterface(this, iid, ppv))) { } // base classes else if (SUCCEEDED(hr = BOleSite::QueryInterfaceMain(iid, ppv))) { } // helpers else if (pDefHandler && SUCCEEDED(hr = pDefHandler->QueryInterface(iid, ppv))) { } return hr; } //************************************************************************** // // IViewObject implementation // //************************************************************************** HRESULT _IFUNC BOleInProcServer::Draw (DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, HDC hdcDraw, LPCRECTL lprcBounds, LPCRECTL lprcWBounds, BOOL(CALLBACK * pfnContinue)(DWORD), DWORD dwContinue) { HRESULT hr = ResultFromScode(VIEW_E_DRAW); // Let provider Draw unless its iconic which the handler does for us // if (dwDrawAspect == DVASPECT_CONTENT) { if (SUCCEEDED(pProvider->Draw(hdcDraw, lprcBounds, // lprcWBounds is NULL unless this is a metafile // lprcWBounds ? lprcWBounds : lprcBounds, (BOleAspect) dwDrawAspect))) { hr = NOERROR; } } // If this failed let the default handler render the Metafile // if (!SUCCEEDED(hr)) { IViewObject *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject, &(LPVOID)pVO))) { hr = pVO->Draw(dwDrawAspect, lindex, pvAspect, ptd, hicTargetDev, hdcDraw, lprcBounds, lprcWBounds, pfnContinue, dwContinue); pVO->Release(); } } return hr; } HRESULT _IFUNC BOleInProcServer::GetColorSet ( DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DVTARGETDEVICE FAR * ptd, HDC hicTargetDev, LPLOGPALETTE FAR* ppColorSet) { // what color pallete will the object use when rendering return pPart->GetPalette (ppColorSet); } HRESULT _IFUNC BOleInProcServer::Freeze ( DWORD dwDrawAspect, LONG lindex, void FAR* pvAspect, DWORD FAR* pdwFreeze) { HRESULT hr; IViewObject *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject, &(LPVOID)pVO))) { hr = pVO->Freeze(dwDrawAspect, lindex, pvAspect, pdwFreeze); pVO->Release(); return hr; } // the object shouldn't change the rendering return ResultFromScode (E_FAIL); } HRESULT _IFUNC BOleInProcServer::Unfreeze (DWORD dwFreeze) { HRESULT hr; IViewObject *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject, &(LPVOID)pVO))) { hr = pVO->Unfreeze(dwFreeze); pVO->Release(); return hr; } // ok it can change again return NOERROR; } HRESULT _IFUNC BOleInProcServer::SetAdvise (DWORD aspects, DWORD advf, LPADVISESINK pAdvSink) { dwAdviseAspects = aspects; dwAdviseFlags = advf; if (pAdviseView) pAdviseView->Release(); pAdviseView = pAdvSink; // // // // // // // if (advf & ADVF_PRIMEFIRST) // Cause advises now // Invalidate(BOLE_INVAL_DATA | BOLE_INVAL_VIEW); return NOERROR; } HRESULT _IFUNC BOleInProcServer::GetAdvise (DWORD FAR* pAspects, DWORD FAR* pAdvf, LPADVISESINK FAR* ppAdvSink) { pAdviseView->AddRef(); *ppAdvSink = pAdviseView; *pAspects = dwAdviseAspects; *pAdvf = dwAdviseFlags; return NOERROR; } HRESULT _IFUNC BOleInProcServer::GetExtent(DWORD dwDrawAspect, LONG lindex, DVTARGETDEVICE FAR *ptd, LPSIZEL lpsizel) { HRESULT hr; if (dwDrawAspect != DVASPECT_CONTENT) { // Get extent from the cache. // IViewObject2 *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject2, &(LPVOID)pVO))) { hr = pVO->GetExtent(dwDrawAspect, lindex, ptd, lpsizel); pVO->Release(); } } else { hr = BOleSite::GetExtent(dwDrawAspect, lpsizel); } return hr; } HRESULT _IFUNC BOleInProcServer::GetExtent(DWORD dwDrawAspect, LPSIZEL lpsizel) { HRESULT hr; if (dwDrawAspect != DVASPECT_CONTENT) { // Get extent from the cache. // IViewObject2 *pVO; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IViewObject2, &(LPVOID)pVO))) { hr = pVO->GetExtent(dwDrawAspect, -1, NULL, lpsizel); pVO->Release(); } } else { hr = BOleSite::GetExtent(dwDrawAspect, lpsizel); } return hr; } //************************************************************************** // Override IPersistStorage to allow OleCache to be persistent. // HRESULT _IFUNC BOleInProcServer::InitNew(IStorage* pStg) { LPPERSISTSTORAGE pPersistCache; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IPersistStorage, &(LPVOID) pPersistCache))) { pPersistCache->InitNew(pStg); pPersistCache->Release(); } return BOleSite::InitNew(pStg); } HRESULT _IFUNC BOleInProcServer::Load(IStorage* pStg) { LPPERSISTSTORAGE pPersistCache; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IPersistStorage, &(LPVOID) pPersistCache))) { pPersistCache->Load(pStg); pPersistCache->Release(); } return BOleSite::Load(pStg); } HRESULT _IFUNC BOleInProcServer::Save(IStorage* pStgSave,BOOL fSameAsLoad) { LPOLECACHE2 pCache; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IOleCache2, &(LPVOID)pCache))) { pCache->UpdateCache(this, ADVFCACHE_ONSAVE, NULL); pCache->Release(); } LPPERSISTSTORAGE pPersistCache; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IPersistStorage, &(LPVOID)pPersistCache))) { pPersistCache->Save(pStgSave, fSameAsLoad); pPersistCache->Release(); } return BOleSite::Save(pStgSave, fSameAsLoad); } HRESULT _IFUNC BOleInProcServer::SaveCompleted(IStorage* pStgSaved) { LPPERSISTSTORAGE pPersistCache; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IPersistStorage, &(LPVOID) pPersistCache))) { pPersistCache->SaveCompleted(pStgSaved); pPersistCache->Release(); } return BOleSite::SaveCompleted(pStgSaved); } HRESULT _IFUNC BOleInProcServer::HandsOffStorage() { LPPERSISTSTORAGE pPersistCache; if (SUCCEEDED(pDefHandler->QueryInterface(IID_IPersistStorage, &(LPVOID) pPersistCache))) { pPersistCache->HandsOffStorage(); pPersistCache->Release(); } return BOleSite::HandsOffStorage(); } //************************************************************************** // // IBSite methods (override this interface on aggregated BOleIPSServer // to implement Invalidate). // //************************************************************************** HRESULT _IFUNC BOleInProcServer::Init(PIBDataProvider pDP, PIBPart pP, LPCOLESTR szProgId, BOOL fHatchWnd) { // Initialize back pointers // pProvider = pDP; pPart = pP; CLSID cid = CLSID_NULL; if (SUCCEEDED(CLSIDFromProgID(szProgId, &cid))) { // create the default handler // CreateDataCache(AsPIUnknown(pObjOuter),cid, IID_IUnknown, &(LPVOID)pDefHandler); // // // } // initialize default IPS // return BOleSite::Init(pDP, pP, szProgId, fHatchWnd); } void _IFUNC BOleInProcServer::Invalidate( BOleInvalidate b) { if ((b & BOLE_INVAL_VIEW) && pAdviseView) { pAdviseView->OnViewChange(dwAdviseAspects, -1); if (dwAdviseFlags == ADVF_ONLYONCE) { pAdviseView->Release(); pAdviseView = NULL; dwAdviseAspects = 0L; dwAdviseFlags = 0L; // } } if (b) // VIEW or DATA or PERSIST remains invalid BOleSite::Invalidate(b); } //************************************************************************** // // IOleInPlaceActiveObject // // This interface is overridden to pre-process translator and other messages // from the container's message loop. // //************************************************************************** // Allow DLL Server to translate accelerators // HRESULT _IFUNC BOleInProcServer::TranslateAccelerator (LPMSG lpmsg) { return pService->GetApplication()->Accelerator(lpmsg); } HRESULT _IFUNC BOleInProcServer::EnumVerbs(IEnumOLEVERB* FAR* ppenumOleVerb) { return OleRegEnumVerbs(cid, ppenumOleVerb); } HRESULT _IFUNC BOleInProcServer::GetUserType(DWORD dwFormOfType, LPOLESTR FAR* pszUserType) { return OleRegGetUserType(cid, dwFormOfType, pszUserType); } HRESULT _IFUNC BOleInProcServer::GetMiscStatus(DWORD dwAspect, DWORD FAR* pdwStatus) { return OleRegGetMiscStatus(cid, dwAspect, pdwStatus); } HRESULT _IFUNC BOleInProcServer::SetExtent (DWORD dwDrawAspect, LPSIZEL lpsizel) { HRESULT hr = BOleSite::SetExtent(dwDrawAspect, lpsizel); return hr; } // IRunnableObject methods // HRESULT _IFUNC BOleInProcServer::GetRunningClass(LPCLSID lpClassID) { *lpClassID = cid; return NOERROR; } HRESULT _IFUNC BOleInProcServer::Run(LPBINDCTX pbc) { // Enter running mode by setting a flag and locking the container // if (!fRunningMode) { fRunningMode = TRUE; // // // // // // // // Should register the moniker here. // Don't register if this is a clone (pPart is NULL) // otherwise we would link to what's on the clipboard... // if (pPart) SetMoniker(OLEWHICHMK_OBJFULL, NULLP); // register } return NOERROR; } BOOL _IFUNC BOleInProcServer::IsRunning() { return fRunningMode; } HRESULT _IFUNC BOleInProcServer::LockRunning(BOOL fLock, BOOL fLastCloses) { return Lock(fLock, fLastCloses); } HRESULT _IFUNC BOleInProcServer::SetContainedObject(BOOL fContained) { return NOERROR; } // IExternalConnection implementation // DWORD _IFUNC BOleInProcServer::AddConnection (DWORD flag, DWORD reserved) { return (flag & EXTCONN_STRONG) ? ++exCon : 0; } DWORD _IFUNC BOleInProcServer::ReleaseConnection (DWORD flag, DWORD reserved, BOOL fLastReleaseCloses) { if (flag & EXTCONN_STRONG) { --exCon; if( exCon == 0 && fLastReleaseCloses){ Close(OLECLOSE_SAVEIFDIRTY); } return exCon; } return 0; } HRESULT _IFUNC BOleInProcServer::Close (DWORD dwSaveOption) { fRunningMode = FALSE; return BOleSite::Close(dwSaveOption); }