home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
BOCOLE.PAK
/
BOLESITE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-29
|
83KB
|
2,602 lines
//
//**************************************************************************
//
// BOleSite.cpp -- Implements the Bolero half of the OLE2 server object.
// BOleSite 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
//
//**************************************************************************
// Bolero headers
//
#include "BOle.h"
#include "BOleSite.h"
#include "BOleDoc.h"
#include "BOleCMan.h"
extern "C" {
#include "ole2ui.h"
}
// System/RTL headers
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
#define NOT_IMPLEMENTED OLERET(E_NOTIMPL);
HRESULT _IFUNC BOleSite::QueryInterfaceMain(REFIID iid, LPVOID FAR *ppv)
{
HRESULT hr = ResultFromScode(E_NOINTERFACE);
*ppv = NULL;
// Self
//
if (IID_BOleSite == iid) {
(BOleSite *)*ppv = this;
AddRef();
return NOERROR;
}
// nested interface class
if (IID_IBApplication == iid) {
((IBApplication *)*ppv) = &iApplication;
AddRef();
return NOERROR;
}
// interfaces
if (SUCCEEDED(hr = IBContainer_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IBLinkable_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IPersistStorage_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IDataObject_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IDropSource_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IOleObject_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IOleInPlaceObject_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IOleInPlaceActiveObject_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IBSite_QueryInterface(this, iid, ppv))) {
}
else if (SUCCEEDED(hr = IEnumFORMATETC_QueryInterface(this, iid, ppv))) {
}
// base classes
else if (SUCCEEDED(hr = BOleComponent::QueryInterfaceMain(iid, ppv))) {
}
return hr;
};
//
// BOleSite implementation -- These functions aren't part of an inherited
// interface, but are part of the private
// implementation of BOleSite
//
BOleSite::BOleSite(BOleClassManager * pFact, IBUnknownMain *pOuter,
BOleService *pSvc)
: BOleComponent (pFact, pOuter) , iApplication(this, pOuter),
cid (CLSID_NULL)
{
pService = pSvc;
#ifdef OLEDBG
DebugMode = 0;
#endif
pClientSite = NULL;
pStg = NULL;
pDAdvHolder = NULL;
pAdvHolder = NULL;
pPart = NULL; // (IPart *) pOuter->InterfaceGet(IID(IPart));
pProvider = NULL;
pIPSite = 0;
pIPFrame = 0;
pIPDoc = 0;
fShown = FALSE;
fInPlaceActive = FALSE;
fInPlaceVisible = FALSE;
fInsideOut = FALSE;
fUIActive = FALSE;
fInHelpMode = FALSE;
fInClose = FALSE;
hWndParent = 0;
pHatchWnd = NULLP;
hWndInPlace = 0;
hOleMenu = 0;
hMenuShared = 0;
pszProgID = NULLP;
pmkDoc = NULLP;
hatchOffset.x = hatchOffset.y = 0;
pFactory->ServerCount(+1L);
regLink = 0L;
pszInstName = NULL;
pWindowTitle = NULL;
pAppName = NULL;
fHandsOff = FALSE;
fIsDirty = TRUE;
formatList = NULL;
formatCount = 0;
formatLink = TRUE; // default pending moniker existence
formatEmbed = TRUE;
pInPlaceName = NULL;
pDocument = NULL;
}
HRESULT _IFUNC BOleSite::Init (PIBDataProvider pProv, PIBPart ppart, LPCOLESTR psz, BOOL fHatchWnd)
{
// If the provider also supports IBPart, then it's a full-fledged
// server object capable of inplace activation. If it doesn't, this
// BOleSite will only be used for data transfer.
//
pProvider = pProv;
pPart = ppart;
// Bind to BOleFact so we can get the CLSID
//
if (pszProgID != NULLP)
delete pszProgID;
pszProgID = new OLECHAR [lstrlen(psz) + 1];
if (!pszProgID)
return ResultFromScode (E_OUTOFMEMORY);
lstrcpy (pszProgID, psz);
CLSIDFromProgID(pszProgID, &cid);
// Cache the available formats because OLE2 will ask for formats
// during link/embed from file, even though no Clip or Drag
// happened.
//
//
//
//
//
//
//
pService->FormatHelper (&formatList, &formatCount, formatLink,
formatEmbed, pProvider);
// Create a hatched window which is visible during visual editing
//
if (pPart && fHatchWnd) {
//pHatchWnd = BOleHatchWindow::Create (NULL, boleInst, this);
pHatchWnd = new BOleHatchWindow(NULL, boleInst, this);
if (!pHatchWnd || !(HANDLE)pHatchWnd)
return ResultFromScode (E_OUTOFMEMORY);
}
// Catenate the APPNAME and the SHORTUSERTYPENAME together. This seems
// to be the convention for SetActiveObject
//
LPOLESTR appname = NULL, shortname = NULL;
int c = 0;
OleRegGetUserType (cid, USERCLASSTYPE_APPNAME, &appname);
if (appname)
c += lstrlen (appname) + lstrlen ( TEXT(" - ") );
OleRegGetUserType (cid, USERCLASSTYPE_SHORT, &shortname);
if (shortname)
c += lstrlen (shortname);
pInPlaceName = new OLECHAR [c + 1]; // +1 for null term
if (!pInPlaceName)
return ResultFromScode (E_OUTOFMEMORY);
pInPlaceName[0] = 0;
if (appname) {
strcat (pInPlaceName, appname);
strcat (pInPlaceName, TEXT(" - ") );
}
if (shortname)
strcat (pInPlaceName, shortname);
IMalloc *pMalloc;
if (SUCCEEDED(CoGetMalloc(MEMCTX_TASK, &pMalloc))) {
pMalloc->Free(appname);
pMalloc->Free(shortname);
pMalloc->Release();
}
return NOERROR;
}
BOleSite::~BOleSite ()
{
// Don't translate any more accelerators through this helper
//
if (pService->pFocusedSite == this)
OnSetFocus (NULL);
DoClose();
// Release the client site here (not in DoClose) so that we can in place
// activate after an open-edit session (Dll server case).
//
if (pClientSite) {
pClientSite->Release ();
pClientSite = NULL;
}
if (pWindowTitle) {
delete [] pWindowTitle;
pWindowTitle = NULL;
}
if (pAppName) {
delete [] pAppName;
pAppName = NULL;
}
if (pszProgID) {
delete pszProgID;
pszProgID = NULL;
}
if (pHatchWnd) {
delete pHatchWnd;
pHatchWnd = NULL;
}
if (pDocument) { // Set in BOleContainer::GetObject
CoLockObjectExternal(pDocument, FALSE, FALSE);
pDocument = NULL;
}
if (pmkDoc) {
pmkDoc->Release();
pmkDoc = NULL;
}
if (pszInstName) {
delete [] pszInstName;
pszInstName = NULL;
}
if (pInPlaceName) {
delete [] pInPlaceName;
pInPlaceName = NULL;
}
if (formatList) {
delete [] formatList;
}
pFactory->ServerCount(-1L);
}
//
// Accessor functions for format lists
//
void _IFUNC BOleSite::GetFormatFlags(BOOL *pfEmbed, BOOL *pfLink)
{
if (pService->dropCount || (pService->clipCount && pService->IsOnClipboard(this))) {
*pfLink = pService->fUseDropList ? pService->dropOkToLink : pService->clipOkToLink;
*pfEmbed = pService->fUseDropList ? pService->dropOkToEmbed : pService->clipOkToEmbed;
}
else {
if (!formatList) {
// Cache the available formats because OLE2 will ask for formats
// during link/embed from file, even though no Clip or Drag
// happened.
pService->FormatHelper (&formatList, &formatCount, formatLink,
formatEmbed, pProvider);
}
*pfLink = formatLink;
*pfEmbed = formatEmbed;
}
}
void _IFUNC BOleSite::GetFormatList(LPFORMATETC *ppList, UINT *pCount)
{
if (pService->dropCount || (pService->clipCount && pService->IsOnClipboard(this))) {
*ppList = pService->fUseDropList ? pService->dropList : pService->clipList;
*pCount = pService->fUseDropList ? pService->dropCount : pService->clipCount;
}
else {
if (!formatList) {
// Cache the available formats because OLE2 will ask for formats
// during link/embed from file, even though no Clip or Drag
// happened.
pService->FormatHelper (&formatList, &formatCount, formatLink,
formatEmbed, pProvider);
}
*ppList = formatList;
*pCount = formatCount;
}
}
void _IFUNC BOleSite::GetFormatCount(UINT *pCount)
{
if (pService->dropCount || (pService->clipCount && pService->IsOnClipboard(this))) {
*pCount = pService->fUseDropList ? pService->dropCount : pService->clipCount;
}
else {
if (!formatList) {
// Cache the available formats because OLE2 will ask for formats
// during link/embed from file, even though no Clip or Drag
// happened.
pService->FormatHelper (&formatList, &formatCount, formatLink,
formatEmbed, pProvider);
}
*pCount = formatCount;
}
}
void _IFUNC BOleSite::GetFormatInfo(BOOL *pfEmbed, BOOL *pfLink, LPFORMATETC *ppList, UINT *pCount)
{
if (pService->dropCount || (pService->clipCount && pService->IsOnClipboard(this))) {
*pfLink = pService->fUseDropList ? pService->dropOkToLink : pService->clipOkToLink;
*pfEmbed = pService->fUseDropList ? pService->dropOkToEmbed : pService->clipOkToEmbed;
*ppList = pService->fUseDropList ? pService->dropList : pService->clipList;
*pCount = pService->fUseDropList ? pService->dropCount : pService->clipCount;
}
else {
if (!formatList) {
// Cache the available formats because OLE2 will ask for formats
// during link/embed from file, even though no Clip or Drag
// happened.
pService->FormatHelper (&formatList, &formatCount, formatLink,
formatEmbed, pProvider);
}
*pfLink = formatLink;
*pfEmbed = formatEmbed;
*ppList = formatList;
*pCount = formatCount;
}
}
// Render this server object onto a storage medium.
//
HRESULT _IFUNC BOleSite::GetEmbeddedObjectData (LPFORMATETC pFmt, LPSTGMEDIUM pMed)
{
LPSTORAGE lpstg = NULL;
SCODE sc = S_OK;
HRESULT hrErr;
pMed->pUnkForRelease = NULL;
if (pMed->tymed == TYMED_NULL) {
// If the tymed passed in is NULL, we will create a temporary storage
// in memory in order to render the object
//
if (pFmt->tymed & TYMED_ISTORAGE) {
lpstg = CreateStorageInMemory (STGM_READWRITE
| STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE /*| STGM_DELETEONRELEASE??*/);
if (!lpstg)
return ResultFromScode(E_OUTOFMEMORY);
pMed->pstg = lpstg;
pMed->tymed = TYMED_ISTORAGE;
pMed->pUnkForRelease = NULL;
}
else
return ResultFromScode(DATA_E_FORMATETC);
}
// If the tymed passed in is non-NULL, we will use the storage they
// gave us. If it's not a storage, return failure.
//
else if (pMed->tymed & TYMED_ISTORAGE) {
pMed->tymed = TYMED_ISTORAGE;
// The online dox say that OleSave does this, but there's no
// CompObj stream without WriteFmtUseTypeStg and no CLSID in the
// stream without WriteClassStg
//
CLSID clsid = CLSID_NULL;
CLSIDFromProgID (pszProgID, &clsid);
if ((hrErr = WriteClassStg (pMed->pstg, clsid)) != NOERROR)
return hrErr;
LPOLESTR lpLongType = NULL;
OleRegGetUserType (clsid, USERCLASSTYPE_FULL, &lpLongType);
hrErr = WriteFmtUserTypeStg (pMed->pstg, pFmt->cfFormat, lpLongType);
}
else
return ResultFromScode(DATA_E_FORMATETC);
// We don't really expect anyone to respond to this call, but WPWin
// is going to try to decide whether a new object is linked or embedded
// based on this notification.
//
BOleFormat f;
f.fmtId = BOleDocument::oleEmbSrcClipFmt;
f.fmtMedium = BOLE_MED_STORAGE;
f.fmtName[0] = 0;
f.fmtResultName[0] = 0;
f.fmtIsLinkable = FALSE;
pProvider->GetFormatData (&f);
hrErr = OleSave(this, pMed->pstg, FALSE /* fSameAsLoad */);
if (hrErr != NOERROR)
sc = GetScode(hrErr);
// Always call SaveCompleted, but don't stomp the error code if
// OleSave failed
//
hrErr = SaveCompleted (NULL);
if (hrErr != NOERROR && sc == S_OK)
sc = GetScode(hrErr);
return ResultFromScode(sc);
}
// Render the data for a link source into a stream medium
//
HRESULT _IFUNC BOleSite::GetLinkSourceData(LPMONIKER lpmk, REFCLSID cid,
LPFORMATETC lpformatetc, LPSTGMEDIUM lpMedium)
{
LPSTREAM lpstm = NULL;
HRESULT hrErr;
// We don't really expect anyone to respond to this call, but WPWin
// is going to try to decide whether a new object is linked or embedded
// based on this notification.
//
BOleFormat f;
f.fmtId = BOleDocument::oleLinkSrcClipFmt;
f.fmtMedium = BOLE_MED_STREAM;
f.fmtName[0] = 0;
f.fmtResultName[0] = 0;
f.fmtIsLinkable = TRUE;
pProvider->GetFormatData (&f);
if (lpMedium->tymed == TYMED_NULL) {
if (lpformatetc->tymed & TYMED_ISTREAM) {
hrErr = CreateStreamOnHGlobal(
NULL, // auto allocate
TRUE, // delete on release
(LPSTREAM FAR*)&lpstm
);
if (hrErr != NOERROR) {
lpMedium->pUnkForRelease = NULL;
return ResultFromScode (E_OUTOFMEMORY);
}
lpMedium->pstm = lpstm;
lpMedium->tymed = TYMED_ISTREAM;
lpMedium->pUnkForRelease = NULL;
}
else {
lpMedium->pUnkForRelease = NULL;
return ResultFromScode (DATA_E_FORMATETC);
}
}
else {
if (lpMedium->tymed & TYMED_ISTREAM) {
lpMedium->tymed = TYMED_ISTREAM;
lpMedium->pstm = lpMedium->pstm;
lpMedium->pUnkForRelease = NULL;
}
else {
lpMedium->pUnkForRelease = NULL;
return ResultFromScode (DATA_E_FORMATETC);
}
}
hrErr = OleSaveToStream((LPPERSISTSTREAM)lpmk, lpMedium->pstm);
if (hrErr != NOERROR)
return hrErr;
return WriteClassStm (lpMedium->pstm, cid);
}
// Creates an LPSTORAGE with the specified flags on a memory lockbytes
//
LPSTORAGE _IFUNC BOleSite::CreateStorageInMemory (DWORD grfMode)
{
DWORD grfCreateMode =grfMode | STGM_CREATE;
HRESULT hrErr;
LPLOCKBYTES lpLockBytes = NULL;
DWORD reserved = 0;
LPSTORAGE lpStg = NULL;
hrErr = CreateILockBytesOnHGlobal(NULL, TRUE /*delete on release*/,
&lpLockBytes);
if (hrErr != NOERROR)
return NULL;
hrErr = StgCreateDocfileOnILockBytes(lpLockBytes, grfCreateMode,
reserved, &lpStg);
if (hrErr != NOERROR) {
lpLockBytes->Release();
return NULL;
}
lpLockBytes->Release();
return lpStg;
}
//**************************************************************************
//
// IDataObject implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::GetData (LPFORMATETC pFormatEtcIn, LPSTGMEDIUM pMedium)
{
#ifdef ANSI
char name[32];
GetClipboardFormatNameA(pFormatEtcIn->cfFormat, name, sizeof(name));
#else
OLECHAR name[32];
GetClipboardFormatName(pFormatEtcIn->cfFormat, name, sizeof(name));
#endif
HRESULT hrErr = ResultFromScode (DATA_E_FORMATETC);
BOOL fLink = TRUE;
BOOL fEmbed = TRUE;
GetFormatFlags(&fEmbed, &fLink);
if (pFormatEtcIn->dwAspect & (DVASPECT_CONTENT | DVASPECT_DOCPRINT)) {
pMedium->tymed = 0L;
pMedium->pUnkForRelease = NULL;
pMedium->hGlobal = NULL;
if (pFormatEtcIn->cfFormat == BOleDocument::oleEmbSrcClipFmt) {
if( fEmbed )
hrErr = GetEmbeddedObjectData (pFormatEtcIn, pMedium);
}
else if (pFormatEtcIn->cfFormat == BOleDocument::oleObjectDescFmt) {
if( fEmbed )
goto _getobjdesc;
}
else if (pFormatEtcIn->cfFormat == BOleDocument::oleLinkSrcClipFmt) {
if( fLink ) {
LPMONIKER pMon;
hrErr = GetMoniker(OLEGETMONIKER_ONLYIFTHERE,OLEWHICHMK_OBJFULL, &pMon);
if (SUCCEEDED(hrErr)) {
CLSID id;
hrErr = GetUserClassID(&id);
pMedium->tymed = TYMED_NULL; // for GetLinkSourceData
pFormatEtcIn->cfFormat = BOleDocument::oleLinkSrcClipFmt; // per Brockshmit's suggestion
pFormatEtcIn->tymed = TYMED_ISTREAM; // pg. 773
if (SUCCEEDED(hrErr)) {
hrErr = GetLinkSourceData(pMon, id, pFormatEtcIn, pMedium);
}
pMon->Release();
}
}
}
else if (pFormatEtcIn->cfFormat == BOleDocument::oleLinkSrcDescFmt) {
if( fLink ) {
_getobjdesc:;
// Object descriptors *must* be returned in a memory handle
//
if (pFormatEtcIn->tymed & TYMED_HGLOBAL) {
pMedium->hGlobal = GetObjDescData ();
if (pMedium->hGlobal) {
pMedium->tymed = TYMED_HGLOBAL;
hrErr = ResultFromScode (S_OK);
}
else
hrErr = ResultFromScode (E_OUTOFMEMORY);
}
}
}
else if (pFormatEtcIn->cfFormat == CF_METAFILEPICT && (pFormatEtcIn->tymed & TYMED_MFPICT)) {
hrErr = GetMetaFileData (pMedium->hGlobal);
if (hrErr == NOERROR)
pMedium->tymed = TYMED_MFPICT;
}
// It's not an OLE2 format, maybe it's a regular clipboard format
// the client would know.
//
else {
BOleFormat boleFmt;
_fmemset(&boleFmt, 0, sizeof(boleFmt));
boleFmt.fmtId = pFormatEtcIn->cfFormat;
boleFmt.fmtMedium = (BOleMedium) pFormatEtcIn->tymed;
//PHP It would be more efficient to use our list of formats
//from enumFormatEtc to check before calling GetFormatData
if (pMedium) {
pMedium->hGlobal = pProvider->GetFormatData (&boleFmt);
if (pMedium->hGlobal) {
pMedium->tymed = boleFmt.fmtMedium & ~BOLE_MED_STATIC;
}
}
if (pMedium->hGlobal)
hrErr = ResultFromScode (S_OK);
}
}
return hrErr;
}
#ifdef TESTMETAFILE
extern HINSTANCE boleInst;
void RenderMetaFile(HGLOBAL hMFPict)
{
LPMETAFILEPICT pMFPict = (LPMETAFILEPICT) GlobalLock (hMFPict);
int xPix = MAP_LOGHIM_TO_PIX (pMFPict->xExt, BOleService::pixPerIn.x);
int yPix = MAP_LOGHIM_TO_PIX (pMFPict->yExt, BOleService::pixPerIn.y);
HWND w = GetDesktopWindow();
if (w) {
HDC dc = GetDC (w);
UINT oldMapMode = SetMapMode(dc, MM_ANISOTROPIC);
SetWindowExt (dc, 1000, 1000);
SetViewportExt (dc, xPix, yPix);
PlayMetaFile (dc, pMFPict->hMF);
SetMapMode (dc, oldMapMode);
ReleaseDC(w, dc);
GlobalUnlock (hMFPict);
}
}
#endif
HRESULT _IFUNC BOleSite::GetMetaFileData (HGLOBAL& hMem)
{
HRESULT hrErr = NOERROR;
#ifdef ANSI
HDC hDC = CreateMetaFileA(NULL);
#else
HDC hDC = CreateMetaFile(NULL);
#endif
if (hDC) {
// Get server size in pixels
SIZE s;
pProvider->GetPartSize (&s);
// Convert server size to himetric, and set up dc for drawing
//
SIZEL sl;
sl.cx = MAP_PIX_TO_LOGHIM (s.cx, BOleService::pixPerIn.x);
sl.cy = MAP_PIX_TO_LOGHIM (s.cy, BOleService::pixPerIn.y);
SetMapMode(hDC, MM_ANISOTROPIC);
SetWindowOrg(hDC, 0, 0);
SetWindowExt(hDC, sl.cx, sl.cy);
RECTL rPos = {0L, 0L, sl.cx, sl.cy}, rExt = {0L, 0L, sl.cx, sl.cy};
pProvider->Draw (hDC, &rPos, &rExt, BOLE_CONTENT);
HMETAFILE hMF = CloseMetaFile (hDC);
if (hMF) {
HGLOBAL hMFPict = ::GlobalAlloc (GMEM_SHARE|GMEM_ZEROINIT, sizeof (METAFILEPICT));
if (hMFPict) {
LPMETAFILEPICT pPict = (LPMETAFILEPICT) ::GlobalLock (hMFPict);
if (pPict) {
pPict->mm = MM_ANISOTROPIC;
pPict->hMF = hMF;
pPict->xExt = sl.cx;
pPict->yExt = sl.cy; // add minus sign to make it +ve
GlobalUnlock (hMFPict);
hMem = hMFPict;
}
else {
GlobalFree (hMFPict);
DeleteMetaFile (hMF);
hrErr = ResultFromScode (E_OUTOFMEMORY);
}
}
else {
DeleteMetaFile (hMF);
hrErr = ResultFromScode (E_OUTOFMEMORY);
}
}
else
hrErr = ResultFromScode (E_OUTOFMEMORY);
}
#ifdef TESTMETAFILE
if (SUCCEEDED(hrErr))
RenderMetaFile(hMem);
#endif
return hrErr;
}
HRESULT _IFUNC BOleSite::GetDataHere (LPFORMATETC pFormatEtc, LPSTGMEDIUM pMedium)
{
#ifdef ANSI
char name[32];
GetClipboardFormatNameA(pFormatEtc->cfFormat, name, sizeof(name));
#else
OLECHAR name[32];
GetClipboardFormatName(pFormatEtc->cfFormat, name, sizeof(name));
#endif
BOOL fLink = TRUE;
BOOL fEmbed = TRUE;
GetFormatFlags(&fEmbed, &fLink);
HRESULT hr = ResultFromScode(DATA_E_FORMATETC);
if (pFormatEtc->cfFormat == BOleDocument::oleEmbSrcClipFmt) {
if( fEmbed )
hr = GetEmbeddedObjectData (pFormatEtc, pMedium);
}
else
if (pFormatEtc->cfFormat == BOleDocument::oleLinkSrcClipFmt) {
if (fLink) {
LPMONIKER pMon;
hr = GetMoniker(OLEGETMONIKER_ONLYIFTHERE,OLEWHICHMK_OBJFULL, &pMon);
if (SUCCEEDED(hr)) {
CLSID id;
hr = GetUserClassID (&id);
pMedium->tymed = TYMED_NULL; // for GetLinkSourceData
pFormatEtc->cfFormat = BOleDocument::oleLinkSrcClipFmt; // per Brockshmit's suggestion
pFormatEtc->tymed = TYMED_ISTREAM; // pg. 773
if (SUCCEEDED(hr))
hr = GetLinkSourceData(pMon, id, pFormatEtc, pMedium);
pMon->Release();
}
}
}
return hr;
}
HRESULT _IFUNC BOleSite::QueryGetData (LPFORMATETC pFormatEtc)
{
#ifdef ANSI
char name[32];
GetClipboardFormatNameA(pFormatEtc->cfFormat, name, sizeof(name));
#else
OLECHAR name[32];
GetClipboardFormatName(pFormatEtc->cfFormat, name, sizeof(name));
#endif
BOOL fLink = TRUE;
BOOL fEmbed = TRUE;
LPFORMATETC pList;
UINT count;
GetFormatInfo(&fEmbed, &fLink, &pList, &count);
HRESULT hrErr = ResultFromScode (DV_E_FORMATETC);
if (pFormatEtc->cfFormat == BOleDocument::oleObjectDescFmt) {
if (fEmbed) {
// Object Descriptors must be offered in global handles
//
if (pFormatEtc->tymed & TYMED_HGLOBAL)
hrErr = NOERROR;
else
hrErr = ResultFromScode (DV_E_FORMATETC);
}
}
else if (pFormatEtc->cfFormat == BOleDocument::oleLinkSrcDescFmt) {
if (fLink) {
// Link Src Desc, like Obj Desc, must be offered in a global handle
//
if (pFormatEtc->tymed & TYMED_HGLOBAL)
hrErr = NOERROR;
else
hrErr = ResultFromScode (DV_E_FORMATETC);
}
}
for (UINT i = 0; i < count; i++) {
if ((pList[i].cfFormat == pFormatEtc->cfFormat) &&
(pList[i].tymed & pFormatEtc->tymed)) {
return ResultFromScode(S_OK);
}
}
return hrErr;
}
HRESULT _IFUNC BOleSite::GetCanonicalFormatEtc (LPFORMATETC pFormatetc, LPFORMATETC pFormatetcOut)
{
if (!pFormatetcOut)
return ResultFromScode( E_INVALIDARG );
pFormatetcOut->ptd = NULL;
if (!pFormatetc)
return ResultFromScode (E_INVALIDARG);
HRESULT hrErr;
hrErr = QueryGetData (pFormatetc);
if (hrErr != NOERROR)
return hrErr;
*pFormatetcOut = *pFormatetc;
if (!pFormatetc->ptd)
return ResultFromScode (DATA_S_SAMEFORMATETC);
pFormatetcOut->ptd = NULL;
return NOERROR;
}
// Set data into the server
//
HRESULT _IFUNC BOleSite::SetData (LPFORMATETC pFormatEtc, STGMEDIUM FAR* pMedium, BOOL fRelease)
{
PIBDataProvider2 pProvider2 = NULL;
// Does client implement IBDataProvider2?
//
if (!SUCCEEDED(pObjOuter->QueryInterfaceMain (IID_IBDataProvider2,&(LPVOID)pProvider2)))
NOT_IMPLEMENTED
HRESULT hr = ResultFromScode (DATA_E_FORMATETC);
if ((BOleMedium) pFormatEtc->tymed == BOLE_MED_HGLOBAL) {
BOleFormat boleFmt;
_fmemset(&boleFmt, 0, sizeof(boleFmt));
boleFmt.fmtId = pFormatEtc->cfFormat;
boleFmt.fmtMedium = (BOleMedium) pFormatEtc->tymed;
if (pMedium) {
hr = pProvider2->SetFormatData(&boleFmt, pMedium->hGlobal, FALSE);
// Always do release here instead of in SetFormatData
//
if (fRelease)
ReleaseStgMedium(pMedium);
}
}
pProvider2->Release();
return hr;
}
HRESULT _IFUNC BOleSite::EnumFormatEtc (DWORD dwDirection, LPENUMFORMATETC FAR* ppenumFormatEtc)
{
if (dwDirection == DATADIR_GET) {
*ppenumFormatEtc = this;
enumFmtIndex = 0L;
AddRef(); // caller must release
return ResultFromScode(S_OK);
}
// I'm not sure what it would mean to call IDataObject::SetData
// on the BOleSite so it's blank until I can do more research
//
return ResultFromScode (E_FAIL);
}
HRESULT _IFUNC BOleSite::DAdvise (FORMATETC FAR* pFormatetc, DWORD advf, IAdviseSink* pAdvSink, DWORD FAR* pdwConnection)
{
HRESULT hrErr;
*pdwConnection = 0;
if (pDAdvHolder == 0)
hrErr = CreateDataAdviseHolder (&pDAdvHolder);
if (pDAdvHolder)
hrErr = pDAdvHolder->Advise (this, pFormatetc, advf, pAdvSink, pdwConnection);
else
hrErr = ResultFromScode (E_OUTOFMEMORY);
return hrErr;
}
HRESULT _IFUNC BOleSite::DUnadvise (DWORD dwConnection)
{
HRESULT hrErr = ResultFromScode(E_FAIL);
if (pDAdvHolder)
hrErr = pDAdvHolder->Unadvise (dwConnection);
return hrErr;
}
HRESULT _IFUNC BOleSite::EnumDAdvise (IEnumSTATDATA* FAR* ppenumAdvise)
{
HRESULT hrErr = ResultFromScode(E_FAIL);
if (pDAdvHolder)
hrErr = pDAdvHolder->EnumAdvise (ppenumAdvise);
return hrErr;
}
//**************************************************************************
//
// IEnumFORMATETC implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::Next (ULONG celt, FORMATETC FAR * pFE, ULONG FAR* pceltFetched)
{
LPFORMATETC pList;
UINT count;
GetFormatList(&pList, &count);
if (pceltFetched)
*pceltFetched = 0;
if( !celt )
return ResultFromScode (E_INVALIDARG);
short nCopied = 0;
while ( (enumFmtIndex < count) && (nCopied < celt) ) {
pFE[nCopied] = pList[enumFmtIndex];
enumFmtIndex++;
nCopied++;
if (pceltFetched)
(*pceltFetched)++;
}
return ResultFromScode( nCopied != celt ? S_FALSE : S_OK);
}
HRESULT _IFUNC BOleSite::Skip (ULONG celt)
{
UINT count;
GetFormatCount(&count);
if( celt > count )
return ResultFromScode (E_INVALIDARG);
if( enumFmtIndex < count ) {
int diff = count - enumFmtIndex;
enumFmtIndex += celt;
return ResultFromScode (diff < celt ? S_OK : S_FALSE);
}
return ResultFromScode (S_FALSE);
}
HRESULT _IFUNC BOleSite::Reset ()
{
enumFmtIndex = 0L;
return ResultFromScode(S_OK);
}
HRESULT _IFUNC BOleSite::Clone (IEnumFORMATETC FAR* FAR* ppenum)
{
return ResultFromScode (E_NOTIMPL);
}
//**************************************************************************
//
// IOleObject implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::SetClientSite (IOleClientSite* pCS)
{
if (pClientSite)
pClientSite->Release ();
pClientSite = pCS;
if (pClientSite)
pClientSite->AddRef ();
return ResultFromScode(S_OK);
}
HRESULT _IFUNC BOleSite::GetClientSite (IOleClientSite* FAR* ppClientSite)
{
if (pClientSite) {
pClientSite->AddRef ();
*ppClientSite = pClientSite;
return ResultFromScode(S_OK);
}
else {
*ppClientSite = NULL;
return ResultFromScode(E_FAIL);
}
}
HRESULT _IFUNC BOleSite::SetHostNames (LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
{
// Delete the old ones if any
//
if (pAppName) {
delete [] pAppName;
pAppName = NULL;
}
if (pWindowTitle) {
delete [] pWindowTitle;
pWindowTitle = NULL;
}
// Copy the new ones into member data so they're around in case
// the part object asks for them (through IBContainer or IBApplication)
//
short c = strlen (szContainerApp) + 1; //+1 for \0 terminator
pAppName = new OLECHAR[c];
if (!pAppName)
return ResultFromScode (E_OUTOFMEMORY);
lstrcpyn( pAppName, szContainerApp, c );
if (szContainerObj) { // docs say this could be NULL
c = strlen (szContainerObj) + 1; //+1 for \0 terminator
pWindowTitle = new OLECHAR[c];
if (!pWindowTitle)
return ResultFromScode (E_OUTOFMEMORY);
lstrcpyn ( pWindowTitle, szContainerObj, c);
}
return NOERROR;
}
HRESULT _IFUNC BOleSite::DoClose ()
{
// If closed while open in place, exit in-place mode
//
if (fInPlaceActive) {
DoInPlaceDeactivate ();
}
// If closed while open editing, exit open edit mode
//
if (fShown) {
// pass FALSE here to not allow Lock(FALSE) to cause ::Close to be
// called recursively in in-proc server case.
// Unlocking is done at the end of ::Close (see comments below).
//
HideWindow(FALSE);
}
// If this object is on the clipboard, render all formats
//
if (pService->IsOnClipboard(this))
pService->FlushClipboardData(FALSE);
// Unregister for linking
//
if (regLink != 0L) {
LPRUNNINGOBJECTTABLE pROT = NULL;
HRESULT hr = OLE::GetRunningObjectTable (0, &pROT);
if (SUCCEEDED(hr)) {
pROT->Revoke(regLink);
regLink = 0L;
pROT->Release();
}
}
// Notify containers of exit from "running state"
//
if (pDAdvHolder) {
pDAdvHolder->SendOnDataChange (this, 0, ADVF_DATAONSTOP);
pDAdvHolder->Release ();
pDAdvHolder = NULL;
}
if (pAdvHolder) {
BOOL tmp = fInClose;
fInClose = TRUE;
pAdvHolder->SendOnClose (); // SendOnClose recursively calls Close!
pAdvHolder->Release ();
fInClose = tmp;
pAdvHolder = NULL;
}
// Release some remaining references to others
//
if (pIPSite) {
pIPSite->Release();
pIPSite = NULL;
}
if (pIPFrame) {
pIPFrame->Release();
pIPFrame = NULL;
}
if (pIPDoc) {
pIPDoc->Release();
pIPDoc = NULL;
}
if (pStg) {
pStg->Release ();
pStg = NULL;
}
return NOERROR;
}
HRESULT _IFUNC BOleSite::Close (DWORD dwSaveOption)
{
HRESULT hrErr = NOERROR;
if (fInClose)
return NOERROR;
AddRef();
fInClose = TRUE;
if (fIsDirty) {
if (dwSaveOption == OLECLOSE_PROMPTSAVE) {
if (pAppName) {
UINT nResponse = MessageBox(NULL, TEXT("Save Object before closing?"),
pAppName, MB_ICONQUESTION | MB_YESNOCANCEL );
switch (nResponse) {
case IDNO:
dwSaveOption = OLECLOSE_NOSAVE;
break;
case IDCANCEL:
hrErr = ResultFromScode(OLE_E_PROMPTSAVECANCELLED); // don't close
fInClose = FALSE;
return hrErr;
case IDYES:
dwSaveOption = OLECLOSE_SAVEIFDIRTY;
break;
}
}
}
switch (dwSaveOption) {
case OLECLOSE_SAVEIFDIRTY:
if (pClientSite) {
pClientSite->SaveObject();
fIsDirty = FALSE;
}
break;
case OLECLOSE_NOSAVE:
break;
}
}
DoClose();
// Might not have a pPart if this helper object was only used by a
// pProvider for data transfer
//
if (pPart) {
pPart->Close();
}
// This allows self embedded apps to in place activate and still shutdown
// properly. In self embed in place activation, default handler aggregator
// seems to have interfaces that don't go away until a last unlock releases.
//
// Unfortunately, the default handler also calls IOleObject::Close
// recursively. Wish it would just drop those references without
// calling Close! or Release those references before calling close...
//
//
//
//
//
//
CoDisconnectObject(AsPIUnknown(pObjOuter), 0);
fInClose = FALSE;
Release();
return hrErr;
}
HRESULT _IFUNC BOleSite::SetMoniker (DWORD dwWhichMoniker, IMoniker* pmk)
{
HRESULT hr= ResultFromScode(E_FAIL);
LPMONIKER pmkFull;
// To play "link to embedding", we need to register this object
// under the full moniker given by the client site.
// get the running object table
LPRUNNINGOBJECTTABLE pROT = NULL;
hr = OLE::GetRunningObjectTable (0, &pROT);
if (SUCCEEDED(hr)) {
// Register the new moniker BEFORE revoking the old moniker.
// Otherwise the object's "StubManager" gets hosed.
//
DWORD oldRegLink = regLink;
hr = GetMoniker(OLEGETMONIKER_ONLYIFTHERE, OLEWHICHMK_OBJFULL, &pmkFull);
if (SUCCEEDED(hr)) {
hr = pROT->Register (0, //ROTFLAGS_REGISTRATIONKEEPSALIVE,
AsPIUnknown(pObjOuter), pmkFull, ®Link);
if (pAdvHolder) {
pAdvHolder->SendOnRename (pmkFull);
}
pmkFull->Release();
}
else
regLink = 0L;
// release any old running object table registration
if (oldRegLink != 0L) {
pROT->Revoke(oldRegLink);
oldRegLink = 0L;
}
pROT->Release();
}
return hr;
}
HRESULT _IFUNC BOleSite::GetMoniker (DWORD dwAssign, DWORD dwWhichMoniker, IMoniker* FAR* ppmk)
{
// If we're open in a server doc its relative to the one in pmkDoc
// If we're an embedding, its relative to the container's doc
HRESULT hr = ResultFromScode(E_FAIL);
*ppmk = NULL;
if (pClientSite) {
hr = pClientSite->GetMoniker(OLEGETMONIKER_ONLYIFTHERE,
OLEWHICHMK_OBJFULL, ppmk);
}
else if (pmkDoc && pszInstName) {
LPMONIKER pmkObj = NULL;
if (SUCCEEDED(CreateItemMoniker(TEXT("!"), pszInstName, &pmkObj))) {
hr = CreateGenericComposite(pmkDoc, pmkObj, ppmk);
pmkObj->Release();
}
}
else if (pmkDoc && !pszInstName) {
*ppmk = pmkDoc;
pmkDoc->AddRef();
hr = NOERROR;
}
return hr;
}
HRESULT _IFUNC BOleSite::InitFromData (IDataObject* pDataObject, BOOL fCreation, DWORD dwReserved)
{
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::GetClipboardData (DWORD dwReserved, IDataObject* FAR* ppDataObject)
{
return ResultFromScode (E_NOTIMPL);
}
// Put external lock on document
HRESULT _IFUNC BOleSite::Lock (BOOL fLock, BOOL fLastUnlockReleases)
{
return CoLockObjectExternal (AsPIUnknown(pObjOuter), fLock, fLastUnlockReleases);
}
HRESULT _IFUNC BOleSite::ShowWindow ()
{
HRESULT hrErr = NOERROR;
if (fShown)
hrErr = pPart->Open(TRUE); // show window and set focus anyway
else {
// If there's no pClientSite, this is a linked object
//
if (!pClientSite) {
hrErr = pPart->Open(TRUE);
fShown = SUCCEEDED(hrErr);
}
else {
// This is an embedded object. ask container to show itself and object
//
pClientSite->ShowObject();
if (!fInPlaceActive) {
hrErr = pPart->Open(TRUE); // show app main window
fShown = SUCCEEDED(hrErr);
if (fShown) // show open edit hatching
pClientSite->OnShowWindow (TRUE);
}
else
fShown = TRUE;
}
if (fShown)
Lock (TRUE, FALSE); // lock document till window is hidden
}
return hrErr;
}
HRESULT _IFUNC BOleSite::HideWindow (BOOL fShutdown)
{
HRESULT hrErr = NOERROR;
if (fShown) {
fShown = FALSE;
// If there's no pClientSite, this is a linked object
//
if (!pClientSite)
hrErr = pPart->Open(FALSE);
else {
// This is an embedded object.
// inform container that our window is hiding
//
if (!fInPlaceVisible) {
pClientSite->OnShowWindow (FALSE); // hide open edit hatching
hrErr = pPart->Open(FALSE);
}
}
// Must unlock at the bottom in case object gets deleted
//
Lock (FALSE, fShutdown);
}
return hrErr;
}
HRESULT _IFUNC BOleSite::AssembleMenus ()
{
HRESULT hrErr = NOERROR;
hMenuShared = CreateMenu ();
if (hMenuShared) {
hrErr = pIPFrame->InsertMenus (hMenuShared, &menuGroupWidths);
if (hrErr == NOERROR) {
hrErr = pPart->InsertMenus (hMenuShared, (BOleMenuWidths *)&menuGroupWidths);
}
else {
// Even when the in-place container does not allow menu merging
// the server must still call OleCreateMenuDescriptor(NULL)
//
DestroyMenu (hMenuShared);
hMenuShared = NULL;
}
}
hOleMenu = OleCreateMenuDescriptor (hMenuShared, &menuGroupWidths);
if (!hOleMenu)
hrErr = ResultFromScode (E_OUTOFMEMORY);
return hrErr;
}
void _IFUNC BOleSite::DisassembleMenus ()
{
if (hOleMenu) {
OleDestroyMenuDescriptor (hOleMenu);
hOleMenu = 0;
}
if (hMenuShared) {
UINT uDeleteAt = 0;
for (UINT uGroup = 0; uGroup < 6; uGroup++) {
uDeleteAt += menuGroupWidths.width [uGroup++];
for (UINT uCount = 0; uCount < menuGroupWidths.width [uGroup]; uCount++)
DeleteMenu (hMenuShared, uDeleteAt, MF_BYPOSITION);
}
if (pIPFrame)
pIPFrame->RemoveMenus (hMenuShared);
DestroyMenu (hMenuShared);
hMenuShared = 0;
}
}
HRESULT _IFUNC BOleSite::DoInPlaceActivate (BOOL fActivateOnly)
{
HRESULT hrErr = NOERROR;
if (pClientSite && !fInPlaceActive /*&& !fShown*/) {
hrErr = pClientSite->QueryInterface(IID_IOleInPlaceSite,&(void *)pIPSite);
if (SUCCEEDED(hrErr)) {
hrErr = pIPSite->CanInPlaceActivate ();
if (GetScode(hrErr) == S_OK) { //returns S_FALSE instead of E_FAIL
hrErr = pIPSite->OnInPlaceActivate ();
if (SUCCEEDED(hrErr)) {
fInPlaceActive = TRUE;
hrErr = DoInPlaceShow (fActivateOnly);
if (SUCCEEDED(hrErr))
hrErr = DoUIActivate ();
}
else {
pIPSite->Release();
pIPSite = 0;
}
}
else {
pIPSite->Release();
pIPSite = 0;
}
}
}
return hrErr;
}
HRESULT _IFUNC BOleSite::CalcZoom( LPCRECT rcPosRect )
{
SIZE sCurrent;
HRESULT hr = pProvider->GetPartSize (&sCurrent);
if (SUCCEEDED(hr)) {
if (sCurrent.cx == 0) {
scale.xN = 1;
scale.xD = 1;
} else {
scale.xN = rcPosRect->right - rcPosRect->left;
scale.xD = sCurrent.cx;
}
if (sCurrent.cy == 0) {
scale.yN = 1;
scale.yD = 1;
} else {
scale.yN = rcPosRect->bottom - rcPosRect->top;
scale.yD = sCurrent.cy;
}
}
return hr;
}
HRESULT _IFUNC BOleSite::DoInPlaceShow (BOOL fActivateOnly)
{
HRESULT hrErr = NOERROR;
if (!fInPlaceVisible) {
fInPlaceVisible = TRUE;
hrErr = pIPSite->GetWindow (&hWndParent);
if (SUCCEEDED(hrErr)) {
frameInfo.cb = sizeof (frameInfo);
hrErr = pIPSite->GetWindowContext (
&pIPFrame, &pIPDoc, &rcPosRect, &rcClipRect, &frameInfo);
CalcZoom( &rcPosRect );
if (SUCCEEDED(hrErr) && pIPFrame) {
// set message filter (ICS)
hWndInPlace = pPart->OpenInPlace (hWndParent);
AssembleMenus ();
if (fInsideOut && fActivateOnly) {
// show object without adornments and border
pPart->SetPartPos (&rcPosRect);
}
}
else {
DoInPlaceDeactivate ();
}
}
else {
DoInPlaceDeactivate ();
}
}
return hrErr;
}
HRESULT _IFUNC BOleSite::DoUIActivate ()
{
HRESULT hrErr = NOERROR;
if (!fUIActive) {
fUIActive = TRUE;
//
//
//
//
//
//
hrErr = pIPSite->OnUIActivate ();
if (SUCCEEDED(hrErr)) {
if (pHatchWnd) {
// Put the hatch window around the inplace window. The offset
// is necessary because we're reparenting the inplace window
// behind the scenes, so the border of the hatch window would
// throw rcPosRect off.
//
::SetParent (hWndInPlace, *pHatchWnd);
::SetParent (*pHatchWnd, hWndParent);
pHatchWnd->SetSize (&rcPosRect, &rcClipRect, &hatchOffset);
pHatchWnd->Show (TRUE, pIPSite);
::OffsetRect (&rcPosRect, hatchOffset.x, hatchOffset.y);
}
pPart->SetPartPos (&rcPosRect);
pPart->Show(TRUE); // Show after SetPos to prevent flashing
// window position of part may need to move but the extent
// should be the same
pPart->Activate (TRUE);
pIPFrame->SetActiveObject (this, pInPlaceName);
if (pIPDoc)
pIPDoc->SetActiveObject (this, pInPlaceName);
pIPFrame->SetMenu (hMenuShared, hOleMenu, hWndInPlace);
pPart->ShowTools (TRUE);
}
else {
fUIActive = FALSE;
}
}
return hrErr;
}
HRESULT _IFUNC BOleSite::DoInPlaceDeactivate ()
{
HRESULT hrErr = NOERROR;
if (fInPlaceActive) {
hrErr = DoUIDeactivate ();
if (SUCCEEDED(hrErr) && fInPlaceActive) {
fInPlaceActive = FALSE;
pIPSite->OnInPlaceDeactivate ();
pIPSite->Release();
pIPSite = 0;
}
}
return hrErr;
}
HRESULT _IFUNC BOleSite::DoUIDeactivate ()
{
if (!SUCCEEDED(pPart->Show (FALSE)))
return ResultFromScode (E_FAIL); // Hide here to match Show which prevents flashing
HRESULT hrErr = NOERROR;
if (fUIActive) {
fUIActive = FALSE;
//
//
//
//
//
//
// remove shading and adornments
if (pIPDoc)
pIPDoc->SetActiveObject (NULL, NULL);
if (pIPFrame)
pIPFrame->SetActiveObject (NULL, NULL);
pPart->ShowTools (FALSE);
pIPSite->OnUIDeactivate (FALSE);
// deactivate contained objects if any
if (!fInsideOut) {
DoInPlaceHide ();
if (pIPFrame) {
pIPFrame->Release();
pIPFrame = 0;
}
if (pIPDoc) {
pIPDoc->Release();
pIPDoc = 0;
}
}
}
return hrErr;
}
HRESULT _IFUNC BOleSite::DoInPlaceHide ()
{
HRESULT hrErr = NOERROR;
if (fInPlaceVisible) {
// deactivate contained objects (ICS)
// remove shading and adornments (ICS)
hrErr = pPart->OpenInPlace (0) == NULL ? ResultFromScode (E_FAIL) : NOERROR;
if (pHatchWnd)
// Hide the hatch window
//
pHatchWnd->Show (FALSE);
// set filter ? (ICS)
DisassembleMenus ();
HideWindow (FALSE);
fInPlaceVisible = FALSE;
}
return hrErr;
}
HRESULT _IFUNC BOleSite::DoVerb (LONG lVerb, LPMSG lpmsg, IOleClientSite* pActiveSite, LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
{
HRESULT hrErr = NOERROR;
switch (lVerb) {
default:
// First ask the server app if it knows this verb
//
hrErr = pPart->DoVerb ((UINT)lVerb);
if (SUCCEEDED(hrErr))
return hrErr;
// If the server app doesn't know it, and it's a predefined (<0)
// verb, return an error
//
hrErr = ResultFromScode (OLEOBJ_S_INVALIDVERB);
if (lVerb < 0)
OLERES(hrErr);
// If it's not a predefined verb and we don't know it, deliberately
// fall through to Primary Verb
case OLEIVERB_PRIMARY:
case OLEIVERB_SHOW:
// If the window is already open (primary verb has already been
// run, just bring the window to the front
//
if (pClientSite && !fShown && !fInPlaceActive &&
(S_OK == GetScode(pPart->CanOpenInPlace())))
hrErr = DoInPlaceActivate (FALSE);
else if (fInPlaceActive && !fInPlaceVisible) {
if (SUCCEEDED(DoInPlaceShow (FALSE))) {
hrErr = DoUIActivate ();
}
}
hrErr = ShowWindow ();
break;
case 1:
case OLEIVERB_OPEN:
if (pClientSite && fInPlaceActive)
hrErr = DoInPlaceDeactivate ();
hrErr = ShowWindow ();
break;
case OLEIVERB_HIDE:
if (pClientSite && fInPlaceActive)
hrErr = DoInPlaceHide ();
else
hrErr = HideWindow (TRUE /*fShutdown*/);
break;
case OLEIVERB_UIACTIVATE:
case OLEIVERB_INPLACEACTIVATE:
// If our window is already open-editing we can't activate in-place.
//
if (pClientSite && !fShown && !fInPlaceActive &&
(S_OK == GetScode(pPart->CanOpenInPlace())))
hrErr = DoInPlaceActivate (lVerb == OLEIVERB_INPLACEACTIVATE);
else
hrErr = ResultFromScode (OLE_E_NOT_INPLACEACTIVE);
break;
}
return hrErr;
}
HRESULT _IFUNC BOleSite::EnumVerbs (IEnumOLEVERB* FAR* ppenumOleVerb)
{
return OleRegEnumVerbs(cid, ppenumOleVerb);
//
//
}
HRESULT _IFUNC BOleSite::Update ()
{
return ResultFromScode(S_OK);
}
HRESULT _IFUNC BOleSite::IsUpToDate ()
{
return ResultFromScode(MK_E_UNAVAILABLE);
}
HRESULT _IFUNC BOleSite::GetUserClassID (CLSID FAR* pClsid)
{
*pClsid = cid;
return NOERROR;
}
HRESULT _IFUNC BOleSite::GetUserType (DWORD dwFormOfType, LPOLESTR FAR* pszUserType)
{
return ResultFromScode (OLE_S_USEREG);
}
HRESULT _IFUNC BOleSite::SetExtent (DWORD dwDrawAspect, LPSIZEL lpsizel)
{
RECT pos;
pos.left = pos.top = 0;
pos.right = MAP_LOGHIM_TO_PIX (lpsizel->cx, BOleService::pixPerIn.x);
pos.bottom = MAP_LOGHIM_TO_PIX (lpsizel->cy, BOleService::pixPerIn.y);
SIZE size;
size.cx = pos.right;
size.cy = pos.bottom;
HRESULT hr = pPart->SetPartSize(&size);
if (SUCCEEDED(hr)) {
Invalidate(BOLE_INVAL_VIEW);
pPart->SetPartPos (&pos);
}
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
return hr;
}
HRESULT _IFUNC BOleSite::GetExtent (DWORD dwDrawAspect, LPSIZEL lpsizel)
{
if (dwDrawAspect != DVASPECT_CONTENT) //PHP for now.
return ResultFromScode (E_FAIL);
if (!lpsizel)
return ResultFromScode (E_INVALIDARG);
SIZE s;
HRESULT hr = pProvider->GetPartSize (&s); //PHP do we need aspect here?
lpsizel->cx = MAP_PIX_TO_LOGHIM (s.cx, BOleService::pixPerIn.x);
lpsizel->cy = MAP_PIX_TO_LOGHIM (s.cy, BOleService::pixPerIn.y);
return hr;
}
HRESULT _IFUNC BOleSite::Advise (IAdviseSink* pAdvSink, DWORD FAR* pdwConnection)
{
HRESULT hrErr;
*pdwConnection = 0;
if (pAdvHolder == 0)
hrErr = CreateOleAdviseHolder (&pAdvHolder);
if (pAdvHolder)
hrErr = pAdvHolder->Advise (pAdvSink, pdwConnection);
else
hrErr = ResultFromScode (E_OUTOFMEMORY);
return hrErr;
}
HRESULT _IFUNC BOleSite::Unadvise (DWORD dwConnection)
{
HRESULT hrErr = ResultFromScode (E_FAIL);
if (pAdvHolder)
hrErr = pAdvHolder->Unadvise (dwConnection);
return hrErr;
}
HRESULT _IFUNC BOleSite::EnumAdvise (IEnumSTATDATA* FAR* ppenumAdvise)
{
HRESULT hrErr = ResultFromScode (E_FAIL);
if (pAdvHolder)
hrErr = pAdvHolder->EnumAdvise (ppenumAdvise);
return hrErr;
}
HRESULT _IFUNC BOleSite::GetMiscStatus (DWORD dwAspect, DWORD FAR* pdwStatus)
{
return ResultFromScode (OLE_S_USEREG);
}
HRESULT _IFUNC BOleSite::SetColorScheme (LPLOGPALETTE lpLogpal)
{
return ResultFromScode (E_NOTIMPL);
}
//**************************************************************************
//
// IPersist implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::GetClassID (LPCLSID lpClassID)
{
*lpClassID = cid;
return NOERROR;
}
HRESULT _IFUNC BOleSite::IsDirty ()
{
return ResultFromScode((fIsDirty) ? S_OK : S_FALSE);
}
//**************************************************************************
//
// IPersistStorage implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::InitNew (IStorage* pStgNew)
{
if (pStg) {
pStg->Release ();
pStg = NULL;
}
pStg = pStgNew;
if (pStg) {
pStg->AddRef();
}
BOleInitInfo bi;
bi.pContainer = NULL;
bi.Where = BOLE_NEW;
bi.How = BOLE_EMBED;
bi.pStorage = pStgNew;
HRESULT hr = pPart->Init(this, &bi);
if (!SUCCEEDED(hr))
return hr;
Invalidate(BOLE_INVAL_DATA);
return ResultFromScode(S_OK);
}
HRESULT _IFUNC BOleSite::Load (IStorage* pStgFrom)
{
HRESULT hresult = NOERROR;
fIsDirty = FALSE; // data will be the same as what was saved
if (pStg) {
pStg->Release ();
pStg= NULL;
}
pStg = pStgFrom;
pStg->AddRef();
BOleInitInfo bi;
bi.pContainer = NULL;
bi.Where = BOLE_STORAGE;
bi.How = BOLE_EMBED;
bi.pStorage = pStg;
hresult = pPart->Init (this, &bi);
return hresult;
}
HRESULT _IFUNC BOleSite::Save (IStorage* pStgSave, BOOL fSameAsLoad)
{
// if (fSameAsLoad && !fIsDirty) // don't bother, its up to date
// return NOERROR;
HRESULT hresult = ResultFromScode(S_OK);
if (!pStgSave && fSameAsLoad)
pStgSave = pStg;
// The online dox say that OleSave does this, but there's no
// CompObj stream without WriteFmtUseTypeStg and no CLSID in the
// stream without WriteClassStg
//
CLSID clsid = CLSID_NULL;
CLSIDFromProgID (pszProgID, &clsid);
if ((hresult = WriteClassStg (pStgSave, clsid)) != NOERROR)
return hresult;
LPOLESTR lpLongType = NULL;
OleRegGetUserType (clsid, USERCLASSTYPE_FULL, &lpLongType);
hresult = WriteFmtUserTypeStg (pStgSave, BOleDocument::oleEmbSrcClipFmt, lpLongType);
// We pass along the fHandsOff flag here to "fRemember"
// If HandsOffStorage was called before it means SaveAs is happening
// and objects need to remember their new substorages as they create them.
// We use the fRemember flag to do what what HandsOffStorage and
// SaveCompleted do (we can't scribble to storages between saves anyway)
if (SUCCEEDED(pProvider->Save( pStgSave, fSameAsLoad, fHandsOff))) {
// since we don't scribble, do the SaveCompleted stuff here
// where we know fSameAsLoad
if (fHandsOff || fSameAsLoad) { // ! save copy as situation
fIsDirty = FALSE;
if (pAdvHolder)
hresult = pAdvHolder->SendOnSave();
if (fHandsOff) {
fHandsOff = FALSE;
pStg = pStgSave; // pStg was Released in HandsOffStorage
if (pStg)
pStg->AddRef();
}
}
}
else
hresult = ResultFromScode(STG_E_CANTSAVE);
return hresult;
}
HRESULT _IFUNC BOleSite::SaveCompleted (IStorage* pStgNew)
{
if (fHandsOff) { // HandsOffStorage, SaveCompleted without Save
Save(pStgNew, FALSE);
}
return ResultFromScode(S_OK);
}
HRESULT _IFUNC BOleSite::HandsOffStorage ()
{
fHandsOff = TRUE;
if (pStg) {
pStg->Release();
pStg = NULL;
}
return ResultFromScode(S_OK);
}
//**************************************************************************
//
// IDropSource implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::QueryContinueDrag (BOOL fEscapePressed, DWORD grfKeyState)
{
if (fEscapePressed) {
OLERET (DRAGDROP_S_CANCEL);
}
if (!(grfKeyState & (MK_LBUTTON))) {
OLERET (DRAGDROP_S_DROP);
}
return ResultFromScode(S_OK);
}
HRESULT _IFUNC BOleSite::GiveFeedback (DWORD dwEffect)
{
POINT p = {0,0};
BOOL fNearScroll = FALSE;
//
// of IBDataProvider so we can do drag/drop with only a provider
//
if (!pPart)
return ResultFromScode (DRAGDROP_S_USEDEFAULTCURSORS);
if (S_OK == GetScode(pPart->DragFeedback (&p, fNearScroll))) {
return ResultFromScode (DRAGDROP_S_USEDEFAULTCURSORS);
}
else {
return ResultFromScode (S_OK);
}
}
//**************************************************************************
//
// IOleWindow implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::GetWindow (HWND FAR* lphwnd)
{
if (lphwnd) {
*lphwnd = hWndInPlace;
return NOERROR;
}
return ResultFromScode (E_INVALIDARG);
}
HRESULT _IFUNC BOleSite::ContextSensitiveHelp (BOOL fEnterMode)
{
return pService->ContextSensitiveHelp (fEnterMode);
}
//**************************************************************************
//
// IOleInPlaceObject implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::InPlaceDeactivate ()
{
return DoInPlaceDeactivate ();
}
HRESULT _IFUNC BOleSite::UIDeactivate ()
{
return DoUIDeactivate ();
}
HRESULT _IFUNC BOleSite::SetObjectRects (LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
rcPosRect = *lprcPosRect;
rcClipRect = *lprcClipRect;
RECT r;
if (pHatchWnd) {
// if (! fUIActive) // hatch and adornments should not be drawn
// lprcClipRect = lprcPosRect;
pHatchWnd->SetSize (&rcPosRect, &rcClipRect, &hatchOffset);
r = rcPosRect;
// offset hatch border
::OffsetRect (&r, hatchOffset.x, hatchOffset.y);
}
else
r = rcPosRect;
CalcZoom (lprcPosRect);
pPart->SetPartPos (&r);
return NOERROR;
}
HRESULT _IFUNC BOleSite::GetZoom( BOleScaleFactor *pScale)
{
if (fInPlaceActive) {
*pScale = scale;
}
else {
pScale->xN = 1;
pScale->yN = 1;
pScale->xD = 1;
pScale->yD = 1;
}
return NOERROR;
}
HRESULT _IFUNC BOleSite::ReactivateAndUndo ()
{
HRESULT hrErr;
if (pClientSite && !fShown && !fInPlaceActive &&
(S_OK == GetScode(pPart->CanOpenInPlace())))
hrErr = DoInPlaceActivate (OLEIVERB_INPLACEACTIVATE);
else
hrErr = ResultFromScode (OLE_E_NOT_INPLACEACTIVE);
// do undo?
return hrErr;
}
//**************************************************************************
//
// IOleInPlaceActiveObject implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::TranslateAccelerator (LPMSG lpmsg)
{
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::OnFrameWindowActivate (BOOL fActivate)
{
// post message to server app ? (ICS)
return NOERROR;
}
HRESULT _IFUNC BOleSite::OnDocWindowActivate (BOOL fActivate)
{
if (fActivate) {
pIPFrame->SetActiveObject ((IOleInPlaceActiveObject *)this, pInPlaceName);
pIPFrame->SetMenu (hMenuShared, hOleMenu, hWndInPlace);
pPart->ShowTools (TRUE);
}
else {
pIPFrame->SetActiveObject (NULL, NULL);
pPart->ShowTools (FALSE);
// deactivate contained objects if any (ICS)
}
return NOERROR;
}
HRESULT _IFUNC BOleSite::ResizeBorder (LPCRECT lprectBorder, LPOLEINPLACEUIWINDOW lpUIWindow, BOOL fFrameWindow)
{
pPart->FrameResized(lprectBorder, fFrameWindow);
return ResultFromScode(S_OK);
}
HRESULT _IFUNC BOleSite::EnableModeless (BOOL fEnable)
{
return pService->GetApplication()->OnModalDialog (!fEnable);
}
//**************************************************************************
//
// IContainer implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::AllowInPlace()
{
// anything we can use this for on server side??
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::BringToFront()
{
// anything we can use this for on server side??
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::FindDropDest (LPPOINT, PIBDropDest FAR*)
{
// anything we can use this for on server side??
return ResultFromScode (E_NOTIMPL);
}
HWND _IFUNC BOleSite::GetWindow()
{
HWND hWnd;
return (pIPSite && pIPSite->GetWindow (&hWnd) == NOERROR) ? hWnd : 0;
}
HRESULT _IFUNC BOleSite::GetWindowRect(LPRECT pR)
{
if (pIPDoc)
return pIPDoc->GetBorder (pR);
return ResultFromScode (E_FAIL);
}
HRESULT _IFUNC BOleSite::RequestBorderSpace(LPCRECT pR)
{
BORDERWIDTHS r;
if (pR) {
r = *pR; // Word bums modify our LPCRECT contents
pR = &r;
}
if (pIPDoc)
return pIPDoc->RequestBorderSpace (pR);
return ResultFromScode (E_FAIL);
}
HRESULT _IFUNC BOleSite::SetBorderSpace(LPCRECT pR)
{
BORDERWIDTHS r;
if (pR) {
r = *pR; // Word bums modify our LPCRECT contents
pR = &r;
}
if (pIPDoc)
return pIPDoc->SetBorderSpace (pR);
return ResultFromScode (E_FAIL);
}
LPCOLESTR _IFUNC BOleSite::GetWindowTitle()
{
return pWindowTitle;
}
void _IFUNC BOleSite::AppendWindowTitle(LPCOLESTR)
{
//PHP Do we need to call SetActiveObject???
}
//**************************************************************************
//
// ISite implementation
//
//**************************************************************************
HRESULT _IFUNC BOleSite::SiteShow(BOOL)
{
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::DiscardUndo()
{
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::GetSiteRect(LPRECT prcPos,LPRECT prcClip)
{
if( prcPos )
*prcPos = rcPosRect;
if( prcClip )
*prcClip = rcClipRect;
return NOERROR;
}
HRESULT _IFUNC BOleSite::SetSiteRect(LPCRECT pR)
{
// Can be useful for hatch window implementations or resizing
// the server when in-place active
HRESULT hr;
SIZE s;
s.cx = pR->right - pR->left;
s.cy = pR->bottom - pR->top;
if (SUCCEEDED(hr = SetSiteExtent(&s))) {
// Ask the client to resize to the new size of the window
if (pIPSite) {
hr = pIPSite->OnPosRectChange (pR);
}
}
return hr;
}
HRESULT _IFUNC BOleSite::SetSiteExtent (LPCSIZE pS)
{
SIZE s = *pS;
// Servers call this to update their own scaled size
// and notify the container of the change
BOleScaleFactor scale;
GetZoom(&scale);
s.cx = s.cx * scale.xD / scale.xN; // unscale
s.cy = s.cy * scale.yD / scale.yN;
HRESULT hr = pPart->SetPartSize(&s);
if (SUCCEEDED(hr)) {
// Invalidate the metafile since it's size has changed
Invalidate(BOLE_INVAL_VIEW);
}
return hr;
}
void _IFUNC BOleSite::Invalidate(BOleInvalidate inval)
{
// The PERSISTENT flag is used for servers "Update" menu.
//
if (inval & BOLE_INVAL_PERSISTENT && pClientSite) {
pClientSite->SaveObject ();
fIsDirty = FALSE;
}
// We're not distinguishing between the other two flags on the
// server side
//
if (inval & BOLE_INVAL_VIEW || inval & BOLE_INVAL_DATA) {
fIsDirty = TRUE;
if (pDAdvHolder)
pDAdvHolder->SendOnDataChange (this, 0, 0);
}
}
void _IFUNC BOleSite::OnSetFocus(BOOL bSet)
{
pService->SetFocusedSite( bSet ? this : NULL );
}
void _IFUNC BOleSite::Disconnect ()
{
//
//
//
Close(OLECLOSE_SAVEIFDIRTY);
}
//**************************************************************************
//
// IApplication implementation
//
//**************************************************************************
LPCOLESTR _IFUNC BOleSite::IBApplicationImpl::GetAppName()
{
return pThis->pAppName;
}
// This is called when an inplace active object receives a Shift-F1
// keystroke. We need to call our container so that other objects can
// be prepared to give context-sensitive help if clicked.
//
BOleHelp _IFUNC BOleSite::IBApplicationImpl::HelpMode (BOleHelp newMode)
{
BOleHelp oldMode = (BOleHelp) pThis->fInHelpMode;
if (newMode != BOLE_HELP_GET)
if (pThis->pIPSite) {
pThis->fInHelpMode = newMode == BOLE_HELP_ENTER;
pThis->pIPSite->ContextSensitiveHelp (pThis->fInHelpMode);
}
return oldMode;
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::InsertContainerMenus(HMENU hMenu,BOleMenuWidths FAR* pMW)
{
return pThis->InsertContainerMenus(hMenu, pMW);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::SetFrameMenu (HMENU h)
{
return pThis->SetFrameMenu(h);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::Accelerator(MSG FAR*pMsg)
{
return pThis->Accelerator(pMsg);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::GetAccelerators (HACCEL FAR*, int FAR*)
{
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::CanLink()
{
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::CanEmbed()
{
return ResultFromScode (E_NOTIMPL);
}
HWND _IFUNC BOleSite::IBApplicationImpl::GetWindow ()
{
HWND hWnd;
return (pThis->pIPFrame && pThis->pIPFrame->GetWindow (&hWnd) == NOERROR) ? hWnd : 0;
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::RequestBorderSpace (LPCRECT pR)
{
BORDERWIDTHS r;
if (pR) {
r = *pR; // Word modifies our LPCRECT contents
pR = &r;
}
if (pThis->pIPFrame)
return pThis->pIPFrame->RequestBorderSpace (pR);
return ResultFromScode (E_FAIL);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::SetBorderSpace (LPCRECT pR)
{
BORDERWIDTHS r;
if (pR) {
r = *pR; // Word bums modify our LPCRECT contents
pR = &r;
}
if (pThis->pIPFrame)
return pThis->pIPFrame->SetBorderSpace (pR);
return ResultFromScode (E_FAIL);
}
void _IFUNC BOleSite::IBApplicationImpl::AppendWindowTitle (LPCOLESTR s)
{
if (pThis->pIPFrame)
pThis->pIPFrame->SetActiveObject(pThis, s);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::SetStatusText (LPCOLESTR s)
{
if (pThis->pIPFrame)
return pThis->pIPFrame->SetStatusText(s);
return ResultFromScode(E_FAIL);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::IsMDI ()
{
if (pThis->pIPDoc)
return ResultFromScode (S_OK);
else
return ResultFromScode (S_FALSE);
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::OnModalDialog (BOOL fDialogComingActive)
{
return (pThis->pIPFrame) ?
pThis->pIPFrame->EnableModeless (!fDialogComingActive) :
NOERROR;
}
void _IFUNC BOleSite::IBApplicationImpl::RestoreUI ()
{
//PHP Server object should use this instead of SetBorderSpace(NULL)
// and AppendWindowTitle(NULL). Semantics are much cleaner.
}
void _IFUNC BOleSite::IBApplicationImpl::DialogHelpNotify (BOleDialogHelp helpCode)
{
// unimplemented in server side helper
}
void _IFUNC BOleSite::IBApplicationImpl::ShutdownMaybe ()
{
// unimplemented in server side helper
}
//
// ILinkable
//
HRESULT _IFUNC BOleSite::GetMoniker(IMoniker FAR* FAR* ppMon)
{
return GetMoniker(OLEGETMONIKER_ONLYIFTHERE,
OLEWHICHMK_OBJFULL, ppMon);
}
HRESULT _IFUNC BOleSite::OnRename(PIBLinkable pCont, LPCOLESTR szName)
{
HRESULT ret = NOERROR;
if (pCont)
pCont->GetMoniker(&pmkDoc);
else if (pmkDoc) {
// Reset cached format list to cause it to be updated next time
// (now that link format is enabled/disabled).
//
//
if (formatList) {
delete [] formatList;
formatLink = FALSE;
formatEmbed = FALSE;
formatList = NULL;
formatCount = 0;
}
if (pService->IsOnClipboard(this)) {
// remove the linking capability from this object if one calls
// OnRename(NULL, NULL) before Close rather during Close
//
//
AddRef();
pService->Clip(NULL, FALSE, FALSE, FALSE);
pService->Clip(pProvider, FALSE, pService->clipOkToEmbed, FALSE);
Release();
}
if (pmkDoc) {
pmkDoc->Release();
pmkDoc = NULL;
}
}
if (pszInstName) {
delete [] pszInstName;
pszInstName = NULL;
}
if (szName) {
pszInstName = new OLECHAR[strlen (szName) +1];
lstrcpy(pszInstName, szName);
}
// Don't register if this is a clone (pPart is NULL)
// otherwise we would link to what's on the clipboard...
//
// Also don't bother if it is only a document (no item name)
// (pszInstName may be NULL and pmkDoc valid, in that case
// we shouldn't register here. BOleContainer already registered it.
//
//
if (pPart && pmkDoc && pszInstName)
SetMoniker(OLEWHICHMK_OBJFULL, NULLP); // register
if (!pmkDoc && (regLink != 0L)) {
// Unregister for linking if pmkDoc is NULL
LPRUNNINGOBJECTTABLE pROT = NULL;
HRESULT hr = OLE::GetRunningObjectTable (0, &pROT);
if (SUCCEEDED(hr)) {
pROT->Revoke(regLink);
regLink = 0L;
pROT->Release();
}
}
return ret;
}
HRESULT _IFUNC BOleSite::SetStatusText (LPCOLESTR s)
{
if (pIPFrame)
return pIPFrame->SetStatusText(s);
return ResultFromScode(E_FAIL);
}
LPCOLESTR _IFUNC BOleSite::IBApplicationImpl::GetWindowTitle()
{
return pThis->pWindowTitle;
}
HRESULT _IFUNC BOleSite::IBApplicationImpl::GetWindowRect(LPRECT pR)
{
if (pThis->pIPFrame)
return pThis->pIPFrame->GetBorder (pR);
return ResultFromScode(CO_E_OBJNOTCONNECTED);
}
HRESULT _IFUNC BOleSite::GetAccelerators( HACCEL FAR *,int far*)
{
return ResultFromScode (E_NOTIMPL);
}
HRESULT _IFUNC BOleSite::Accelerator(MSG FAR*pMsg)
{
// Give the container a chance to handle its accelerators.
// Returns S_OK if processed or S_FALSE if no accelerator was met.
if (pIPFrame)
return OleTranslateAccelerator( pIPFrame, &frameInfo, pMsg );
return ResultFromScode(S_FALSE);
}
void _IFUNC BOleSite::RestoreUI()
{
}
// This little trick allows Bolero servers to dynamically renegotiate
// the menu bar in case some state changes while they're inplace active
//
HRESULT _IFUNC BOleSite::SetFrameMenu(HMENU)
{
// First get the client to let go of the menus so we can put new ones up
//
if (pIPFrame)
pIPFrame->SetMenu (NULL, hOleMenu, hWndInPlace);
DisassembleMenus (); // Tear down the old shared menu
HRESULT hr = AssembleMenus (); // Put together a new shared menu
if (!SUCCEEDED(hr))
return hr;
// Tell the client to install it
return pIPFrame->SetMenu (hMenuShared, hOleMenu, hWndInPlace);
}
HRESULT _IFUNC BOleSite::InsertContainerMenus(HMENU hMenu,BOleMenuWidths far*)
{
if (pIPFrame)
return pIPFrame->InsertMenus (hMenu, &menuGroupWidths);
return ResultFromScode (CO_E_OBJNOTCONNECTED);
}