|
|
/****************************** Module Header ******************************\
* Module Name: BM.C * * Handles all API routines for the bitmap sub-dll of the ole dll. * * Created: 1990 * * Copyright (c) 1990, 1991 Microsoft Corporation * * History: * Raor,Srinik (../../1990,91) Designed, coded * \***************************************************************************/
#include <windows.h>
#include "dll.h"
#include "pict.h"
extern int maxPixelsX, maxPixelsY; void INTERNAL GetHimetricUnits(HBITMAP, LPPOINT);
#pragma alloc_text(_TEXT, BmSaveToStream, BmStreamWrite, BmLoadFromStream, BmStreamRead, GetBytes, PutBytes, PutStrWithLen, BmQueryBounds, BmChangeData, BmCopy, BmDuplicate, BmUpdateStruct, GetHimetricUnits)
OLEOBJECTVTBL vtblBM = {
ErrQueryProtocol, // check whether the speced protocol is supported
BmRelease, // Release
ErrShow, // Show
ErrPlay, // play
BmGetData, // Get the object data
ErrSetData, // Set the object data
ErrSetTargetDevice,//
ErrSetBounds, // set viewport bounds
BmEnumFormat, // enumerate supported formats
ErrSetColorScheme, //
BmRelease, // delete
ErrSetHostNames, //
BmSaveToStream, // write to file
BmClone, // clone object
ErrCopyFromLink, // Create embedded from Link
BmEqual, // compares the given objects for data equality
BmCopy, // copy to clip
BmDraw, // draw the object
ErrActivate, // open
ErrExecute, // excute
ErrClose, // Stop
ErrUpdate, // Update
ErrReconnect, // Reconnect
ErrObjectConvert, // convert object to specified type
ErrGetUpdateOptions,// update options
ErrSetUpdateOptions,// update options
ObjRename, // Change Object name
ObjQueryName, // Get current object name
ObjQueryType, // Object type
BmQueryBounds, // QueryBounds
ObjQuerySize, // Find the size of the object
ErrQueryOpen, // Query open
ErrQueryOutOfDate, // query whether object is current
ErrQueryRelease, // release related stuff
ErrQueryRelease, ErrQueryRelease,
ErrRequestData, // requestdata
ErrObjectLong, // objectLong
BmChangeData // change data of the existing object
};
OLESTATUS FARINTERNAL BmRelease (lpobj) LPOBJECT_BM lpobj; { HOBJECT hobj;
if (lpobj->hBitmap) { DeleteObject (lpobj->hBitmap); lpobj->hBitmap = NULL; }
if (lpobj->head.lhclientdoc) DocDeleteObject ((LPOLEOBJECT) lpobj); if (hobj = lpobj->head.hobj){ lpobj->head.hobj = NULL; GlobalUnlock (hobj); GlobalFree (hobj); }
return OLE_OK; }
OLESTATUS FARINTERNAL BmSaveToStream (lpobj, lpstream) LPOBJECT_BM lpobj; LPOLESTREAM lpstream; { if (!lpobj->hBitmap || !lpobj->sizeBytes) return OLE_ERROR_BLANK; if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG))) return OLE_ERROR_STREAM;
if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG))) return OLE_ERROR_STREAM;
if (PutStrWithLen(lpstream, (LPSTR)"BITMAP")) return OLE_ERROR_STREAM;
if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) { if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) if (!PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD))) return BmStreamWrite (lpstream, lpobj); } return OLE_ERROR_STREAM; }
OLESTATUS FARINTERNAL BmClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) LPOBJECT_BM lpobjsrc; LPOLECLIENT lpclient; LHCLIENTDOC lhclientdoc; LPSTR lpobjname; LPOBJECT_BM FAR * lplpobj; { if (!CheckClientDoc ((LPCLIENTDOC)lhclientdoc)) return OLE_ERROR_HANDLE; if (!(*lplpobj = BmCreateObject (lpobjsrc->hBitmap, lpclient, FALSE, lhclientdoc, lpobjname, lpobjsrc->head.ctype))) return OLE_ERROR_MEMORY; else return OLE_OK; }
OLESTATUS FARINTERNAL BmEqual (lpobj1, lpobj2) LPOBJECT_BM lpobj1; LPOBJECT_BM lpobj2; { HANDLE hBits1 = NULL, hBits2 = NULL; LPSTR lpBits1 = NULL, lpBits2 = NULL; OLESTATUS retVal; DWORD dwBytes1, dwBytes2;
if (lpobj1->sizeBytes != lpobj2->sizeBytes) return OLE_ERROR_NOT_EQUAL; retVal = OLE_ERROR_MEMORY; if (!(hBits1 = GlobalAlloc (GMEM_MOVEABLE, lpobj1->sizeBytes))) goto errEqual; if (!(lpBits1 = GlobalLock (hBits1))) goto errEqual; if (!(hBits2 = GlobalAlloc (GMEM_MOVEABLE, lpobj2->sizeBytes))) goto errEqual; if (!(lpBits2 = GlobalLock (hBits2))) goto errEqual; dwBytes1 = GetBitmapBits (lpobj1->hBitmap, lpobj1->sizeBytes, lpBits1); dwBytes2 = GetBitmapBits (lpobj2->hBitmap, lpobj2->sizeBytes, lpBits2); if (dwBytes1 != dwBytes2) { retVal = OLE_ERROR_NOT_EQUAL; goto errEqual; } // !!! UtilMemCmp has to be redone for >64k bitmaps
if (UtilMemCmp (lpBits1, lpBits2, dwBytes1)) retVal = OLE_ERROR_NOT_EQUAL; else retVal = OLE_OK;
errEqual: if (lpBits1) GlobalUnlock (hBits1); if (lpBits2) GlobalUnlock (hBits2); if (hBits1) GlobalFree (hBits1); if (hBits2) GlobalFree (hBits2); return retVal; }
OLESTATUS FARINTERNAL BmCopy (lpobj) LPOBJECT_BM lpobj; { HBITMAP hBitmap; DWORD size; if (!lpobj->hBitmap) return OLE_ERROR_BLANK;
if(!(hBitmap = BmDuplicate (lpobj->hBitmap, &size, NULL))) return OLE_ERROR_MEMORY;
SetClipboardData(CF_BITMAP, hBitmap); return OLE_OK; }
OLESTATUS FARINTERNAL BmQueryBounds (lpobj, lpRc) LPOBJECT_BM lpobj; LPRECT lpRc; { Puts("BmQueryBounds"); if (!lpobj->hBitmap) return OLE_ERROR_BLANK;
lpRc->left = 0; lpRc->top = 0; lpRc->right = (int) lpobj->head.cx; lpRc->bottom = (int) lpobj->head.cy; return OLE_OK; }
OLECLIPFORMAT FARINTERNAL BmEnumFormat (lpobj, cfFormat) LPOBJECT_BM lpobj; OLECLIPFORMAT cfFormat; { if (!cfFormat) return CF_BITMAP; return NULL; }
OLESTATUS FARINTERNAL BmGetData (lpobj, cfFormat, lphandle) LPOBJECT_BM lpobj; OLECLIPFORMAT cfFormat; LPHANDLE lphandle; { if (cfFormat != CF_BITMAP) return OLE_ERROR_FORMAT; if (!(*lphandle = lpobj->hBitmap)) return OLE_ERROR_BLANK; return OLE_OK;
}
OLESTATUS FARINTERNAL BmLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpoleobject, objType) LPOLESTREAM lpstream; LPOLECLIENT lpclient; LHCLIENTDOC lhclientdoc; LPSTR lpobjname; LPOLEOBJECT FAR * lplpoleobject; LONG objType; { LPOBJECT_BM lpobj = NULL;
*lplpoleobject = NULL;
if (!(lpobj = BmCreateBlank (lhclientdoc, lpobjname, objType))) return OLE_ERROR_MEMORY;
lpobj->head.lpclient = lpclient;
if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) { if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) if (!GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD))) if (BmStreamRead (lpstream, lpobj)) { *lplpoleobject = (LPOLEOBJECT)lpobj; return OLE_OK; } } OleDelete ((LPOLEOBJECT)lpobj); return OLE_ERROR_STREAM;; }
OLESTATUS INTERNAL BmStreamWrite (lpstream, lpobj) LPOLESTREAM lpstream; LPOBJECT_BM lpobj; { HANDLE hBits; LPSTR lpBits; int retVal = OLE_ERROR_STREAM; BITMAP bm; DWORD dwSize; // size of bit array
dwSize = lpobj->sizeBytes - sizeof(BITMAP); if (hBits = GlobalAlloc (GMEM_MOVEABLE, dwSize)) { if (lpBits = (LPSTR) GlobalLock (hBits)) { if (GetBitmapBits (lpobj->hBitmap, dwSize, lpBits)) { GetObject (lpobj->hBitmap, sizeof(BITMAP), (LPSTR) &bm); if (!PutBytes (lpstream, (LPSTR) &bm, sizeof(BITMAP))) if (!PutBytes (lpstream, (LPSTR) lpBits, dwSize)) retVal = OLE_OK; } GlobalUnlock(hBits); } else retVal = OLE_ERROR_MEMORY; GlobalFree(hBits); } else retVal = OLE_ERROR_MEMORY;
return retVal; }
BOOL INTERNAL BmStreamRead (lpstream, lpobj) LPOLESTREAM lpstream; LPOBJECT_BM lpobj; { HANDLE hBits; LPSTR lpBits; BOOL retVal = FALSE; BITMAP bm; POINT point;
if (GetBytes (lpstream, (LPSTR)&bm, sizeof(BITMAP))) return FALSE;
lpobj->sizeBytes = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) * ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel); if (hBits = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes)) { if (lpBits = (LPSTR) GlobalLock (hBits)) { if (!GetBytes(lpstream, lpBits, lpobj->sizeBytes)) { if (lpobj->hBitmap = CreateBitmap (bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel, lpBits)) { retVal = TRUE; lpobj->xSize = point.x = bm.bmWidth; lpobj->ySize = point.y = bm.bmHeight; // size of (bitmap header + bits)
lpobj->sizeBytes += sizeof(BITMAP); #ifdef OLD
// !!! We shouldn't do the conversion. The info should be
// part of the stream.
if (!lpobj->head.cx) { ConvertToHimetric (&point); lpobj->head.cx = (LONG) point.x; lpobj->head.cy = (LONG) point.y; } #endif
} } GlobalUnlock(hBits); } GlobalFree(hBits); } return retVal; }
OLESTATUS FARINTERNAL BmPaste (lpclient, lhclientdoc, lpobjname, lplpoleobject, objType) LPOLECLIENT lpclient; LHCLIENTDOC lhclientdoc; LPSTR lpobjname; LPOLEOBJECT FAR * lplpoleobject; LONG objType; { HBITMAP hBitmap;
*lplpoleobject = NULL;
if ((hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP)) == NULL) return OLE_ERROR_MEMORY;
if (!(*lplpoleobject = (LPOLEOBJECT) BmCreateObject (hBitmap, lpclient, FALSE, lhclientdoc, lpobjname, objType))) return OLE_ERROR_MEMORY; return OLE_OK;
}
LPOBJECT_BM INTERNAL BmCreateObject (hBitmap, lpclient, fDelete, lhclientdoc, lpobjname, objType) HBITMAP hBitmap; LPOLECLIENT lpclient; BOOL fDelete; LHCLIENTDOC lhclientdoc; LPSTR lpobjname; LONG objType; { LPOBJECT_BM lpobj; if (lpobj = BmCreateBlank (lhclientdoc, lpobjname, objType)) { if (BmChangeData (lpobj, hBitmap, lpclient, fDelete) != OLE_OK) { BmRelease (lpobj); lpobj = NULL; } }
return lpobj; }
// If the routine fails then the object will be left with it's old data.
// If fDelete is TRUE, then hNewBitmap will be deleted whether the routine
// is successful or not.
OLESTATUS FARINTERNAL BmChangeData (lpobj, hNewBitmap, lpclient, fDelete) LPOBJECT_BM lpobj; HBITMAP hNewBitmap; LPOLECLIENT lpclient; BOOL fDelete; { BITMAP bm; DWORD dwSize; HBITMAP hOldBitmap; hOldBitmap = lpobj->hBitmap;
if (!fDelete) { if (!(hNewBitmap = BmDuplicate (hNewBitmap, &dwSize, &bm))) return OLE_ERROR_MEMORY; } else { if (!GetObject (hNewBitmap, sizeof(BITMAP), (LPSTR) &bm)) { DeleteObject (hNewBitmap); return OLE_ERROR_MEMORY; }
dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) * ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel); }
BmUpdateStruct (lpobj, lpclient, hNewBitmap, &bm, dwSize); if (hOldBitmap) DeleteObject (hOldBitmap); return OLE_OK; }
void INTERNAL BmUpdateStruct (lpobj, lpclient, hBitmap, lpBm, dwBytes) LPOBJECT_BM lpobj; LPOLECLIENT lpclient; HBITMAP hBitmap; LPBITMAP lpBm; DWORD dwBytes; { POINT point;
lpobj->head.lpclient = lpclient; lpobj->xSize = point.x = lpBm->bmWidth; lpobj->ySize = point.y = lpBm->bmHeight; GetHimetricUnits (hBitmap, &point); lpobj->head.cx = (LONG) point.x; lpobj->head.cy = (LONG) point.y; lpobj->sizeBytes = dwBytes + sizeof(BITMAP); lpobj->hBitmap = hBitmap; }
LPOBJECT_BM FARINTERNAL BmCreateBlank (lhclientdoc, lpobjname, objType) LHCLIENTDOC lhclientdoc; LPSTR lpobjname; LONG objType; { HOBJECT hobj; LPOBJECT_BM lpobj;
if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_BM))) == NULL) return NULL;
if (!(lpobj = (LPOBJECT_BM) GlobalLock (hobj))){ GlobalFree (hobj); return NULL; }
lpobj->head.objId[0] = 'L'; lpobj->head.objId[1] = 'E'; lpobj->head.mm = MM_TEXT; lpobj->head.ctype = objType; lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblBM; lpobj->head.iTable = INVALID_INDEX; lpobj->head.hobj = hobj; if (objType == CT_STATIC) DocAddObject ((LPCLIENTDOC) lhclientdoc, (LPOLEOBJECT) lpobj, lpobjname);
return lpobj; }
HBITMAP FARINTERNAL BmDuplicate (hold, lpdwSize, lpBm) HBITMAP hold; DWORD FAR * lpdwSize; LPBITMAP lpBm; { HBITMAP hnew; HANDLE hMem; LPSTR lpMem; LONG retVal = TRUE; DWORD dwSize; BITMAP bm; DWORD dwExtents = NULL; // !!! another way to duplicate the bitmap
GetObject (hold, sizeof(BITMAP), (LPSTR) &bm); dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) * ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel);
if (!(hMem = GlobalAlloc (GMEM_MOVEABLE, dwSize))) return NULL;
if (!(lpMem = GlobalLock (hMem))){ GlobalFree (hMem); return NULL; } GetBitmapBits (hold, dwSize, lpMem); if (hnew = CreateBitmap (bm.bmWidth, bm.bmHeight, bm.bmPlanes, bm.bmBitsPixel, NULL)) retVal = SetBitmapBits (hnew, dwSize, lpMem);
GlobalUnlock (hMem); GlobalFree (hMem);
if (hnew && (!retVal)) { DeleteObject (hnew); hnew = NULL; } *lpdwSize = dwSize; if (lpBm) *lpBm = bm; if (dwExtents = GetBitmapDimension (hold)) SetBitmapDimension (hnew, LOWORD(dwExtents), HIWORD(dwExtents)); return hnew; }
void INTERNAL GetHimetricUnits(HBITMAP hBitmap, LPPOINT lpPoint) { HDC hdc; DWORD dwDim; if (dwDim = GetBitmapDimension (hBitmap)) { lpPoint->x = 10 * LOWORD(dwDim); lpPoint->y = - (10 * HIWORD(dwDim)); return; } // clip if it exceeds maxPixels. Note that we have a limitation of
// 0x8FFF HIMETRIC units in OLE1.0
if (lpPoint->x > maxPixelsX) lpPoint->x = maxPixelsX; if (lpPoint->y > maxPixelsY) lpPoint->y = maxPixelsY; if (hdc = GetDC (NULL)) { lpPoint->x = MulDiv (lpPoint->x, 2540, GetDeviceCaps (hdc, LOGPIXELSX)); lpPoint->y = - MulDiv (lpPoint->y, 2540, GetDeviceCaps (hdc, LOGPIXELSY)); ReleaseDC (NULL, hdc); } else { lpPoint->x = 0; lpPoint->y = 0; } }
|