/****************************** Module Header ******************************\ * Module Name: Pbhandlr.C -- Native data based handler (for Pbrush server) * * PURPOSE: Contains handler routines for Pbrush server. This handler makes * use of most of the standard library methods. It replaces only the "Draw", * "QueryBounds", "CopyToClipboard" methods of the OLE object. Note that this * handler draws the picture from the native data. * * Created: December 1990 * * Copyright (c) 1990 Microsoft Corporation * * History: * SriniK (../12/1990) Original * curts created portable version for WIN16/32 * \***************************************************************************/ #include #include "dll.h" OLESTATUS FAR PASCAL _LOADDS PbDraw (LPOLEOBJECT, HDC, OLE_CONST RECT FAR*, OLE_CONST RECT FAR*, HDC); OLESTATUS FAR PASCAL _LOADDS PbQueryBounds (LPOLEOBJECT, LPRECT); OLESTATUS FAR PASCAL _LOADDS PbCopyToClipboard (LPOLEOBJECT); OLESTATUS FAR PASCAL _LOADDS PbGetData (LPOLEOBJECT, OLECLIPFORMAT, HANDLE FAR *); OLECLIPFORMAT FAR PASCAL _LOADDS PbEnumFormats (LPOLEOBJECT, OLECLIPFORMAT); extern OLESTATUS FARINTERNAL wDibDraw (HANDLE, HDC, LPRECT, LPRECT, HDC, BOOL); void PbGetExtents (LPSTR, LPPOINT); void PbReplaceFunctions (LPOLEOBJECT); HANDLE PbGetPicture (LPOLEOBJECT); BOOL IsStandardPict (LPOLEOBJECT); extern void FARINTERNAL DibGetExtents(LPSTR, LPPOINT); OLEOBJECTVTBL vtblDLL; extern OLECLIPFORMAT cfOwnerLink; extern OLECLIPFORMAT cfObjectLink; extern OLECLIPFORMAT cfNative; OLESTATUS (FAR PASCAL *DefQueryBounds) (LPOLEOBJECT, LPRECT); OLESTATUS (FAR PASCAL *DefDraw) (LPOLEOBJECT, HDC, LPRECT, LPRECT, HDC); OLESTATUS (FAR PASCAL *DefCopyToClipboard) (LPOLEOBJECT); OLECLIPFORMAT (FAR PASCAL *DefEnumFormats) (LPOLEOBJECT, OLECLIPFORMAT); OLESTATUS (FAR PASCAL *DefGetData) (LPOLEOBJECT, OLECLIPFORMAT, HANDLE FAR *); OLESTATUS FAR PASCAL PbLoadFromStream ( LPOLESTREAM lpstream, LPSTR lpprotocol, LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, LONG objType, ATOM aClass, OLECLIPFORMAT cfFormat ){ OLESTATUS retVal; if (objType == OT_LINK) retVal = DefLoadFromStream (lpstream, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, objType, aClass, cfNative); else retVal = DefLoadFromStream (lpstream, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, objType, aClass, cfFormat); if (retVal <= OLE_WAIT_FOR_RELEASE) PbReplaceFunctions (*lplpobj); return retVal; } OLESTATUS FAR PASCAL PbCreateFromClip ( LPSTR lpprotocol, LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, OLEOPT_RENDER optRender, OLECLIPFORMAT cfFormat, LONG objType ){ OLESTATUS retVal; if ((optRender == olerender_draw) && (IsClipboardFormatAvailable (cfNative))) { if (objType == OT_EMBEDDED) retVal = DefCreateFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, olerender_none, 0, objType); else retVal = DefCreateFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, olerender_format, cfNative, objType); } else { retVal = DefCreateFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, objType); } if (retVal <= OLE_WAIT_FOR_RELEASE) PbReplaceFunctions (*lplpobj); return retVal; } OLESTATUS FAR PASCAL PbCreateLinkFromClip ( LPSTR lpprotocol, LPOLECLIENT lpclient, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, OLEOPT_RENDER optRender, OLECLIPFORMAT cfFormat ){ OLESTATUS retVal; if ((optRender == olerender_draw) && (IsClipboardFormatAvailable (cfNative))) { retVal = DefCreateLinkFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, olerender_format, cfNative); } else { retVal = DefCreateLinkFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat); } if (retVal <= OLE_WAIT_FOR_RELEASE) PbReplaceFunctions (*lplpobj); return retVal; } OLESTATUS FAR PASCAL PbCreateFromTemplate ( LPSTR lpprotocol, LPOLECLIENT lpclient, LPSTR lptemplate, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, OLEOPT_RENDER optRender, OLECLIPFORMAT cfFormat ){ OLESTATUS retVal; if (optRender == olerender_draw) retVal = DefCreateFromTemplate (lpprotocol, lpclient, lptemplate, lhclientdoc, lpobjname, lplpobj, olerender_none, 0); else retVal = DefCreateFromTemplate (lpprotocol, lpclient, lptemplate, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat); if (retVal <= OLE_WAIT_FOR_RELEASE) PbReplaceFunctions (*lplpobj); return retVal; } OLESTATUS FAR PASCAL PbCreate ( LPSTR lpprotocol, LPOLECLIENT lpclient, LPSTR lpclass, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, OLEOPT_RENDER optRender, OLECLIPFORMAT cfFormat ){ OLESTATUS retVal; if (optRender == olerender_draw) retVal = DefCreate (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpobj, olerender_none, 0); else retVal = DefCreate (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat); if (retVal <= OLE_WAIT_FOR_RELEASE) PbReplaceFunctions (*lplpobj); return retVal; } OLESTATUS FAR PASCAL PbCreateFromFile ( LPSTR lpprotocol, LPOLECLIENT lpclient, LPSTR lpclass, LPSTR lpfile, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, OLEOPT_RENDER optRender, OLECLIPFORMAT cfFormat ){ OLESTATUS retVal; if (optRender == olerender_draw) retVal = DefCreateFromFile (lpprotocol, lpclient, lpclass, lpfile, lhclientdoc, lpobjname, lplpobj, olerender_none, 0); else retVal = DefCreateFromFile (lpprotocol, lpclient, lpclass, lpfile, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat); if (retVal <= OLE_WAIT_FOR_RELEASE) PbReplaceFunctions (*lplpobj); return retVal; } OLESTATUS FAR PASCAL PbCreateLinkFromFile ( LPSTR lpprotocol, LPOLECLIENT lpclient, LPSTR lpclass, LPSTR lpfile, LPSTR lpitem, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, OLEOPT_RENDER optRender, OLECLIPFORMAT cfFormat ){ OLESTATUS retVal; if (optRender == olerender_draw) retVal = DefCreateLinkFromFile (lpprotocol, lpclient, lpclass, lpfile, lpitem, lhclientdoc, lpobjname, lplpobj, olerender_format, cfNative); else retVal = DefCreateLinkFromFile (lpprotocol, lpclient, lpclass, lpfile, lpitem, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat); if (retVal <= OLE_WAIT_FOR_RELEASE) PbReplaceFunctions (*lplpobj); return retVal; } OLESTATUS FAR PASCAL PbCreateInvisible ( LPSTR lpprotocol, LPOLECLIENT lpclient, LPSTR lpclass, LHCLIENTDOC lhclientdoc, LPSTR lpobjname, LPOLEOBJECT FAR * lplpobj, OLEOPT_RENDER optRender, OLECLIPFORMAT cfFormat, BOOL fActivate ){ OLESTATUS retVal; if (optRender == olerender_draw) retVal = DefCreateInvisible (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpobj, olerender_none, 0, fActivate); else retVal = DefCreateInvisible (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, fActivate); if (retVal <= OLE_WAIT_FOR_RELEASE) PbReplaceFunctions (*lplpobj); return retVal; } void PbReplaceFunctions ( LPOLEOBJECT lpobj ){ if (IsStandardPict (lpobj)) return; vtblDLL = *lpobj->lpvtbl; lpobj->lpvtbl = (LPOLEOBJECTVTBL) &vtblDLL; DefDraw = lpobj->lpvtbl->Draw; DefQueryBounds = lpobj->lpvtbl->QueryBounds; DefCopyToClipboard = lpobj->lpvtbl->CopyToClipboard; DefEnumFormats = lpobj->lpvtbl->EnumFormats; DefGetData = lpobj->lpvtbl->GetData; lpobj->lpvtbl->Draw = PbDraw; lpobj->lpvtbl->QueryBounds = PbQueryBounds; lpobj->lpvtbl->CopyToClipboard = PbCopyToClipboard; lpobj->lpvtbl->EnumFormats = PbEnumFormats; lpobj->lpvtbl->GetData = PbGetData; } OLESTATUS FAR PASCAL _LOADDS PbQueryBounds ( LPOLEOBJECT lpobj, LPRECT lprc ){ OLESTATUS retVal; HANDLE hData = NULL; LPSTR lpData; POINT point; HANDLE hbminfo = NULL; LPBITMAPINFO lpbminfo; if ((retVal = (*DefQueryBounds) (lpobj, lprc)) == OLE_OK) { if (lprc->top || lprc->bottom || lprc->right || lprc->left) return OLE_OK; } if ((*DefGetData) (lpobj, cfNative, &hData) != OLE_OK) return retVal; if (!hData) return OLE_ERROR_BLANK; if (!(lpData = GlobalLock (hData))) goto error; if (!(hbminfo = GlobalAlloc(GHND, sizeof(BITMAPINFO))) ) goto error; if (!(lpbminfo = (LPBITMAPINFO)GlobalLock(hbminfo)) ) goto error; memcpy((LPSTR)lpbminfo, (LPSTR)(lpData+sizeof(BITMAPFILEHEADER)), sizeof(BITMAPINFO)); DibGetExtents ((LPSTR)lpbminfo, &point); GlobalUnlock (hData); GlobalUnlock (hbminfo); GlobalFree (hbminfo); lprc->left = 0; lprc->top = 0; lprc->right = point.x; lprc->bottom = point.y; return OLE_OK; error: if (hData) GlobalUnlock (hData); if (hbminfo) { GlobalUnlock (hbminfo); GlobalFree (hbminfo); } return OLE_ERROR_MEMORY; } OLESTATUS FAR PASCAL _LOADDS PbDraw ( LPOLEOBJECT lpobj, HDC hdc, OLE_CONST RECT FAR* lprc, OLE_CONST RECT FAR* lpWrc, HDC hdcTarget ){ HANDLE hData; if ((*DefGetData) (lpobj, cfNative, &hData) != OLE_OK) return (*DefDraw) (lpobj, hdc, (LPRECT)lprc, (LPRECT)lpWrc, hdcTarget); return wDibDraw (hData, hdc, (LPRECT)lprc, (LPRECT)lpWrc, hdcTarget, TRUE); } OLECLIPFORMAT FAR PASCAL _LOADDS PbEnumFormats ( LPOLEOBJECT lpobj, OLECLIPFORMAT cfFormat ){ OLECLIPFORMAT retFormat = 0; if (cfFormat == CF_METAFILEPICT) return 0; if (!(retFormat = (*DefEnumFormats) (lpobj, cfFormat))) return CF_METAFILEPICT; return retFormat; } OLESTATUS FAR PASCAL _LOADDS PbGetData ( LPOLEOBJECT lpobj, OLECLIPFORMAT cfFormat, HANDLE FAR * lpHandle ){ OLESTATUS retval; retval = (*DefGetData) (lpobj, cfFormat, lpHandle); if (retval == OLE_OK || retval == OLE_BUSY || retval == OLE_ERROR_BLANK) return retval; if (cfFormat == CF_METAFILEPICT) { if (*lpHandle = PbGetPicture (lpobj)) return OLE_WARN_DELETE_DATA; return OLE_ERROR_MEMORY; } return OLE_ERROR_FORMAT; } OLESTATUS FAR PASCAL _LOADDS PbCopyToClipboard ( LPOLEOBJECT lpobj ){ OLESTATUS retVal; HANDLE hPict; if ((retVal = (*DefCopyToClipboard) (lpobj)) == OLE_OK) { if (hPict = PbGetPicture (lpobj)) SetClipboardData (CF_METAFILEPICT, hPict); else return OLE_ERROR_MEMORY; } return retVal; } HANDLE PbGetPicture ( LPOLEOBJECT lpobj ){ HANDLE hMF, hMfp; HANDLE hData = NULL; HANDLE hbminfo = NULL; RECT rc = {0, 0, 0, 0}; POINT point; HDC hMetaDC; LPMETAFILEPICT lpmfp; OLESTATUS retVal; LPSTR lpData; LPBITMAPINFO lpbminfo; if ((*DefGetData) (lpobj, cfNative, &hData) != OLE_OK) return NULL; if (!hData) return NULL; if (!(lpData = GlobalLock (hData))) return NULL; if (!(hbminfo = GlobalAlloc(GHND, sizeof(BITMAPINFO))) ) goto memory_error; if (!(lpbminfo = (LPBITMAPINFO)GlobalLock(hbminfo)) ) goto memory_error; memcpy((LPSTR)lpbminfo, (LPSTR)(lpData+sizeof(BITMAPFILEHEADER)), sizeof(BITMAPINFO)); rc.right = (int) lpbminfo->bmiHeader.biWidth; rc.bottom = (int) lpbminfo->bmiHeader.biHeight; DibGetExtents((LPSTR)lpbminfo, &point); GlobalUnlock (hData); GlobalUnlock (hbminfo); GlobalFree (hbminfo); if (!(hMetaDC = CreateMetaFile (NULL))) return NULL; MSetWindowOrg (hMetaDC, 0, 0); MSetWindowExt (hMetaDC, rc.right, rc.bottom); retVal = PbDraw (lpobj, hMetaDC, &rc, NULL, NULL); hMF = CloseMetaFile (hMetaDC); if (retVal != OLE_OK) goto error; if (hMF && (hMfp = GlobalAlloc (GMEM_MOVEABLE, sizeof(METAFILEPICT))) && (lpmfp = (LPMETAFILEPICT) GlobalLock (hMfp))) { lpmfp->hMF = hMF; lpmfp->xExt = point.x; lpmfp->yExt = -point.y; lpmfp->mm = MM_ANISOTROPIC; GlobalUnlock (hMfp); return hMfp; } error: if (hMF) DeleteMetaFile (hMF); if (hMfp) GlobalFree (hMfp); return NULL; memory_error: GlobalUnlock(hData); if (hbminfo) { GlobalUnlock(hbminfo); GlobalFree(hbminfo); } return(NULL); } // normal handler can't do this. since this handler is part of olecli.dll, we // we are doing this. BOOL IsStandardPict ( LPOLEOBJECT lpobj ){ LPOBJECT_LE lpLEobj; LONG type; lpLEobj = (LPOBJECT_LE) lpobj; if (!lpLEobj->lpobjPict) return FALSE; if ((*lpLEobj->lpobjPict->lpvtbl->QueryType) (lpLEobj->lpobjPict, &type) == OLE_ERROR_GENERIC) return FALSE; return TRUE; }