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.

454 lines
12 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 "CompData.h"
  20. #include "Space.h"
  21. #include "DataObj.h"
  22. #include <commctrl.h> // Needed for button styles...
  23. #include <crtdbg.h>
  24. #include <stdio.h> // needed for _stprintf
  25. #include "globals.h"
  26. #include "resource.h"
  27. #include "DeleBase.h"
  28. #include "CompData.h"
  29. CComponent::CComponent(CComponentData *pParent)
  30. : m_pParent(pParent), m_cref(0), m_ipConsole(NULL), m_pLastNode(NULL)
  31. {
  32. OBJECT_CREATED
  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. else if (IsEqualIID(riid, IID_IResultOwnerData))
  48. *ppv = static_cast<IResultOwnerData *>(this);
  49. if (*ppv)
  50. {
  51. reinterpret_cast<IUnknown *>(*ppv)->AddRef();
  52. return S_OK;
  53. }
  54. return E_NOINTERFACE;
  55. }
  56. STDMETHODIMP_(ULONG) CComponent::AddRef()
  57. {
  58. return InterlockedIncrement((LONG *)&m_cref);
  59. }
  60. STDMETHODIMP_(ULONG) CComponent::Release()
  61. {
  62. if (InterlockedDecrement((LONG *)&m_cref) == 0)
  63. {
  64. delete this;
  65. return 0;
  66. }
  67. return m_cref;
  68. }
  69. ///////////////////////////////
  70. // Interface IComponent
  71. ///////////////////////////////
  72. STDMETHODIMP CComponent::Initialize(
  73. /* [in] */ LPCONSOLE lpConsole)
  74. {
  75. HRESULT hr = S_OK;
  76. // Save away all the interfaces we'll need.
  77. // Fail if we can't QI the required interfaces.
  78. m_ipConsole = lpConsole;
  79. m_ipConsole->AddRef();
  80. return hr;
  81. }
  82. STDMETHODIMP CComponent::Notify(
  83. /* [in] */ LPDATAOBJECT lpDataObject,
  84. /* [in] */ MMC_NOTIFY_TYPE event,
  85. /* [in] */ LPARAM arg,
  86. /* [in] */ LPARAM param)
  87. {
  88. MMCN_Crack(FALSE, lpDataObject, NULL, this, event, arg, param);
  89. HRESULT hr = S_FALSE;
  90. // MMCN_VIEW_CHANGE
  91. if (MMCN_VIEW_CHANGE == event) {
  92. switch (param) {//arg holds the data. For a scope item, this is the
  93. //item's HSCOPEITEM. For a result item, this is
  94. //the item's nId value, but we don't use it
  95. //param holds the hint passed to IConsole::UpdateAllViews.
  96. //hint is a value of the UPDATE_VIEWS_HINT enumeration
  97. case UPDATE_SCOPEITEM:
  98. hr = m_ipConsole->SelectScopeItem( (HSCOPEITEM)arg );
  99. _ASSERT( S_OK == hr);
  100. break;
  101. case UPDATE_RESULTITEM:
  102. CDelegationBase *base = GetOurDataObject(lpDataObject)->GetBaseNodeObject();
  103. hr = base->OnUpdateItem(m_ipConsole, (long)arg, RESULT);
  104. break;
  105. }
  106. return S_OK;
  107. }
  108. //Remaining notifications
  109. CDelegationBase *base = GetOurDataObject(lpDataObject)->GetBaseNodeObject();
  110. switch (event)
  111. {
  112. case MMCN_SHOW:
  113. hr = base->OnShow(m_ipConsole, (BOOL)arg, (HSCOPEITEM)param);
  114. break;
  115. case MMCN_ADD_IMAGES:
  116. hr = base->OnAddImages((IImageList *)arg, (HSCOPEITEM)param);
  117. break;
  118. case MMCN_SELECT:
  119. //check for multiselection
  120. if ( MMC_MULTI_SELECT_COOKIE == GetOurDataObject(lpDataObject)->GetCookie() )
  121. {
  122. if ( (BOOL)LOWORD(arg) == 0 && (BOOL)HIWORD(arg) == 1 )
  123. {
  124. //We need the cookie of any of the multiselection items
  125. //to enable the delete verb for all the items.
  126. MMC_COOKIE ourCookie = GetOurDataObject(lpDataObject)->GetMultiSelectCookie(0);
  127. base = reinterpret_cast<CDelegationBase *>(ourCookie);
  128. hr = base->OnSelect(m_ipConsole, (BOOL)LOWORD(arg), (BOOL)HIWORD(arg));
  129. }
  130. return hr;
  131. }
  132. else
  133. hr = base->OnSelect(m_ipConsole, (BOOL)LOWORD(arg), (BOOL)HIWORD(arg));
  134. break;
  135. case MMCN_REFRESH:
  136. hr = base->OnRefresh(m_pParent->m_ipConsole);
  137. break;
  138. case MMCN_DELETE:
  139. //check for multiselection. if true, delete each item
  140. if ( MMC_MULTI_SELECT_COOKIE == GetOurDataObject(lpDataObject)->GetCookie() )
  141. {
  142. int n = 0;
  143. MMC_COOKIE ourCookie;
  144. while ( ourCookie = GetOurDataObject(lpDataObject)->GetMultiSelectCookie(n) )
  145. {
  146. base = reinterpret_cast<CDelegationBase *>(ourCookie);
  147. hr = base->OnDelete(m_ipConsole);
  148. n++;
  149. //Uncomment the following line to display a message box
  150. //for each item deletion.
  151. //DisplayMessageBox(base);
  152. }
  153. }
  154. else
  155. {
  156. //select item deletion
  157. hr = base->OnDelete(m_ipConsole);
  158. }
  159. //Now call IConsole::UpdateAllViews to redraw all views
  160. //owned by the parent scope item. OnRefresh already does
  161. //this for us, so use it.
  162. //Do this for both multiselection and single selection
  163. hr = base->OnRefresh(m_pParent->m_ipConsole);
  164. break;
  165. case MMCN_RENAME:
  166. hr = base->OnRename((LPOLESTR)param);
  167. //Now call IConsole::UpdateAllViews to redraw the item in all views.
  168. hr = m_pParent->m_ipConsole->UpdateAllViews(lpDataObject, 0, UPDATE_RESULTITEM);
  169. _ASSERT( S_OK == hr);
  170. break;
  171. }//end switch
  172. return hr;
  173. }
  174. STDMETHODIMP CComponent::Destroy(
  175. /* [in] */ MMC_COOKIE cookie)
  176. {
  177. if (m_ipConsole) {
  178. m_ipConsole->Release();
  179. m_ipConsole = NULL;
  180. }
  181. return S_OK;
  182. }
  183. STDMETHODIMP CComponent::QueryDataObject(
  184. /* [in] */ MMC_COOKIE cookie,
  185. /* [in] */ DATA_OBJECT_TYPES type,
  186. /* [out] */ LPDATAOBJECT __RPC_FAR *ppDataObject)
  187. {
  188. HRESULT hr;
  189. CDataObject *pObj = NULL;
  190. CDelegationBase *pBase = NULL;
  191. //Use The IS_SPECIAL_COOKIE macro to see if cookie is a special cookie
  192. if ( IS_SPECIAL_COOKIE (cookie) ) {
  193. if ( MMC_MULTI_SELECT_COOKIE == cookie) {
  194. pObj = new CDataObject(cookie, type);
  195. if (!pObj)
  196. return E_OUTOFMEMORY;
  197. //create the multiselection data object
  198. hr = GetCurrentSelections(pObj);
  199. _ASSERT( SUCCEEDED(hr) );
  200. hr = pObj->QueryInterface(IID_IDataObject, (void **)ppDataObject);
  201. _ASSERT( SUCCEEDED(hr) );
  202. return hr;
  203. }
  204. }
  205. //Remaining code for "regular" cookies, and for the next item
  206. //during a multiselection
  207. if (IsBadReadPtr((void *)cookie, sizeof(CDelegationBase))) {
  208. if (NULL == m_pLastNode)
  209. return E_FAIL;
  210. pBase = m_pLastNode->GetChildPtr((int)cookie);
  211. } else {
  212. pBase = (cookie == 0) ? m_pParent->m_pStaticNode : (CDelegationBase *)cookie;
  213. }
  214. if (pBase == NULL)
  215. return E_FAIL;
  216. pObj = new CDataObject((MMC_COOKIE)pBase, type);
  217. if (!pObj)
  218. return E_OUTOFMEMORY;
  219. pObj->QueryInterface(IID_IDataObject, (void **)ppDataObject);
  220. return S_OK;
  221. }
  222. STDMETHODIMP CComponent::GetResultViewType(
  223. /* [in] */ MMC_COOKIE cookie,
  224. /* [out] */ LPOLESTR __RPC_FAR *ppViewType,
  225. /* [out] */ long __RPC_FAR *pViewOptions)
  226. {
  227. CDelegationBase *base = m_pLastNode = (CDelegationBase *)cookie;
  228. //
  229. // Ask for default listview.
  230. //
  231. if (base == NULL)
  232. {
  233. *pViewOptions = MMC_VIEW_OPTIONS_NONE;
  234. *ppViewType = NULL;
  235. }
  236. else
  237. return base->GetResultViewType(ppViewType, pViewOptions);
  238. return S_OK;
  239. }
  240. STDMETHODIMP CComponent::GetDisplayInfo(
  241. /* [out][in] */ RESULTDATAITEM __RPC_FAR *pResultDataItem)
  242. {
  243. HRESULT hr = S_OK;
  244. CDelegationBase *base = NULL;
  245. // if they are asking for the RDI_STR we have one of those to give
  246. if (pResultDataItem->lParam) {
  247. base = (CDelegationBase *)pResultDataItem->lParam;
  248. if (pResultDataItem->mask & RDI_STR) {
  249. LPCTSTR pszT = base->GetDisplayName(pResultDataItem->nCol);
  250. MAKE_WIDEPTR_FROMTSTR_ALLOC(pszW, pszT);
  251. pResultDataItem->str = pszW;
  252. }
  253. if (pResultDataItem->mask & RDI_IMAGE) {
  254. pResultDataItem->nImage = base->GetBitmapIndex();
  255. }
  256. } else {
  257. m_pLastNode->GetChildColumnInfo(pResultDataItem);
  258. }
  259. return hr;
  260. }
  261. STDMETHODIMP CComponent::CompareObjects(
  262. /* [in] */ LPDATAOBJECT lpDataObjectA,
  263. /* [in] */ LPDATAOBJECT lpDataObjectB)
  264. {
  265. CDelegationBase *baseA = GetOurDataObject(lpDataObjectA)->GetBaseNodeObject();
  266. CDelegationBase *baseB = GetOurDataObject(lpDataObjectB)->GetBaseNodeObject();
  267. // compare the object pointers
  268. if (baseA->GetCookie() == baseB->GetCookie())
  269. return S_OK;
  270. return S_FALSE;
  271. }
  272. ///////////////////////////////
  273. // Interface IComponent
  274. ///////////////////////////////
  275. STDMETHODIMP CComponent::FindItem(
  276. /* [in] */ LPRESULTFINDINFO pFindInfo,
  277. /* [out] */ int __RPC_FAR *pnFoundIndex)
  278. {
  279. return E_NOTIMPL;
  280. }
  281. STDMETHODIMP CComponent::CacheHint(
  282. /* [in] */ int nStartIndex,
  283. /* [in] */ int nEndIndex)
  284. {
  285. return E_NOTIMPL;
  286. }
  287. STDMETHODIMP CComponent::SortItems(
  288. /* [in] */ int nColumn,
  289. /* [in] */ DWORD dwSortOptions,
  290. /* [in] */ LPARAM lUserParam)
  291. {
  292. return E_NOTIMPL;
  293. }
  294. ///////////////////////////////////////////
  295. // GetCurrentSelections() finds the currently
  296. // selected result items and the data object
  297. // passed to it with their cookie values.
  298. // The multi-select cookie is cached so that
  299. // we don't have to calculate multiselection
  300. // dataobject for other notifications.
  301. // It is destroyed at appropriate time.
  302. ///////////////////////////////////////////
  303. HRESULT CComponent::GetCurrentSelections(CDataObject *pMultiSelectDataObject)
  304. {
  305. HRESULT hr = S_FALSE;
  306. //GetCurrentSelections only works for multiselection data objects
  307. if ( !( MMC_MULTI_SELECT_COOKIE == GetOurDataObject(pMultiSelectDataObject)->GetCookie() ) )
  308. return hr = E_INVALIDARG;
  309. IResultData *pResultData = NULL;
  310. hr = m_ipConsole->QueryInterface(IID_IResultData, (void **)&pResultData);
  311. _ASSERT( SUCCEEDED(hr) );
  312. RESULTDATAITEM rdi;
  313. BOOL isLastSelected = FALSE;
  314. int nIndex = -1;
  315. int nIndexCookies = 0;
  316. while (!isLastSelected)
  317. {
  318. ZeroMemory(&rdi, sizeof(RESULTDATAITEM) );
  319. rdi.mask = RDI_STATE; // nState is valid
  320. rdi.nCol = 0;
  321. rdi.nIndex = nIndex; // nIndex == -1 to start at first item
  322. rdi.nState = LVIS_SELECTED; // only interested in selected items
  323. hr = pResultData->GetNextItem(&rdi);
  324. _ASSERT( SUCCEEDED(hr) );
  325. if (rdi.nIndex != -1) {
  326. //rdi is the RESULTDATAITEM of a selected item. add its
  327. //lParam to the pCookies array of the pMultiSelectDataObject data object
  328. _ASSERT( nIndexCookies < 20 ); // MAX_COOKIES == 20
  329. pMultiSelectDataObject->AddMultiSelectCookie(nIndexCookies, rdi.lParam);
  330. nIndexCookies++;
  331. nIndex = rdi.nIndex;
  332. }
  333. else
  334. isLastSelected = TRUE;
  335. }
  336. pResultData->Release();
  337. return hr;
  338. }
  339. void CComponent::DisplayMessageBox(CDelegationBase* base)
  340. {
  341. _TCHAR szVehicle[128];
  342. static _TCHAR buf[128];
  343. _stprintf(buf, _T("%s"), base->GetDisplayName() );
  344. wsprintf(szVehicle, _T("%s deleted"), buf);
  345. int ret = 0;
  346. MAKE_WIDEPTR_FROMTSTR_ALLOC(wszVehicle, szVehicle);
  347. m_ipConsole->MessageBox(wszVehicle,
  348. L"Vehicle command", MB_OK | MB_ICONINFORMATION, &ret);
  349. return;
  350. }