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.

199 lines
6.0 KiB

  1. //==============================================================;
  2. //
  3. // This source code is only intended as a supplement to existing Microsoft documentation.
  4. //
  5. //
  6. //
  7. //
  8. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  9. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  10. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  11. // PURPOSE.
  12. //
  13. // Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  14. //
  15. //
  16. //
  17. //==============================================================;
  18. #include "CMenuExt.h"
  19. #include "globals.h"
  20. #include "resource.h"
  21. #include <crtdbg.h>
  22. // we need to do this to get around MMC.IDL - it explicitly defines
  23. // the clipboard formats as WCHAR types...
  24. #define _T_CCF_DISPLAY_NAME _T("CCF_DISPLAY_NAME")
  25. #define _T_CCF_NODETYPE _T("CCF_NODETYPE")
  26. #define _T_CCF_SNAPIN_CLASSID _T("CCF_SNAPIN_CLASSID")
  27. // These are the clipboard formats that we must supply at a minimum.
  28. // mmc.h actually defined these. We can make up our own to use for
  29. // other reasons. We don't need any others at this time.
  30. UINT CContextMenuExtension::s_cfDisplayName = RegisterClipboardFormat(_T_CCF_DISPLAY_NAME);
  31. UINT CContextMenuExtension::s_cfNodeType = RegisterClipboardFormat(_T_CCF_NODETYPE);
  32. UINT CContextMenuExtension::s_cfSnapInCLSID = RegisterClipboardFormat(_T_CCF_SNAPIN_CLASSID);
  33. CContextMenuExtension::CContextMenuExtension() : m_cref(0)
  34. {
  35. OBJECT_CREATED
  36. }
  37. CContextMenuExtension::~CContextMenuExtension()
  38. {
  39. OBJECT_DESTROYED
  40. }
  41. ///////////////////////
  42. // IUnknown implementation
  43. ///////////////////////
  44. STDMETHODIMP CContextMenuExtension::QueryInterface(REFIID riid, LPVOID *ppv)
  45. {
  46. if (!ppv)
  47. return E_FAIL;
  48. *ppv = NULL;
  49. if (IsEqualIID(riid, IID_IUnknown))
  50. *ppv = static_cast<IExtendContextMenu *>(this);
  51. else if (IsEqualIID(riid, IID_IExtendContextMenu))
  52. *ppv = static_cast<IExtendContextMenu *>(this);
  53. if (*ppv)
  54. {
  55. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  56. return S_OK;
  57. }
  58. return E_NOINTERFACE;
  59. }
  60. STDMETHODIMP_(ULONG) CContextMenuExtension::AddRef()
  61. {
  62. return InterlockedIncrement((LONG *)&m_cref);
  63. }
  64. STDMETHODIMP_(ULONG) CContextMenuExtension::Release()
  65. {
  66. if (InterlockedDecrement((LONG *)&m_cref) == 0)
  67. {
  68. // we need to decrement our object count in the DLL
  69. delete this;
  70. return 0;
  71. }
  72. return m_cref;
  73. }
  74. HRESULT CContextMenuExtension::ExtractData( IDataObject* piDataObject,
  75. CLIPFORMAT cfClipFormat,
  76. BYTE* pbData,
  77. DWORD cbData )
  78. {
  79. HRESULT hr = S_OK;
  80. FORMATETC formatetc = {cfClipFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  81. STGMEDIUM stgmedium = {TYMED_HGLOBAL, NULL};
  82. stgmedium.hGlobal = ::GlobalAlloc(GPTR, cbData);
  83. do // false loop
  84. {
  85. if (NULL == stgmedium.hGlobal)
  86. {
  87. hr = E_OUTOFMEMORY;
  88. break;
  89. }
  90. hr = piDataObject->GetDataHere( &formatetc, &stgmedium );
  91. if ( FAILED(hr) )
  92. {
  93. break;
  94. }
  95. BYTE* pbNewData = reinterpret_cast<BYTE*>(stgmedium.hGlobal);
  96. if (NULL == pbNewData)
  97. {
  98. hr = E_UNEXPECTED;
  99. break;
  100. }
  101. ::memcpy( pbData, pbNewData, cbData );
  102. } while (FALSE); // false loop
  103. if (NULL != stgmedium.hGlobal)
  104. {
  105. ::GlobalFree(stgmedium.hGlobal);
  106. }
  107. return hr;
  108. } // ExtractData()
  109. HRESULT CContextMenuExtension::ExtractString( IDataObject *piDataObject,
  110. CLIPFORMAT cfClipFormat,
  111. WCHAR *pstr,
  112. DWORD cchMaxLength)
  113. {
  114. return ExtractData( piDataObject, cfClipFormat, (PBYTE)pstr, cchMaxLength );
  115. }
  116. HRESULT CContextMenuExtension::ExtractSnapInCLSID( IDataObject* piDataObject, CLSID* pclsidSnapin )
  117. {
  118. return ExtractData( piDataObject, s_cfSnapInCLSID, (PBYTE)pclsidSnapin, sizeof(CLSID) );
  119. }
  120. HRESULT CContextMenuExtension::ExtractObjectTypeGUID( IDataObject* piDataObject, GUID* pguidObjectType )
  121. {
  122. return ExtractData( piDataObject, s_cfNodeType, (PBYTE)pguidObjectType, sizeof(GUID) );
  123. }
  124. ///////////////////////////////
  125. // Interface IExtendContextMenu
  126. ///////////////////////////////
  127. HRESULT CContextMenuExtension::AddMenuItems(
  128. /* [in] */ LPDATAOBJECT piDataObject,
  129. /* [in] */ LPCONTEXTMENUCALLBACK piCallback,
  130. /* [out][in] */ long __RPC_FAR *pInsertionAllowed)
  131. {
  132. HRESULT hr = S_OK;
  133. CONTEXTMENUITEM menuItemsTask[] =
  134. {
  135. {
  136. L"People Extension", L"Do an extension thing",
  137. 1, CCM_INSERTIONPOINTID_3RDPARTY_TASK , 0, 0
  138. },
  139. { NULL, NULL, 0, 0, 0 }
  140. };
  141. // Loop through and add each of the menu items
  142. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK)
  143. {
  144. for (CONTEXTMENUITEM *m = menuItemsTask; m->strName; m++)
  145. {
  146. hr = piCallback->AddItem(m);
  147. if (FAILED(hr))
  148. break;
  149. }
  150. }
  151. return hr;
  152. }
  153. HRESULT CContextMenuExtension::Command(
  154. /* [in] */ long lCommandID,
  155. /* [in] */ LPDATAOBJECT piDataObject)
  156. {
  157. WCHAR pszName[255];
  158. HRESULT hr = ExtractString(piDataObject, s_cfDisplayName, pszName, sizeof(pszName));
  159. MAKE_TSTRPTR_FROMWIDE(ptrname, pszName);
  160. if (SUCCEEDED(hr)) {
  161. switch (lCommandID)
  162. {
  163. case 1:
  164. ::MessageBox(NULL, ptrname, _T("Menu Command"), MB_OK|MB_ICONEXCLAMATION);
  165. break;
  166. }
  167. }
  168. return hr;
  169. }