summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow16/mciole/mciole.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/wow16/mciole/mciole.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/mvdm/wow16/mciole/mciole.c')
-rw-r--r--private/mvdm/wow16/mciole/mciole.c1553
1 files changed, 1553 insertions, 0 deletions
diff --git a/private/mvdm/wow16/mciole/mciole.c b/private/mvdm/wow16/mciole/mciole.c
new file mode 100644
index 000000000..ad925cd57
--- /dev/null
+++ b/private/mvdm/wow16/mciole/mciole.c
@@ -0,0 +1,1553 @@
+//
+// MCIOLE - OLE handler DLL for MCI objects
+//
+//
+// NOTES:
+// The whole reason for this handler DLL is to supply the function
+//
+// OleQueryObjPos()
+//
+// this function gives information to the server application on the
+// location (in the client document) of the activated OLE object.
+// the server can use this information to play the object in place
+// or position the server window correctly
+//
+// IMPLEMENTION:
+//
+// in theory all this DLL (handler) has to do is save the information
+// passed to OleActivate(). But in reality no app correctly calls
+// OleActivate(). They either pass no information or the wrong
+// information.
+//
+// this DLL is a OLE handler, because of global data (vtblDef!) it
+// can only be a handler for one class at a time.
+//
+// the handler intercepts the OleDraw, OleActivate, and all the
+// creation/destuction OLE APIs. for each OLE object a info
+// structure is maintained (a OBJINFO structure) when ever the
+// client draws (using OleDraw...) the drawing position, and the
+// window drawn to is remembered.
+//
+// when the client calls OleActivate, the saved draw location is
+// recalled, or if the app never called OleDraw() (plays
+// the meta-file itself) then the rectangle passed to OleActivate()
+// is used. (if one is supplied)
+//
+// there are many classes of apps:
+//
+// calls OleActivate() with correct info
+// calls OleActivate() with incorrect info
+// calls OleActivate() with no info
+//
+// calls OleDraw()
+// does not call OleDraw()
+//
+// here is a table of known OLE Clients....
+//
+// OleDraw OleActivate()
+// App Y or N Y, N, X
+// (X = wrong info)
+// ------------- ---------- ------------
+// Write Y N
+// CardFile Y N
+// Packager Y N
+//
+// Excel N N (uses DDE)
+// Excel 4.0 N N (uses DDE)
+// PowerPnt 2.0 N N (uses DDE)
+//
+// WinWord N N
+// WinWorks Y X
+// PowerPnt 3.0 N Y
+// MsPublisher N X
+// ClTest Y N
+// Cirus Y X
+// WinProj ? ?
+//
+// AmiPro Y ?
+//
+#include <windows.h>
+#include "ole.h"
+#include "shellapi.h"
+#include "mciole.h"
+
+HANDLE ghInstance;
+
+OLEOBJECTVTBL vtblDll; // these are our functions.
+OLEOBJECTVTBL vtblDef; // these are the default functions.
+HBITMAP hbmStock;
+
+#ifdef DEBUG
+RECT rcNull = {0,0,0,0};
+#define PUSHRC(prc) *((prc) ? (prc) : &rcNull)
+#define CARETPOS() // {POINT pt; GetCaretPos(&pt); DPRINTF(("CaretPos: [%d, %d]", pt.x, pt.y));}
+#endif
+
+/****************************************************************************
+****************************************************************************/
+
+void ReplaceFunctions(LPOLEOBJECT);
+BOOL CanReplace(LPOLEOBJECT);
+
+/****************************************************************************
+
+ FUNCTION: LibMain(HANDLE hInstance)
+
+****************************************************************************/
+
+BOOL NEAR PASCAL LibMain (HANDLE hInstance)
+{
+ HDC hdc;
+ HBITMAP hbm;
+
+ ghInstance = hInstance;
+
+ //
+ // get the stock 1x1 mono bitmap.
+ //
+ hbm = CreateBitmap(1,1,1,1,NULL);
+ hdc = CreateCompatibleDC(NULL);
+ hbmStock = SelectObject(hdc, hbm);
+ SelectObject(hdc, hbmStock);
+ DeleteDC(hdc);
+ DeleteObject(hbm);
+
+// // register clipboard formats.
+// cfObjectLink = RegisterClipboardFormat("ObjectLink");
+// cfOwnerLink = RegisterClipboardFormat("OwnerLink");
+// cfNative = RegisterClipboardFormat("Native");
+
+ return TRUE;
+}
+
+/****************************************************************************
+
+ FUNCTION: WEP(int)
+
+ PURPOSE: Standard exit routine for the DLL
+
+****************************************************************************/
+
+int FAR PASCAL _loadds WEP(nParameter)
+int nParameter;
+{
+ return 1;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+BOOL NEAR PASCAL IsApp(LPSTR szApp)
+{
+ char ach[80];
+ int i;
+ WORD wStack;
+
+ _asm mov wStack,ss
+
+ GetModuleFileName((HINSTANCE)wStack, ach, sizeof(ach));
+
+ for (i = lstrlen(ach);
+ i > 0 && ach[i-1] != '\\' && ach[i-1] != '/' && ach[i] != ':';
+ i--)
+ ;
+
+ return lstrcmpi(ach + i, szApp) == 0;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+BOOL NEAR PASCAL IsDcMemory(HDC hdc)
+{
+ HBITMAP hbmT;
+
+ if (hbmT = SelectObject(hdc, hbmStock))
+ SelectObject(hdc, hbmT);
+
+ return hbmT != NULL;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+typedef struct _OBJINFO {
+
+ struct _OBJINFO*poiNext;
+
+ LPOLEOBJECT lpobj; // client side LPOLEOBJECT
+
+ HWND hwnd; // client window (passed to OleActivate)
+ RECT rcActivate; // activation rectangle (passed to OleActivate)
+
+ HWND hwndDraw; // active window at time of OleDraw
+ RECT rcDraw; // rectangle of draw
+} OBJINFO;
+
+#ifdef DEBUG
+int nObjects = 0;
+#endif
+OBJINFO *poiFirst = NULL;
+
+LPOLEOBJECT lpobjActive;
+BOOL RegSetGetData(OBJINFO *poi, BOOL Write);
+
+OBJINFO *FindObj(LPOLEOBJECT lpobj)
+{
+ OBJINFO *poi;
+
+ for (poi=poiFirst; poi; poi=poi->poiNext)
+ if (poi->lpobj == lpobj)
+ return poi;
+
+ DPRINTF(("FindObj: Unable to find object %lx", lpobj));
+
+ return NULL;
+}
+
+void DelObj(LPOLEOBJECT lpobj)
+{
+ OBJINFO *poi;
+ OBJINFO *poiT;
+
+ for (poiT=NULL,poi=poiFirst; poi; poiT=poi,poi=poi->poiNext)
+ {
+ if (poi->lpobj == lpobj)
+ {
+ if (poiT)
+ poiT->poiNext = poi->poiNext;
+ else
+ poiFirst = poi->poiNext;
+
+ poi->lpobj = NULL;
+ LocalFree((HLOCAL)poi);
+
+ DPRINTF(("DelObj(%lx): %d objects", lpobj, --nObjects));
+ return;
+ }
+ }
+
+ DPRINTF(("DelObj(%lx): Cant find object to delete.", lpobj));
+}
+
+BOOL RegSetGetData(OBJINFO *poi, BOOL Write)
+{
+
+ static char szKey[] = "PlayData";
+ static char szFormat[] = "%ld %ld %d %d %d %d %d %d %d %d";
+
+
+ if (Write) {
+ LONG Rc;
+
+ char Data[100];
+
+ //
+ // Store hwnd, hwnddraw, rcDraw, rcActivate
+ //
+
+#ifdef WIN32
+ wsprintf(Data, szFormat,
+ (LONG)poi->hwnd,
+ (LONG)poi->hwndDraw,
+ poi->rcDraw.left,
+ poi->rcDraw.right,
+ poi->rcDraw.top,
+ poi->rcDraw.bottom,
+ poi->rcActivate.left,
+ poi->rcActivate.right,
+ poi->rcActivate.top,
+ poi->rcActivate.bottom);
+
+#else
+ wsprintf(Data, szFormat,
+ (LONG)(poi->hwnd == NULL ? (LONG)0 : MAKELONG(poi->hwnd, 0xFFFF)),
+ (LONG)(poi->hwndDraw == NULL ? (LONG)0 : MAKELONG(poi->hwndDraw, 0xFFFF)),
+ poi->rcDraw.left,
+ poi->rcDraw.right,
+ poi->rcDraw.top,
+ poi->rcDraw.bottom,
+ poi->rcActivate.left,
+ poi->rcActivate.right,
+ poi->rcActivate.top,
+ poi->rcActivate.bottom);
+#endif
+
+ Rc = RegSetValue(HKEY_CLASSES_ROOT,
+ szKey,
+ REG_SZ,
+ Data,
+ lstrlen(Data));
+
+ return Rc == ERROR_SUCCESS;
+ } else {
+
+#ifdef WIN32
+ LONG Rc;
+ CHAR Data[100];
+ DWORD hwnd, hwndDraw;
+ LONG Length;
+
+ Length = sizeof(Data);
+
+ Rc = RegQueryValue(HKEY_CLASSES_ROOT, szKey,
+ Data, &Length);
+
+ RegSetValue(HKEY_CLASSES_ROOT, szKey, REG_SZ, "", 0);
+
+ //
+ // Extract our data - sscanf doesn't work yet!!!
+ //
+
+ if (Rc == ERROR_SUCCESS) {
+ LONG OurData[10];
+ int i;
+ LPTSTR lpData;
+
+ for (i = 0, lpData = Data; i < 10; i++) {
+ OurData[i] = atol(lpData);
+ while (*lpData != ' ' && *lpData != '\0') {
+ lpData++;
+ }
+
+ if (*lpData == ' ') {
+ lpData++;
+ }
+ }
+
+ poi->hwnd = (HWND)OurData[0];
+ poi->hwndDraw = (HWND)OurData[1];
+ poi->rcDraw.left = OurData[2];
+ poi->rcDraw.right = OurData[3];
+ poi->rcDraw.top = OurData[4];
+ poi->rcDraw.bottom = OurData[5];
+ poi->rcActivate.left = OurData[6];
+ poi->rcActivate.right = OurData[7];
+ poi->rcActivate.top = OurData[8];
+ poi->rcActivate.bottom = OurData[9];
+ }
+
+ return Rc == ERROR_SUCCESS && Length != 0;
+#else
+ return FALSE;
+#endif
+ }
+}
+
+//
+// for some reason we dont get all the OleDelete() calls that we should
+// so lets try to "weed out the bad apples" so we dont choke.
+//
+void CleanObjects()
+{
+ OBJINFO *poi;
+
+again:
+ for (poi=poiFirst; poi; poi=poi->poiNext)
+ {
+ if (IsBadReadPtr(poi->lpobj, 0))
+ {
+ DPRINTF(("Freeing bad object %lx", poi->lpobj));
+ DelObj(poi->lpobj);
+ goto again;
+ }
+ }
+}
+
+OBJINFO *NewObj(LPOLEOBJECT lpobj)
+{
+ OBJINFO *poi;
+
+ CleanObjects();
+
+ if (poi = FindObj(lpobj))
+ {
+ DPRINTF(("NewObj(%lx): Trying to add object twice!", lpobj));
+ return poi;
+ }
+
+ if (poi = (OBJINFO*)LocalAlloc(LPTR, sizeof(OBJINFO)))
+ {
+ poi->lpobj = lpobj;
+ poi->hwnd = NULL;
+ poi->hwndDraw = NULL;
+ SetRectEmpty(&poi->rcDraw);
+ SetRectEmpty(&poi->rcActivate);
+
+ poi->poiNext = poiFirst;
+ poiFirst = poi;
+
+ DPRINTF(("NewObj(%lx): %d objects", lpobj, ++nObjects));
+ }
+ else
+ {
+ DPRINTF(("NewObj(%lx): Out of room in the object table", lpobj));
+ }
+
+ return poi;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+HWND LookForDC(HWND hwndP, HDC hdc)
+{
+ RECT rc;
+ DWORD dw;
+ HWND hwnd;
+
+ if (hwndP == NULL)
+ return NULL;
+
+ dw = GetDCOrg(hdc);
+
+ for (hwnd = hwndP; hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT))
+ {
+ GetClientRect(hwnd, &rc);
+ ClientToScreen(hwnd, (LPPOINT)&rc);
+ ClientToScreen(hwnd, (LPPOINT)&rc+1);
+
+ if ((int)LOWORD(dw) == rc.left && (int)HIWORD(dw) == rc.top)
+ return hwnd;
+
+ if (PtInRect(&rc, MAKEPOINT(dw)) && (hwndP = GetWindow(hwnd, GW_CHILD)))
+ if (hwndP = LookForDC(hwndP,hdc))
+ return hwndP;
+ }
+
+ return NULL;
+}
+
+HWND WindowFromDC(HDC hdc)
+{
+ return LookForDC(GetDesktopWindow(), hdc);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+BOOL RectSameSize(LPRECT lprc1, LPRECT lprc2)
+{
+ return lprc1->right - lprc1->left == lprc2->right - lprc2->left &&
+ lprc1->bottom - lprc1->top == lprc2->bottom - lprc2->top;
+}
+
+/****************************************************************************
+
+ OleQueryObjPos - this function retuns the last drawn or activated
+ position of a object
+
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds OleQueryObjPos(
+LPOLEOBJECT lpobj, /* object to query */
+HWND FAR * lphwnd, /* window of the document containing the object */
+LPRECT lprc, /* rect (client cords) of object. */
+LPRECT lprcWBounds)/* rect (client cords) of bounding rect. */
+{
+ OBJINFO *poi;
+
+ //
+ // we dont do this any more
+ //
+ if (lprcWBounds)
+ SetRectEmpty(lprcWBounds);
+
+ //
+ // because the server side calls this API the passed lpobj is
+ // a server side LPOLEOBJECT, we can't search our table for this
+ // object.
+ //
+ // this API is only callable by the server during the DoVerb
+ // server callback
+ //
+ //!!! this only works for the last active object!!!!
+
+ DPRINTF(("OleQueryObjPos(%lx)", lpobj));
+
+ if (lpobjActive != NULL && (poi = FindObj(lpobjActive)))
+ {
+ //
+ // set lpobjActive to NULL so we will never retrive the
+ // wrong info again.
+ //
+ lpobjActive = NULL;
+
+ *lphwnd = poi->hwnd;
+
+// if (IsRectEmpty(&poi->rcActivate))
+ if (!IsRectEmpty(&poi->rcDraw))
+ {
+ DPRINTF(("Using the OleDraw() rectange...."));
+
+ //
+ // use the draw rectangle
+ //
+ *lprc = poi->rcDraw;
+
+ if (poi->hwndDraw)
+ {
+ ClientToScreen(poi->hwndDraw, (LPPOINT)lprc);
+ ClientToScreen(poi->hwndDraw, (LPPOINT)lprc+1);
+ }
+
+ ScreenToClient(poi->hwnd, (LPPOINT)lprc);
+ ScreenToClient(poi->hwnd, (LPPOINT)lprc+1);
+ }
+ else
+ {
+ //
+ // use the activate rectangle
+ //
+ *lprc = poi->rcActivate;
+ }
+
+ if (poi->hwnd && !IsRectEmpty(lprc))
+ return OLE_OK;
+ else
+ return OLE_ERROR_BLANK; // return a error, we dont know about this OBJ
+ }
+ else
+ {
+ *lphwnd = NULL;
+ SetRectEmpty(lprc);
+
+ return OLE_ERROR_BLANK; // return a error, we dont know about this OBJ
+ }
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllLoadFromStream (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;
+
+ DPRINTF(("OleLoadFromStream(%s,%s)", lpprotocol, lpobjname));
+
+ retVal = DefLoadFromStream (lpstream, lpprotocol, lpclient,
+ lhclientdoc, lpobjname, lplpobj,
+ objType, aClass, cfFormat);
+
+ if (retVal <= OLE_WAIT_FOR_RELEASE)
+ ReplaceFunctions(*lplpobj);
+
+ return retVal;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllCreateFromClip (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;
+
+ DPRINTF(("OleCreateFromClip(%s,%s)", lpprotocol, lpobjname));
+
+ retVal = DefCreateFromClip (lpprotocol, lpclient,
+ lhclientdoc, lpobjname, lplpobj,
+ optRender, cfFormat, objType);
+
+ if (retVal <= OLE_WAIT_FOR_RELEASE)
+ ReplaceFunctions(*lplpobj);
+
+ return retVal;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllCreateLinkFromClip (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;
+ BOOL bReplace = FALSE;
+
+ DPRINTF(("OleCreateLinkFromClip(%s,%s)", lpprotocol, lpobjname));
+
+ retVal = DefCreateLinkFromClip (lpprotocol, lpclient,
+ lhclientdoc, lpobjname, lplpobj,
+ optRender, cfFormat);
+
+ if (retVal <= OLE_WAIT_FOR_RELEASE)
+ ReplaceFunctions(*lplpobj);
+
+ return retVal;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllCreateFromTemplate (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;
+
+ DPRINTF(("OleCreateFromTemplate(%s,%s,%s)", lpprotocol, lptemplate, lpobjname));
+
+ retVal = DefCreateFromTemplate (lpprotocol, lpclient, lptemplate,
+ lhclientdoc, lpobjname, lplpobj,
+ optRender, cfFormat);
+
+ if (retVal <= OLE_WAIT_FOR_RELEASE)
+ ReplaceFunctions(*lplpobj);
+
+ return retVal;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllCreate (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;
+
+ DPRINTF(("OleCreate(%s,%s,%s)", lpprotocol, lpclass, lpobjname));
+
+ retVal = DefCreate (lpprotocol, lpclient, lpclass,
+ lhclientdoc, lpobjname, lplpobj,
+ optRender, cfFormat);
+
+ if (retVal <= OLE_WAIT_FOR_RELEASE)
+ ReplaceFunctions(*lplpobj);
+
+ return retVal;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllCreateFromFile (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;
+
+ DPRINTF(("OleCreateFromFile(%s,%s,%s,%s)", lpprotocol, lpclass, lpfile, lpobjname));
+
+ retVal = DefCreateFromFile (lpprotocol, lpclient, lpclass, lpfile,
+ lhclientdoc, lpobjname, lplpobj,
+ optRender, cfFormat);
+
+ if (retVal <= OLE_WAIT_FOR_RELEASE)
+ ReplaceFunctions(*lplpobj);
+
+ return retVal;
+}
+
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllCreateLinkFromFile (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;
+
+ DPRINTF(("OleCreateLinkFromFile(%s,%s,%s,%s,%s)", lpprotocol, lpclass, lpfile, lpitem, lpobjname));
+
+ retVal = DefCreateLinkFromFile (lpprotocol, lpclient,
+ lpclass, lpfile, lpitem,
+ lhclientdoc, lpobjname, lplpobj,
+ optRender, cfFormat);
+
+ if (retVal <= OLE_WAIT_FOR_RELEASE)
+ ReplaceFunctions(*lplpobj);
+
+ return retVal;
+}
+
+
+/****************************************************************************
+****************************************************************************/
+
+void ReplaceFunctions(LPOLEOBJECT lpobj)
+{
+// OBJINFO *poi;
+
+ if (!CanReplace(lpobj))
+ return;
+
+ NewObj(lpobj);
+
+ //
+ // get the default handlers
+ //
+ if (vtblDef.Draw == NULL) // only get the handlers once!
+ vtblDef = *lpobj->lpvtbl; // save default handlers
+
+ //
+ // make the OLE object use our handlers
+ //
+ lpobj->lpvtbl = (LPOLEOBJECTVTBL)&vtblDll;
+
+ //
+ // init our VTBL, ie replace any handlers we want to override.
+ // any handlers we dont replace we set the the default ones.
+ //
+ vtblDll = vtblDef;
+
+////(FARPROC)vtblDll.QueryProtocol = (FARPROC)DllQueryProtocol;
+////(FARPROC)vtblDll.Release = (FARPROC)DllRelease;
+////(FARPROC)vtblDll.Show = (FARPROC)DllShow;
+////(FARPROC)vtblDll.DoVerb = (FARPROC)DllDoVerb;
+////(FARPROC)vtblDll.GetData = (FARPROC)DllGetData;
+////(FARPROC)vtblDll.SetData = (FARPROC)DllSetData;
+////(FARPROC)vtblDll.SetTargetDevice = (FARPROC)DllSetTargetDevice;
+////(FARPROC)vtblDll.SetBounds = (FARPROC)DllSetBounds;
+////(FARPROC)vtblDll.EnumFormats = (FARPROC)DllEnumFormats;
+////(FARPROC)vtblDll.SetColorScheme = (FARPROC)DllSetColorScheme;
+
+ (FARPROC)vtblDll.Delete = (FARPROC)DllDelete;
+////(FARPROC)vtblDll.SetHostNames = (FARPROC)DllSetHostNames;
+////(FARPROC)vtblDll.SaveToStream = (FARPROC)DllSaveToStream;
+ (FARPROC)vtblDll.Clone = (FARPROC)DllClone;
+ (FARPROC)vtblDll.CopyFromLink = (FARPROC)DllCopyFromLink;
+////(FARPROC)vtblDll.Equal = (FARPROC)DllEqual;
+////(FARPROC)vtblDll.CopyToClipboard = (FARPROC)DllCopyToClipboard;
+ (FARPROC)vtblDll.Draw = (FARPROC)DllDraw;
+ (FARPROC)vtblDll.Activate = (FARPROC)DllActivate;
+////(FARPROC)vtblDll.Execute = (FARPROC)DllExecute;
+////(FARPROC)vtblDll.Close = (FARPROC)DllClose;
+////(FARPROC)vtblDll.Update = (FARPROC)DllUpdate;
+////(FARPROC)vtblDll.Reconnect = (FARPROC)DllReconnect;
+ (FARPROC)vtblDll.ObjectConvert = (FARPROC)DllObjectConvert;
+////(FARPROC)vtblDll.GetLinkUpdateOptions = (FARPROC)DllGetLinkUpdateOptions;
+////(FARPROC)vtblDll.SetLinkUpdateOptions = (FARPROC)DllSetLinkUpdateOptions;
+////(FARPROC)vtblDll.Rename = (FARPROC)DllRename;
+////(FARPROC)vtblDll.QueryName = (FARPROC)DllQueryName;
+////(FARPROC)vtblDll.QueryType = (FARPROC)DllQueryType;
+////(FARPROC)vtblDll.QueryBounds = (FARPROC)DllQueryBounds;
+////(FARPROC)vtblDll.QuerySize = (FARPROC)DllQuerySize;
+////(FARPROC)vtblDll.QueryOpen = (FARPROC)DllQueryOpen;
+////(FARPROC)vtblDll.QueryOutOfDate = (FARPROC)DllQueryOutOfDate;
+////(FARPROC)vtblDll.QueryReleaseStatus = (FARPROC)DllQueryReleaseStatus;
+////(FARPROC)vtblDll.QueryReleaseError = (FARPROC)DllQueryReleaseError;
+////(FARPROC)vtblDll.QueryReleaseMethod = (FARPROC)DllQueryReleaseMethod;
+////(FARPROC)vtblDll.RequestData = (FARPROC)DllRequestData;
+////(FARPROC)vtblDll.ObjectLong = (FARPROC)DllObjectLong;
+////(FARPROC)vtblDll.ChangeData = (FARPROC)DllChangeData;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+BOOL CanReplace(LPOLEOBJECT lpobj)
+{
+#if 0 // did not work anyway.
+ //
+ // we dont work on the wierd OLE shipped with PenWindows so don't load
+ //
+#pragma message("Disabling handler because we are on PenWindows...")
+ if (GetSystemMetrics(SM_PENWINDOWS))
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+LPVOID GetData(LPOLEOBJECT lpobj, WORD cf)
+{
+ HANDLE h;
+
+ if ( (*vtblDef.GetData)(lpobj, cf, &h) != OLE_OK || h == NULL)
+ return NULL;
+
+ return GlobalLock(h);
+}
+
+/****************************************************************************
+
+these are the actual handlers.....
+
+****************************************************************************/
+
+/****************************************************************************
+****************************************************************************/
+
+LPVOID FAR PASCAL _loadds DllQueryProtocol (
+LPOLEOBJECT lpobj,
+LPSTR lpsz)
+{
+ DPRINTF(("OleQueryProtocol(%ls)", lpsz));
+
+ return vtblDef.QueryProtocol(lpobj, lpsz);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllRelease (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleRelease()"));
+
+ return vtblDef.Release(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllShow (
+LPOLEOBJECT lpobj,
+BOOL fShow)
+{
+ DPRINTF(("OleShow(%d)", fShow));
+
+ return vtblDef.Show(lpobj, fShow);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllDoVerb (
+LPOLEOBJECT lpobj,
+WORD verb,
+BOOL fShow,
+BOOL fActivate)
+{
+ DPRINTF(("OleDoVerb(%d, %d, %d)", verb, fShow, fActivate));
+
+ return vtblDef.DoVerb(lpobj, verb, fShow, fActivate);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllGetData (
+LPOLEOBJECT lpobj,
+OLECLIPFORMAT cf,
+LPHANDLE lph)
+{
+ DPRINTF(("OleGetData(%d)", cf));
+
+ return vtblDef.GetData(lpobj, cf, lph);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllSetData (
+LPOLEOBJECT lpobj,
+OLECLIPFORMAT cf,
+HANDLE h)
+{
+ DPRINTF(("OleSetData(%d, %d)", cf, h));
+
+ return vtblDef.SetData(lpobj, cf, h);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllSetTargetDevice (
+LPOLEOBJECT lpobj,
+HANDLE h)
+{
+ DPRINTF(("OleSetTargetDevice()"));
+
+ return vtblDef.SetTargetDevice(lpobj, h);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllSetBounds (
+LPOLEOBJECT lpobj,
+LPRECT lprc)
+{
+ DPRINTF(("OleSetBounds([%d,%d,%d,%d])", PUSHRC(lprc)));
+
+ return vtblDef.SetBounds(lpobj, lprc);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLECLIPFORMAT FAR PASCAL _loadds DllEnumFormats (
+LPOLEOBJECT lpobj,
+OLECLIPFORMAT cf)
+{
+ DPRINTF(("OleEnumFormats(%d)", cf));
+
+ return vtblDef.EnumFormats(lpobj, cf);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllSetColorScheme (
+LPOLEOBJECT lpobj,
+LPLOGPALETTE lppal)
+{
+ DPRINTF(("OleSetColorScheme()"));
+
+ return vtblDef.SetColorScheme(lpobj, lppal);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllDelete (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleDelete(%lx)", lpobj));
+
+ DelObj(lpobj);
+ CleanObjects();
+
+ return vtblDef.Delete(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllSetHostNames (
+LPOLEOBJECT lpobj,
+LPSTR szClientName,
+LPSTR szDocName)
+{
+ DPRINTF(("OleSetHostNames(%ls,%ls)", szClientName, szDocName));
+
+ return vtblDef.SetHostNames(lpobj, szClientName, szDocName);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllSaveToStream (
+LPOLEOBJECT lpobj,
+LPOLESTREAM lpstream)
+{
+ DPRINTF(("OleSaveToStream()"));
+
+ return vtblDef.SaveToStream(lpobj, lpstream);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllClone (
+LPOLEOBJECT lpobj,
+LPOLECLIENT lpClient,
+LHCLIENTDOC lhClientDoc,
+LPSTR szObjName,
+LPOLEOBJECT FAR*lplpobj)
+{
+ OLESTATUS err;
+
+ DPRINTF(("OleClone(%ls)", szObjName));
+
+ err = vtblDef.Clone(lpobj, lpClient, lhClientDoc, szObjName, lplpobj);
+
+ //
+ // if the object cloned correctly then clone our object information
+ //
+ if (err <= OLE_WAIT_FOR_RELEASE)
+ {
+ OBJINFO *poi, *poiT;
+
+ if ((poiT = FindObj(lpobj)) && (poi = NewObj(NULL)))
+ {
+ poi->lpobj = *lplpobj;
+ poi->hwnd = poiT->hwnd;
+ poi->rcActivate = poiT->rcActivate;
+ poi->hwndDraw = poiT->hwndDraw;
+ poi->rcDraw = poiT->rcDraw;
+ }
+ }
+
+ return err;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllCopyFromLink (
+LPOLEOBJECT lpobj,
+LPOLECLIENT lpClient,
+LHCLIENTDOC lhClientDoc,
+LPSTR szObjName,
+LPOLEOBJECT FAR*lplpobj)
+{
+ OLESTATUS err;
+
+ DPRINTF(("OleCopyFromLink(%ls)", szObjName));
+
+ err = vtblDef.CopyFromLink(lpobj, lpClient, lhClientDoc, szObjName, lplpobj);
+
+ if (err <= OLE_WAIT_FOR_RELEASE)
+ NewObj(*lplpobj);
+
+ return err;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllEqual (
+LPOLEOBJECT lpobj1,
+LPOLEOBJECT lpobj2)
+{
+ DPRINTF(("OleEqual()"));
+
+ return vtblDef.Equal(lpobj1, lpobj2);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllCopyToClipboard (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleCopyToClipboard()"));
+
+ return vtblDef.CopyToClipboard(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllDraw (
+LPOLEOBJECT lpobj,
+HDC hdc,
+LPRECT lprcBounds,
+LPRECT lprcWBounds,
+HDC hdcFormat)
+{
+ OBJINFO *poi;
+ RECT rc;
+ DWORD dw;
+
+ DPRINTF(("OleDraw(%lx,[%d,%d,%d,%d], [%d,%d,%d,%d])", lpobj, PUSHRC(lprcBounds), PUSHRC(lprcWBounds)));
+
+#ifdef DEBUG
+ if (OleIsDcMeta(hdc))
+ DPRINTF(("OleDraw: drawing to a meta-file"));
+ else if (IsDcMemory(hdc))
+ DPRINTF(("OleDraw: drawing to a bitmap"));
+#endif
+
+ if ((poi = FindObj(lpobj)) && !OleIsDcMeta(hdc) && !IsDcMemory(hdc))
+ {
+ //!!!get the window from the HDC!!!
+
+ poi->hwndDraw = WindowFromDC(hdc);
+ DPRINTF(("OleDraw: hwndDraw = %04X", poi->hwndDraw));
+
+ if (lprcBounds && !IsRectEmpty(lprcBounds))
+ {
+ poi->rcDraw = *lprcBounds;
+
+ //
+ // convert the bound rectange into coordinates.
+ // relative to hwndDraw
+ //
+ LPtoDP(hdc, (LPPOINT)&poi->rcDraw, 2);
+
+ if (poi->hwndDraw == NULL)
+ {
+ dw = GetDCOrg(hdc);
+ OffsetRect(&poi->rcDraw, LOWORD(dw), HIWORD(dw));
+ }
+ }
+
+ if (GetClipBox(hdc, &rc) == NULLREGION)
+ return OLE_OK;
+ }
+
+ return vtblDef.Draw(lpobj, hdc, lprcBounds, lprcWBounds, hdcFormat);
+}
+
+/****************************************************************************
+
+ scan WinWords stack and "extract" the info it should have passed to
+ OleActivate() this has been tested with WinWord 2.0 and 2.0a.
+
+ we expect future verisons of WinWord to pass the correct info to
+ OleActivate() so we will never get here.
+
+****************************************************************************/
+
+BOOL NEAR PASCAL GetOpusRect(LPRECT lprcBound)
+{
+ LPRECT lprc;
+ LPVOID lp;
+// int i,dx,dy;
+
+ //
+ // see if the current app is WinWord
+ //
+ if (!IsApp("WINWORD.EXE"))
+ return FALSE;
+
+ //
+ // lets scan the stack looking for a RECT, this is a total
+ // hack to get MSWORD to work.
+ //
+ _asm
+ {
+ mov bx,ss:[bp] ; get saved BP DllActivate()
+ and bx, not 1
+ mov bx,ss:[bx] ; get saved saved BP OleActivate()
+ and bx, not 1
+ mov bx,ss:[bx] ; get saved saved saved BP "winword"
+ and bx, not 1
+
+ mov word ptr lp[0], bx
+ mov word ptr lp[2], ss
+ }
+
+#ifdef DEBUG
+ DPRINTF(("****** SCANING WINWORDs STACK ********"));
+ lprc = lp;
+
+ for (i=0; i<1000; i++)
+ {
+ dx = lprc->right - lprc->left;
+ dy = lprc->bottom - lprc->top;
+
+ if (dx >= 158 && dx <= 162 &&
+ dy >= 118 && dy <= 122)
+ {
+ DPRINTF(("found a RECT at offset %d, [%d, %d, %d, %d]",
+ (LPBYTE)lprc - (LPBYTE)lp, PUSHRC(lprc)));
+ }
+
+ ((LPBYTE)lprc)++;
+ }
+ DPRINTF(("**************************************"));
+#endif
+
+ lprc = (LPRECT)((LPBYTE)lp + 6);
+
+ if (lprc->right - lprc->left > 0 && lprc->bottom - lprc->top > 0)
+ {
+ DPRINTF(("*** HACK FOR WINWORD, [%d, %d, %d, %d]", PUSHRC(lprc)));
+ *lprcBound = *lprc;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllActivate (
+LPOLEOBJECT lpobj,
+WORD verb,
+BOOL fShow,
+BOOL fActivate,
+HWND hwnd,
+LPRECT lprcBound)
+{
+ OBJINFO *poi;
+ RECT rc;
+
+ DPRINTF(("OleActivate(%lx, %d, %d, %d, %04X, [%d,%d,%d,%d])", lpobj, verb, fShow, fActivate, hwnd, PUSHRC(lprcBound)));
+
+ //
+ // hack for Write
+ //
+ if (IsWindow(fActivate))
+ {
+ DPRINTF(("OleActivate: Write pre-realase work around"));
+ hwnd = fActivate;
+ fActivate = TRUE;
+ }
+
+ if (poi = FindObj(lpobj))
+ {
+ lpobjActive = lpobj;
+
+ poi->hwnd = hwnd;
+
+ if (poi->hwnd == NULL)
+ {
+ if (GetFocus())
+ {
+ DPRINTF(("OleActivate: no window specifed, using the focus window"));
+ poi->hwnd = GetFocus();
+ }
+ else
+ {
+ DPRINTF(("OleActivate: no window specifed, using the active window"));
+ poi->hwnd = GetActiveWindow();
+ }
+ }
+
+ if (lprcBound && !IsRectEmpty(lprcBound))
+ {
+ poi->rcActivate = *lprcBound;
+ }
+ else
+ {
+ GetOpusRect(&poi->rcActivate);
+ }
+
+ //
+ // MS-Publisher gives use the *wrong* rectangle in the OleActivate call
+ // and never calls OleDraw() we are hosed!
+ //
+ // so we check if the rect is off in space, and dont use it if so.
+ //
+ if (poi->hwnd)
+ {
+ GetClientRect(poi->hwnd, &rc);
+
+ IntersectRect(&rc,&rc,&poi->rcActivate);
+
+ if (IsRectEmpty(&rc))
+ {
+ DPRINTF(("OleActivate: rectangle specifed is not valid"));
+ SetRectEmpty(&poi->rcActivate);
+ }
+ }
+
+ if (IsRectEmpty(&poi->rcActivate))
+ {
+ DPRINTF(("OleActivate: stupid ole app!!!"));
+ }
+
+ //
+ // Shove it in the registry
+ //
+
+ {
+ RegSetGetData(poi, TRUE);
+ }
+ }
+
+ return vtblDef.Activate(lpobj, verb, fShow, fActivate, hwnd, lprcBound);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllExecute (
+LPOLEOBJECT lpobj,
+HANDLE hCmds,
+WORD reserved)
+{
+ DPRINTF(("OleExecute(%ls)", GlobalLock(hCmds)));
+
+ return vtblDef.Execute(lpobj, hCmds, reserved);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllClose (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleClose(%lx)", lpobj));
+
+////DelObj(lpobj);
+
+ return vtblDef.Close(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllUpdate (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleUpdate()"));
+
+ return vtblDef.Update(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllReconnect (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleReconnect()"));
+
+ return vtblDef.Reconnect(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllObjectConvert (
+LPOLEOBJECT lpobj,
+LPSTR szProtocol,
+LPOLECLIENT lpClient,
+LHCLIENTDOC lhClientDoc,
+LPSTR szObjName,
+LPOLEOBJECT FAR*lplpobj)
+{
+ OLESTATUS err;
+
+ DPRINTF(("OleObjectConvert(%ls,%ls)", szProtocol, szObjName));
+
+ err = vtblDef.ObjectConvert(lpobj, szProtocol, lpClient, lhClientDoc, szObjName, lplpobj);
+
+ if (err <= OLE_WAIT_FOR_RELEASE)
+ NewObj(*lplpobj);
+
+ return err;
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllGetLinkUpdateOptions (
+LPOLEOBJECT lpobj,
+OLEOPT_UPDATE FAR *lpoleopt)
+{
+ DPRINTF(("OleGetLinkUpdateOptions()"));
+
+ return vtblDef.GetLinkUpdateOptions(lpobj, lpoleopt);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllSetLinkUpdateOptions (
+LPOLEOBJECT lpobj,
+OLEOPT_UPDATE oleopt)
+{
+ DPRINTF(("OleSetLinkUpdateOptions()"));
+
+ return vtblDef.SetLinkUpdateOptions(lpobj, oleopt);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllRename (
+LPOLEOBJECT lpobj,
+LPSTR szName)
+{
+ DPRINTF(("OleRename(%ls)", szName));
+
+ return vtblDef.Rename(lpobj, szName);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllQueryName (
+LPOLEOBJECT lpobj,
+LPSTR szObjName,
+WORD FAR * lpwSize)
+{
+ DPRINTF(("OleQueryName(%ls)", szObjName));
+
+ return vtblDef.QueryName(lpobj, szObjName, lpwSize);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllQueryType (
+LPOLEOBJECT lpobj,
+LPLONG lpType)
+{
+ DPRINTF(("OleQueryType()"));
+
+ return vtblDef.QueryType(lpobj, lpType);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllQueryBounds (
+LPOLEOBJECT lpobj,
+LPRECT lprc)
+{
+ DPRINTF(("OleQueryBounds()"));
+
+ return vtblDef.QueryBounds(lpobj, lprc);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllQuerySize (
+LPOLEOBJECT lpobj,
+DWORD FAR * lpdwSize)
+{
+ DPRINTF(("OleQuerySize()"));
+
+ return vtblDef.QuerySize(lpobj, lpdwSize);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllQueryOpen (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleQueryOpen()"));
+
+ return vtblDef.QueryOpen(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllQueryOutOfDate (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleQueryOutOfDate()"));
+
+ return vtblDef.QueryOutOfDate(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllQueryReleaseStatus (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleQueryReleaseStatus()"));
+
+ return vtblDef.QueryReleaseStatus(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllQueryReleaseError (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleQueryReleaseError()"));
+
+ return vtblDef.QueryReleaseError(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllRequestData (
+LPOLEOBJECT lpobj,
+OLECLIPFORMAT cf)
+{
+ DPRINTF(("OleRequestData(%d)", cf));
+
+ return vtblDef.RequestData(lpobj, cf);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllObjectLong (
+LPOLEOBJECT lpobj,
+WORD w,
+LPLONG lpl)
+{
+ DPRINTF(("OleObjectLong()"));
+
+ return vtblDef.ObjectLong(lpobj, w, lpl);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLE_RELEASE_METHOD FAR PASCAL _loadds DllQueryReleaseMethod (
+LPOLEOBJECT lpobj)
+{
+ DPRINTF(("OleQueryReleaseMethod()"));
+
+ return vtblDef.QueryReleaseMethod(lpobj);
+}
+
+/****************************************************************************
+****************************************************************************/
+
+OLESTATUS FAR PASCAL _loadds DllChangeData (
+LPOLEOBJECT lpobj,
+HANDLE h,
+LPOLECLIENT lpClient,
+BOOL f)
+{
+ DPRINTF(("OleChangeData()"));
+
+ return vtblDef.ChangeData(lpobj, h, lpClient, f);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// DEBUG STUFF
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifdef DEBUG
+
+void FAR cdecl dprintf(LPSTR szFormat, ...)
+{
+ char ach[128];
+
+ extern FAR PASCAL OutputDebugStr(LPSTR);
+
+ lstrcpy(ach, "MCIOLE: ");
+ wvsprintf(ach + 8,szFormat,(LPSTR)(&szFormat+1));
+ lstrcat(ach,"\r\n");
+
+ OutputDebugString(ach);
+}
+
+#endif