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.

421 lines
13 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 "Comp.h"
  19. #include "DataObj.h"
  20. #include <commctrl.h> // Needed for button styles...
  21. #include <crtdbg.h>
  22. #include "resource.h"
  23. #include "DeleBase.h"
  24. #include "CompData.h"
  25. #include "globals.h"
  26. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  27. CComponent::CComponent(CComponentData *parent)
  28. : m_pComponentData(parent), m_cref(0), m_ipConsole(NULL)
  29. {
  30. OBJECT_CREATED
  31. m_ipControlBar = NULL;
  32. m_ipToolbar = NULL;
  33. }
  34. CComponent::~CComponent()
  35. {
  36. OBJECT_DESTROYED
  37. }
  38. STDMETHODIMP CComponent::QueryInterface(REFIID riid, LPVOID *ppv)
  39. {
  40. if (!ppv)
  41. return E_FAIL;
  42. *ppv = NULL;
  43. if (IsEqualIID(riid, IID_IUnknown))
  44. *ppv = static_cast<IComponent *>(this);
  45. else if (IsEqualIID(riid, IID_IComponent))
  46. *ppv = static_cast<IComponent *>(this);
  47. // first things first, make sure that when MMC
  48. // asks if we do property sheets, that we actually
  49. // say "yes"
  50. else if (IsEqualIID(riid, IID_IExtendPropertySheet))
  51. *ppv = static_cast<IExtendPropertySheet2 *>(this);
  52. else if (IsEqualIID(riid, IID_IExtendPropertySheet2))
  53. *ppv = static_cast<IExtendPropertySheet2 *>(this);
  54. else if (IsEqualIID(riid, IID_IExtendControlbar))
  55. *ppv = static_cast<IExtendControlbar *>(this);
  56. if (*ppv)
  57. {
  58. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  59. return S_OK;
  60. }
  61. return E_NOINTERFACE;
  62. }
  63. STDMETHODIMP_(ULONG) CComponent::AddRef()
  64. {
  65. return InterlockedIncrement((LONG *)&m_cref);
  66. }
  67. STDMETHODIMP_(ULONG) CComponent::Release()
  68. {
  69. if (InterlockedDecrement((LONG *)&m_cref) == 0)
  70. {
  71. delete this;
  72. return 0;
  73. }
  74. return m_cref;
  75. }
  76. ///////////////////////////////
  77. // Interface IComponent
  78. ///////////////////////////////
  79. STDMETHODIMP CComponent::Initialize(
  80. /* [in] */ LPCONSOLE lpConsole)
  81. {
  82. HRESULT hr = S_OK;
  83. // Save away all the interfaces we'll need.
  84. // Fail if we can't QI the required interfaces.
  85. m_ipConsole = lpConsole;
  86. m_ipConsole->AddRef();
  87. return hr;
  88. }
  89. STDMETHODIMP CComponent::Notify(
  90. /* [in] */ LPDATAOBJECT lpDataObject,
  91. /* [in] */ MMC_NOTIFY_TYPE event,
  92. /* [in] */ LPARAM arg,
  93. /* [in] */ LPARAM param)
  94. {
  95. MMCN_Crack(FALSE, lpDataObject, NULL, this, event, arg, param);
  96. HRESULT hr = S_FALSE;
  97. CDelegationBase *base = NULL;
  98. // we need to watch for property change and delegate it
  99. // a little differently, we're actually going to send
  100. // the CDelegationBase object pointer in the property page
  101. // PSN_APPLY handler via MMCPropPageNotify()
  102. if (MMCN_PROPERTY_CHANGE != event && MMCN_VIEW_CHANGE != event) {
  103. if (NULL == lpDataObject)
  104. return S_FALSE;
  105. base = GetOurDataObject(lpDataObject)->GetBaseNodeObject();
  106. } else if (MMCN_PROPERTY_CHANGE == event) {
  107. base = (CDelegationBase *)param;
  108. }
  109. // MMCN_VIEW_CHANGE
  110. static CDelegationBase *pLastPasteQuery = NULL;
  111. if (MMCN_VIEW_CHANGE == event) {
  112. switch (param) {//arg holds the data. For a scope item, this is the
  113. //item's myhscopeitem. For a result item, this is
  114. //the item's nId value, but we don't use it
  115. //param holds the hint passed to IConsole::UpdateAllViews.
  116. //hint is a value of the UPDATE_VIEWS_HINT enumeration
  117. case UPDATE_SCOPEITEM:
  118. hr = m_ipConsole->SelectScopeItem( (HSCOPEITEM)arg );
  119. _ASSERT( S_OK == hr);
  120. break;
  121. case UPDATE_RESULTITEM:
  122. base = GetOurDataObject(lpDataObject)->GetBaseNodeObject();
  123. hr = base->OnUpdateItem(m_ipConsole, (long)arg, RESULT);
  124. break;
  125. }
  126. return S_OK;
  127. }
  128. //The remaining notifications
  129. switch (event) {
  130. case MMCN_SHOW:
  131. hr = base->OnShow(m_ipConsole, (BOOL)arg, (HSCOPEITEM)param);
  132. break;
  133. case MMCN_ADD_IMAGES:
  134. hr = base->OnAddImages((IImageList *)arg, (HSCOPEITEM)param);
  135. break;
  136. case MMCN_SELECT:
  137. hr = base->OnSelect(this, m_ipConsole, (BOOL)LOWORD(arg), (BOOL)HIWORD(arg));
  138. break;
  139. case MMCN_RENAME:
  140. hr = base->OnRename((LPOLESTR)param);
  141. //Now call IConsole::UpdateAllViews to redraw the item in all views.
  142. hr = m_pComponentData->m_ipConsole->UpdateAllViews(lpDataObject, 0, UPDATE_RESULTITEM);
  143. _ASSERT( S_OK == hr);
  144. break;
  145. case MMCN_REFRESH:
  146. //we pass CComponentData's stored IConsole pointer here,
  147. //so that the IConsole::UpdateAllViews can be called in OnRefresh
  148. hr = base->OnRefresh(m_pComponentData->m_ipConsole);
  149. break;
  150. case MMCN_DELETE: {
  151. //first delete the selected result item
  152. hr = base->OnDelete(m_ipConsole);
  153. //Now call IConsole::UpdateAllViews to redraw all views
  154. //owned by the parent scope item. OnRefresh already does
  155. //this for us, so use it.
  156. hr = base->OnRefresh(m_pComponentData->m_ipConsole);
  157. break;
  158. }
  159. // handle the property change notification if we need to do anything
  160. // special with it
  161. case MMCN_PROPERTY_CHANGE:
  162. //we pass CComponentData's stored IConsole pointer here,
  163. //so that the IConsole::UpdateAllViews can be called in OnPropertyChange
  164. hr = base->OnPropertyChange(m_pComponentData->m_ipConsole, this);
  165. break;
  166. }
  167. return hr;
  168. }
  169. STDMETHODIMP CComponent::Destroy(
  170. /* [in] */ MMC_COOKIE cookie)
  171. {
  172. if (m_ipConsole) {
  173. m_ipConsole->Release();
  174. m_ipConsole = NULL;
  175. }
  176. return S_OK;
  177. }
  178. STDMETHODIMP CComponent::QueryDataObject(
  179. /* [in] */ MMC_COOKIE cookie,
  180. /* [in] */ DATA_OBJECT_TYPES type,
  181. /* [out] */ LPDATAOBJECT __RPC_FAR *ppDataObject)
  182. {
  183. CDataObject *pObj = NULL;
  184. if (cookie == 0)
  185. pObj = new CDataObject((MMC_COOKIE)m_pComponentData->m_pStaticNode, type);
  186. else
  187. pObj = new CDataObject(cookie, type);
  188. if (!pObj)
  189. return E_OUTOFMEMORY;
  190. pObj->QueryInterface(IID_IDataObject, (void **)ppDataObject);
  191. return S_OK;
  192. }
  193. STDMETHODIMP CComponent::GetResultViewType(
  194. /* [in] */ MMC_COOKIE cookie,
  195. /* [out] */ LPOLESTR __RPC_FAR *ppViewType,
  196. /* [out] */ long __RPC_FAR *pViewOptions)
  197. {
  198. CDelegationBase *base = (CDelegationBase *)cookie;
  199. //
  200. // Ask for default listview.
  201. //
  202. if (base == NULL)
  203. {
  204. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  205. *ppViewType = NULL;
  206. }
  207. else
  208. return base->GetResultViewType(ppViewType, pViewOptions);
  209. return S_OK;
  210. }
  211. STDMETHODIMP CComponent::GetDisplayInfo(
  212. /* [out][in] */ RESULTDATAITEM __RPC_FAR *pResultDataItem)
  213. {
  214. HRESULT hr = S_OK;
  215. CDelegationBase *base = NULL;
  216. // if they are asking for the RDI_STR we have one of those to give
  217. if (pResultDataItem->lParam) {
  218. base = (CDelegationBase *)pResultDataItem->lParam;
  219. if (pResultDataItem->mask & RDI_STR) {
  220. LPCTSTR pszT = base->GetDisplayName(pResultDataItem->nCol);
  221. MAKE_WIDEPTR_FROMTSTR_ALLOC(pszW, pszT);
  222. pResultDataItem->str = pszW;
  223. }
  224. if (pResultDataItem->mask & RDI_IMAGE) {
  225. pResultDataItem->nImage = base->GetBitmapIndex();
  226. }
  227. }
  228. return hr;
  229. }
  230. STDMETHODIMP CComponent::CompareObjects(
  231. /* [in] */ LPDATAOBJECT lpDataObjectA,
  232. /* [in] */ LPDATAOBJECT lpDataObjectB)
  233. {
  234. CDelegationBase *baseA = GetOurDataObject(lpDataObjectA)->GetBaseNodeObject();
  235. CDelegationBase *baseB = GetOurDataObject(lpDataObjectB)->GetBaseNodeObject();
  236. // compare the object pointers
  237. if (baseA->GetCookie() == baseB->GetCookie())
  238. return S_OK;
  239. return S_FALSE;
  240. }
  241. ///////////////////////////////////
  242. // Interface IExtendPropertySheet2
  243. ///////////////////////////////////
  244. HRESULT CComponent::CreatePropertyPages(
  245. /* [in] */ LPPROPERTYSHEETCALLBACK lpProvider,
  246. /* [in] */ LONG_PTR handle,
  247. /* [in] */ LPDATAOBJECT lpIDataObject)
  248. {
  249. CDelegationBase *base = GetOurDataObject(lpIDataObject)->GetBaseNodeObject();
  250. return base->CreatePropertyPages(lpProvider, handle);
  251. }
  252. HRESULT CComponent::QueryPagesFor(
  253. /* [in] */ LPDATAOBJECT lpDataObject)
  254. {
  255. CDelegationBase *base = GetOurDataObject(lpDataObject)->GetBaseNodeObject();
  256. return base->HasPropertySheets();
  257. }
  258. HRESULT CComponent::GetWatermarks(
  259. /* [in] */ LPDATAOBJECT lpIDataObject,
  260. /* [out] */ HBITMAP __RPC_FAR *lphWatermark,
  261. /* [out] */ HBITMAP __RPC_FAR *lphHeader,
  262. /* [out] */ HPALETTE __RPC_FAR *lphPalette,
  263. /* [out] */ BOOL __RPC_FAR *bStretch)
  264. {
  265. CDelegationBase *base = GetOurDataObject(lpIDataObject)->GetBaseNodeObject();
  266. return base->GetWatermarks(lphWatermark, lphHeader, lphPalette, bStretch);
  267. }
  268. ///////////////////////////////
  269. // Interface IExtendControlBar
  270. ///////////////////////////////
  271. static MMCBUTTON SnapinButtons1[] =
  272. {
  273. { 0, ID_BUTTONSTART, TBSTATE_ENABLED, TBSTYLE_GROUP, L"Start Vehicle", L"Start Vehicle" },
  274. { 1, ID_BUTTONPAUSE, TBSTATE_ENABLED, TBSTYLE_GROUP, L"Pause Vehicle", L"Pause Vehicle"},
  275. { 2, ID_BUTTONSTOP, TBSTATE_ENABLED, TBSTYLE_GROUP, L"Stop Vehicle", L"Stop Vehicle" },
  276. };
  277. HRESULT CComponent::SetControlbar(
  278. /* [in] */ LPCONTROLBAR pControlbar)
  279. {
  280. HRESULT hr = S_OK;
  281. //
  282. // Clean up
  283. //
  284. // if we've got a cached toolbar, release it
  285. if (m_ipToolbar) {
  286. m_ipToolbar->Release();
  287. m_ipToolbar = NULL;
  288. }
  289. // if we've got a cached control bar, release it
  290. if (m_ipControlBar) {
  291. m_ipControlBar->Release();
  292. m_ipControlBar = NULL;
  293. }
  294. //
  295. // Install new pieces if necessary
  296. //
  297. // if a new one came in, cache and AddRef
  298. if (pControlbar) {
  299. m_ipControlBar = pControlbar;
  300. m_ipControlBar->AddRef();
  301. hr = m_ipControlBar->Create(TOOLBAR, // type of control to be created
  302. dynamic_cast<IExtendControlbar *>(this),
  303. reinterpret_cast<IUnknown **>(&m_ipToolbar));
  304. _ASSERT(SUCCEEDED(hr));
  305. // The IControlbar::Create AddRefs the toolbar object it created
  306. // so no need to do any addref on the interface.
  307. // add the bitmap to the toolbar
  308. HBITMAP hbmp = LoadBitmap(g_hinst, MAKEINTRESOURCE(IDR_TOOLBAR1));
  309. hr = m_ipToolbar->AddBitmap(3, hbmp, 16, 16, RGB(0, 128, 128)); // NOTE, hardcoded value 3
  310. _ASSERT(SUCCEEDED(hr));
  311. // Add the buttons to the toolbar
  312. hr = m_ipToolbar->AddButtons(ARRAYLEN(SnapinButtons1), SnapinButtons1);
  313. _ASSERT(SUCCEEDED(hr));
  314. }
  315. return hr;
  316. }
  317. HRESULT CComponent::ControlbarNotify(
  318. /* [in] */ MMC_NOTIFY_TYPE event,
  319. /* [in] */ LPARAM arg,
  320. /* [in] */ LPARAM param)
  321. {
  322. HRESULT hr = S_OK;
  323. if (event == MMCN_SELECT) {
  324. BOOL bScope = (BOOL) LOWORD(arg);
  325. BOOL bSelect = (BOOL) HIWORD(arg);
  326. CDelegationBase *base = GetOurDataObject(reinterpret_cast<IDataObject *>(param))->GetBaseNodeObject();
  327. hr = base->OnSetToolbar(m_ipControlBar, m_ipToolbar, bScope, bSelect);
  328. }
  329. else if (event == MMCN_BTN_CLICK) {
  330. CDelegationBase *base = GetOurDataObject(reinterpret_cast<IDataObject *>(arg))->GetBaseNodeObject();
  331. hr = base->OnToolbarCommand(m_pComponentData->m_ipConsole, (MMC_CONSOLE_VERB)param, reinterpret_cast<IDataObject *>(arg));
  332. }
  333. return hr;
  334. }