|
|
/****************************** Module Header ******************************\
* Module Name: GENERIC.C * * Handles all API routines for the generic sub-dll of the ole dll. * Since the data format is unknown, all the routines are written with the * assumption that all the relevant data is placed in a single global data * segment. Note that this assumption is not valid for metafiles, bitmaps, and * and there can always be some other formats with such idiosyncracies. To * accommodate those cases the rendering dll writer should replace the relevant * routines after the creation of the generic object. If for a given class this * assumption (about data format) is valid then the dll writer need to replace * only the Draw and QueryBounds functions. * * Created: November-1990 * * Copyright (c) 1990, 1991 Microsoft Corporation * * History: * * Srinik, Raor (11/05/90) Designed, coded * Curts created NT version * \***************************************************************************/
#include <windows.h>
#include "dll.h"
#include "pict.h"
char aMacText[4] = {'T', 'E', 'X', 'T'}; char aMacRtf[4] = "RTF";
extern OLESTATUS FARINTERNAL wCreateDummyMetaFile (LPOBJECT_MF, int, int);
#ifdef WIN16
#pragma alloc_text(_TEXT, GenSaveToStream, GenLoadFromStream, GetBytes, PutBytes, PutStrWithLen, PutAtomIntoStream, GenQueryBounds)
#endif
OLEOBJECTVTBL vtblGEN = {
ErrQueryProtocol, // check whether the speced protocol is supported
GenRelease, // Release
ErrShow, // Show
ErrPlay, // plat
GenGetData, // Get the object data
GenSetData, // Set the object data
ErrSetTargetDevice, //
ErrSetBounds, // set viewport bounds
GenEnumFormat, // enumerate supported formats
ErrSetColorScheme, //
GenRelease, // delete
ErrSetHostNames, //
GenSaveToStream, // write to file
GenClone, // clone object
ErrCopyFromLink, // Create embedded from Link
GenEqual, // compares the given objects for data equality
GenCopy, // copy to clip
GenDraw, // draw the object
ErrActivate, // open
ErrExecute, // excute
ErrClose, // Stop
ErrUpdate, // Update
ErrReconnect, // Reconnect
ErrObjectConvert, // convert object to specified type
ErrGetUpdateOptions, // update options
ErrSetUpdateOptions, // update options
ObjRename, // Change Object name
ObjQueryName, // Get current object name
GenQueryType, // Object type
GenQueryBounds, // QueryBounds
ObjQuerySize, // Find the size of the object
ErrQueryOpen, // Query open
ErrQueryOutOfDate, // query whether object is current
ErrQueryRelease, // release related stuff
ErrQueryRelease, ErrQueryReleaseMethod,
ErrRequestData, // requestdata
ErrObjectLong, // objectLong
GenChangeData // change data of the existing object
};
OLESTATUS FARINTERNAL GenRelease (LPOLEOBJECT lpoleobj) { LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj; HOBJECT hobj;
if (lpobj->hData) { GlobalFree (lpobj->hData); lpobj->hData = NULL; }
if (lpobj->aClass) GlobalDeleteAtom (lpobj->aClass);
if (lpobj->head.lhclientdoc) DocDeleteObject ((LPOLEOBJECT) lpobj);
if (hobj = lpobj->head.hobj){ lpobj->head.hobj = NULL; GlobalUnlock (hobj); GlobalFree (hobj); }
return OLE_OK; }
OLESTATUS FARINTERNAL GenSaveToStream ( LPOLEOBJECT lpoleobj, LPOLESTREAM lpstream ){ DWORD dwFileVer = GetFileVersion(lpoleobj); LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj; LPSTR lpData; OLESTATUS retVal = OLE_OK; DWORD dwClipFormat = 0; char formatName[MAX_STR];
if (!lpobj->hData) return OLE_ERROR_BLANK;
if (PutBytes (lpstream, (LPSTR) &dwFileVer, sizeof(LONG))) return OLE_ERROR_STREAM;
if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG))) return OLE_ERROR_STREAM;
if (PutAtomIntoStream (lpstream, lpobj->aClass)) return OLE_ERROR_STREAM;
if (lpobj->cfFormat < 0xC000) // then it is a predefined format
dwClipFormat = lpobj->cfFormat;
if (PutBytes (lpstream, (LPSTR) &dwClipFormat, sizeof(DWORD))) return OLE_ERROR_STREAM;
if (!dwClipFormat) { if (!GetClipboardFormatName (lpobj->cfFormat, (LPSTR) formatName, sizeof(formatName))) return OLE_ERROR_FORMAT;
if (PutStrWithLen (lpstream, formatName)) return OLE_ERROR_STREAM; }
if (!lpobj->sizeBytes) return OLE_ERROR_BLANK;
if (PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD))) return OLE_ERROR_STREAM;
if (!(lpData = GlobalLock (lpobj->hData))) return OLE_ERROR_MEMORY;
if (PutBytes (lpstream, lpData, lpobj->sizeBytes)) retVal = OLE_ERROR_STREAM;
GlobalUnlock (lpobj->hData); return retVal; }
OLESTATUS FARINTERNAL GenClone ( LPOLEOBJECT lpoleobjsrc, LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, OLE_LPCSTR lpobjname, LPOLEOBJECT FAR * lplpoleobj ){ LPOBJECT_GEN lpobjsrc = (LPOBJECT_GEN)lpoleobjsrc;
if (!lpobjsrc->hData) return OLE_ERROR_BLANK;
if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) return OLE_ERROR_HANDLE;
if (!(*lplpoleobj = (LPOLEOBJECT)GenCreateObject (lpobjsrc->hData, lpclient, FALSE, lhclientdoc, (LPSTR)lpobjname, lpobjsrc->head.ctype))) return OLE_ERROR_MEMORY; else { ((LPOBJECT_GEN)(*lplpoleobj))->cfFormat = lpobjsrc->cfFormat; ((LPOBJECT_GEN)(*lplpoleobj))->aClass = DuplicateAtom (lpobjsrc->aClass); return OLE_OK; } }
OLESTATUS FARINTERNAL GenEqual ( LPOLEOBJECT lpoleobj1, LPOLEOBJECT lpoleobj2 ){ LPOBJECT_GEN lpobj1 = (LPOBJECT_GEN)lpoleobj1; LPOBJECT_GEN lpobj2 = (LPOBJECT_GEN)lpoleobj2;
if (CmpGlobals (lpobj1->hData, lpobj2->hData)) return OLE_OK;
return OLE_ERROR_NOT_EQUAL; }
OLESTATUS FARINTERNAL GenCopy (LPOLEOBJECT lpoleobj) { LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj; HANDLE hData;
if (!lpobj->hData) return OLE_ERROR_BLANK;
if (!(hData = DuplicateGlobal (lpobj->hData, GMEM_MOVEABLE))) return OLE_ERROR_MEMORY;
SetClipboardData (lpobj->cfFormat, hData); return OLE_OK; }
OLESTATUS FARINTERNAL GenLoadFromStream ( LPOLESTREAM lpstream, LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, LONG objType, ATOM aClass, OLECLIPFORMAT cfFormat ){ LPOBJECT_GEN lpobj = NULL; OLESTATUS retVal = OLE_ERROR_STREAM; HANDLE hData; LPSTR lpData; DWORD dwClipFormat; char formatName[MAX_STR]; LONG length;
if (!(*lplpobj = (LPOLEOBJECT) (lpobj = GenCreateBlank(lhclientdoc, lpobjname, objType, aClass)))) { if (aClass) GlobalDeleteAtom(aClass); return OLE_ERROR_MEMORY; }
if (GetBytes (lpstream, (LPSTR) &dwClipFormat, sizeof (DWORD))) goto errLoad;
// If object is from MAC then we will keep the data intact if the data
// format is either TEXT or RTF
if (HIWORD(dwVerFromFile) == OS_MAC) { if (dwClipFormat == *((DWORD *) aMacText)) lpobj->cfFormat = CF_TEXT; else if (dwClipFormat == *((DWORD *) aMacRtf)) lpobj->cfFormat = (OLECLIPFORMAT)RegisterClipboardFormat ((LPSTR) "Rich Text Format"); else lpobj->cfFormat = 0; } else { // object is created on windows
if (!dwClipFormat) { // this is new file format. format name string follows
if (GetBytes (lpstream, (LPSTR) &length, sizeof (LONG)) || GetBytes (lpstream, (LPSTR)formatName, length) || (!(lpobj->cfFormat = (OLECLIPFORMAT)RegisterClipboardFormat ((LPSTR) formatName)))) goto errLoad; } else if ((lpobj->cfFormat = (WORD) dwClipFormat) >= 0xc000) { // if format is not predefined and file format is old, then use
// what value is passed to you through "cfFormat" argument
lpobj->cfFormat = cfFormat; } }
if (GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof (DWORD))) goto errLoad;
lpobj->head.lpclient = lpclient;
retVal = OLE_ERROR_MEMORY; if (!(hData = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes))) goto errLoad;
if (!(lpData = GlobalLock (hData))) goto errMem;
if (GetBytes (lpstream, lpData, lpobj->sizeBytes)) { retVal = OLE_ERROR_STREAM; GlobalUnlock (hData); goto errMem; }
lpobj->hData = hData; GlobalUnlock (hData);
// if the object is from MAC then we want delete this and create blank
// metafile object, which draws a rectangle
if ((HIWORD(dwVerFromFile) == OS_MAC) && !lpobj->cfFormat) { LPOBJECT_MF lpobjMf;
OleDelete ((LPOLEOBJECT)lpobj); // delete generic object
// Now create a dummy metafile object which draws a rectangle of size
// 1" x 1". Note that 1" = 2540 HIMETRIC units
lpobjMf = MfCreateBlank (lhclientdoc, lpobjname, objType); lpobjMf->head.cx = lpobjMf->mfp.xExt = 2540; lpobjMf->head.cy = - (lpobjMf->mfp.yExt = 2540); if ((retVal = wCreateDummyMetaFile (lpobjMf, lpobjMf->mfp.xExt, lpobjMf->mfp.yExt)) != OLE_OK) { OleDelete ((LPOLEOBJECT) lpobjMf); return retVal; } }
return OLE_OK;
errMem: GlobalFree (hData);
errLoad: OleDelete ((LPOLEOBJECT)lpobj); *lplpobj = NULL; return OLE_ERROR_STREAM;
}
LPOBJECT_GEN INTERNAL GenCreateObject ( HANDLE hData, LPOLECLIENT lpclient, BOOL fDelete, LHCLIENTDOC lhclientdoc, LPCSTR lpobjname, LONG objType ){ LPOBJECT_GEN lpobj;
if (!hData) return NULL;
if (lpobj = GenCreateBlank (lhclientdoc, (LPSTR)lpobjname, objType, (ATOM)0)) { if (GenChangeData ((LPOLEOBJECT)lpobj, hData, lpclient, fDelete) != OLE_OK) { GenRelease ((LPOLEOBJECT)lpobj); lpobj = NULL; } }
return lpobj; }
// If the routine fails then the object will be left with it's old data.
// If fDelete is TRUE, then hNewData will be deleted whether the routine
// is successful or not.
OLESTATUS FARINTERNAL GenChangeData ( LPOLEOBJECT lpoleobj, HANDLE hSrcData, LPOLECLIENT lpclient, BOOL fDelete ){ LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj; HANDLE hDestData;
if (!fDelete) { if (!(hDestData = DuplicateGlobal (hSrcData, GMEM_MOVEABLE))) return OLE_ERROR_MEMORY; } else { // change the ownership to yourself
if (!(hDestData = GlobalReAlloc(hSrcData,0L,GMEM_MODIFY|GMEM_SHARE))){ hDestData = DuplicateGlobal (hSrcData, GMEM_MOVEABLE); GlobalFree (hSrcData); if (!hDestData) return OLE_ERROR_MEMORY; } }
lpobj->head.lpclient = lpclient; if (lpobj->hData) GlobalFree (lpobj->hData); lpobj->hData = hDestData; lpobj->sizeBytes = (DWORD)GlobalSize (hDestData);
return OLE_OK; }
LPOBJECT_GEN FARINTERNAL GenCreateBlank( LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LONG objType, ATOM aClass ){ HOBJECT hobj; LPOBJECT_GEN lpobj;
if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_GEN))) == NULL) return NULL;
if (!(lpobj = (LPOBJECT_GEN) GlobalLock (hobj))){ GlobalFree (hobj); return NULL; }
lpobj->head.objId[0] = 'L'; lpobj->head.objId[1] = 'E'; lpobj->head.mm = MM_TEXT; lpobj->head.ctype = objType; lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblGEN; lpobj->head.iTable = INVALID_INDEX; lpobj->head.hobj = hobj; lpobj->aClass = aClass;
if (objType == CT_STATIC) DocAddObject ((LPCLIENTDOC) lhclientdoc, (LPOLEOBJECT) lpobj, lpobjname);
return lpobj; }
OLESTATUS FARINTERNAL GenPaste ( LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, LPSTR lpClass, OLECLIPFORMAT cfFormat, LONG objType ){ HANDLE hData = NULL;
*lplpobj = NULL; if (!cfFormat) return OLE_ERROR_FORMAT;
if (!(hData = GetClipboardData(cfFormat))) return OLE_ERROR_MEMORY;
if (!(*lplpobj = (LPOLEOBJECT) GenCreateObject (hData, lpclient, FALSE, lhclientdoc, lpobjname, objType))) return OLE_ERROR_MEMORY;
((LPOBJECT_GEN)(*lplpobj))->cfFormat = cfFormat; ((LPOBJECT_GEN)(*lplpobj))->aClass = GlobalAddAtom (lpClass); return OLE_OK;
}
OLESTATUS FARINTERNAL GenQueryType ( LPOLEOBJECT lpobj, LPLONG lptype ){ UNREFERENCED_PARAMETER(lpobj); UNREFERENCED_PARAMETER(lptype);
return OLE_ERROR_GENERIC;; }
OLESTATUS FARINTERNAL GenSetData ( LPOLEOBJECT lpoleobj, OLECLIPFORMAT cfFormat, HANDLE hData ){ LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
if (lpobj->cfFormat != cfFormat) return OLE_ERROR_FORMAT;
if (!hData) return OLE_ERROR_BLANK;
GlobalFree (lpobj->hData); lpobj->hData = hData; lpobj->sizeBytes = (DWORD)GlobalSize (hData); return OLE_OK; }
OLESTATUS FARINTERNAL GenGetData ( LPOLEOBJECT lpoleobj, OLECLIPFORMAT cfFormat, LPHANDLE lphandle ){ LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
if (cfFormat != lpobj->cfFormat) return OLE_ERROR_FORMAT;
if (!(*lphandle = lpobj->hData)) return OLE_ERROR_BLANK;
return OLE_OK;
}
OLECLIPFORMAT FARINTERNAL GenEnumFormat ( LPOLEOBJECT lpoleobj, OLECLIPFORMAT cfFormat ){ LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
if (!cfFormat) return lpobj->cfFormat;
return 0; }
OLESTATUS FARINTERNAL GenQueryBounds ( LPOLEOBJECT lpoleobj, LPRECT lpRc ){ LPOBJECT_GEN lpobj = (LPOBJECT_GEN)lpoleobj;
lpRc->right = 0; lpRc->left = 0; lpRc->top = 0; lpRc->bottom = 0; return OLE_ERROR_GENERIC; }
|