Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

633 lines
16 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: BM.C
  3. *
  4. * Handles all API routines for the bitmap sub-dll of the ole dll.
  5. *
  6. * Created: 1990
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * Raor,Srinik (../../1990,91) Designed, coded
  12. * Curts create NT version
  13. *
  14. \***************************************************************************/
  15. #include <windows.h>
  16. #include "dll.h"
  17. #include "pict.h"
  18. extern int maxPixelsX, maxPixelsY;
  19. void INTERNAL GetHimetricUnits(HBITMAP, LPPOINT);
  20. #ifdef WIN16
  21. #pragma alloc_text(_TEXT, BmSaveToStream, BmStreamWrite, BmLoadFromStream, BmStreamRead, GetBytes, PutBytes, PutStrWithLen, BmQueryBounds, BmChangeData, BmCopy, BmDuplicate, BmUpdateStruct, GetHimetricUnits)
  22. #endif
  23. OLEOBJECTVTBL vtblBM = {
  24. ErrQueryProtocol, // check whether the speced protocol is supported
  25. BmRelease, // Release
  26. ErrShow, // Show
  27. ErrPlay, // play
  28. BmGetData, // Get the object data
  29. ErrSetData, // Set the object data
  30. ErrSetTargetDevice,//
  31. ErrSetBounds, // set viewport bounds
  32. BmEnumFormat, // enumerate supported formats
  33. ErrSetColorScheme, //
  34. BmRelease, // delete
  35. ErrSetHostNames, //
  36. BmSaveToStream, // write to file
  37. BmClone, // clone object
  38. ErrCopyFromLink, // Create embedded from Link
  39. BmEqual, // compares the given objects for data equality
  40. BmCopy, // copy to clip
  41. BmDraw, // draw the object
  42. ErrActivate, // open
  43. ErrExecute, // excute
  44. ErrClose, // Stop
  45. ErrUpdate, // Update
  46. ErrReconnect, // Reconnect
  47. ErrObjectConvert, // convert object to specified type
  48. ErrGetUpdateOptions,// update options
  49. ErrSetUpdateOptions,// update options
  50. ObjRename, // Change Object name
  51. ObjQueryName, // Get current object name
  52. ObjQueryType, // Object type
  53. BmQueryBounds, // QueryBounds
  54. ObjQuerySize, // Find the size of the object
  55. ErrQueryOpen, // Query open
  56. ErrQueryOutOfDate, // query whether object is current
  57. ErrQueryRelease, // release related stuff
  58. ErrQueryRelease,
  59. ErrQueryReleaseMethod,
  60. ErrRequestData, // requestdata
  61. ErrObjectLong, // objectLong
  62. BmChangeData // change data of the existing object
  63. };
  64. OLESTATUS FARINTERNAL BmRelease (LPOLEOBJECT lpoleobj)
  65. {
  66. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  67. HOBJECT hobj;
  68. if (lpobj->hBitmap) {
  69. DeleteObject (lpobj->hBitmap);
  70. lpobj->hBitmap = NULL;
  71. }
  72. if (lpobj->head.lhclientdoc)
  73. DocDeleteObject ((LPOLEOBJECT) lpobj);
  74. if (hobj = lpobj->head.hobj){
  75. lpobj->head.hobj = NULL;
  76. GlobalUnlock (hobj);
  77. GlobalFree (hobj);
  78. }
  79. return OLE_OK;
  80. }
  81. OLESTATUS FARINTERNAL BmSaveToStream (
  82. LPOLEOBJECT lpoleobj,
  83. LPOLESTREAM lpstream
  84. ){
  85. DWORD dwFileVer = GetFileVersion(lpoleobj);
  86. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  87. DWORD dwSize = lpobj->sizeBytes - sizeof(BITMAP) + sizeof(WIN16BITMAP);
  88. if (!lpobj->hBitmap || !lpobj->sizeBytes)
  89. return OLE_ERROR_BLANK;
  90. if (PutBytes (lpstream, (LPSTR) &dwFileVer, sizeof(LONG)))
  91. return OLE_ERROR_STREAM;
  92. if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG)))
  93. return OLE_ERROR_STREAM;
  94. if (PutStrWithLen(lpstream, (LPSTR)"BITMAP"))
  95. return OLE_ERROR_STREAM;
  96. if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) {
  97. if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  98. if (!PutBytes (lpstream, (LPSTR) &dwSize, sizeof(DWORD)))
  99. return BmStreamWrite (lpstream, lpobj);
  100. }
  101. return OLE_ERROR_STREAM;
  102. }
  103. OLESTATUS FARINTERNAL BmClone (
  104. LPOLEOBJECT lpoleobj,
  105. LPOLECLIENT lpclient,
  106. LHCLIENTDOC lhclientdoc,
  107. OLE_LPCSTR lpobjname,
  108. LPOLEOBJECT FAR * lplpoleobj
  109. ){
  110. LPOBJECT_BM lpobjsrc = (LPOBJECT_BM)lpoleobj;
  111. LPOBJECT_BM FAR * lplpobj = (LPOBJECT_BM FAR *)lplpoleobj;
  112. if (!CheckClientDoc ((LPCLIENTDOC)lhclientdoc))
  113. return OLE_ERROR_HANDLE;
  114. if (!(*lplpobj = BmCreateObject (lpobjsrc->hBitmap, lpclient, FALSE,
  115. lhclientdoc, lpobjname,
  116. lpobjsrc->head.ctype)))
  117. return OLE_ERROR_MEMORY;
  118. else
  119. return OLE_OK;
  120. }
  121. OLESTATUS FARINTERNAL BmEqual (
  122. LPOLEOBJECT lpoleobj1,
  123. LPOLEOBJECT lpoleobj2
  124. ){
  125. LPOBJECT_BM lpobj1 = (LPOBJECT_BM)lpoleobj1;
  126. LPOBJECT_BM lpobj2 = (LPOBJECT_BM)lpoleobj2;
  127. HANDLE hBits1 = NULL, hBits2 = NULL;
  128. LPSTR lpBits1 = NULL, lpBits2 = NULL;
  129. OLESTATUS retVal;
  130. DWORD dwBytes1, dwBytes2;
  131. if (lpobj1->sizeBytes != lpobj2->sizeBytes)
  132. return OLE_ERROR_NOT_EQUAL;
  133. retVal = OLE_ERROR_MEMORY;
  134. if (!(hBits1 = GlobalAlloc (GMEM_MOVEABLE, lpobj1->sizeBytes)))
  135. goto errEqual;
  136. if (!(lpBits1 = GlobalLock (hBits1)))
  137. goto errEqual;
  138. if (!(hBits2 = GlobalAlloc (GMEM_MOVEABLE, lpobj2->sizeBytes)))
  139. goto errEqual;
  140. if (!(lpBits2 = GlobalLock (hBits2)))
  141. goto errEqual;
  142. dwBytes1 = GetBitmapBits (lpobj1->hBitmap, lpobj1->sizeBytes, lpBits1);
  143. dwBytes2 = GetBitmapBits (lpobj2->hBitmap, lpobj2->sizeBytes, lpBits2);
  144. if (dwBytes1 != dwBytes2) {
  145. retVal = OLE_ERROR_NOT_EQUAL;
  146. goto errEqual;
  147. }
  148. // !!! UtilMemCmp has to be redone for >64k bitmaps
  149. if (UtilMemCmp (lpBits1, lpBits2, dwBytes1))
  150. retVal = OLE_ERROR_NOT_EQUAL;
  151. else
  152. retVal = OLE_OK;
  153. errEqual:
  154. if (lpBits1)
  155. GlobalUnlock (hBits1);
  156. if (lpBits2)
  157. GlobalUnlock (hBits2);
  158. if (hBits1)
  159. GlobalFree (hBits1);
  160. if (hBits2)
  161. GlobalFree (hBits2);
  162. return retVal;
  163. }
  164. OLESTATUS FARINTERNAL BmCopy (
  165. LPOLEOBJECT lpoleobj
  166. ){
  167. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  168. HBITMAP hBitmap;
  169. DWORD size;
  170. if (!lpobj->hBitmap)
  171. return OLE_ERROR_BLANK;
  172. if(!(hBitmap = BmDuplicate (lpobj->hBitmap, &size, NULL)))
  173. return OLE_ERROR_MEMORY;
  174. SetClipboardData(CF_BITMAP, hBitmap);
  175. return OLE_OK;
  176. }
  177. OLESTATUS FARINTERNAL BmQueryBounds (
  178. LPOLEOBJECT lpoleobj,
  179. LPRECT lpRc
  180. ){
  181. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  182. Puts("BmQueryBounds");
  183. if (!lpobj->hBitmap)
  184. return OLE_ERROR_BLANK;
  185. lpRc->left = 0;
  186. lpRc->top = 0;
  187. lpRc->right = (int) lpobj->head.cx;
  188. lpRc->bottom = (int) lpobj->head.cy;
  189. return OLE_OK;
  190. }
  191. OLECLIPFORMAT FARINTERNAL BmEnumFormat (
  192. LPOLEOBJECT lpoleobj,
  193. OLECLIPFORMAT cfFormat
  194. ){
  195. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  196. if (!cfFormat)
  197. return CF_BITMAP;
  198. return 0;
  199. }
  200. OLESTATUS FARINTERNAL BmGetData (
  201. LPOLEOBJECT lpoleobj,
  202. OLECLIPFORMAT cfFormat,
  203. LPHANDLE lphandle
  204. ){
  205. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  206. if (cfFormat != CF_BITMAP)
  207. return OLE_ERROR_FORMAT;
  208. if (!(*lphandle = lpobj->hBitmap))
  209. return OLE_ERROR_BLANK;
  210. return OLE_OK;
  211. }
  212. OLESTATUS FARINTERNAL BmLoadFromStream (
  213. LPOLESTREAM lpstream,
  214. LPOLECLIENT lpclient,
  215. LHCLIENTDOC lhclientdoc,
  216. LPSTR lpobjname,
  217. LPOLEOBJECT FAR * lplpoleobject,
  218. LONG objType
  219. ){
  220. LPOBJECT_BM lpobj = NULL;
  221. *lplpoleobject = NULL;
  222. if (!(lpobj = BmCreateBlank (lhclientdoc, lpobjname, objType)))
  223. return OLE_ERROR_MEMORY;
  224. lpobj->head.lpclient = lpclient;
  225. if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) {
  226. if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  227. if (!GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD)))
  228. if (BmStreamRead (lpstream, lpobj)) {
  229. *lplpoleobject = (LPOLEOBJECT)lpobj;
  230. return OLE_OK;
  231. }
  232. }
  233. OleDelete ((LPOLEOBJECT)lpobj);
  234. return OLE_ERROR_STREAM;;
  235. }
  236. OLESTATUS INTERNAL BmStreamWrite (
  237. LPOLESTREAM lpstream,
  238. LPOBJECT_BM lpobj
  239. ){
  240. HANDLE hBits;
  241. LPSTR lpBits;
  242. int retVal = OLE_ERROR_STREAM;
  243. BITMAP bm;
  244. DWORD dwSize;
  245. dwSize = lpobj->sizeBytes - sizeof(BITMAP);
  246. if (hBits = GlobalAlloc (GMEM_MOVEABLE, dwSize)) {
  247. if (lpBits = (LPSTR) GlobalLock (hBits)) {
  248. if (GetBitmapBits (lpobj->hBitmap, dwSize, lpBits)) {
  249. WIN16BITMAP w16bm;
  250. GetObject (lpobj->hBitmap, sizeof(BITMAP), (LPSTR) &bm);
  251. ConvertBM32to16(&bm, &w16bm);
  252. if (!PutBytes (lpstream, (LPSTR) &w16bm, sizeof(WIN16BITMAP)))
  253. if (!PutBytes (lpstream, (LPSTR) lpBits, dwSize))
  254. retVal = OLE_OK;
  255. }
  256. GlobalUnlock(hBits);
  257. } else
  258. retVal = OLE_ERROR_MEMORY;
  259. GlobalFree(hBits);
  260. } else
  261. retVal = OLE_ERROR_MEMORY;
  262. return retVal;
  263. }
  264. BOOL INTERNAL BmStreamRead (
  265. LPOLESTREAM lpstream,
  266. LPOBJECT_BM lpobj
  267. ){
  268. HANDLE hBits;
  269. LPSTR lpBits;
  270. BOOL retVal = FALSE;
  271. BITMAP bm;
  272. WIN16BITMAP w16bm;
  273. POINT point;
  274. if (GetBytes (lpstream, (LPSTR)&w16bm, sizeof(WIN16BITMAP)))
  275. return FALSE;
  276. ConvertBM16to32(&w16bm,&bm);
  277. lpobj->sizeBytes -= sizeof(WIN16BITMAP) ;
  278. if (hBits = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes)) {
  279. if (lpBits = (LPSTR) GlobalLock (hBits)) {
  280. if (!GetBytes(lpstream, lpBits, lpobj->sizeBytes)) {
  281. if (lpobj->hBitmap = CreateBitmap (bm.bmWidth,
  282. bm.bmHeight,
  283. bm.bmPlanes,
  284. bm.bmBitsPixel,
  285. lpBits)) {
  286. retVal = TRUE;
  287. lpobj->xSize = point.x = bm.bmWidth;
  288. lpobj->ySize = point.y = bm.bmHeight;
  289. // size of (bitmap header + bits)
  290. lpobj->sizeBytes += sizeof(BITMAP);
  291. #ifdef OLD
  292. // !!! We shouldn't do the conversion. The info should be
  293. // part of the stream.
  294. if (!lpobj->head.cx) {
  295. ConvertToHimetric (&point);
  296. lpobj->head.cx = (LONG) point.x;
  297. lpobj->head.cy = (LONG) point.y;
  298. }
  299. #endif
  300. }
  301. }
  302. GlobalUnlock(hBits);
  303. }
  304. GlobalFree(hBits);
  305. }
  306. return retVal;
  307. }
  308. OLESTATUS FARINTERNAL BmPaste (
  309. LPOLECLIENT lpclient,
  310. LHCLIENTDOC lhclientdoc,
  311. LPSTR lpobjname,
  312. LPOLEOBJECT FAR * lplpoleobject,
  313. LONG objType
  314. ){
  315. HBITMAP hBitmap;
  316. *lplpoleobject = NULL;
  317. if ((hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP)) == NULL)
  318. return OLE_ERROR_MEMORY;
  319. if (!(*lplpoleobject = (LPOLEOBJECT) BmCreateObject (hBitmap,
  320. lpclient, FALSE, lhclientdoc,
  321. lpobjname, objType)))
  322. return OLE_ERROR_MEMORY;
  323. return OLE_OK;
  324. }
  325. LPOBJECT_BM INTERNAL BmCreateObject (
  326. HBITMAP hBitmap,
  327. LPOLECLIENT lpclient,
  328. BOOL fDelete,
  329. LHCLIENTDOC lhclientdoc,
  330. LPCSTR lpobjname,
  331. LONG objType
  332. ){
  333. LPOBJECT_BM lpobj;
  334. if (lpobj = BmCreateBlank (lhclientdoc, (LPSTR)lpobjname, objType)) {
  335. if (BmChangeData ((LPOLEOBJECT)lpobj, (HANDLE)hBitmap, lpclient, fDelete) != OLE_OK) {
  336. BmRelease ((LPOLEOBJECT)lpobj);
  337. lpobj = NULL;
  338. }
  339. }
  340. return lpobj;
  341. }
  342. // If the routine fails then the object will be left with it's old data.
  343. // If fDelete is TRUE, then hNewBitmap will be deleted whether the routine
  344. // is successful or not.
  345. OLESTATUS FARINTERNAL BmChangeData (
  346. LPOLEOBJECT lpoleobj,
  347. HANDLE hNewBitmap,
  348. LPOLECLIENT lpclient,
  349. BOOL fDelete
  350. ){
  351. LPOBJECT_BM lpobj = (LPOBJECT_BM)lpoleobj;
  352. BITMAP bm;
  353. DWORD dwSize;
  354. HBITMAP hOldBitmap;
  355. hOldBitmap = lpobj->hBitmap;
  356. if (!fDelete) {
  357. if (!(hNewBitmap = BmDuplicate (hNewBitmap, &dwSize, &bm)))
  358. return OLE_ERROR_MEMORY;
  359. }
  360. else {
  361. if (!GetObject (hNewBitmap, sizeof(BITMAP), (LPSTR) &bm)) {
  362. DeleteObject (hNewBitmap);
  363. return OLE_ERROR_MEMORY;
  364. }
  365. //*add get bitmap bits
  366. dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) *
  367. ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel);
  368. }
  369. BmUpdateStruct (lpobj, lpclient, hNewBitmap, &bm, dwSize);
  370. if (hOldBitmap)
  371. DeleteObject (hOldBitmap);
  372. return OLE_OK;
  373. }
  374. void INTERNAL BmUpdateStruct (
  375. LPOBJECT_BM lpobj,
  376. LPOLECLIENT lpclient,
  377. HBITMAP hBitmap,
  378. LPBITMAP lpBm,
  379. DWORD dwBytes
  380. ){
  381. POINT point;
  382. lpobj->head.lpclient = lpclient;
  383. lpobj->xSize = point.x = lpBm->bmWidth;
  384. lpobj->ySize = point.y = lpBm->bmHeight;
  385. GetHimetricUnits (hBitmap, &point);
  386. lpobj->head.cx = (LONG) point.x;
  387. lpobj->head.cy = (LONG) point.y;
  388. lpobj->sizeBytes = dwBytes + sizeof(BITMAP);
  389. lpobj->hBitmap = hBitmap;
  390. }
  391. LPOBJECT_BM FARINTERNAL BmCreateBlank (
  392. LHCLIENTDOC lhclientdoc,
  393. LPSTR lpobjname,
  394. LONG objType
  395. ){
  396. HOBJECT hobj;
  397. LPOBJECT_BM lpobj;
  398. if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_BM)))
  399. == NULL)
  400. return NULL;
  401. if (!(lpobj = (LPOBJECT_BM) GlobalLock (hobj))){
  402. GlobalFree (hobj);
  403. return NULL;
  404. }
  405. lpobj->head.objId[0] = 'L';
  406. lpobj->head.objId[1] = 'E';
  407. lpobj->head.mm = MM_TEXT;
  408. lpobj->head.ctype = objType;
  409. lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblBM;
  410. lpobj->head.iTable = INVALID_INDEX;
  411. lpobj->head.hobj = hobj;
  412. if (objType == CT_STATIC)
  413. DocAddObject ((LPCLIENTDOC) lhclientdoc,
  414. (LPOLEOBJECT) lpobj, lpobjname);
  415. return lpobj;
  416. }
  417. HBITMAP FARINTERNAL BmDuplicate (
  418. HBITMAP hold,
  419. DWORD FAR * lpdwSize,
  420. LPBITMAP lpBm
  421. ){
  422. HBITMAP hnew;
  423. HANDLE hMem;
  424. LPSTR lpMem;
  425. LONG retVal = TRUE;
  426. DWORD dwSize;
  427. BITMAP bm;
  428. INT iX,iY;
  429. // !!! another way to duplicate the bitmap
  430. GetObject (hold, sizeof(BITMAP), (LPSTR) &bm);
  431. dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) *
  432. ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel);
  433. if (!(hMem = GlobalAlloc (GMEM_MOVEABLE, dwSize)))
  434. return NULL;
  435. if (!(lpMem = GlobalLock (hMem))){
  436. GlobalFree (hMem);
  437. return NULL;
  438. }
  439. GetBitmapBits (hold, dwSize, lpMem);
  440. if (hnew = CreateBitmap (bm.bmWidth, bm.bmHeight,
  441. bm.bmPlanes, bm.bmBitsPixel, NULL)) {
  442. if (hnew) retVal = SetBitmapBits (hnew, dwSize, lpMem);
  443. }
  444. GlobalUnlock (hMem);
  445. GlobalFree (hMem);
  446. if (hnew && (!retVal)) {
  447. DeleteObject (hnew);
  448. hnew = NULL;
  449. }
  450. *lpdwSize = dwSize;
  451. if (lpBm)
  452. *lpBm = bm;
  453. if (MGetBitmapDimension (hold,&iX,&iY))
  454. if (hnew) MSetBitmapDimension (hnew, iX, iY);
  455. return hnew;
  456. }
  457. void INTERNAL GetHimetricUnits(HBITMAP hBitmap, LPPOINT lpPoint)
  458. {
  459. HDC hdc;
  460. INT iX,iY;
  461. MGetBitmapDimension (hBitmap,&iX,&iY);
  462. if (iX || iY) {
  463. lpPoint->x = 10 * iX;
  464. lpPoint->y = - (10 * iY);
  465. return;
  466. }
  467. // clip if it exceeds maxPixels. Note that we have a limitation of
  468. // 0x8FFF HIMETRIC units in OLE1.0
  469. if (lpPoint->x > maxPixelsX)
  470. lpPoint->x = maxPixelsX;
  471. if (lpPoint->y > maxPixelsY)
  472. lpPoint->y = maxPixelsY;
  473. if (hdc = GetDC (NULL)) {
  474. lpPoint->x = MulDiv (lpPoint->x, 2540,
  475. GetDeviceCaps (hdc, LOGPIXELSX));
  476. lpPoint->y = - MulDiv (lpPoint->y, 2540,
  477. GetDeviceCaps (hdc, LOGPIXELSY));
  478. ReleaseDC (NULL, hdc);
  479. }
  480. else {
  481. lpPoint->x = 0;
  482. lpPoint->y = 0;
  483. }
  484. }