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.

544 lines
13 KiB

  1. // ResultsPaneItem.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "ResultsPaneView.h"
  5. #include "ResultsPaneItem.h"
  6. #include "ResultsPane.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. // {8A7DC72D-2D81-11d3-BE0E-0000F87A3912}
  13. static GUID GUID_ResultItem =
  14. { 0x8a7dc72d, 0x2d81, 0x11d3, { 0xbe, 0xe, 0x0, 0x0, 0xf8, 0x7a, 0x39, 0x12 } };
  15. LPGUID CResultsPaneItem::m_lpguidItemType = &GUID_ResultItem;
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CResultsPaneItem
  18. IMPLEMENT_DYNCREATE(CResultsPaneItem, CCmdTarget)
  19. /////////////////////////////////////////////////////////////////////////////
  20. // Construction/Destruction
  21. CResultsPaneItem::CResultsPaneItem()
  22. {
  23. EnableAutomation();
  24. m_pOwnerResultsView = NULL;
  25. m_hResultItem = NULL;
  26. m_iCurrentIconIndex = -1;
  27. // To keep the application running as long as an OLE automation
  28. // object is active, the constructor calls AfxOleLockApp.
  29. AfxOleLockApp();
  30. }
  31. CResultsPaneItem::~CResultsPaneItem()
  32. {
  33. Destroy();
  34. // To terminate the application when all objects created with
  35. // with OLE automation, the destructor calls AfxOleUnlockApp.
  36. AfxOleUnlockApp();
  37. }
  38. /////////////////////////////////////////////////////////////////////////////
  39. // Create/Destroy
  40. bool CResultsPaneItem::Create(CResultsPaneView* pOwnerView, const CStringArray& saNames, CUIntArray& uiaIconResIds, int iIconIndex)
  41. {
  42. TRACEX(_T("CResultsPaneItem::Create\n"));
  43. TRACEARGn(pOwnerView);
  44. TRACEARGn(saNames.GetSize());
  45. TRACEARGn(uiaIconResIds.GetSize());
  46. TRACEARGn(iIconIndex);
  47. if( ! GfxCheckObjPtr(pOwnerView,CResultsPaneView) )
  48. {
  49. TRACE(_T("FAILED : pOwnerView is an invalid pointer.\n"));
  50. return false;
  51. }
  52. SetOwnerResultsView(pOwnerView);
  53. if( saNames.GetSize() )
  54. {
  55. SetDisplayNames(saNames);
  56. }
  57. if( uiaIconResIds.GetSize() )
  58. {
  59. SetIconIds(uiaIconResIds);
  60. }
  61. SetIconIndex(iIconIndex);
  62. return true;
  63. }
  64. bool CResultsPaneItem::Create(CResultsPaneView* pOwnerView)
  65. {
  66. TRACEX(_T("CResultsPaneItem::Create\n"));
  67. TRACEARGn(pOwnerView);
  68. if( ! GfxCheckObjPtr(pOwnerView,CResultsPaneView) )
  69. {
  70. TRACE(_T("FAILED : pOwnerView is an invalid pointer.\n"));
  71. return false;
  72. }
  73. SetOwnerResultsView(pOwnerView);
  74. return true;
  75. }
  76. void CResultsPaneItem::Destroy()
  77. {
  78. TRACEX(_T("CResultsPaneItem::Destroy\n"));
  79. m_IconResIds.RemoveAll();
  80. m_saDisplayNames.RemoveAll();
  81. m_iCurrentIconIndex = -1;
  82. m_hResultItem = NULL;
  83. m_pOwnerResultsView = NULL;
  84. }
  85. /////////////////////////////////////////////////////////////////////////////
  86. // Owner ResultsView Members
  87. CResultsPaneView* CResultsPaneItem::GetOwnerResultsView()
  88. {
  89. TRACEX(_T("CResultsPaneItem::GetOwnerResultsView\n"));
  90. if( GfxCheckObjPtr(m_pOwnerResultsView,CResultsPaneView) )
  91. return m_pOwnerResultsView;
  92. TRACE(_T("FAILED : m_pOwnerResultsView is not valid.\n"));
  93. return NULL;
  94. }
  95. void CResultsPaneItem::SetOwnerResultsView(CResultsPaneView* pView)
  96. {
  97. TRACEX(_T("CResultsPaneItem::SetOwnerResultsView\n"));
  98. TRACEARGn(pView);
  99. if( ! GfxCheckObjPtr(pView,CResultsPaneView) )
  100. {
  101. TRACE(_T("FAILED : pView is not a valid pointer.\n"));
  102. return;
  103. }
  104. m_pOwnerResultsView = pView;
  105. }
  106. /////////////////////////////////////////////////////////////////////////////
  107. // Display Names Members
  108. CString CResultsPaneItem::GetDisplayName(int nIndex /* = 0*/)
  109. {
  110. TRACEX(_T("CResultsPaneItem::GetDisplayName\n"));
  111. TRACEARGn(nIndex);
  112. if( nIndex >= m_saDisplayNames.GetSize() || nIndex < 0 )
  113. {
  114. TRACE(_T("FAILED : nIndex is out of array bounds.\n"));
  115. return _T("");
  116. }
  117. return m_saDisplayNames[nIndex];
  118. }
  119. void CResultsPaneItem::SetDisplayName(int nIndex, const CString& sName)
  120. {
  121. TRACEX(_T("CResultsPaneItem::SetDisplayName\n"));
  122. TRACEARGn(nIndex);
  123. if( nIndex >= m_saDisplayNames.GetSize() || nIndex < 0 )
  124. {
  125. TRACE(_T("FAILED : nIndex is out of array bounds.\n"));
  126. return;
  127. }
  128. m_saDisplayNames.SetAt(nIndex,sName);
  129. }
  130. void CResultsPaneItem::SetDisplayNames(const CStringArray& saNames)
  131. {
  132. TRACEX(_T("CResultsPaneItem::SetDisplayNames\n"));
  133. TRACEARGn(saNames.GetSize());
  134. m_saDisplayNames.Copy(saNames);
  135. }
  136. /////////////////////////////////////////////////////////////////////////////
  137. // MMC-Related Members
  138. bool CResultsPaneItem::InsertItem(CResultsPane* pPane, int nIndex, bool bResizeColumns /*= false*/)
  139. {
  140. TRACEX(_T("CResultsPaneItem::InsertItem\n"));
  141. TRACEARGn(pPane);
  142. TRACEARGn(nIndex);
  143. TRACEARGn(bResizeColumns);
  144. if( ! GfxCheckObjPtr(pPane,CResultsPane) )
  145. {
  146. TRACE(_T("FAILED : pPane is not a valid pointer.\n"));
  147. return false;
  148. }
  149. HRESULT hr = S_OK;
  150. RESULTDATAITEM rdi;
  151. ZeroMemory(&rdi,sizeof(rdi));
  152. rdi.mask = RDI_STR | // displayname is valid
  153. RDI_IMAGE | // nImage is valid
  154. RDI_INDEX | // nIndex is valid
  155. RDI_PARAM; // lParam is valid
  156. rdi.nIndex = nIndex;
  157. rdi.str = MMC_CALLBACK;
  158. rdi.nImage = pPane->GetIconIndex(GetIconId());
  159. rdi.lParam = (LPARAM)this;
  160. LPRESULTDATA lpResultData = pPane->GetResultDataPtr();
  161. if( ! GfxCheckPtr(lpResultData,IResultData) )
  162. {
  163. TRACE(_T("FAILED : CResultsPane::GetResultDataPtr returns an invalid pointer.\n"));
  164. return false;
  165. }
  166. hr = lpResultData->InsertItem( &rdi );
  167. if( ! CHECKHRESULT(hr) )
  168. {
  169. TRACE(_T("FAILED : IResultData::InsertItem failed.\n"));
  170. return false;
  171. }
  172. m_hResultItem = rdi.itemID;
  173. ASSERT(m_hResultItem);
  174. if( bResizeColumns )
  175. {
  176. LPHEADERCTRL2 lpHeaderCtrl = pPane->GetHeaderCtrlPtr();
  177. if( GfxCheckPtr(lpHeaderCtrl,IHeaderCtrl2) )
  178. {
  179. CDC dc;
  180. dc.Attach(GetDC(NULL));
  181. int iWidth = 0;
  182. // set the widths of the columns for this item
  183. for( int i = 0; i < m_saDisplayNames.GetSize(); i++ )
  184. {
  185. // get the width in pixels of the item
  186. CSize size = dc.GetTextExtent(m_saDisplayNames[i]);
  187. lpHeaderCtrl->GetColumnWidth(i,&iWidth);
  188. if( size.cx > iWidth )
  189. lpHeaderCtrl->SetColumnWidth(i,size.cx);
  190. }
  191. HDC hDC = dc.Detach();
  192. int iResult = ReleaseDC(NULL,hDC);
  193. ASSERT(iResult == 1);
  194. lpHeaderCtrl->Release();
  195. }
  196. }
  197. lpResultData->Release();
  198. return true;
  199. }
  200. bool CResultsPaneItem::SetItem(CResultsPane* pPane)
  201. {
  202. TRACEX(_T("CResultsPaneItem::SetItem\n"));
  203. TRACEARGn(pPane);
  204. if( ! GfxCheckObjPtr(pPane,CResultsPane) )
  205. {
  206. TRACE(_T("FAILED : pPane is an invalid pointer.\n"));
  207. return false;
  208. }
  209. HRESULT hr = S_OK;
  210. RESULTDATAITEM rdi;
  211. ZeroMemory(&rdi,sizeof(rdi));
  212. rdi.mask = RDI_STR | // displayname is valid
  213. RDI_IMAGE; // nImage is valid
  214. rdi.str = MMC_CALLBACK;
  215. rdi.nImage = pPane->GetIconIndex(GetIconId());
  216. LPRESULTDATA lpResultData = pPane->GetResultDataPtr();
  217. if( ! GfxCheckPtr(lpResultData,IResultData) )
  218. {
  219. TRACE(_T("FAILED : lpResultData is an invalid pointer.\n"));
  220. return false;
  221. }
  222. hr = lpResultData->FindItemByLParam((LPARAM)this,&rdi.itemID);
  223. if( ! CHECKHRESULT(hr) )
  224. {
  225. TRACE(_T("FAILED : IResultData::FindItemByLParam failed.\n"));
  226. lpResultData->Release();
  227. return false;
  228. }
  229. hr = lpResultData->SetItem( &rdi );
  230. if( ! CHECKHRESULT(hr) )
  231. {
  232. TRACE(_T("FAILED : IResultData::SetItem failed.\n"));
  233. lpResultData->Release();
  234. return false;
  235. }
  236. lpResultData->Release();
  237. return true;
  238. }
  239. int CResultsPaneItem::CompareItem(CResultsPaneItem* pItem, int iColumn /*= 0*/ )
  240. {
  241. TRACEX(_T("CResultsPaneItem::CompareItem\n"));
  242. TRACEARGn(pItem);
  243. TRACEARGn(iColumn);
  244. CString sDisplayName1 = GetDisplayName(iColumn);
  245. CString sDisplayName2 = pItem->GetDisplayName(iColumn);
  246. //---------------------------------------------------------
  247. // v-marfin : 60246 Detect numeric type and compare on that
  248. long dw1=0,dw2=0;
  249. dw1 = _ttol((TCHAR*)(const TCHAR*)sDisplayName1);
  250. dw2 = _ttol((TCHAR*)(const TCHAR*)sDisplayName2);
  251. if ((dw1==0) && (dw2==0))
  252. {
  253. // Could not convert to numeric, so sort as string
  254. return sDisplayName1.CompareNoCase(sDisplayName2);
  255. }
  256. else
  257. {
  258. if (dw1 < dw2) return -1;
  259. if (dw1 > dw2) return 1;
  260. return 0;
  261. }
  262. //---------------------------------------------------------
  263. }
  264. bool CResultsPaneItem::RemoveItem(CResultsPane* pPane)
  265. {
  266. TRACEX(_T("CResultsPaneItem::RemoveItem\n"));
  267. TRACEARGn(pPane);
  268. if( ! GfxCheckObjPtr(pPane,CResultsPane) )
  269. {
  270. TRACE(_T("FAILED : pPane is an invalid pointer.\n"));
  271. return false;
  272. }
  273. LPRESULTDATA lpResultData = pPane->GetResultDataPtr();
  274. if( ! lpResultData )
  275. {
  276. TRACE(_T("FAILED : CResultsPane::GetResultDataPtr returned NULL.\n"));
  277. return false;
  278. }
  279. HRESULTITEM hri = NULL;
  280. if( lpResultData->FindItemByLParam((LPARAM)this,&hri) == S_OK )
  281. {
  282. HRESULT hr = lpResultData->DeleteItem(hri,0);
  283. if( ! CHECKHRESULT(hr) )
  284. {
  285. TRACE(_T("FAILED : IResultData::DeleteItem failed.\n"));
  286. lpResultData->Release();
  287. return false;
  288. }
  289. }
  290. lpResultData->Release();
  291. return true;
  292. }
  293. HRESULTITEM CResultsPaneItem::GetItemHandle()
  294. {
  295. TRACEX(_T("CResultsPaneItem::GetItemHandle\n"));
  296. if( m_hResultItem == NULL )
  297. {
  298. TRACE(_T("WARNING : m_hResultItem is NULL.\n"));
  299. }
  300. return m_hResultItem;
  301. }
  302. HRESULT CResultsPaneItem::WriteExtensionData(LPSTREAM pStream)
  303. {
  304. TRACEX(_T("CResultsPaneItem::WriteExtensionData\n"));
  305. TRACEARGn(pStream);
  306. return S_OK;
  307. }
  308. /////////////////////////////////////////////////////////////////////////////
  309. // Icon Members
  310. void CResultsPaneItem::SetIconIndex(int iIndex)
  311. {
  312. TRACEX(_T("CResultsPaneItem::SetIconIndex\n"));
  313. TRACEARGn(iIndex);
  314. if( iIndex >= m_IconResIds.GetSize() || iIndex < 0 )
  315. {
  316. TRACE(_T("FAILED : iIndex is out of array bounds.\n"));
  317. return;
  318. }
  319. m_iCurrentIconIndex = iIndex;
  320. }
  321. int CResultsPaneItem::GetIconIndex()
  322. {
  323. TRACEX(_T("CResultsPaneItem::GetIconIndex\n"));
  324. if( m_iCurrentIconIndex >= m_IconResIds.GetSize() || m_iCurrentIconIndex < 0 )
  325. {
  326. TRACE(_T("WARNING : m_iCurrentIconIndex is out of array bounds.\n"));
  327. return -1;
  328. }
  329. return m_iCurrentIconIndex;
  330. }
  331. UINT CResultsPaneItem::GetIconId()
  332. {
  333. TRACEX(_T("CResultsPaneItem::GetIconId\n"));
  334. if( m_iCurrentIconIndex >= m_IconResIds.GetSize() || m_iCurrentIconIndex < 0 )
  335. {
  336. TRACE(_T("FAILED : m_iCurrentIconIndex is out of array bounds.\n"));
  337. return 0;
  338. }
  339. return m_IconResIds[m_iCurrentIconIndex];
  340. }
  341. void CResultsPaneItem::SetIconIds(CUIntArray& uiaIconResIds)
  342. {
  343. TRACEX(_T("CResultsPaneItem::SetIconIds\n"));
  344. TRACEARGn(uiaIconResIds.GetSize());
  345. m_IconResIds.Copy(uiaIconResIds);
  346. m_iCurrentIconIndex = -1;
  347. }
  348. /////////////////////////////////////////////////////////////////////////////
  349. // MMC Notify Handlers
  350. HRESULT CResultsPaneItem::OnAddMenuItems(LPCONTEXTMENUCALLBACK piCallback,long __RPC_FAR *pInsertionAllowed)
  351. {
  352. TRACEX(_T("CResultsPaneItem::OnAddMenuItems\n"));
  353. TRACEARGn(piCallback);
  354. TRACEARGn(pInsertionAllowed);
  355. // Add New Menu Items
  356. if( CCM_INSERTIONALLOWED_NEW & *pInsertionAllowed )
  357. {
  358. // TODO: Add any context menu items for the New Menu here
  359. }
  360. // Add Task Menu Items
  361. if( CCM_INSERTIONALLOWED_TASK & *pInsertionAllowed )
  362. {
  363. // TODO: Add any context menu items for the Task Menu here
  364. }
  365. // Add Top Menu Items
  366. if( CCM_INSERTIONALLOWED_TOP & *pInsertionAllowed )
  367. {
  368. // TODO: Add any context menu items for the Task Menu here
  369. }
  370. return S_OK;
  371. }
  372. HRESULT CResultsPaneItem::OnCommand(CResultsPane* pPane, long lCommandID)
  373. {
  374. TRACEX(_T("CResultsPaneItem::OnCommand\n"));
  375. TRACEARGn(pPane);
  376. TRACEARGn(lCommandID);
  377. return S_OK;
  378. }
  379. void CResultsPaneItem::OnFinalRelease()
  380. {
  381. // When the last reference for an automation object is released
  382. // OnFinalRelease is called. The base class will automatically
  383. // deletes the object. Add additional cleanup required for your
  384. // object before calling the base class.
  385. CCmdTarget::OnFinalRelease();
  386. }
  387. BEGIN_MESSAGE_MAP(CResultsPaneItem, CCmdTarget)
  388. //{{AFX_MSG_MAP(CResultsPaneItem)
  389. // NOTE - the ClassWizard will add and remove mapping macros here.
  390. //}}AFX_MSG_MAP
  391. END_MESSAGE_MAP()
  392. BEGIN_DISPATCH_MAP(CResultsPaneItem, CCmdTarget)
  393. //{{AFX_DISPATCH_MAP(CResultsPaneItem)
  394. // NOTE - the ClassWizard will add and remove mapping macros here.
  395. //}}AFX_DISPATCH_MAP
  396. END_DISPATCH_MAP()
  397. // Note: we add support for IID_IResultsPaneItem to support typesafe binding
  398. // from VBA. This IID must match the GUID that is attached to the
  399. // dispinterface in the .ODL file.
  400. // {7D4A6867-9056-11D2-BD45-0000F87A3912}
  401. static const IID IID_IResultsPaneItem =
  402. { 0x7d4a6867, 0x9056, 0x11d2, { 0xbd, 0x45, 0x0, 0x0, 0xf8, 0x7a, 0x39, 0x12 } };
  403. BEGIN_INTERFACE_MAP(CResultsPaneItem, CCmdTarget)
  404. INTERFACE_PART(CResultsPaneItem, IID_IResultsPaneItem, Dispatch)
  405. END_INTERFACE_MAP()
  406. // {7D4A6868-9056-11D2-BD45-0000F87A3912}
  407. IMPLEMENT_OLECREATE_EX(CResultsPaneItem, "SnapIn.ResultsPaneItem", 0x7d4a6868, 0x9056, 0x11d2, 0xbd, 0x45, 0x0, 0x0, 0xf8, 0x7a, 0x39, 0x12)
  408. BOOL CResultsPaneItem::CResultsPaneItemFactory::UpdateRegistry(BOOL bRegister)
  409. {
  410. if (bRegister)
  411. return AfxOleRegisterServerClass(m_clsid, m_lpszProgID, m_lpszProgID, m_lpszProgID, OAT_DISPATCH_OBJECT);
  412. else
  413. return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
  414. }
  415. /////////////////////////////////////////////////////////////////////////////
  416. // CResultsPaneItem message handlers