Leaked source code of windows server 2003
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.

583 lines
16 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name:EMF.C (Extensible Compound Documents - EnhancedMetafile)
  3. *
  4. * PURPOSE:Handles all API routines for the metafile sub-dll of the ole dll.
  5. *
  6. * Created: 1990
  7. *
  8. * Copyright (c) 1990, 1991 Microsoft Corporation
  9. *
  10. * History:
  11. * cloned mf.c and banged into form curts March 92
  12. *
  13. * Comments:
  14. * fun, fun, until hockl takes the enhanced metafile api away
  15. *
  16. \***************************************************************************/
  17. #include <windows.h>
  18. #include "dll.h"
  19. #include "pict.h"
  20. #define RECORD_COUNT 16
  21. OLEOBJECTVTBL vtblEMF = {
  22. ErrQueryProtocol, // check whether the speced protocol is supported
  23. EmfRelease, // Release
  24. ErrShow, // show
  25. ErrPlay, // play
  26. EmfGetData, // Get the object data
  27. ErrSetData, // Set the object data
  28. ErrSetTargetDevice, //
  29. ErrSetBounds, // set viewport bounds
  30. EmfEnumFormat, // enumerate supported formats
  31. ErrSetColorScheme, //
  32. EmfRelease, // delete
  33. ErrSetHostNames, //
  34. EmfSaveToStream, // write to file
  35. EmfClone, // clone object
  36. ErrCopyFromLink, // Create embedded from Lnk
  37. EmfEqual, // compares the given objects for data equality
  38. EmfCopy, // copy to clip
  39. EmfDraw, // draw the object
  40. ErrActivate, // open
  41. ErrExecute, // excute
  42. ErrClose, // stop
  43. ErrUpdate, // Update
  44. ErrReconnect, // Reconnect
  45. ErrObjectConvert, // convert object to specified type
  46. ErrGetUpdateOptions, // update options
  47. ErrSetUpdateOptions, // update options
  48. ObjRename, // Change Object name
  49. ObjQueryName, // Get current object name
  50. ObjQueryType, // Object type
  51. EmfQueryBounds, // QueryBounds
  52. ObjQuerySize, // Find the size of the object
  53. ErrQueryOpen, // Query open
  54. ErrQueryOutOfDate, // query whether object is current
  55. ErrQueryRelease, // release related stuff
  56. ErrQueryRelease,
  57. ErrQueryReleaseMethod,
  58. ErrRequestData, // requestdata
  59. ErrObjectLong, // objectLong
  60. EmfChangeData // change data of the existing object
  61. };
  62. OLESTATUS FARINTERNAL EmfRelease (LPOLEOBJECT lpoleobj)
  63. {
  64. LPOBJECT_EMF lpobj = (LPOBJECT_EMF)lpoleobj;
  65. HOBJECT hobj;
  66. if (lpobj->hemf) {
  67. DeleteEnhMetaFile ((HENHMETAFILE)lpobj->hemf);
  68. lpobj->hemf = NULL;
  69. }
  70. if (lpobj->head.lhclientdoc)
  71. DocDeleteObject ((LPOLEOBJECT)lpobj);
  72. if (hobj = lpobj->head.hobj) {
  73. lpobj->head.hobj = NULL;
  74. GlobalUnlock (hobj);
  75. GlobalFree (hobj);
  76. }
  77. return OLE_OK;
  78. }
  79. OLESTATUS FARINTERNAL SaveEmfAsMfToStream (
  80. LPOLEOBJECT lpoleobj,
  81. LPOLESTREAM lpstream
  82. ){
  83. DWORD dwFileVer = (DWORD)MAKELONG(wReleaseVer,OS_WIN32);
  84. LPOBJECT_EMF lpobj = (LPOBJECT_EMF)lpoleobj;
  85. OLESTATUS retval = OLE_ERROR_MEMORY;
  86. HDC hdc = NULL ;
  87. LPBYTE lpBytes = NULL ;
  88. HANDLE hBytes = NULL ;
  89. WIN16METAFILEPICT w16mfp;
  90. UINT lSizeBytes;
  91. w16mfp.mm = MM_ANISOTROPIC;
  92. w16mfp.xExt = (short)lpobj->head.cx;
  93. if ((short)lpobj->head.cy <0 ) {
  94. w16mfp.yExt = -(short)lpobj->head.cy;
  95. } else {
  96. w16mfp.yExt = (short)lpobj->head.cy;
  97. }
  98. if (PutBytes (lpstream, (LPSTR) &dwFileVer, sizeof(LONG)))
  99. return OLE_ERROR_STREAM;
  100. if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG)))
  101. return OLE_ERROR_STREAM;
  102. if (PutStrWithLen(lpstream, (LPSTR)"METAFILEPICT"))
  103. return OLE_ERROR_STREAM;
  104. if (PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG)))
  105. return OLE_ERROR_STREAM;
  106. if (PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  107. return OLE_ERROR_STREAM;
  108. hdc = GetDC(NULL);
  109. if (!(lSizeBytes = GetWinMetaFileBits((HENHMETAFILE)lpobj->hemf, 0, NULL, MM_ANISOTROPIC, hdc)) ) {
  110. if (hdc) ReleaseDC(NULL, hdc);
  111. return OLE_ERROR_METAFILE;
  112. }
  113. if (!(hBytes = GlobalAlloc(GHND, lSizeBytes)) )
  114. goto error;
  115. if (!(lpBytes = (LPBYTE)GlobalLock(hBytes)) )
  116. goto error;
  117. if (GetWinMetaFileBits((HENHMETAFILE)lpobj->hemf, lSizeBytes, lpBytes, MM_ANISOTROPIC, hdc) != lSizeBytes) {
  118. retval = OLE_ERROR_METAFILE;
  119. goto error;
  120. }
  121. lSizeBytes += sizeof(WIN16METAFILEPICT);
  122. if (PutBytes (lpstream, (LPSTR) &lSizeBytes, sizeof(UINT)))
  123. return OLE_ERROR_STREAM;
  124. if (PutBytes (lpstream, (LPSTR)&w16mfp, sizeof(WIN16METAFILEPICT)))
  125. goto error;
  126. if (!PutBytes (lpstream, (LPSTR)lpBytes, lSizeBytes - sizeof(WIN16METAFILEPICT)))
  127. retval = OLE_OK;
  128. error:
  129. if (lpBytes)
  130. GlobalUnlock(hBytes);
  131. if (hBytes)
  132. GlobalFree(hBytes);
  133. if (hdc)
  134. ReleaseDC(NULL, hdc);
  135. return retval;
  136. }
  137. OLESTATUS FARINTERNAL EmfSaveToStream (
  138. LPOLEOBJECT lpoleobj,
  139. LPOLESTREAM lpstream
  140. ){
  141. DWORD dwFileVer = GetFileVersion(lpoleobj);
  142. LPOBJECT_EMF lpobj = (LPOBJECT_EMF)lpoleobj;
  143. OLESTATUS retval = OLE_ERROR_MEMORY;
  144. LPBYTE lpBytes = NULL ;
  145. HANDLE hBytes = NULL ;
  146. if (!lpobj->hemf)
  147. return OLE_ERROR_BLANK;
  148. if (HIWORD(dwFileVer) == OS_WIN16)
  149. if (!SaveEmfAsMfToStream(lpoleobj,lpstream))
  150. return OLE_OK;
  151. if (PutBytes (lpstream, (LPSTR) &dwFileVer, sizeof(LONG)))
  152. return OLE_ERROR_STREAM;
  153. if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG)))
  154. return OLE_ERROR_STREAM;
  155. if (PutStrWithLen(lpstream, (LPSTR)"ENHMETAFILE"))
  156. return OLE_ERROR_STREAM;
  157. if (PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG)))
  158. return OLE_ERROR_STREAM;
  159. if (PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  160. return OLE_ERROR_STREAM;
  161. if (PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(LONG)))
  162. return OLE_ERROR_STREAM;
  163. if (!(hBytes = GlobalAlloc(GHND, lpobj->sizeBytes)) )
  164. goto error;
  165. if (!(lpBytes = (LPBYTE)GlobalLock(hBytes)) )
  166. goto error;
  167. retval = OLE_ERROR_METAFILE;
  168. if (GetEnhMetaFileBits((HENHMETAFILE)lpobj->hemf, lpobj->sizeBytes, lpBytes) != lpobj->sizeBytes )
  169. goto error;
  170. if (!PutBytes (lpstream, (LPSTR)lpBytes, lpobj->sizeBytes))
  171. retval = OLE_OK;
  172. error:
  173. if (lpBytes)
  174. GlobalUnlock(hBytes);
  175. if (hBytes)
  176. GlobalFree(hBytes);
  177. return retval;
  178. }
  179. OLESTATUS FARINTERNAL EmfClone (
  180. LPOLEOBJECT lpoleobjsrc,
  181. LPOLECLIENT lpclient,
  182. LHCLIENTDOC lhclientdoc,
  183. OLE_LPCSTR lpobjname,
  184. LPOLEOBJECT FAR * lplpoleobj
  185. ){
  186. LPOBJECT_EMF lpobjsrc = (LPOBJECT_EMF)lpoleobjsrc;
  187. LPOBJECT_EMF lpobjEmf;
  188. HENHMETAFILE hemf;
  189. *lplpoleobj = (LPOLEOBJECT)NULL;
  190. if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc))
  191. return OLE_ERROR_HANDLE;
  192. if (!((HENHMETAFILE)hemf = CopyEnhMetaFile ((HENHMETAFILE)lpobjsrc->hemf, NULL)))
  193. return OLE_ERROR_MEMORY;
  194. if (lpobjEmf = EmfCreateBlank (lhclientdoc, (LPSTR)lpobjname,
  195. lpobjsrc->head.ctype)) {
  196. lpobjEmf->sizeBytes = lpobjsrc->sizeBytes;
  197. lpobjEmf->head.lpclient = lpclient;
  198. lpobjEmf->hemf = hemf;
  199. EmfSetExtents (lpobjEmf);
  200. *lplpoleobj = (LPOLEOBJECT)lpobjEmf;
  201. return OLE_OK;
  202. }
  203. return OLE_ERROR_MEMORY;
  204. }
  205. OLESTATUS FARINTERNAL EmfEqual (
  206. LPOLEOBJECT lpoleobj1,
  207. LPOLEOBJECT lpoleobj2
  208. ){
  209. LPOBJECT_EMF lpobj1 = (LPOBJECT_EMF)lpoleobj1;
  210. HANDLE hBytes1 = NULL;
  211. LPBYTE lpBytes1 = NULL;
  212. LPOBJECT_EMF lpobj2 = (LPOBJECT_EMF)lpoleobj2;
  213. HANDLE hBytes2 = NULL;
  214. LPBYTE lpBytes2 = NULL;
  215. OLESTATUS retval = OLE_ERROR_MEMORY;
  216. if (lpobj1->sizeBytes != lpobj2->sizeBytes)
  217. return OLE_ERROR_NOT_EQUAL;
  218. if (!(hBytes1 = GlobalAlloc(GHND, lpobj1->sizeBytes)) )
  219. goto errMemory;
  220. if (!(lpBytes1 = (LPBYTE)GlobalLock(hBytes1)) )
  221. goto errMemory;
  222. if (!(hBytes2 = GlobalAlloc(GHND, lpobj2->sizeBytes)) )
  223. goto errMemory;
  224. if (!(lpBytes2 = (LPBYTE)GlobalLock(hBytes2)) )
  225. goto errMemory;
  226. if (GetEnhMetaFileBits((HENHMETAFILE)lpobj1->hemf, lpobj1->sizeBytes, lpBytes1) != lpobj1->sizeBytes)
  227. goto errMemory;
  228. if (GetEnhMetaFileBits((HENHMETAFILE)lpobj2->hemf, lpobj2->sizeBytes, lpBytes2) != lpobj2->sizeBytes)
  229. goto errMemory;
  230. if (CmpGlobals (hBytes1, hBytes2))
  231. retval = OLE_OK;
  232. else
  233. retval = OLE_ERROR_NOT_EQUAL;
  234. errMemory:
  235. if (lpBytes1)
  236. GlobalUnlock(lpBytes1);
  237. if (hBytes1)
  238. GlobalFree(hBytes1);
  239. if (lpBytes2)
  240. GlobalUnlock(lpBytes2);
  241. if (hBytes2)
  242. GlobalFree(hBytes2);
  243. return retval;
  244. }
  245. OLESTATUS FARINTERNAL EmfCopy (LPOLEOBJECT lpoleobj)
  246. {
  247. LPOBJECT_EMF lpobj = (LPOBJECT_EMF)lpoleobj;
  248. HENHMETAFILE hemf;
  249. if (!((HENHMETAFILE)hemf = CopyEnhMetaFile ((HENHMETAFILE)lpobj->hemf, NULL)))
  250. return OLE_ERROR_MEMORY;
  251. SetClipboardData(CF_ENHMETAFILE, hemf);
  252. return OLE_OK;
  253. }
  254. OLESTATUS FARINTERNAL EmfQueryBounds (
  255. LPOLEOBJECT lpoleobj,
  256. LPRECT lpRc
  257. ){
  258. LPOBJECT_EMF lpobj = (LPOBJECT_EMF)lpoleobj;
  259. Puts("EmfQueryBounds");
  260. if (!lpobj->hemf)
  261. return OLE_ERROR_BLANK;
  262. // Bounds are given in MM_HIMETRIC mode.
  263. lpRc->left = 0;
  264. lpRc->top = 0;
  265. lpRc->right = (int) lpobj->head.cx;
  266. lpRc->bottom = (int) lpobj->head.cy;
  267. return OLE_OK;
  268. }
  269. OLECLIPFORMAT FARINTERNAL EmfEnumFormat (
  270. LPOLEOBJECT lpoleobj,
  271. OLECLIPFORMAT cfFormat
  272. ){
  273. UNREFERENCED_PARAMETER(lpoleobj);
  274. if (!cfFormat)
  275. return CF_ENHMETAFILE;
  276. return 0;
  277. }
  278. OLESTATUS FARINTERNAL EmfGetData (
  279. LPOLEOBJECT lpoleobj,
  280. OLECLIPFORMAT cfFormat,
  281. LPHANDLE lphandle
  282. ){
  283. LPOBJECT_EMF lpobj = (LPOBJECT_EMF)lpoleobj;
  284. if (cfFormat != CF_ENHMETAFILE)
  285. return OLE_ERROR_FORMAT;
  286. if (!(*lphandle = lpobj->hemf))
  287. return OLE_ERROR_BLANK;
  288. return OLE_OK;
  289. }
  290. LPOBJECT_EMF FARINTERNAL EmfCreateObject (
  291. HANDLE hMeta,
  292. LPOLECLIENT lpclient,
  293. BOOL fDelete,
  294. LHCLIENTDOC lhclientdoc,
  295. LPCSTR lpobjname,
  296. LONG objType
  297. ){
  298. LPOBJECT_EMF lpobj;
  299. if (lpobj = EmfCreateBlank (lhclientdoc, (LPSTR)lpobjname, objType)) {
  300. if (EmfChangeData ((LPOLEOBJECT)lpobj, hMeta, lpclient, fDelete) != OLE_OK) {
  301. EmfRelease ((LPOLEOBJECT)lpobj);
  302. lpobj = NULL;
  303. }
  304. }
  305. return lpobj;
  306. }
  307. // If the routine fails then the object will be left with it's old data.
  308. // If fDelete is TRUE, then hMeta, and the hMF it contains will be deleted
  309. // whether the routine is successful or not.
  310. OLESTATUS FARINTERNAL EmfChangeData (
  311. LPOLEOBJECT lpoleobj,
  312. HANDLE hMeta,
  313. LPOLECLIENT lpclient,
  314. BOOL fDelete
  315. ){
  316. LPOBJECT_EMF lpobj = (LPOBJECT_EMF)lpoleobj;
  317. DWORD dwSizeBytes;
  318. Puts("EmfChangeData");
  319. if (hMeta) {
  320. dwSizeBytes = lpobj->sizeBytes;
  321. if (lpobj->sizeBytes = GetEnhMetaFileBits(hMeta, 0, NULL)) {
  322. if (lpobj->hemf)
  323. DeleteEnhMetaFile ((HENHMETAFILE)lpobj->hemf);
  324. if (fDelete)
  325. lpobj->hemf = hMeta;
  326. else
  327. (HENHMETAFILE)lpobj->hemf = CopyEnhMetaFile(hMeta,NULL);
  328. lpobj->head.lpclient = lpclient;
  329. EmfSetExtents (lpobj);
  330. return OLE_OK;
  331. }
  332. else
  333. lpobj->sizeBytes = dwSizeBytes;
  334. }
  335. return OLE_ERROR_METAFILE;
  336. }
  337. LPOBJECT_EMF FARINTERNAL EmfCreateBlank(
  338. LHCLIENTDOC lhclientdoc,
  339. LPSTR lpobjname,
  340. LONG objType
  341. ){
  342. HOBJECT hobj;
  343. LPOBJECT_EMF lpobj;
  344. if(!(hobj = GlobalAlloc (GHND, sizeof(OBJECT_EMF))))
  345. return NULL;
  346. if (!(lpobj = (LPOBJECT_EMF) GlobalLock (hobj))){
  347. GlobalFree (hobj);
  348. return NULL;
  349. }
  350. lpobj->head.objId[0] = 'L';
  351. lpobj->head.objId[1] = 'E';
  352. lpobj->head.ctype = objType;
  353. lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblEMF;
  354. lpobj->head.iTable = INVALID_INDEX;
  355. lpobj->head.hobj = hobj;
  356. if (objType == CT_STATIC)
  357. DocAddObject ((LPCLIENTDOC) lhclientdoc,
  358. (LPOLEOBJECT) lpobj, lpobjname);
  359. // Unlock will be done at object deletion time.
  360. return lpobj;
  361. }
  362. OLESTATUS FARINTERNAL EmfLoadFromStream (
  363. LPOLESTREAM lpstream,
  364. LPOLECLIENT lpclient,
  365. LHCLIENTDOC lhclientdoc,
  366. LPSTR lpobjname,
  367. LPOLEOBJECT FAR * lplpobj,
  368. LONG objType
  369. ){
  370. LPOBJECT_EMF lpobj = NULL;
  371. OLESTATUS retval = OLE_ERROR_STREAM;
  372. HANDLE hBytes = NULL;
  373. LPBYTE lpBytes = NULL;
  374. // Class name would've been read by this time.
  375. *lplpobj = NULL;
  376. if (!(lpobj = EmfCreateBlank (lhclientdoc, lpobjname, objType)))
  377. return OLE_ERROR_MEMORY;
  378. lpobj->head.lpclient = lpclient;
  379. if (GetBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG)))
  380. goto error;
  381. if (GetBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG)))
  382. goto error;
  383. if (GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(LONG)))
  384. goto error;
  385. if (!lpobj->sizeBytes) {
  386. retval = OLE_ERROR_BLANK;
  387. goto error;
  388. }
  389. retval = OLE_ERROR_MEMORY;
  390. if (!(hBytes = GlobalAlloc (GHND, lpobj->sizeBytes)))
  391. goto error;
  392. if (!(lpBytes = (LPBYTE)GlobalLock (hBytes)))
  393. goto error;
  394. if (GetBytes (lpstream, (LPSTR)lpBytes, lpobj->sizeBytes))
  395. goto error;
  396. if (!((HENHMETAFILE)lpobj->hemf = SetEnhMetaFileBits (lpobj->sizeBytes,lpBytes)) )
  397. goto error;
  398. EmfSetExtents (lpobj);
  399. *lplpobj = (LPOLEOBJECT) lpobj;
  400. GlobalUnlock(hBytes);
  401. GlobalFree (hBytes);
  402. return OLE_OK;
  403. error:
  404. if (lpBytes)
  405. GlobalUnlock(hBytes);
  406. if (hBytes)
  407. GlobalFree (hBytes);
  408. OleDelete ((LPOLEOBJECT)lpobj);
  409. return retval;
  410. }
  411. OLESTATUS FARINTERNAL EmfPaste (
  412. LPOLECLIENT lpclient,
  413. LHCLIENTDOC lhclientdoc,
  414. LPSTR lpobjname,
  415. LPOLEOBJECT FAR * lplpoleobject,
  416. LONG objType
  417. ){
  418. HANDLE hMeta;
  419. *lplpoleobject = NULL;
  420. if((hMeta = GetClipboardData (CF_ENHMETAFILE)) == NULL)
  421. return OLE_ERROR_MEMORY;
  422. if (!(*lplpoleobject = (LPOLEOBJECT) EmfCreateObject (hMeta, lpclient,
  423. FALSE, lhclientdoc,
  424. lpobjname, objType)))
  425. return OLE_ERROR_MEMORY;
  426. return OLE_OK;
  427. }
  428. void FARINTERNAL EmfSetExtents (LPOBJECT_EMF lpobj)
  429. {
  430. ENHMETAHEADER enhmetaheader;
  431. GetEnhMetaFileHeader((HENHMETAFILE)lpobj->hemf, sizeof(enhmetaheader), &enhmetaheader);
  432. lpobj->head.cx = enhmetaheader.rclFrame.right - enhmetaheader.rclFrame.left;
  433. lpobj->head.cy = enhmetaheader.rclFrame.top - enhmetaheader.rclFrame.bottom;
  434. }