windows-nt/Source/XPSP1/NT/base/mvdm/wow16/ole/client/pbhandlr.c
2020-09-26 16:20:57 +08:00

512 lines
15 KiB
C

/****************************** 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
*
\***************************************************************************/
#include <windows.h>
#include "dll.h"
OLESTATUS FAR PASCAL _loadds PbDraw (LPOLEOBJECT, HDC, LPRECT, LPRECT, 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) (LPVOID, LPRECT);
OLESTATUS (FAR PASCAL *DefDraw) (LPVOID, HDC, LPRECT, LPRECT, HDC);
OLESTATUS (FAR PASCAL *DefCopyToClipboard) (LPVOID);
OLECLIPFORMAT (FAR PASCAL *DefEnumFormats) (LPVOID, OLECLIPFORMAT);
OLESTATUS (FAR PASCAL *DefGetData) (LPVOID, OLECLIPFORMAT, HANDLE FAR *);
OLESTATUS FAR PASCAL PbLoadFromStream (lpstream, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, objType, aClass, cfFormat)
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 (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, objType)
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, NULL, 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 (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat)
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 (lpprotocol, lpclient, lptemplate, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat)
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, NULL);
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 (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat)
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, NULL);
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 (lpprotocol, lpclient, lpclass, lpfile, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat)
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, NULL);
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 (lpprotocol, lpclient, lpclass, lpfile, lpitem, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat)
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 (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, fActivate)
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, NULL, 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 (lpobj)
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 (lpobj, lprc)
LPOLEOBJECT lpobj;
LPRECT lprc;
{
OLESTATUS retVal;
HANDLE hData;
LPSTR lpData;
POINT point;
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)))
return OLE_ERROR_MEMORY;
DibGetExtents ((lpData+sizeof(BITMAPFILEHEADER)), &point);
GlobalUnlock (hData);
lprc->left = 0;
lprc->top = 0;
lprc->right = point.x;
lprc->bottom = point.y;
return OLE_OK;
}
OLESTATUS FAR PASCAL _loadds PbDraw (lpobj, hdc, lprc, lpWrc, hdcTarget)
LPOLEOBJECT lpobj;
HDC hdc;
LPRECT lprc;
LPRECT lpWrc;
HDC hdcTarget;
{
HANDLE hData;
if ((*DefGetData) (lpobj, cfNative, &hData) != OLE_OK)
return (*DefDraw) (lpobj, hdc, lprc, lpWrc, hdcTarget);
return wDibDraw (hData, hdc, lprc, lpWrc, hdcTarget, TRUE);
}
OLECLIPFORMAT FAR PASCAL _loadds PbEnumFormats (lpobj, cfFormat)
LPOLEOBJECT lpobj;
OLECLIPFORMAT cfFormat;
{
OLECLIPFORMAT retFormat = NULL;
if (cfFormat == CF_METAFILEPICT)
return NULL;
if (!(retFormat = (*DefEnumFormats) (lpobj, cfFormat)))
return CF_METAFILEPICT;
return retFormat;
}
OLESTATUS FAR PASCAL _loadds PbGetData (lpobj, cfFormat, lpHandle)
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 (lpobj)
LPOLEOBJECT lpobj;
{
OLESTATUS retVal;
HANDLE hPict;
if ((retVal = (*DefCopyToClipboard) (lpobj)) == OLE_OK) {
if (hPict = PbGetPicture (lpobj))
SetClipboardData (CF_METAFILEPICT, hPict);
else
retVal = OLE_ERROR_MEMORY;
}
return retVal;
}
HANDLE PbGetPicture (lpobj)
LPOLEOBJECT lpobj;
{
HANDLE hMF, hMfp, hData;
RECT rc = {0, 0, 0, 0};
POINT point;
HDC hMetaDC;
LPMETAFILEPICT lpmfp;
OLESTATUS retVal;
LPSTR lpData;
if ((*DefGetData) (lpobj, cfNative, &hData) != OLE_OK)
return NULL;
if (!hData)
return NULL;
if (!(lpData = GlobalLock (hData)))
return NULL;
lpData += sizeof(BITMAPFILEHEADER);
rc.right = (int) ((LPBITMAPINFOHEADER)lpData)->biWidth;
rc.bottom = (int) ((LPBITMAPINFOHEADER)lpData)->biHeight;
DibGetExtents(lpData, &point);
GlobalUnlock (hData);
if (!(hMetaDC = CreateMetaFile (NULL)))
return NULL;
SetWindowOrg (hMetaDC, 0, 0);
SetWindowExt (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;
}
// normal handler can't do this. since this handler is part of olecli.dll, we
// we are doing this.
BOOL IsStandardPict (lpobj)
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;
}