Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

432 lines
11 KiB

#include "project.hpp"
#pragma hdrstop
#include "contain.hpp"
#include "csite.hpp"
#include "helpers.hpp"
// {C71E9420-E82F-11ce-B6CF-00AA00A74DAF}
static const GUID CLSID_ScriptIntegrator =
{ 0xc71e9420, 0xe82f, 0x11ce, { 0xb6, 0xcf, 0x0, 0xaa, 0x0, 0xa7, 0x4d, 0xaf } };
// {0BB43480-E20B-11ce-B6CF-00AA00A74DAF}
static const GUID IID_IScriptIntegration =
{ 0xbb43480, 0xe20b, 0x11ce, { 0xb6, 0xcf, 0x0, 0xaa, 0x0, 0xa7, 0x4d, 0xaf } };
CSite::CSite(HText *text)
{
ASSERT(text != NULL);
ASSERT(IsWindow(text->tw->win));
_docWnd = text->tw->win;
_dwRef = 0L;
// Set our interfaces to NULL
_pIOleClientSite = NULL;
_pIOleControlSite = NULL;
_pIAdviseSink = NULL;
_pIOleInPlaceSite = NULL;
_pXObject = NULL;
_pIOleDispatchAmbientProps = NULL;
// Set the script integration interface pointer to NULL.
_pIntegrator = NULL;
}
CSite::~CSite()
{
ASSERT(_pIAdviseSink != NULL && _pIAdviseSink->GetRef() == 0);
ASSERT(_pIOleControlSite != NULL && _pIOleControlSite->GetRef() == 0);
ASSERT(_pIOleClientSite != NULL && _pIOleClientSite->GetRef() == 0);
ASSERT(_pIOleInPlaceSite != NULL && _pIOleInPlaceSite->GetRef() == 0);
ASSERT(_pIOleDispatchAmbientProps != NULL && _pIOleDispatchAmbientProps->GetRef() == 0);
// No need to delete _pXObject. It is a special interface that handles
// reference counting and deletes itself when the ref count goes to zero.
SAFEDELETE(_pIAdviseSink);
SAFEDELETE(_pIOleClientSite);
SAFEDELETE(_pIOleControlSite);
SAFEDELETE(_pIOleInPlaceSite);
SAFEDELETE(_pIOleDispatchAmbientProps);
}
HRESULT CSite::InitializeSite(const char *name)
{
HRESULT hr = E_OUTOFMEMORY;
_pIAdviseSink = new (CAdviseSink(this, this));
if (_pIAdviseSink == NULL)
goto cleanup;
_pIOleClientSite = new (COleClientSite(this, this));
if (_pIOleClientSite == NULL)
goto cleanup;
_pIOleControlSite = new (COleControlSite(this, this));
if (_pIOleControlSite == NULL)
goto cleanup;
_pIOleInPlaceSite = new (COleInPlaceSite(this, this));
if (_pIOleInPlaceSite == NULL)
goto cleanup;
_pXObject = new (CXObject(this, name));
if (_pXObject == NULL)
goto cleanup;
_pIOleDispatchAmbientProps = new (CAmbientDispatch( this, this));
if (_pIOleDispatchAmbientProps == NULL)
goto cleanup;
g_Container->AddSite(this, &_SiteCookie);
AddRef(); // Stay around, jack!
return S_OK;
cleanup:
SAFERELEASE(_pIAdviseSink);
SAFERELEASE(_pIOleClientSite);
SAFERELEASE(_pIOleControlSite);
SAFERELEASE(_pIOleInPlaceSite);
SAFERELEASE(_pXObject);
SAFERELEASE(_pIOleDispatchAmbientProps);
return hr;
}
// IUnknown methods
STDMETHODIMP_(ULONG) CSite::AddRef(void)
{
return ++_dwRef;
}
STDMETHODIMP_(ULONG) CSite::Release(void)
{
if (--_dwRef == 0)
{
delete this;
return 0;
}
return _dwRef;
}
STDMETHODIMP CSite::QueryInterface(REFIID riid, LPVOID *ppvObj)
{
// ppvObj must not be NULL
ASSERT(ppvObj != NULL);
if (ppvObj == NULL)
return E_INVALIDARG;
*ppvObj = NULL;
if (IsEqualIID(riid, IID_IUnknown))
*ppvObj = this;
else if (IsEqualIID(riid, IID_IOleClientSite))
*ppvObj = _pIOleClientSite;
else if (IsEqualIID(riid, IID_IOleControlSite))
*ppvObj = _pIOleControlSite;
else if (IsEqualIID(riid, IID_IAdviseSink))
*ppvObj = _pIAdviseSink;
else if (IsEqualIID(riid, IID_IOleInPlaceSite))
*ppvObj = _pIOleInPlaceSite;
else if (IsEqualIID(riid, IID_IDispatch))
*ppvObj = _pIOleDispatchAmbientProps;
else
return g_Container->QueryInterface(riid, ppvObj); // Delegate to global container object
if (*ppvObj != NULL) // Should always be non-NULL at this point, but just to be safe...
((LPUNKNOWN)*ppvObj)->AddRef();
return S_OK;
}
HRESULT CSite::Destroy()
{
HRESULT hr = S_OK;
// Deactivate the control
_pXObject->Deactivate();
_pXObject->Destroy();
g_Container->DeleteSite(&_SiteCookie);
Release(); // Decrement reference count on site object.
return hr;
}
HRESULT CSite::CreateEmbedding(CLSID clsid)
{
// BUGBUG: Need to check to see if this is really a control before aggregating with x object...
if (SUCCEEDED(Mpolevtbl->CoCreateInstance(clsid, _pXObject, CLSCTX_INPROC_SERVER, IID_IUnknown, (void **)_pXObject->GetInnerUnknown())))
{
_pXObject->Initialize();
return _pXObject->SetClientSite(_pIOleClientSite); // Control will addref the client site interface
}
else
return E_FAIL;
}
HRESULT CSite::ConnectEvents(const char* pSinkID, const char* progid)
{
ASSERT((pSinkID != NULL) || (progid != NULL)); // Got to have one or the other...
HRESULT hr;
CLSID clsid;
if (progid != NULL) // We prefer a ProgID
hr = ConvertANSIProgIDtoCLSID(progid, &clsid);
else
hr = ConvertANSItoCLSID(pSinkID, &clsid);
if (FAILED(hr))
{
DBGOUT("Could not convert SINK id to CLSID");
return hr;
}
LPDISPATCH pEventSink = NULL;
// Instantiate the event sink
if SUCCEEDED(Mpolevtbl->CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_IDispatch, (void **)&pEventSink))
{
// Load up the glue DLL
hr = Mpolevtbl->CoCreateInstance(CLSID_ScriptIntegrator, NULL, CLSCTX_INPROC_SERVER, IID_IScriptIntegration, (void **)&_pIntegrator);
if (SUCCEEDED(hr))
hr = _pIntegrator->IntegrateUI(g_Container->_pIOleContainer, pEventSink);
}
else
DBGOUT("Could not load script DLL");
return hr;
}
void HText_addEmbed(HText *text, const char* pszClsid, const char* events, const char * height, const char *name,
const char* progid, const char* properties, const char* propertysrc, const char * sink,
const char* src, const char* width)
{
ASSERT(text != NULL);
ASSERT(pszClsid != NULL); // Need to have a CLSID to create!!
InitializeContainer();
PCSite pSite = new (CSite(text));
CLSID clsid;
ConvertANSItoCLSID(pszClsid, &clsid);
// Create a new C++ site object
if (pSite == NULL)
return; // Couldn't allocate memory for site object
else
pSite->InitializeSite(name); // Initialize the site object.
if (SUCCEEDED(pSite->CreateEmbedding(clsid)))
{
pSite->_pXObject->Activate();
// If this embedding sources out events, hook 'em up!
// if (sink || progid) pSite->ConnectEvents(sink, progid);
}
else
{
if (pSite)
delete pSite;
return; // Couldn't create embedded object
}
// If successful, add a new form element;
if (pSite)
{
HText_add_element(text, ELE_EMBED);
text->bOpen = FALSE;
text->w3doc->aElements[text->iElement].form = (struct _form_element *) GTR_MALLOC(sizeof(struct _form_element));
memset(text->w3doc->aElements[text->iElement].form, 0, sizeof(struct _form_element));
text->w3doc->aElements[text->iElement].form->iBeginForm = text->iBeginForm;
text->w3doc->aElements[text->iElement].form->pSite = pSite;
}
}
// Callback for destroying site object. After this function executes, the
// site object is **gone**.
HRESULT CloseSite(void * ptr)
{
// ptr is really a pointer to a CSite class instance
ASSERT(ptr != NULL);
PCSite pSite = (PCSite) ptr;
pSite->Destroy();
return S_OK;
}
#ifdef FEATURE_IMG_THREADS
#define HIDDEN_X_POS 10000
#define HIDDEN_Y_POS 0
BOOL bUnformatted = TRUE;
int nLastGoodElement = -1;
int nLastLine;
#endif
// Callback for positioning control during layout.
HRESULT SetEmbeddedObjectRect(BOOL bUnformatted, struct Mwin *tw, struct _element *el)
{
PCSite pSite = (PCSite) el->form->pSite;
ASSERT(pSite != NULL);
LPOLEOBJECT pObj = pSite->_pXObject->GetObject();
LPOLEINPLACEOBJECT pOIPO = NULL;
if (pObj != NULL)
{
pObj->QueryInterface(IID_IOleInPlaceObject, (void **)&pOIPO);
if (pOIPO)
{
RECT rSize;
SetRectEmpty(&rSize);
SIZEL *size = pSite->_pXObject->GetSize();
SetRect(&rSize,
#ifdef FEATURE_IMG_THREADS
bUnformatted ? HIDDEN_X_POS:el->r.left - tw->offl,
bUnformatted ? HIDDEN_Y_POS:el->r.top - tw->offt,
#else
el->r.left - tw->offl,
el->r.top - tw->offt,
#endif
(el->r.left + size->cx),
(el->r.top + size->cy)
);
pOIPO->SetObjectRects(&rSize, NULL);
CopyRect(pSite->_pXObject->GetRect(), &rSize);
SAFERELEASE(pOIPO);
}
SAFERELEASE(pObj);
}
return S_OK;
}
struct _line
{
#ifdef WIN32
HDC hdc; /* working var, not really related to a line */
#endif
int nLineNum;
int iFirstElement; /* in */
int iLastElement; /* out */
RECT r; /* left, right, and top go in, bottom comes out */
int baseline; /* calculated */
int leading; /* out */
int nWSBelow; /* Minimum whitespace below the line */
int nWSAbove; /* Whitespace above current line */
int gIndentLevel;
int gRightIndentLevel;
int Flags;
int deferedFloatImgs[10]; // array of defered floating images
int numDeferedFloatImgs; // count of defered floating images
};
/* FormatEmbbedObject fills in the r structure which indicated the size of the element. This
is later used to format each line. This code is called (and essentially copied) from the
case statement in x_format_one_line in the file reformat.c
*/
HRESULT FormatEmbeddedObject(struct _element* pel, int *cThings, BOOL *bNeedsAdjust, int right_margin, struct _line * line, int *x, int *done, int prev_i)
{
ASSERT(pel != NULL && cThings != NULL && bNeedsAdjust != NULL);
ASSERT(pel->form != NULL);
ASSERT(pel->form->pSite != NULL);
PCSite pSite = (PCSite)pel->form->pSite;
if (pel->form->pSite == NULL)
return E_INVALIDARG;
/*
For printing, form controls need to be scaled too
{
float fScale;
if (pdoc->pStyles->image_res != 72)
{
fScale = (float) ((float) pdoc->pStyles->image_res / 96.0);
siz.cx = (long) (siz.cx * fScale);
siz.cy = (long) (siz.cy * fScale);
}
}
*/
SIZE *size = pSite->_pXObject->GetSize();
if ((!*cThings) || ((*x + size->cx) <= right_margin))
{
// Make sure the rectangle is initialized. Shouldn't matter, but hey!!
SetRectEmpty(&pel->r);
pel->r.left = *x;
pel->r.right = pel->r.left + size->cx;
pel->r.top = line->r.top;
pel->r.bottom = pel->r.top + size->cy;
//
// Baseline adjusts by 2 because of 3D effect on window controls.
// Note: This currently isn't used because ALIGN_MIDDLE is always set.
//
pel->baseline = pel->r.bottom - 2;
pel->alignment = ALIGN_MIDDLE;
*x += (size->cx);
if (line->r.bottom < pel->r.bottom)
{
line->r.bottom = pel->r.bottom;
}
*bNeedsAdjust = TRUE;
*cThings++;
XX_DMsg(DBG_TEXT, ("FORM CONTROL: cThings -> %d\n", *cThings));
}
else
{
line->iLastElement = prev_i;
*done = 1;
}
return S_OK;
}
HRESULT ShowAllEmbeddings(struct _www *w3doc, struct Mwin *tw, int nCmdShow)
{
if (w3doc->elementCount)
{
for (int i = 0; i >= 0; i = w3doc->aElements[i].next)
{
if (w3doc->aElements[i].form)
{
if (w3doc->aElements[i].form->pSite)
{
// We've got an embedding here, folks.
PCSite pSite = (PCSite)w3doc->aElements[i].form->pSite;
// There is a new doc window
pSite->_docWnd = tw->win;
if (nCmdShow == SW_HIDE)
pSite->_pXObject->Hide();
else if (nCmdShow == SW_SHOW)
pSite->_pXObject->Show();
}
}
}
}
return S_OK;
}