|
|
/****************************** Module Header ******************************\
* Module Name:MF.C (Extensible Compound Documents - Metafile) * * PURPOSE:Handles all API routines for the metafile sub-dll of the ole dll. * * Created: 1990 * * Copyright (c) 1990, 1991 Microsoft Corporation * * History: * * Raor, Srinik (../../1990,91) Designed, coded * Curts create NT version * \***************************************************************************/
#include <windows.h>
#include "dll.h"
#include "pict.h"
WORD wGDIds = 0; OLESTATUS FARINTERNAL wCreateDummyMetaFile (LPOBJECT_MF, int, int);
OLEOBJECTVTBL vtblMF = {
ErrQueryProtocol, // check whether the speced protocol is supported
MfRelease, // Release
ErrShow, // show
ErrPlay, // play
MfGetData, // Get the object data
ErrSetData, // Set the object data
ErrSetTargetDevice,//
ErrSetBounds, // set viewport bounds
MfEnumFormat, // enumerate supported formats
ErrSetColorScheme, //
MfRelease, // delete
ErrSetHostNames, //
MfSaveToStream, // write to file
MfClone, // clone object
ErrCopyFromLink, // Create embedded from Lnk
MfEqual, // compares the given objects for data equality
MfCopy, // copy to clip
MfDraw, // 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
ObjQueryType, // Object type
MfQueryBounds, // 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
MfChangeData // change data of the existing object
};
OLESTATUS FARINTERNAL MfRelease (LPOLEOBJECT lpoleobj) { LPOBJECT_MF lpobj = (LPOBJECT_MF)lpoleobj; HOBJECT hobj;
if (lpobj->mfp.hMF) { DeleteMetaFile (lpobj->mfp.hMF); lpobj->mfp.hMF = NULL; }
if (lpobj->hmfp) GlobalFree (lpobj->hmfp);
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 MfSaveToStream ( LPOLEOBJECT lpoleobj, LPOLESTREAM lpstream ){ DWORD dwFileVer = GetFileVersion(lpoleobj); LPOBJECT_MF lpobj = (LPOBJECT_MF)lpoleobj; OLESTATUS retVal = OLE_ERROR_STREAM; HANDLE hBits; LPSTR lpBits; LONG lSizeBytes;
lSizeBytes = lpobj->sizeBytes - sizeof(METAFILEPICT) + sizeof(WIN16METAFILEPICT);
if (!lpobj->mfp.hMF) 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 (PutStrWithLen(lpstream, (LPSTR)"METAFILEPICT")) return OLE_ERROR_STREAM;
if (PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) return OLE_ERROR_STREAM;
if (PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) return OLE_ERROR_STREAM;
if (PutBytes (lpstream, (LPSTR) &lSizeBytes, sizeof(LONG))) return OLE_ERROR_STREAM;
if (!(hBits = MGetMetaFileBits (lpobj->mfp.hMF))) return OLE_ERROR_MEMORY;
if (lpBits = (LPSTR) GlobalLock (hBits)) { WIN16METAFILEPICT w16mfp;
ConvertMF32to16(&lpobj->mfp, &w16mfp);
if (!PutBytes (lpstream, (LPSTR)&w16mfp, sizeof(WIN16METAFILEPICT))) if (!PutBytes (lpstream, (LPSTR)lpBits, lSizeBytes - sizeof(WIN16METAFILEPICT))) retVal = OLE_OK;
GlobalUnlock(hBits); } else retVal = OLE_ERROR_MEMORY;
lpobj->mfp.hMF = MSetMetaFileBits (hBits); return retVal; }
OLESTATUS FARINTERNAL MfClone ( LPOLEOBJECT lpoleobjsrc, LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, OLE_LPCSTR lpobjname, LPOLEOBJECT FAR * lplpoleobj ){ LPOBJECT_MF lpobjsrc = (LPOBJECT_MF)lpoleobjsrc; LPOBJECT_MF lpobjMf; HANDLE hmf;
*lplpoleobj = (LPOLEOBJECT)NULL;
if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) return OLE_ERROR_HANDLE;
if (!(hmf = CopyMetaFile (lpobjsrc->mfp.hMF, NULL))) return OLE_ERROR_MEMORY;
if (lpobjMf = MfCreateBlank (lhclientdoc, (LPSTR)lpobjname, lpobjsrc->head.ctype)) { lpobjMf->mfp = lpobjsrc->mfp; lpobjMf->sizeBytes = lpobjsrc->sizeBytes; lpobjMf->mfp.hMF = hmf; lpobjMf->head.lpclient = lpclient; lpobjMf->head.mm = lpobjMf->mfp.mm; MfSetExtents (lpobjMf);
*lplpoleobj = (LPOLEOBJECT)lpobjMf; return OLE_OK; }
return OLE_ERROR_MEMORY; }
OLESTATUS FARINTERNAL MfEqual ( LPOLEOBJECT lpoleobj1, LPOLEOBJECT lpoleobj2 ){ LPOBJECT_MF lpobj1 = (LPOBJECT_MF)lpoleobj1; LPOBJECT_MF lpobj2 = (LPOBJECT_MF)lpoleobj2; HANDLE hBits1 = NULL, hBits2 = NULL; OLESTATUS retval = OLE_ERROR_NOT_EQUAL;
if (!(hBits1 = MGetMetaFileBits (lpobj1->mfp.hMF))) goto errEqual;
if (!(hBits2 = MGetMetaFileBits (lpobj2->mfp.hMF))) goto errEqual;
if (CmpGlobals (hBits1, hBits2)) retval = OLE_OK;
errEqual: if (hBits1) lpobj1->mfp.hMF = MSetMetaFileBits (hBits1);
if (hBits2) lpobj2->mfp.hMF = MSetMetaFileBits (hBits2);
return retval; }
OLESTATUS FARINTERNAL MfCopy (LPOLEOBJECT lpoleobj) { LPOBJECT_MF lpobj = (LPOBJECT_MF)lpoleobj; HANDLE hMF;
if (!(hMF = CopyMetaFile (lpobj->mfp.hMF, NULL))) return OLE_ERROR_MEMORY;
return (MfCopyToClip (lpobj, hMF)); }
OLESTATUS FARINTERNAL MfQueryBounds ( LPOLEOBJECT lpoleobj, LPRECT lpRc ){ LPOBJECT_MF lpobj = (LPOBJECT_MF)lpoleobj; Puts("MfQueryBounds");
if (!lpobj->mfp.hMF) return OLE_ERROR_BLANK;
// Bounds are given in MM_HIMETRIC mode.
lpRc->left = 0; lpRc->top = 0; lpRc->right = (int) lpobj->head.cx; lpRc->bottom = (int) lpobj->head.cy; return OLE_OK; }
OLECLIPFORMAT FARINTERNAL MfEnumFormat ( LPOLEOBJECT lpoleobj, OLECLIPFORMAT cfFormat ){ LPOBJECT_MF lpobj = (LPOBJECT_MF)lpoleobj;
if (!cfFormat) return CF_METAFILEPICT;
return 0; }
OLESTATUS FARINTERNAL MfGetData ( LPOLEOBJECT lpoleobj, OLECLIPFORMAT cfFormat, LPHANDLE lphandle ){ LPOBJECT_MF lpobj = (LPOBJECT_MF)lpoleobj;
if (cfFormat != CF_METAFILEPICT) return OLE_ERROR_FORMAT;
if (!(*lphandle = GetHmfp (lpobj))) return OLE_ERROR_BLANK;
return OLE_OK; }
LPOBJECT_MF FARINTERNAL MfCreateObject ( HANDLE hMeta, LPOLECLIENT lpclient, BOOL fDelete, LHCLIENTDOC lhclientdoc, LPCSTR lpobjname, LONG objType ){ LPOBJECT_MF lpobj;
if (lpobj = MfCreateBlank (lhclientdoc, (LPSTR)lpobjname, objType)) { if (MfChangeData ((LPOLEOBJECT)lpobj, hMeta, lpclient, fDelete) != OLE_OK) { MfRelease ((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 hMeta, and the hMF it contains will be deleted
// whether the routine is successful or not.
OLESTATUS FARINTERNAL MfChangeData ( LPOLEOBJECT lpoleobj, HANDLE hMeta, LPOLECLIENT lpclient, BOOL fDelete ){ LPOBJECT_MF lpobj = (LPOBJECT_MF)lpoleobj; HANDLE hNewMF; LPMETAFILEPICT lpMetaPict;
if ((lpMetaPict = (LPMETAFILEPICT) GlobalLock (hMeta)) == NULL) { if (fDelete) GlobalFree (hMeta); return OLE_ERROR_MEMORY; }
GlobalUnlock (hMeta);
if (!fDelete) { if (!(hNewMF = CopyMetaFile (lpMetaPict->hMF, NULL))) return OLE_ERROR_MEMORY; } else { hNewMF = lpMetaPict->hMF; }
return MfUpdateStruct (lpobj, lpclient, hMeta, lpMetaPict, hNewMF, fDelete); }
OLESTATUS INTERNAL MfUpdateStruct ( LPOBJECT_MF lpobj, LPOLECLIENT lpclient, HANDLE hMeta, LPMETAFILEPICT lpMetaPict, HANDLE hMF, BOOL fDelete ){ OLESTATUS retVal; DWORD size; HANDLE hOldMF;
hOldMF = lpobj->mfp.hMF;
ASSERT(lpMetaPict->mm == MM_ANISOTROPIC, "Wrong mapping mode") if (lpMetaPict->mm != MM_ANISOTROPIC) retVal = OLE_ERROR_METAFILE; else if (!(size = MfGetSize (&hMF))) retVal = OLE_ERROR_BLANK; else { lpobj->mfp = *lpMetaPict; lpobj->mfp.hMF = hMF; lpobj->sizeBytes = size + sizeof(METAFILEPICT); lpobj->head.lpclient = lpclient; lpobj->head.mm = lpobj->mfp.mm; if (lpobj->hmfp) { GlobalFree (lpobj->hmfp); lpobj->hmfp = NULL; } MfSetExtents (lpobj); if (hOldMF) DeleteMetaFile (hOldMF); retVal = OLE_OK; }
if (retVal != OLE_OK) DeleteMetaFile (hMF);
if (fDelete) GlobalFree (hMeta); return retVal; }
LPOBJECT_MF FARINTERNAL MfCreateBlank( LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LONG objType ){ HOBJECT hobj; LPOBJECT_MF lpobj;
if(!(hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_MF)))) return NULL;
if (!(lpobj = (LPOBJECT_MF) GlobalLock (hobj))){ GlobalFree (hobj); return NULL; }
lpobj->head.objId[0] = 'L'; lpobj->head.objId[1] = 'E'; lpobj->head.ctype = objType; lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblMF; lpobj->head.iTable = INVALID_INDEX; lpobj->head.mm = MM_TEXT; lpobj->head.hobj = hobj;
if (objType == CT_STATIC) DocAddObject ((LPCLIENTDOC) lhclientdoc, (LPOLEOBJECT) lpobj, lpobjname);
// Unlock will be done at object deletion time.
return lpobj; }
OLESTATUS FARINTERNAL MfLoadFromStream ( LPOLESTREAM lpstream, LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, LONG objType ){ LPOLEOBJECT lpoleobj = NULL; OLESTATUS retval = OLE_ERROR_STREAM; HANDLE hBytes = NULL; LPSTR lpBytes = NULL; DWORD dwSizeBytes; METAFILEPICT mfp;
// Class name would've been read by this time.
*lplpobj = NULL;
switch (HIWORD(dwVerFromFile)) {
case OS_WIN32: if (!(lpoleobj = (LPOLEOBJECT)EmfCreateBlank (lhclientdoc, lpobjname, objType))) return OLE_ERROR_MEMORY; break;
case OS_WIN16: case OS_MAC: if (!(lpoleobj = (LPOLEOBJECT)MfCreateBlank (lhclientdoc, lpobjname, objType))) return OLE_ERROR_MEMORY; break;
default: return OLE_ERROR_FILE_VER;
}
lpoleobj->lpclient = lpclient;
if (GetBytes (lpstream, (LPSTR) &lpoleobj->cx, sizeof(LONG))) goto error;
if (GetBytes (lpstream, (LPSTR) &lpoleobj->cy, sizeof(LONG))) goto error;
if (GetBytes (lpstream, (LPSTR) &dwSizeBytes, sizeof(LONG))) goto error;
if (!dwSizeBytes) { retval = OLE_ERROR_BLANK; goto error; }
// if we are reading a MAC object we want to skip this
if (HIWORD(dwVerFromFile) != OS_MAC) { WIN16METAFILEPICT w16mfp;
if (GetBytes (lpstream, (LPSTR) &w16mfp, sizeof(WIN16METAFILEPICT))) goto error;
ConvertMF16to32(&w16mfp, &mfp); }
retval = OLE_ERROR_MEMORY; dwSizeBytes -= sizeof(WIN16METAFILEPICT);
if (!(hBytes = GlobalAlloc (GMEM_MOVEABLE, dwSizeBytes))) goto error;
if (!(lpBytes = (LPSTR)GlobalLock (hBytes))) goto error;
if (GetBytes (lpstream, (LPSTR)lpBytes, dwSizeBytes)) goto error;
switch (HIWORD(dwVerFromFile)){
case OS_WIN32: { LPOBJECT_EMF lpemfobj = (LPOBJECT_EMF)lpoleobj;
lpemfobj->sizeBytes = dwSizeBytes; if (!((HENHMETAFILE)lpemfobj->hemf = SetWinMetaFileBits(dwSizeBytes, lpBytes, 0 , &mfp))) goto error; EmfSetExtents (lpemfobj);
break; }
case OS_WIN16: { LPOBJECT_MF lpmfobj = (LPOBJECT_MF)lpoleobj; lpmfobj->mfp = mfp; lpmfobj->sizeBytes = dwSizeBytes + sizeof(METAFILEPICT); lpmfobj->head.mm = lpmfobj->mfp.mm; GlobalUnlock (hBytes); lpBytes = NULL; if (!(lpmfobj->mfp.hMF = MSetMetaFileBits(hBytes))) goto error; hBytes = NULL; MfSetExtents (lpmfobj);
break; }
case OS_MAC: { LPOBJECT_MF lpmfobj = (LPOBJECT_MF)lpoleobj;
lpmfobj->mfp.xExt = (int) lpmfobj->head.cx; lpmfobj->mfp.yExt = (int) lpmfobj->head.cy;
if ((retval = wCreateDummyMetaFile (lpmfobj, lpmfobj->mfp.xExt, lpmfobj->mfp.yExt)) != OLE_OK) goto error;
break; }
}
*lplpobj = lpoleobj; retval = OLE_OK;
error:
if (hBytes) { if (lpBytes) GlobalUnlock (hBytes); GlobalFree (hBytes); }
if (retval != OLE_OK) OleDelete (lpoleobj);
return retval; }
OLESTATUS FARINTERNAL MfPaste ( LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpoleobject, LONG objType ){ HANDLE hMeta;
*lplpoleobject = NULL;
if((hMeta = GetClipboardData (CF_METAFILEPICT)) == NULL) return OLE_ERROR_MEMORY;
if (!(*lplpoleobject = (LPOLEOBJECT) MfCreateObject (hMeta, lpclient, FALSE, lhclientdoc, lpobjname, objType))) return OLE_ERROR_MEMORY;
return OLE_OK; }
OLESTATUS INTERNAL MfCopyToClip ( LPOBJECT_MF lpobj, HANDLE hMF ){ LPMETAFILEPICT lpMeta; HANDLE hMeta;
if (!(hMeta = GlobalAlloc (GMEM_MOVEABLE, sizeof(METAFILEPICT)))) return OLE_ERROR_MEMORY;
if (lpMeta = (LPMETAFILEPICT) GlobalLock(hMeta)){ *lpMeta = lpobj->mfp; if (hMF) lpMeta->hMF = hMF; else lpobj->mfp.hMF = NULL; GlobalUnlock (hMeta); SetClipboardData(CF_METAFILEPICT, hMeta); return OLE_OK; }
GlobalFree(hMeta); return OLE_ERROR_MEMORY; }
void FARINTERNAL MfSetExtents (LPOBJECT_MF lpobj) { if (lpobj->mfp.xExt > 0) { // The extents are assumed to be in MM_HIMETIRC units
lpobj->head.cx = (LONG) lpobj->mfp.xExt; lpobj->head.cy = (LONG) - lpobj->mfp.yExt; } }
DWORD INTERNAL MfGetSize (LPHANDLE lphmf) { HANDLE hBits; DWORD size;
if ((hBits = MGetMetaFileBits (*lphmf)) == NULL) return 0;
size = (DWORD)GlobalSize(hBits); *lphmf = MSetMetaFileBits (hBits); return size; }
HANDLE INTERNAL GetHmfp (LPOBJECT_MF lpobj) { HANDLE hmfp; LPMETAFILEPICT lpmfp = NULL;
if (lpobj->hmfp) return lpobj->hmfp;
if (!(hmfp = GlobalAlloc (GMEM_MOVEABLE, sizeof(METAFILEPICT)))) return NULL;
if (!(lpmfp = (LPMETAFILEPICT) GlobalLock (hmfp))) { GlobalFree (hmfp); return NULL; }
*lpmfp = lpobj->mfp; GlobalUnlock (hmfp); return (lpobj->hmfp = hmfp); }
OLESTATUS FARINTERNAL wCreateDummyMetaFile ( LPOBJECT_MF lpobj, int xExt, int yExt ){ HDC hMetaDC;
if (!(hMetaDC = CreateMetaFile (NULL))) return OLE_ERROR_MEMORY;
MSetWindowOrg (hMetaDC, 0, 0); MSetWindowExt (hMetaDC, xExt, yExt); Rectangle (hMetaDC, 0, 0, xExt, yExt); if (!(lpobj->mfp.hMF = CloseMetaFile (hMetaDC))) return OLE_ERROR_MEMORY; lpobj->mfp.mm = MM_ANISOTROPIC; lpobj->sizeBytes = MfGetSize ( (LPHANDLE) &lpobj->mfp.hMF) + sizeof(METAFILEPICT); return OLE_OK; }
|