OLEDOC.C

/* 
* OLEDOC.C
*
* Contains all callback functions in the OLESERVERDOCVTBL struture:
* DocClose
* DocGetObject
* DocExecute
* DocRelease
* DocSave
* DocSetColorScheme
* DocSetDocDimensions
* DocSetHostNames
*
* Also contains two helper functions, PDocumentAllocate and DocumentClean.
* PDocumentAllocate acts like a C++ constructor.
*
* Copyright(c) Microsoft Corp. 1992-1994 All Rights Reserved
* Win32 version, January 1994
*/

#ifdef MAKEOLESERVER

#include <windows.h>
#include <ole.h>
#include "cosmo.h"
#include "oleglobl.h"


/*
* PDocumentAllocate
*
* Purpose:
* Allocates a COSMODOC structure and sets the defaults in its fields.
* Used from application initialization and various server methods that
* create a document.
*
* Parameters:
* pVtblDoc LPOLESERVERDOCVTBL used to initialize the pvtbl field.
*
* Return Value:
* LPCOSMODOC Pointer to the allocated structure in local memory.
* The hMem field will contain a handle to the structure
* to pass to LocalFree.
*
*/

LPCOSMODOC WINAPI PDocumentAllocate(LPOLESERVERDOCVTBL pVtblDoc)
{
HLOCAL hMem;
LPCOSMODOC pDoc;

hMem=LocalAlloc(LPTR, CBCOSMODOC);

if (NULL==hMem)
return NULL;

pDoc=(LPCOSMODOC)(PSTR)hMem;

pDoc->hMem=hMem;
pDoc->fRelease=TRUE;
pDoc->pvtbl=pVtblDoc;

return pDoc;
}




/*
* DocClose
*
* Purpose:
* Instructs the server to unconditionally close the document. OLESVR
* calls DocClose when the client initiates a shutdown. OLESVR always
* calls this function before calling ServerRelease.
*
* Parameters:
* pDoc LPCOSMODOC identifying the document affected.
*
* Return Value:
* OLESTATUS OLE_OK if all is well, otherwise an OLE_* error value.
*/

OLESTATUS WINAPI DocClose(LPCOSMODOC pDoc)
{
OLESTATUS os;

/*
* Take no action to notify user--Client will take care of that.
*
* 1. Call OleRevokeServerDoc; resources are freed when OLESVR
* calls DocRelease.
* 2. Return the return value of OleRevokeServerDoc, which will
* generally be OLE_OK.
*/

os=OleRevokeServerDoc(pDoc->lh);
return os;
}






/*
* DocGetObject
*
* Purpose:
* Requests the server application to create an OLEOBJECT structure.
*
* Parameters:
* pDoc LPCOSMODOC identifying the document affected.
* pszItem OLE_LPCSTR specifying the name of the item in a document
* for which the object is to be created. If NULL, then
* the entire document is requested. This could be a
* range of spreadsheet cells like "R1:C3-R10:C50"
* ppObj LPLPOLEOBJECT at which to store a pointer to the
* OLEOBJECT structure.
* pClient LPOLECLIENT that should be associated with
* the object in order to notify OLECLI when the object
* changes.
*
* Return Value:
* OLESTATUS OLE_OK if all is well, otherwise an OLE_* error value.
*/

OLESTATUS WINAPI DocGetObject(LPCOSMODOC pDoc, OLE_LPCSTR pszItem
, LPLPOLEOBJECT ppObj, LPOLECLIENT pClient)
{
LPCOSMOOBJECT pObj;

/*
* 1. Allocate and initialize an OLEOBJECT structure.
* 2. Store pClient in the object's OLEOBJECT structure for use
* in sending notifications to the client.
* 3. Store a pointer to the new OLEOBJECT structure in ppObj.
* 4. Return OLE_OK if successful, OLE_ERROR_NAME if pszObj is
* not recognized, or OLE_ERROR_MEMORY if the object could not
* be allocated.
*
* This function is called in response to a client calling
* OleGetObject.
*/

//Allocate one from local FIXED memory.
pObj=PObjectAllocate(&pOLE->vtblObj);

if (NULL==pObj)
return OLE_ERROR_MEMORY;

//Remember who we created for freeing in DocRelease.
pDoc->pObj=pObj;

//Must save this for sending notifications.
pObj->pClient=pClient;

//Pass back the pointer to this object.
*ppObj=(LPOLEOBJECT)pObj;
return OLE_OK;
}



/*
* DocExecute
*
* Purpose:
* Passes DDE Execute strings related to the document to the server
* application.
*
* Parameters:
* pDoc LPCOSMODOC identifying the document affected.
* hCommands HGLOBAL to memory containing DDE execute strings.
*
* Return Value:
* OLESTATUS OLE_OK if all is well, otherwise an OLE_* error value.
*/

OLESTATUS WINAPI DocExecute(LPCOSMODOC pDoc, HGLOBAL hCommands)
{
/*
* 1. Lock the hCommands handle to access the execute strings.
* 2. Parse and execute the commands as necessary.
* 3. DO NOT FREE hCommands.
* 4. Return OLE_OK if successful, OLE_ERROR_COMMAND otherwise.
*/

return OLE_ERROR_COMMAND;
}





/*
* DocRelease
*
* Purpose:
* Notifies the server when a revoked document may be destroyed.
*
* Parameters:
* pDoc LPCOSMODOC identifying the document affected.
*
* Return Value:
* OLESTATUS OLE_OK if all is well, otherwise an OLE_* error value.
*/

