diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/wow16/mciole/mciole.c | |
download | NT4.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.c | 1553 |
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 |