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.

371 lines
7.5 KiB

  1. /*++
  2. Module Name:
  3. mmcdispl.cpp
  4. Abstract:
  5. This class implements IDataObject interface and also provides a template
  6. for Display Object Classes.
  7. --*/
  8. #include "stdafx.h"
  9. #include "MmcDispl.h"
  10. #include "DfsGUI.h"
  11. #include "Utils.h" // For LoadStringFromResource
  12. #include "DfsNodes.h"
  13. // Register the clipboard formats that MMC expects us to register
  14. CLIPFORMAT CMmcDisplay::mMMC_CF_NodeType = (CLIPFORMAT)RegisterClipboardFormat(CCF_NODETYPE);
  15. CLIPFORMAT CMmcDisplay::mMMC_CF_NodeTypeString = (CLIPFORMAT)RegisterClipboardFormat(CCF_SZNODETYPE);
  16. CLIPFORMAT CMmcDisplay::mMMC_CF_DisplayName = (CLIPFORMAT)RegisterClipboardFormat(CCF_DISPLAY_NAME);
  17. CLIPFORMAT CMmcDisplay::mMMC_CF_CoClass = (CLIPFORMAT)RegisterClipboardFormat(CCF_SNAPIN_CLASSID);
  18. CLIPFORMAT CMmcDisplay::mMMC_CF_Dfs_Snapin_Internal = (CLIPFORMAT)RegisterClipboardFormat(CCF_DFS_SNAPIN_INTERNAL);
  19. CMmcDisplay::CMmcDisplay() : m_dwRefCount(1), m_hrValueFromCtor(S_OK)
  20. /*++
  21. Routine Description:
  22. The ctor for CMmcDisplay. This sets the class variables to default values
  23. Arguments:
  24. None.
  25. Return value:
  26. None
  27. --*/
  28. {
  29. dfsDebugOut((_T("CMmcDisplay::CMmcDisplay this=%p\n"), this));
  30. ZeroMemory(&m_CLSIDClass, sizeof m_CLSIDClass);
  31. ZeroMemory(&m_CLSIDNodeType, sizeof m_CLSIDNodeType);
  32. }
  33. CMmcDisplay::~CMmcDisplay()
  34. /*++
  35. Routine Description:
  36. The dtor for CMmcDisplay.
  37. Arguments:
  38. None.
  39. Return value:
  40. None
  41. --*/
  42. {
  43. dfsDebugOut((_T("CMmcDisplay::~CMmcDisplay this=%p\n"), this));
  44. }
  45. // IUnknown Interface Implementation
  46. STDMETHODIMP
  47. CMmcDisplay::QueryInterface(
  48. IN const struct _GUID & i_refiid,
  49. OUT void ** o_pUnk
  50. )
  51. /*++
  52. Routine Description:
  53. QueryInterface of IUnknown.
  54. Arguments:
  55. Return value:
  56. S_OK, if successful.
  57. E_NOINTERFACE, if The Interface QIed for is not supported.
  58. --*/
  59. {
  60. if (NULL == o_pUnk)
  61. {
  62. return(E_INVALIDARG);
  63. }
  64. if (i_refiid == __uuidof(IDataObject))
  65. {
  66. *o_pUnk = (IDataObject *)this;
  67. }
  68. else if (i_refiid == __uuidof(IUnknown))
  69. {
  70. *o_pUnk = (IUnknown *)this;
  71. }
  72. else
  73. {
  74. return(E_NOINTERFACE);
  75. }
  76. m_dwRefCount++;
  77. return (S_OK);
  78. }
  79. unsigned long __stdcall
  80. CMmcDisplay::AddRef()
  81. /*++
  82. Routine Description:
  83. AddRef of IUnknown.
  84. Arguments:
  85. Return value:
  86. The New RefCount Value.
  87. --*/
  88. {
  89. m_dwRefCount++;
  90. return(m_dwRefCount);
  91. }
  92. unsigned long __stdcall
  93. CMmcDisplay::Release()
  94. /*++
  95. Routine Description:
  96. Release of IUnknown.
  97. Arguments:
  98. Return value:
  99. The New RefCount Value.
  100. --*/
  101. {
  102. m_dwRefCount--;
  103. if (0 == m_dwRefCount)
  104. {
  105. delete this;
  106. return 0;
  107. }
  108. return(m_dwRefCount);
  109. }
  110. STDMETHODIMP
  111. CMmcDisplay::put_CoClassCLSID(
  112. IN CLSID newVal
  113. )
  114. /*++
  115. Routine Description:
  116. Gets the new value for the CLSID of the object.
  117. Arguments:
  118. newVal - The new value for CLSID of Snapin.
  119. Return value:
  120. S_OK On success
  121. E_INVALIDARG, if one of the arguments is null.
  122. --*/
  123. {
  124. HRESULT hr = E_UNEXPECTED;
  125. ZeroMemory(&m_CLSIDClass, sizeof m_CLSIDClass);
  126. m_CLSIDClass = newVal;
  127. return S_OK;
  128. }
  129. STDMETHODIMP
  130. CMmcDisplay::GetDataHere(
  131. IN LPFORMATETC i_lpFormatetc,
  132. OUT LPSTGMEDIUM o_lpMedium
  133. )
  134. /*++
  135. Routine Description:
  136. Return the Data expected. The clipboard format specifies what kind of data
  137. is expected.
  138. Arguments:
  139. i_lpFormatetc - Indicates what kind of data is expected back.
  140. o_lpMedium - The data is return here.
  141. Return value:
  142. S_OK, if successful.
  143. E_INVALIDARG, if one of the arguments is null.
  144. DV_E_CLIPFORMAT, if the clipboard format requested is not supported.
  145. --*/
  146. {
  147. RETURN_INVALIDARG_IF_NULL(i_lpFormatetc);
  148. RETURN_INVALIDARG_IF_NULL(o_lpMedium);
  149. HRESULT hr = DV_E_CLIPFORMAT;
  150. // Based on the required clipboard format, write data to the stream
  151. const CLIPFORMAT clipFormat = i_lpFormatetc->cfFormat;
  152. if ( clipFormat == mMMC_CF_NodeType ) // CCF_NODETYPE
  153. {
  154. hr = WriteToStream(reinterpret_cast<const void*>(&m_CLSIDNodeType), sizeof(m_CLSIDNodeType), o_lpMedium);
  155. return hr;
  156. }
  157. if ( clipFormat == mMMC_CF_Dfs_Snapin_Internal ) // CCF_DFS_SNAPIN_INTERNAL
  158. {
  159. PVOID pThis = this;
  160. hr = WriteToStream(reinterpret_cast<const void*>(&pThis), sizeof(pThis), o_lpMedium);
  161. return hr;
  162. }
  163. if ( clipFormat == mMMC_CF_NodeTypeString ) // CCF_SZNODETYPE
  164. {
  165. hr = WriteToStream( m_bstrDNodeType,(( m_bstrDNodeType.Length() + 1)*sizeof TCHAR), o_lpMedium);
  166. return hr;
  167. }
  168. // This is the display named used in the scope pane and snap-in manager
  169. if ( clipFormat == mMMC_CF_DisplayName ) // CCF_DISPLAY_NAME
  170. {
  171. CComBSTR bstrDisplayName;
  172. hr = LoadStringFromResource(IDS_NODENAME, &bstrDisplayName);
  173. RETURN_IF_FAILED(hr);
  174. hr = WriteToStream(bstrDisplayName, ((bstrDisplayName.Length() + 1) * sizeof(TCHAR)), o_lpMedium);
  175. return hr;
  176. }
  177. if ( clipFormat == mMMC_CF_CoClass ) // CCF_SNAPIN_CLASSID
  178. {
  179. // Create the CoClass information
  180. hr = WriteToStream(reinterpret_cast<const void*>(&m_CLSIDClass), sizeof m_CLSIDClass, o_lpMedium);
  181. return hr;
  182. }
  183. return DV_E_CLIPFORMAT;
  184. }
  185. HRESULT
  186. CMmcDisplay::WriteToStream(
  187. IN const void* i_pBuffer,
  188. IN int i_iBufferLen,
  189. OUT LPSTGMEDIUM o_lpMedium
  190. )
  191. /*++
  192. Routine Description:
  193. Writes data given in a buffer to a Global stream created on a handle passed in
  194. the STGMEDIUM structure.
  195. Only HGLOBAL is supported as the medium
  196. Arguments:
  197. i_pBuffer - The buffer to be written to the stream
  198. i_iBufferLen - The length of the buffer.
  199. o_lpMedium - The data is return here.
  200. --*/
  201. {
  202. RETURN_INVALIDARG_IF_NULL(i_pBuffer);
  203. RETURN_INVALIDARG_IF_NULL(o_lpMedium);
  204. HRESULT hr = E_UNEXPECTED;
  205. LPSTREAM lpStream = NULL;
  206. ULONG ulBytesWritten = 0;
  207. if (i_iBufferLen < 0)
  208. {
  209. return E_UNEXPECTED;
  210. }
  211. // Make sure the type medium is HGLOBAL
  212. if (TYMED_HGLOBAL != o_lpMedium->tymed)
  213. {
  214. return DV_E_TYMED;
  215. }
  216. // Create the stream on the hGlobal passed in
  217. hr = CreateStreamOnHGlobal(o_lpMedium->hGlobal, FALSE, &lpStream);
  218. RETURN_IF_FAILED(hr);
  219. // Write to the stream the number of bytes
  220. hr = lpStream->Write(i_pBuffer, i_iBufferLen, &ulBytesWritten);
  221. RETURN_IF_FAILED(hr);
  222. _ASSERTE((ULONG)i_iBufferLen == ulBytesWritten);
  223. // Only the stream is released here. The caller will free the HGLOBAL
  224. lpStream->Release();
  225. return S_OK;
  226. }
  227. HRESULT
  228. CMmcDisplay::OnAddImages(IImageList *pImageList, HSCOPEITEM hsi)
  229. {
  230. HRESULT hr = S_OK;
  231. HBITMAP pBMapSm = NULL;
  232. HBITMAP pBMapLg = NULL;
  233. if (!(pBMapSm = LoadBitmap(_Module.GetModuleInstance(),
  234. MAKEINTRESOURCE(IDB_SCOPE_IMAGES_16x16))) ||
  235. !(pBMapLg = LoadBitmap(_Module.GetModuleInstance(),
  236. MAKEINTRESOURCE(IDB_SCOPE_IMAGES_32x32))))
  237. {
  238. hr = HRESULT_FROM_WIN32(GetLastError());
  239. } else
  240. {
  241. hr = pImageList->ImageListSetStrip(
  242. (LONG_PTR *)pBMapSm,
  243. (LONG_PTR *)pBMapLg,
  244. 0,
  245. RGB(255, 0, 255)
  246. );
  247. }
  248. if (pBMapSm)
  249. DeleteObject(pBMapSm);
  250. if (pBMapLg)
  251. DeleteObject(pBMapLg);
  252. return hr;
  253. }