OLESTATUS WINAPI DocRelease(LPCOSMODOC pDoc)
{
/*
* 1. Free any resources allocated for this document, but
* DO NOT free the OLESERVERDOC structure itself. This could
* include freeing objects, however.
* 2. Set a flag to indicate that Release has been called.
* 3. Return OLE_OK if successful, OLE_ERROR_GENERIC otherwise.
*/

if (0!=pDoc->aObject)
{
DeleteAtom(pDoc->aObject);
pDoc->aObject=0;
}

if (0!=pDoc->aClient)
{
DeleteAtom(pDoc->aClient);
pDoc->aClient=0;
}


//Release any object stored in this document.
if (0!=pDoc->pObj)
{
if (NULL!=pDoc->pObj->hMem)
LocalFree(pDoc->pObj->hMem);
}

pDoc->pObj=NULL;

pDoc->fRelease=TRUE;
return OLE_OK;
}





/*
* DocSave
*
* Purpose:
* Instructs the server application to save the document. If DocSave is
* called you are assumed to have a know filename to which you can save
* since this method is only used in linking.
*
* Parameters:
* pDoc LPCOSMODOC identifying the document affected.
*
* Return Value:
* OLESTATUS OLE_OK if all is well, otherwise an OLE_* error value.
*/

OLESTATUS WINAPI DocSave(LPCOSMODOC pDoc)
{
/*
* 1. Save the document to the known filename. How you save
* documents is application-specific.
* 2. Return OLE_OK if the save is successful, OLE_ERROR_GENERIC
* otherwise.
*/

SendMessage(pGlob->hWnd, WM_COMMAND, IDM_FILESAVE, 0L);
return OLE_OK;
}





/*
* DocSetColorScheme
*
* Purpose:
* Provides a color scheme that the client application recommends for
* rendering graphical data.
*
* Parameters:
* pDoc LPCOSMODOC identifying the document affected.
* pPal LPLOGPALETTE describing the recommended palette.
*
* Return Value:
* OLESTATUS OLE_OK if all is well, otherwise an OLE_* error value.
*/

OLESTATUS WINAPI DocSetColorScheme(LPCOSMODOC pDoc
, OLE_CONST LOGPALETTE FAR *pPal)
{
/*
* Servers are not required to use this palette. The LPLOGPALETTE
* only is a convenient structure to contain the color scheme; IT DOES
* not REPRESENT A PALETTE IN STRICT TERMS! Do NOT call CreatePalette
* and try to realize it.
*
* The color scheme contained in the LOGPALETTE structure contains
* a number of colors where the first color is the suggested foreground,
* the second the suggested background, then the first HALF of those
* remaining are suggested fill colors and the last half suggested
* line colors. If there are an odd number of colors, give the extra
* color to the fill colors, that is, there is one less line color than
* fill colors.
*/

return OLE_ERROR_PALETTE;
}



/*
* DocSetDocDimensions
*
* Purpose:
* Specifies the rectangle on the target device for which EMBEDDED
* objects should be formatted.
*
* Parameters:
* pDoc LPCOSMODOC identifying the document affected.
* pRect LPRECT to the device rectangle in MM_HIMETRIC units.
*
* Return Value:
* OLESTATUS OLE_OK if all is well, otherwise an OLE_* error value.
*/

OLESTATUS WINAPI DocSetDocDimensions(LPCOSMODOC pDoc
, OLE_CONST RECT FAR *pRect)
{
/*
* OLESVR will call this method when the client has resized the
* object.
*
* In this case we try to make the parent window the correct size
* to just contain the object.
*/

//First, convert the rectangle to units we can deal with MM_TEXT.
RectConvertToDevice(pGlob->hWnd, (LPRECT)pRect);

/*
* Tell the Polyline document to use this rectangle, also notifying
* the parent which will then resize itself.
*/
SendMessage(pGlob->hWndPolyline, PLM_RECTSET, TRUE, (LONG)pRect);

return OLE_OK;
}





/*
* DocSetHostNames
*
* Purpose:
* Set names that should be used for window titles, only for
* embedded objects; linked objects have their own titles as they
* are loaded through the server application's usual file loading
* mechanism.
*
* Parameters:
* pDoc LPCOSMODOC identifying the document affected.
* pszClient OLE_LPCSTR to the name of the client application.
* pszObj OLE_LPCSTR to the name of the embedded object.
*
* Return Value:
* OLESTATUS OLE_OK if all is well, otherwise an OLE_* error value.
*/

OLESTATUS WINAPI DocSetHostNames(LPCOSMODOC pDoc, OLE_LPCSTR pszClient
, OLE_LPCSTR pszObj)
{
char szTemp[256];

/*
* 1. Change the title bar to reflect the embedded state with the
* appropriate names.
* 2. Change the File menu to reflect the embedded state and the name
* of the client application.
* 3. Store the object and client names in teh OLESERVERDOC structure.
* These will be needed later for message boxes where the name of
* the client application must be displayed.
* 4. Return OLE_OK if successful, OLE_ERROR_GENERIC otherwise.
*/

wsprintf(szTemp, "%s in %s", pszObj, pszClient);
WindowTitleSet(pGlob->hWnd, szTemp);
MenuEmbeddingSet(pGlob->hWnd, (LPSTR)pszClient, TRUE);

if (0!=pDoc->aObject)
DeleteAtom(pDoc->aObject);

pDoc->aObject=AddAtom(pszObj);

if (0!=pDoc->aClient)
DeleteAtom(pDoc->aClient);

pDoc->aClient=AddAtom(pszClient);

return OLE_OK;
}





#endif //MAKEOLESERVER