638 lines
17 KiB
C++
638 lines
17 KiB
C++
|
//**********************************************************************
|
||
|
// File name: SITE.CPP
|
||
|
//
|
||
|
// Implementation file for CSimpleSite
|
||
|
//
|
||
|
// Functions:
|
||
|
//
|
||
|
// See SITE.H for class definition
|
||
|
//
|
||
|
// Copyright (c) 1992 - 1993 Microsoft Corporation. All rights reserved.
|
||
|
//**********************************************************************
|
||
|
|
||
|
#include "pre.h"
|
||
|
#include "iocs.h"
|
||
|
#include "ias.h"
|
||
|
#include "ioipf.h"
|
||
|
#include "ioips.h"
|
||
|
#include "app.h"
|
||
|
#include "site.h"
|
||
|
#include "doc.h"
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::Create
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Creation routine for CSimpleSite
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// CSimpleDoc FAR *lpDoc - Pointer to CSimpleDoc
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// CSimpleSite::CSimpleSite SITE.CPP
|
||
|
// IStorage::CreateStorage OLE API
|
||
|
// CSimpleSite::AddRef SITE.CPP
|
||
|
// assert C Runtime
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
CSimpleSite FAR * CSimpleSite::Create(CSimpleDoc FAR *lpDoc)
|
||
|
{
|
||
|
CSimpleSite FAR * lpTemp = new CSimpleSite(lpDoc);
|
||
|
|
||
|
if (!lpTemp)
|
||
|
return NULL;
|
||
|
|
||
|
// create a sub-storage for the object
|
||
|
HRESULT hErr = lpDoc->m_lpStorage->CreateStorage( OLESTR("Object"),
|
||
|
STGM_READWRITE | STGM_TRANSACTED | STGM_SHARE_EXCLUSIVE,
|
||
|
0,
|
||
|
0,
|
||
|
&lpTemp->m_lpObjStorage);
|
||
|
|
||
|
assert(hErr == NOERROR);
|
||
|
|
||
|
if (hErr != NOERROR)
|
||
|
{
|
||
|
delete lpTemp;
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// we will add one ref count on our Site. later when we want to destroy
|
||
|
// the Site object we will release this ref count. when the Site's ref
|
||
|
// count goes to 0, it will be deleted.
|
||
|
lpTemp->AddRef();
|
||
|
|
||
|
return lpTemp;
|
||
|
}
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::CSimpleSite
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Constructor for CSimpleSite
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// CSimpleDoc FAR *lpDoc - Pointer to CSimpleDoc
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
#pragma warning(disable : 4355) // turn off this warning. This warning
|
||
|
// tells us that we are passing this in
|
||
|
// an initializer, before "this" is through
|
||
|
// initializing. This is ok, because
|
||
|
// we just store the ptr in the other
|
||
|
// constructors
|
||
|
|
||
|
CSimpleSite::CSimpleSite (CSimpleDoc FAR *lpDoc) : m_OleClientSite(this),
|
||
|
m_AdviseSink(this),
|
||
|
m_OleInPlaceSite(this)
|
||
|
#pragma warning (default : 4355) // Turn the warning back on
|
||
|
{
|
||
|
TestDebugOut (TEXT("In CSimpleSite's Constructor \r\n"));
|
||
|
|
||
|
// remember the pointer to the doc
|
||
|
m_lpDoc = lpDoc;
|
||
|
|
||
|
// clear the reference count
|
||
|
m_nCount = 0;
|
||
|
|
||
|
m_dwDrawAspect = DVASPECT_CONTENT;
|
||
|
m_lpOleObject = NULL;
|
||
|
m_lpInPlaceObject = NULL;
|
||
|
m_hwndIPObj = NULL;
|
||
|
m_fInPlaceActive = FALSE;
|
||
|
m_fObjectOpen = FALSE;
|
||
|
}
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::~CSimpleSite
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Destructor for CSimpleSite
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// TestDebugOut Windows API
|
||
|
// IOleObject::Release Object
|
||
|
// IStorage::Release OLE API
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
CSimpleSite::~CSimpleSite ()
|
||
|
{
|
||
|
TestDebugOut (TEXT("In CSimpleSite's Destructor \r\n"));
|
||
|
|
||
|
if (m_lpOleObject)
|
||
|
m_lpOleObject->Release();
|
||
|
|
||
|
if (m_lpObjStorage)
|
||
|
m_lpObjStorage->Release();
|
||
|
}
|
||
|
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::CloseOleObject
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Call IOleObject::Close on the object of the CSimpleSite
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// TestDebugOut Windows API
|
||
|
// IOleObject::QueryInterface Object
|
||
|
// IOleObject::Close Object
|
||
|
// IOleInPlaceObject::UIDeactivate Object
|
||
|
// IOleInPlaceObject::InPlaceDeactivate Object
|
||
|
// IOleInPlaceObject::Release Object
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
void CSimpleSite::CloseOleObject (void)
|
||
|
{
|
||
|
LPOLEINPLACEOBJECT lpObject;
|
||
|
LPVIEWOBJECT lpViewObject = NULL;
|
||
|
|
||
|
TestDebugOut (TEXT("In CSimpleSite::CloseOleObject \r\n"));
|
||
|
|
||
|
if (m_lpOleObject)
|
||
|
{
|
||
|
if (m_fInPlaceActive)
|
||
|
{
|
||
|
m_lpOleObject->QueryInterface(IID_IOleInPlaceObject,
|
||
|
(LPVOID FAR *)&lpObject);
|
||
|
lpObject->UIDeactivate();
|
||
|
// don't need to worry about inside-out because the object
|
||
|
// is going away.
|
||
|
lpObject->InPlaceDeactivate();
|
||
|
lpObject->Release();
|
||
|
}
|
||
|
|
||
|
m_lpOleObject->Close(OLECLOSE_NOSAVE);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::UnloadOleObject
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Close and release all pointers to the object of the CSimpleSite
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// TestDebugOut Windows API
|
||
|
// CSimpleSite::CloseOleObject SITE.CPP
|
||
|
// IOleObject::QueryInterface Object
|
||
|
// IOleObject::Release Object
|
||
|
// IViewObject::SetAdvise Object
|
||
|
// IViewObject::Release Object
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
void CSimpleSite::UnloadOleObject (void)
|
||
|
{
|
||
|
TestDebugOut (TEXT("In CSimpleSite::UnloadOleObject \r\n"));
|
||
|
|
||
|
if (m_lpOleObject)
|
||
|
{
|
||
|
LPVIEWOBJECT lpViewObject;
|
||
|
CloseOleObject(); // ensure object is closed; NOP if already closed
|
||
|
|
||
|
m_lpOleObject->QueryInterface(IID_IViewObject,
|
||
|
(LPVOID FAR *)&lpViewObject);
|
||
|
|
||
|
if (lpViewObject)
|
||
|
{
|
||
|
// Remove the view advise
|
||
|
lpViewObject->SetAdvise(m_dwDrawAspect, 0, NULL);
|
||
|
lpViewObject->Release();
|
||
|
}
|
||
|
|
||
|
m_lpOleObject->Release();
|
||
|
m_lpOleObject = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::QueryInterface
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Used for interface negotiation of the container Site.
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// REFIID riid - A reference to the interface that is
|
||
|
// being queried.
|
||
|
//
|
||
|
// LPVOID FAR* ppvObj - An out parameter to return a pointer to
|
||
|
// the interface.
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// S_OK - The interface is supported.
|
||
|
// E_NOINTERFACE - The interface is not supported
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// TestDebugOut Windows API
|
||
|
// IsEqualIID OLE API
|
||
|
// ResultFromScode OLE API
|
||
|
// CSimpleSite::AddRef OBJ.CPP
|
||
|
// COleClientSite::AddRef IOCS.CPP
|
||
|
// CAdviseSink::AddRef IAS.CPP
|
||
|
// COleInPlaceSite::AddRef IOIPS.CPP
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
STDMETHODIMP CSimpleSite::QueryInterface(REFIID riid, LPVOID FAR* ppvObj)
|
||
|
{
|
||
|
TestDebugOut(TEXT("In CSimpleSite::QueryInterface\r\n"));
|
||
|
|
||
|
*ppvObj = NULL; // must set out pointer parameters to NULL
|
||
|
|
||
|
if ( IsEqualIID(riid, IID_IUnknown))
|
||
|
{
|
||
|
AddRef();
|
||
|
*ppvObj = this;
|
||
|
return ResultFromScode(S_OK);
|
||
|
}
|
||
|
|
||
|
if ( IsEqualIID(riid, IID_IOleClientSite))
|
||
|
{
|
||
|
m_OleClientSite.AddRef();
|
||
|
*ppvObj = &m_OleClientSite;
|
||
|
return ResultFromScode(S_OK);
|
||
|
}
|
||
|
|
||
|
if ( IsEqualIID(riid, IID_IAdviseSink))
|
||
|
{
|
||
|
m_AdviseSink.AddRef();
|
||
|
*ppvObj = &m_AdviseSink;
|
||
|
return ResultFromScode(S_OK);
|
||
|
}
|
||
|
|
||
|
if ( IsEqualIID(riid, IID_IOleInPlaceSite))
|
||
|
{
|
||
|
m_OleInPlaceSite.AddRef();
|
||
|
*ppvObj = &m_OleInPlaceSite;
|
||
|
return ResultFromScode(S_OK);
|
||
|
}
|
||
|
|
||
|
// Not a supported interface
|
||
|
return ResultFromScode(E_NOINTERFACE);
|
||
|
}
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::AddRef
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Increments the reference count of the container Site.
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// ULONG - The new reference count of the site.
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// TestDebugOut Windows API
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CSimpleSite::AddRef()
|
||
|
{
|
||
|
TestDebugOut(TEXT("In CSimpleSite::AddRef\r\n"));
|
||
|
|
||
|
return ++m_nCount;
|
||
|
}
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::Release
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Decrements the reference count of the container Site
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// ULONG - The new reference count of the Site.
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// TestDebugOut Windows API
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
STDMETHODIMP_(ULONG) CSimpleSite::Release()
|
||
|
{
|
||
|
TestDebugOut(TEXT("In CSimpleSite::Release\r\n"));
|
||
|
|
||
|
if (--m_nCount == 0)
|
||
|
{
|
||
|
delete this;
|
||
|
return 0;
|
||
|
}
|
||
|
return m_nCount;
|
||
|
}
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::InitObject
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Used to initialize a newly create object (can't be done in the
|
||
|
// constructor).
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// BOOL fCreateNew - TRUE if insert NEW object
|
||
|
// FALSE if create object FROM FILE
|
||
|
//
|
||
|
// Return Value:
|
||
|
//
|
||
|
// None
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// IOleObject::SetHostNames Object
|
||
|
// IOleObject::QueryInterface Object
|
||
|
// IViewObject2::GetExtent Object
|
||
|
// IOleObject::DoVerb Object
|
||
|
// IViewObject2::SetAdvise Object
|
||
|
// IViewObject2::Release Object
|
||
|
// GetClientRect Windows API
|
||
|
// OleSetContainedObject OLE API
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
void CSimpleSite::InitObject(BOOL fCreateNew)
|
||
|
{
|
||
|
LPVIEWOBJECT2 lpViewObject2;
|
||
|
RECT rect;
|
||
|
|
||
|
TestDebugOut(TEXT("In CSimpleSite::InitObject\r\n"));
|
||
|
|
||
|
// Set a View Advise
|
||
|
m_lpOleObject->QueryInterface(IID_IViewObject2,
|
||
|
(LPVOID FAR *)&lpViewObject2);
|
||
|
lpViewObject2->SetAdvise(m_dwDrawAspect, ADVF_PRIMEFIRST, &m_AdviseSink);
|
||
|
|
||
|
// get the initial size of the object
|
||
|
lpViewObject2->GetExtent(m_dwDrawAspect, -1 /*lindex*/, NULL /*ptd*/,
|
||
|
&m_sizel);
|
||
|
GetObjRect(&rect); // get the rectangle of the object in pixels
|
||
|
lpViewObject2->Release();
|
||
|
|
||
|
// give the object the name of the container app/document
|
||
|
m_lpOleObject->SetHostNames(OLESTR("Simple Application"),
|
||
|
OLESTR("Simple OLE 2.0 In-Place Container"));
|
||
|
|
||
|
// inform object handler/DLL object that it is used in the embedding
|
||
|
// container's context
|
||
|
HRESULT hRes;
|
||
|
if ((hRes = OleSetContainedObject(m_lpOleObject, TRUE))
|
||
|
!= ResultFromScode(S_OK) )
|
||
|
{
|
||
|
TestDebugOut(TEXT("Fail in OleSetContainedObject\n"));
|
||
|
}
|
||
|
|
||
|
if (fCreateNew)
|
||
|
{
|
||
|
// force new object to save to guarantee valid object in our storage.
|
||
|
// OLE 1.0 objects may close w/o saving. this is NOT necessary if the
|
||
|
// object is created FROM FILE; its data in storage is already valid.
|
||
|
m_OleClientSite.SaveObject();
|
||
|
|
||
|
// we only want to DoVerb(SHOW) if this is an InsertNew object.
|
||
|
// we should NOT DoVerb(SHOW) if the object is created FromFile.
|
||
|
m_lpOleObject->DoVerb(
|
||
|
OLEIVERB_SHOW,
|
||
|
NULL,
|
||
|
&m_OleClientSite,
|
||
|
-1,
|
||
|
m_lpDoc->m_hDocWnd,
|
||
|
&rect);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::PaintObj
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Paints the object
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// HDC hDC - Device context of the document window
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// CSimpleSite::GetObjRect SITE.CPP
|
||
|
// IOleObject::QueryInterface Object
|
||
|
// IViewObject::GetColorSet Object
|
||
|
// IViewObject::Release Object
|
||
|
// SetROP2 Windows API
|
||
|
// Rectamgle Windows API
|
||
|
// CreateHatchBrush Windows API
|
||
|
// SelectObject Windows API
|
||
|
// DeleteObject Windows API
|
||
|
// CreatePalette Windows API
|
||
|
// SelectPalette Windows API
|
||
|
// RealizePalette Windows API
|
||
|
// OleStdFree OLE2UI Function
|
||
|
// OleDraw OLE API
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
void CSimpleSite::PaintObj(HDC hDC)
|
||
|
{
|
||
|
RECT rect;
|
||
|
|
||
|
// need to check to make sure there is a valid object
|
||
|
// available. This is needed if there is a paint msg
|
||
|
// between the time that CSimpleSite is instantiated
|
||
|
// and OleUIInsertObject returns.
|
||
|
if (!m_lpOleObject)
|
||
|
return;
|
||
|
|
||
|
// convert it to pixels
|
||
|
GetObjRect(&rect);
|
||
|
|
||
|
LPLOGPALETTE pColorSet = NULL;
|
||
|
LPVIEWOBJECT lpView = NULL;
|
||
|
|
||
|
// get a pointer to IViewObject
|
||
|
m_lpOleObject->QueryInterface(IID_IViewObject,(LPVOID FAR *) &lpView);
|
||
|
|
||
|
// if the QI succeeds, get the LOGPALETTE for the object
|
||
|
if (lpView)
|
||
|
lpView->GetColorSet(m_dwDrawAspect, -1, NULL, NULL, NULL, &pColorSet);
|
||
|
|
||
|
HPALETTE hPal=NULL;
|
||
|
HPALETTE hOldPal=NULL;
|
||
|
|
||
|
// if a LOGPALETTE was returned (not guarateed), create the palette and
|
||
|
// realize it.NOTE:A smarter application would want to get the LOGPALETTE
|
||
|
// for each of its visible objects, and try to create a palette that
|
||
|
// satisfies all of the visible objects. ALSO: OleStdFree() is use to
|
||
|
// free the returned LOGPALETTE.
|
||
|
if ((pColorSet))
|
||
|
{
|
||
|
hPal = CreatePalette((const LPLOGPALETTE) pColorSet);
|
||
|
hOldPal = SelectPalette(hDC, hPal, FALSE);
|
||
|
RealizePalette(hDC);
|
||
|
OleStdFree(pColorSet);
|
||
|
}
|
||
|
|
||
|
// draw the object
|
||
|
HRESULT hRes;
|
||
|
hRes = OleDraw(m_lpOleObject, m_dwDrawAspect, hDC, &rect);
|
||
|
if ((hRes != ResultFromScode(S_OK)) &&
|
||
|
(hRes != ResultFromScode(OLE_E_BLANK)) &&
|
||
|
(hRes != ResultFromScode(DV_E_NOIVIEWOBJECT)))
|
||
|
{
|
||
|
TestDebugOut(TEXT("Fail in OleDraw\n"));
|
||
|
}
|
||
|
|
||
|
// if the object is open, draw a hatch rect.
|
||
|
if (m_fObjectOpen)
|
||
|
{
|
||
|
HBRUSH hBrush = CreateHatchBrush ( HS_BDIAGONAL, RGB(0,0,0) );
|
||
|
HBRUSH hOldBrush = (HBRUSH) SelectObject (hDC, hBrush);
|
||
|
SetROP2(hDC, R2_MASKPEN);
|
||
|
Rectangle (hDC, rect.left, rect.top, rect.right, rect.bottom);
|
||
|
SelectObject(hDC, hOldBrush);
|
||
|
DeleteObject(hBrush);
|
||
|
}
|
||
|
|
||
|
// if we created a palette, restore the old one, and destroy
|
||
|
// the object.
|
||
|
if (hPal)
|
||
|
{
|
||
|
SelectPalette(hDC,hOldPal,FALSE);
|
||
|
DeleteObject(hPal);
|
||
|
}
|
||
|
|
||
|
// if a view pointer was successfully returned, it needs to be released.
|
||
|
if (lpView)
|
||
|
lpView->Release();
|
||
|
}
|
||
|
|
||
|
//**********************************************************************
|
||
|
//
|
||
|
// CSimpleSite::GetObjRect
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// Retrieves the rect of the object in pixels
|
||
|
//
|
||
|
// Parameters:
|
||
|
//
|
||
|
// LPRECT lpRect - Rect structure filled with object's rect in pixels
|
||
|
//
|
||
|
// Return Value:
|
||
|
// None
|
||
|
//
|
||
|
// Function Calls:
|
||
|
// Function Location
|
||
|
//
|
||
|
// XformWidthInHimetricToPixels OLE2UI Function
|
||
|
// XformHeightInHimetricToPixels OLE2UI Function
|
||
|
//
|
||
|
//
|
||
|
//********************************************************************
|
||
|
|
||
|
void CSimpleSite::GetObjRect(LPRECT lpRect)
|
||
|
{
|
||
|
// convert it to pixels
|
||
|
lpRect->left = lpRect->top = 0;
|
||
|
lpRect->right = XformWidthInHimetricToPixels(NULL,(int)m_sizel.cx);
|
||
|
lpRect->bottom = XformHeightInHimetricToPixels(NULL,(int)m_sizel.cy);
|
||
|
}
|