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.

336 lines
11 KiB

  1. //+---------------------------------------------------------------------
  2. //
  3. // File: dvutils.cxx
  4. //
  5. // Contents: Helper functions for implementing IDataObject and IViewObject
  6. //
  7. //----------------------------------------------------------------------
  8. #include "headers.hxx"
  9. #pragma hdrstop
  10. //
  11. // Globals
  12. //
  13. UINT OleClipFormat[OCF_LAST+1]; // array of OLE standard clipboard formats
  14. // these are the names of the standard OLE clipboard formats that need to
  15. // be registered.
  16. LPTSTR OleClipNames[OCF_LAST+1] =
  17. {
  18. TEXT("ObjectLink"),
  19. TEXT("OwnerLink"),
  20. TEXT("Native"),
  21. TEXT("FileName"),
  22. TEXT("NetworkName"),
  23. TEXT("DataObject"),
  24. TEXT("Embedded Object"),
  25. TEXT("Embed Source"),
  26. TEXT("Link Source"),
  27. TEXT("Link Source Descriptor"),
  28. TEXT("Object Descriptor"),
  29. TEXT("OleDraw")
  30. };
  31. //+---------------------------------------------------------------
  32. //
  33. // Function: RegisterOleClipFormats
  34. //
  35. // Synopsis: Initializes the OleClipFormat table of standard
  36. // OLE clipboard formats.
  37. //
  38. // Notes: The OleClipFormat table is a table of registered,
  39. // standard, OLE-related clipboard formats. The table
  40. // is indexed by the OLECLIPFORMAT enumeration.
  41. // Before this table can be used it must be initialized
  42. // via this function.
  43. // This function is usually called in the WinMain or
  44. // LibMain of the module using the OleClipFormat table.
  45. //
  46. //----------------------------------------------------------------
  47. void
  48. RegisterOleClipFormats(void)
  49. {
  50. for (int i = 0; i<= OCF_LAST; i++)
  51. OleClipFormat[i] = RegisterClipboardFormat(OleClipNames[i]);
  52. }
  53. //+---------------------------------------------------------------
  54. //
  55. // Function: IsCompatibleDevice, public
  56. //
  57. // Synopsis: Compares two DEVICETARGET structures and returns
  58. // TRUE if they are compatible.
  59. //
  60. // Arguments: [ptdLeft] -- A pointer to a device target
  61. // [ptdRight] -- Another pointer to a device target
  62. //
  63. // Notes: The target devices are compatible if they are both
  64. // NULL or if they are identical. Otherwise they are
  65. // incompatible.
  66. //
  67. //----------------------------------------------------------------
  68. BOOL
  69. IsCompatibleDevice(DVTARGETDEVICE FAR* ptdLeft, DVTARGETDEVICE FAR* ptdRight)
  70. {
  71. // same address of td; must be same (handles NULL case)
  72. if (ptdLeft == ptdRight)
  73. return TRUE;
  74. #if 1
  75. //fix for NTbug 20692 - reason: see bad assumption below
  76. if ((ptdRight == DVTARGETIGNORE) || (ptdLeft == DVTARGETIGNORE))
  77. return TRUE;
  78. #endif
  79. // The following is a wrong assumption for device independant formats
  80. // like CF_DIB and CF_METAFILE
  81. // if ones NULL, and the others not then they are incompatible
  82. if ((ptdRight == NULL) || (ptdLeft == NULL))
  83. return FALSE;
  84. // different sizes, not equal
  85. if (ptdLeft->tdSize != ptdRight->tdSize)
  86. return FALSE;
  87. return _fmemcmp(ptdLeft, ptdRight, (size_t)ptdLeft->tdSize) == 0;
  88. }
  89. //+---------------------------------------------------------------
  90. //
  91. // Function: IsCompatibleFormat, public
  92. //
  93. // Synopsis: Compares two FORMATETC structures and returns
  94. // TRUE if they are compatible.
  95. //
  96. // Arguments: [f1] -- A FORMATETC structure
  97. // [f2] -- Another FORMATETC structure
  98. //
  99. // Notes: This function ignores the lindex member of the
  100. // FORMATETCs.
  101. //
  102. //----------------------------------------------------------------
  103. BOOL
  104. IsCompatibleFormat(FORMATETC& f1, FORMATETC& f2)
  105. {
  106. return f1.cfFormat == f2.cfFormat
  107. && IsCompatibleDevice(f1.ptd, f2.ptd)
  108. && (f1.dwAspect & f2.dwAspect) != 0L
  109. && (f1.tymed & f2.tymed) != 0;
  110. }
  111. //+---------------------------------------------------------------
  112. //
  113. // Function: FindCompatibleFormat
  114. //
  115. // Synopsis: Searches a table of FORMATETC structures and
  116. // returns the index of the first entry that is
  117. // compatible with a specified FORMATETC.
  118. //
  119. // Arguments: [FmtTable] -- the table of FORMATETCs
  120. // [iSize] -- the number of entries in the format table
  121. // [formatetc] -- the FORMATETC we are comparing for compatibility
  122. //
  123. // Returns: The index into the table of the compatible format, or
  124. // -1 if no compatible format was found.
  125. //
  126. // Notes: This function is typically used in conjunction with
  127. // IDataObject methods that need to check if a requested format
  128. // is available.
  129. //
  130. //----------------------------------------------------------------
  131. int
  132. FindCompatibleFormat(FORMATETC FmtTable[], int iSize, FORMATETC& formatetc)
  133. {
  134. // look through the table for a compatible format
  135. for (int i = 0; i < iSize; i++)
  136. {
  137. if (IsCompatibleFormat(formatetc, FmtTable[i]))
  138. return i;
  139. }
  140. return -1;
  141. }
  142. //+---------------------------------------------------------------
  143. //
  144. // Function: GetObjectDescriptor
  145. //
  146. // Synopsis: Extracts an OBJECTDESCRIPTOR from an IDataObject,
  147. // if available.
  148. //
  149. // Arguments: [pDataObj] -- data object from which to extract an object descriptor
  150. // [pDescOut] -- object descriptor structure to fill in
  151. //
  152. // Returns: Success iff the object descriptor could be extracted.
  153. // This does not copy out the dwFullUserTypeName or
  154. // dwSrcOfCopy strings.
  155. //
  156. //----------------------------------------------------------------
  157. HRESULT
  158. GetObjectDescriptor(LPDATAOBJECT pDataObj, LPOBJECTDESCRIPTOR pDescOut)
  159. {
  160. HRESULT r;
  161. HGLOBAL hglobal = GlobalAlloc(GMEM_SHARE, sizeof(OBJECTDESCRIPTOR)+256);
  162. LPOBJECTDESCRIPTOR pObjDesc = (LPOBJECTDESCRIPTOR)GlobalLock(hglobal);
  163. if (pObjDesc == NULL)
  164. {
  165. DOUT(TEXT("o2base/dvutils/GetObjectDescriptor failed\r\n"));
  166. r = E_OUTOFMEMORY;
  167. }
  168. else
  169. {
  170. FORMATETC formatetc =
  171. { (WORD)OleClipFormat[OCF_OBJECTDESCRIPTOR],
  172. NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  173. STGMEDIUM stgmedium;
  174. stgmedium.tymed = TYMED_HGLOBAL;
  175. stgmedium.hGlobal = hglobal;
  176. stgmedium.pUnkForRelease = NULL;
  177. if (OK(r = pDataObj->GetDataHere(&formatetc, &stgmedium)))
  178. {
  179. if (pDescOut != NULL)
  180. {
  181. // note: in the future we may wish to copy out the strings
  182. // into two out parameters. This would be used in
  183. // implementing the Paste Special dialog box.
  184. *pDescOut = *pObjDesc;
  185. pDescOut->dwFullUserTypeName = 0;
  186. pDescOut->dwSrcOfCopy = 0;
  187. }
  188. }
  189. GlobalUnlock(hglobal);
  190. GlobalFree(hglobal);
  191. }
  192. return r;
  193. }
  194. //+---------------------------------------------------------------
  195. //
  196. // Function: UpdateObjectDescriptor
  197. //
  198. // Synopsis: Updates the pointl and dwDrawAspects of an OBJECTDESCRIPTOR
  199. // on a data object
  200. //
  201. // Arguments: [pDataObj] -- the data object to update
  202. // [ptl] -- the pointl to update in the object descriptor
  203. // [dwAspect] -- the draw aspect to update in the object descriptor
  204. //
  205. // Returns: Success iff the object descriptor could be updated
  206. //
  207. // Notes: This method is for IDataObjects used in drag-drop.
  208. // The object being dragged supplies the object descriptor but only
  209. // the container knows where the point that the mouse button went
  210. // down relative to the corner of the object, and what aspect
  211. // of the object the container is displaying.
  212. // The container uses this method to fill in that missing information.
  213. // This performs a GetDataHere on the object to get a filled-in
  214. // object descriptor. It then updates the pointl and dwDrawAspect
  215. // fields and uses SetData to update the object.
  216. //
  217. //----------------------------------------------------------------
  218. HRESULT
  219. UpdateObjectDescriptor(LPDATAOBJECT pDataObj, POINTL& ptl, DWORD dwAspect)
  220. {
  221. HRESULT r;
  222. HGLOBAL hglobal = GlobalAlloc(GMEM_SHARE, sizeof(OBJECTDESCRIPTOR)+256);
  223. LPOBJECTDESCRIPTOR pObjDesc = (LPOBJECTDESCRIPTOR)GlobalLock(hglobal);
  224. if (pObjDesc == NULL)
  225. {
  226. DOUT(TEXT("o2base/dvutils/UpdateObjectDescriptor failed\r\n"));
  227. r = E_OUTOFMEMORY;
  228. }
  229. else
  230. {
  231. FORMATETC formatetc =
  232. { (WORD)OleClipFormat[OCF_OBJECTDESCRIPTOR],
  233. NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  234. STGMEDIUM stgmedium;
  235. stgmedium.tymed = TYMED_HGLOBAL;
  236. stgmedium.hGlobal = hglobal;
  237. stgmedium.pUnkForRelease = NULL;
  238. if (OK(r = pDataObj->GetDataHere(&formatetc, &stgmedium)))
  239. {
  240. pObjDesc->pointl = ptl;
  241. pObjDesc->dwDrawAspect = dwAspect;
  242. r = pDataObj->SetData(&formatetc, &stgmedium, FALSE);
  243. }
  244. GlobalUnlock(hglobal);
  245. GlobalFree(hglobal);
  246. }
  247. return r;
  248. }
  249. //+---------------------------------------------------------------
  250. //
  251. // Function: DrawMetafile
  252. //
  253. // Synopsis: Creates a metafile from an IViewObject using the Draw method
  254. //
  255. // Arguments: [pVwObj] -- the view object
  256. // [rc] -- rectangle on the view object to draw
  257. // [dwAspect] -- aspect of the view object to draw, typically
  258. // content or icon
  259. // [pHMF] -- place where handle to the metafile is drawn
  260. //
  261. // Returns: Success iff the metafile was drawn successfully.
  262. //
  263. //----------------------------------------------------------------
  264. HRESULT
  265. DrawMetafile(LPVIEWOBJECT pVwObj,
  266. RECT& rc,
  267. DWORD dwAspect,
  268. HMETAFILE FAR* pHMF)
  269. {
  270. HRESULT hr;
  271. HMETAFILE hmf = NULL;
  272. HDC hdc;
  273. if ((hdc = CreateMetaFile(NULL)) == NULL)
  274. {
  275. DOUT(TEXT("o2base/dvutils/DrawMetafile failed to create metafile\r\n"));
  276. hr = E_OUTOFMEMORY;
  277. }
  278. else
  279. {
  280. SetMapMode(hdc, MM_ANISOTROPIC);
  281. SetWindowOrgEx(hdc, 0, 0, NULL);
  282. SetWindowExtEx(hdc, rc.right, rc.bottom, NULL);
  283. hr = OleDraw(pVwObj, dwAspect, hdc, &rc);
  284. hmf = CloseMetaFile(hdc);
  285. if (!OK(hr))
  286. {
  287. DeleteMetaFile(hmf);
  288. hmf = NULL;
  289. }
  290. if (hmf == NULL)
  291. {
  292. DOUT(TEXT("o2base/dvutils/DrawMetafile failed\r\n"));
  293. hr = E_OUTOFMEMORY;
  294. }
  295. }
  296. *pHMF = hmf;
  297. return hr;
  298. }