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.

408 lines
11 KiB

  1. /* Taskpad.cpp
  2. *
  3. * Code to handle the taskpad interface.
  4. *
  5. * Copyright (c) 1998-1999 Microsoft Corporation
  6. */
  7. #include "StdAfx.h"
  8. #include "DataObj.h"
  9. #include "SysInfo.h"
  10. #include "Taskpad.h"
  11. #include <atlbase.h>
  12. #ifndef IDS_TASK_TITLE
  13. #include "resrc1.h"
  14. #endif
  15. static inline void GetMSInfoResourceName(LPOLESTR &, UINT);
  16. static inline void GetMMCResourceName(LPOLESTR &, UINT);
  17. static inline void LoadNewString(LPOLESTR &, UINT);
  18. static inline LPOLESTR CoTaskStrDup(const CString &);
  19. /*
  20. * GetResultViewType - Set the Result view to the default.
  21. *
  22. * History: a-jsari 9/1/97 Initial version
  23. */
  24. STDMETHODIMP CSystemInfo::GetResultViewType(MMC_COOKIE cookie, LPOLESTR *ppViewType, long *pViewOptions)
  25. {
  26. #ifdef _DEBUG
  27. TRACE(_T("CSystemInfo::GetResultViewType(%lx, ViewType, ViewOptions)\n"), cookie);
  28. #endif
  29. ASSERT(ppViewType != NULL);
  30. ASSERT(pViewOptions != NULL);
  31. if (ppViewType == NULL || pViewOptions == NULL) return E_POINTER;
  32. // Remove the default list menu items.
  33. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  34. // Remove our taskpad view for now...
  35. //
  36. // if (cookie == ((CSystemInfoScope *)pComponentData())->RootCookie()) {
  37. // GetMMCResourceName(*ppViewType, IDS_TASKPAD_DHTML);
  38. // return S_OK;
  39. // }
  40. CViewObject * pDataCategory = reinterpret_cast<CViewObject *>(cookie);
  41. if (pDataCategory)
  42. {
  43. CFolder * pFolder = pDataCategory->Category();
  44. if (pFolder && pFolder->GetType() == CDataSource::OCX)
  45. {
  46. // Check to see if the OCX is present.
  47. HKEY hkey;
  48. CString strCLSID;
  49. reinterpret_cast<COCXFolder *>(pFolder)->GetCLSIDString(strCLSID);
  50. strCLSID = CString(_T("CLSID\\")) + strCLSID;
  51. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, strCLSID, 0, KEY_QUERY_VALUE, &hkey))
  52. {
  53. RegCloseKey(hkey);
  54. if ((reinterpret_cast<COCXFolder *>(pFolder))->GetCLSID(ppViewType))
  55. return S_OK;
  56. }
  57. }
  58. }
  59. return S_FALSE;
  60. }
  61. // IExtendTaskpad interface in CSystemInfo
  62. /*
  63. * TaskNotify - The notify function for when the user selects a taskpad item.
  64. *
  65. * History: a-jsari 2/2/98 Initial version
  66. */
  67. STDMETHODIMP CSystemInfo::TaskNotify(LPDATAOBJECT, VARIANT *pvarg, VARIANT *)
  68. {
  69. // ASSERT(lpDataObject != NULL);
  70. ASSERT(pvarg != NULL);
  71. // ASSERT(pvparam != NULL);
  72. if (pvarg->vt == VT_I4) {
  73. CString strPath;
  74. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  75. switch(pvarg->lVal) {
  76. case CTaskEnumPrimary::IDM_DISPLAY_BASIC:
  77. VERIFY(strPath.LoadString(IDS_SUMMARY_PATH));
  78. if (dynamic_cast<CSystemInfoScope *>(pComponentData())->SelectItem(strPath))
  79. dynamic_cast<CSystemInfoScope *>(pComponentData())->SetView(BASIC);
  80. break;
  81. case CTaskEnumPrimary::IDM_DISPLAY_ADVANCED:
  82. VERIFY(strPath.LoadString(IDS_SUMMARY_PATH));
  83. if (dynamic_cast<CSystemInfoScope *>(pComponentData())->SelectItem(strPath))
  84. dynamic_cast<CSystemInfoScope *>(pComponentData())->SetView(ADVANCED);
  85. break;
  86. case CTaskEnumPrimary::IDM_TASK_SAVE_FILE:
  87. dynamic_cast<CSystemInfoScope *>(pComponentData())->SaveFile();
  88. break;
  89. case CTaskEnumPrimary::IDM_TASK_PRINT_REPORT:
  90. OnPrint();
  91. break;
  92. case CTaskEnumPrimary::IDM_PROBLEM_DEVICES:
  93. VERIFY(strPath.LoadString(IDS_PROBLEM_DEVICES_PATH));
  94. dynamic_cast<CSystemInfoScope *>(pComponentData())->SelectItem(strPath);
  95. break;
  96. case CTaskEnumExtension::IDM_MSINFO32:
  97. VERIFY(strPath.LoadString(IDS_INITIAL_PATH));
  98. dynamic_cast<CSystemInfoScope *>(pComponentData())->SelectItem(strPath);
  99. break;
  100. default:
  101. ASSERT(FALSE);
  102. break;
  103. }
  104. }
  105. return S_OK;
  106. }
  107. /*
  108. * EnumTasks - Enumerate our available tasks.
  109. *
  110. * History: a-jsari 2/2/98 Initial version
  111. */
  112. STDMETHODIMP CSystemInfo::EnumTasks(LPDATAOBJECT, LPOLESTR szGroup, LPENUMTASK *ppEnumTask)
  113. {
  114. ASSERT(ppEnumTask != NULL);
  115. CString strTaskpadName;
  116. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  117. VERIFY(strTaskpadName.LoadString(IDS_ROOT_TASKPAD));
  118. if (!strTaskpadName.Compare(szGroup)) {
  119. CComObject<CTaskEnumPrimary> *pEnumTask;
  120. CComObject<CTaskEnumPrimary>::CreateInstance(&pEnumTask);
  121. ASSERT(pEnumTask != NULL);
  122. if (pEnumTask == NULL) ::AfxThrowMemoryException();
  123. pEnumTask->AddRef();
  124. HRESULT hr = pEnumTask->QueryInterface(IID_IEnumTASK, (void **)ppEnumTask);
  125. ASSERT(hr == S_OK);
  126. pEnumTask->Release();
  127. } else {
  128. CComObject<CTaskEnumExtension> *pEnumTask;
  129. CComObject<CTaskEnumExtension>::CreateInstance(&pEnumTask);
  130. ASSERT(pEnumTask != NULL);
  131. if (pEnumTask == NULL) ::AfxThrowMemoryException();
  132. pEnumTask->AddRef();
  133. HRESULT hr = pEnumTask->QueryInterface(IID_IEnumTASK, (void **)ppEnumTask);
  134. ASSERT(hr == S_OK);
  135. pEnumTask->Release();
  136. }
  137. return S_OK;
  138. }
  139. /*
  140. * GetListPadInfo - Return information about the list view version of the task pad.
  141. *
  142. * History: a-jsari 3/24/98 Initial version
  143. */
  144. STDMETHODIMP CSystemInfo::GetListPadInfo(LPOLESTR, MMC_LISTPAD_INFO *lpListPadInfo)
  145. {
  146. const int LISTPAD_COMMAND = 1234;
  147. // We don't distinguish between which way we're loaded for the data we display.
  148. // If we need to, switch off of the first LPOLESTR parameter. Our taskpad group
  149. // is IDS_ROOT_TASKPAD.
  150. // Use our main title as the same title for the List view.
  151. GetTitle((BSTR) 0, &lpListPadInfo->szTitle);
  152. LoadNewString(lpListPadInfo->szButtonText, IDS_LISTPAD_BUTTON);
  153. lpListPadInfo->nCommandID = LISTPAD_COMMAND;
  154. return S_OK;
  155. }
  156. /*
  157. * GetTitle - Return in pszTitle a pointer to the title for the taskpad.
  158. *
  159. * History: a-jsari 2/2/98 Initial version
  160. */
  161. STDMETHODIMP CSystemInfo::GetTitle(BSTR, LPOLESTR *pszTitle)
  162. {
  163. ASSERT(pszTitle != NULL);
  164. LoadNewString(*pszTitle, IDS_TASK_TITLE);
  165. return S_OK;
  166. }
  167. /*
  168. * GetBackground - Return the background resource.
  169. *
  170. * History: a-jsari 2/2/98 Initial version
  171. */
  172. STDMETHODIMP CSystemInfo::GetBackground(BSTR, MMC_TASK_DISPLAY_OBJECT *)
  173. {
  174. // ASSERT(pszBackground != NULL);
  175. // GetMSInfoResourceName(*pszBackground, IDS_BACKGROUND_RESPATH);
  176. return S_OK;
  177. }
  178. STDMETHODIMP CSystemInfo::GetDescriptiveText(BSTR, LPOLESTR *)
  179. {
  180. return S_OK;
  181. }
  182. #if 0
  183. /*
  184. * OnListPad - Listpad notification. I don't expect we will receive this
  185. * notification unless we implement listpads.
  186. *
  187. * History: a-jsari 3/24/98 Initial version
  188. */
  189. STDMETHODIMP CSystemInfo::OnListPad()
  190. {
  191. return E_NOTIMPL;
  192. }
  193. #endif
  194. /*
  195. * Next - Get the next task. Since we have only one, this function is quite
  196. * small.
  197. *
  198. * History: a-jsari 3/4/98 Initial version
  199. */
  200. STDMETHODIMP CTaskEnumBase::Next(ULONG celt, MMC_TASK *rgelt, ULONG *pceltFetched)
  201. {
  202. ASSERT(rgelt != NULL);
  203. ASSERT(!IsBadWritePtr(rgelt, celt * sizeof(MMC_TASK)));
  204. ASSERT(pceltFetched != NULL);
  205. ULONG i;
  206. // According to the documentation, celt will always be 1.
  207. ::memset(rgelt, 0, celt * sizeof(MMC_TASK));
  208. try {
  209. for (i = 0 ; i < celt ; ++i, ++m_iTask, ++rgelt) {
  210. // Increment our task value and test to see if they are fetching an invalid task.
  211. if (m_iTask >= m_cTasks) {
  212. *pceltFetched = i;
  213. return S_FALSE;
  214. }
  215. // GetMSInfoResourceName(rgelt->szMouseOverBitmap, MouseOverResourceID());
  216. // GetMSInfoResourceName(rgelt->szMouseOffBitmap, FirstMouseOffResourceID() + m_iTask);
  217. // The resource IDs for these items must be sequential.
  218. LoadNewString(rgelt->szText, FirstTaskTextResourceID() + m_iTask);
  219. LoadNewString(rgelt->szHelpString, FirstTaskHelpResourceID() + m_iTask);
  220. rgelt->eActionType = MMC_ACTION_ID;
  221. // The Command IDs are in sorted order.
  222. rgelt->nCommandID = FirstCommandID() + m_iTask;
  223. }
  224. }
  225. catch (CMemoryException *) {
  226. // if (rgelt->szMouseOverBitmap)
  227. // ::CoTaskMemFree(rgelt->szMouseOverBitmap);
  228. // if (rgelt->szMouseOffBitmap)
  229. // ::CoTaskMemFree(rgelt->szMouseOffBitmap);
  230. if (rgelt->szText)
  231. ::CoTaskMemFree(rgelt->szText);
  232. if (rgelt->szHelpString)
  233. ::CoTaskMemFree(rgelt->szHelpString);
  234. *pceltFetched = i;
  235. return S_FALSE;
  236. }
  237. return S_OK;
  238. }
  239. /*
  240. * Skip - Skip the next task. Will reportedly never be called.
  241. *
  242. * History: a-jsari 3/4/98 Initial version
  243. */
  244. STDMETHODIMP CTaskEnumBase::Skip(ULONG celt)
  245. {
  246. m_iTask += celt;
  247. if (m_iTask >= m_cTasks) {
  248. m_iTask = m_cTasks;
  249. return S_FALSE;
  250. }
  251. return S_OK;
  252. }
  253. /*
  254. * Reset - Reset to the first task.
  255. *
  256. * History: a-jsari 3/4/98 Initial version.
  257. */
  258. STDMETHODIMP CTaskEnumBase::Reset()
  259. {
  260. m_iTask = 0;
  261. return S_OK;
  262. }
  263. /*
  264. * Clone - Clone this task. Will reportedly never be called.
  265. *
  266. * History: a-jsari 3/4/98 Initial version
  267. */
  268. STDMETHODIMP CTaskEnumBase::Clone(IEnumTASK **)
  269. {
  270. ASSERT(FALSE);
  271. return E_NOTIMPL;
  272. }
  273. /*
  274. * CoTaskStrDup - Copy the CString passed in as a LPOLESTR, allocating
  275. * the memory to store the string using CoTaskMemAlloc.
  276. *
  277. * History: a-jsari 3/4/98 Initial version
  278. */
  279. static inline LPOLESTR CoTaskStrDup(const CString &strCopy)
  280. {
  281. USES_CONVERSION;
  282. LPOLESTR szDuplicate = (LPOLESTR) ::CoTaskMemAlloc((strCopy.GetLength() + 1)
  283. * sizeof(OLECHAR));
  284. ASSERT(szDuplicate != NULL);
  285. if (szDuplicate != NULL) {
  286. ::lstrcpy(szDuplicate, T2CW((LPCTSTR)strCopy));
  287. }
  288. return szDuplicate;
  289. }
  290. /*
  291. * GetMSInfoResourceName - Get the initial path to a resource in the currently
  292. * loaded DLL.
  293. *
  294. * History: a-jsari 3/4/98 Initial version.
  295. */
  296. static inline void GetMSInfoResourceName(LPOLESTR &szNewString, UINT nResource)
  297. {
  298. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  299. OLECHAR szExePath[MAX_PATH];
  300. CString strResource;
  301. strResource = _T("res://");
  302. HINSTANCE hInstance = ::AfxGetInstanceHandle();
  303. ASSERT(hInstance != NULL);
  304. DWORD dwCount = ::GetModuleFileName(hInstance, szExePath, MAX_PATH);
  305. ASSERT(dwCount != 0);
  306. strResource += szExePath;
  307. CString strResPath;
  308. VERIFY(strResPath.LoadString(nResource));
  309. strResource += strResPath;
  310. szNewString = CoTaskStrDup(strResource);
  311. if (szNewString == NULL) ::AfxThrowMemoryException();
  312. }
  313. /*
  314. * GetMMCResourceName - Get the initial path to a resource in MMC.EXE.
  315. *
  316. * History: a-jsari 3/5/98 Initial version
  317. */
  318. static inline void GetMMCResourceName(LPOLESTR &szNewString, UINT nResource)
  319. {
  320. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  321. OLECHAR szExePath[MAX_PATH];
  322. CString strResource;
  323. VERIFY(strResource.LoadString(IDS_MMCEXE));
  324. HINSTANCE hInstance = ::GetModuleHandle(strResource);
  325. ASSERT(hInstance != NULL);
  326. DWORD dwCount = ::GetModuleFileName(hInstance, szExePath, MAX_PATH);
  327. ASSERT(dwCount != 0);
  328. strResource = _T("res://");
  329. strResource += szExePath;
  330. CString strResPath;
  331. VERIFY(strResPath.LoadString(nResource));
  332. strResource += strResPath;
  333. szNewString = CoTaskStrDup(strResource);
  334. if (szNewString == NULL) ::AfxThrowMemoryException();
  335. }
  336. /*
  337. * LoadNewString - Load the string at nResource from the Resources, then
  338. * allocate memory for the pointer and copy that string in.
  339. *
  340. * History: a-jsari 3/4/98 Initial version.
  341. */
  342. static inline void LoadNewString(LPOLESTR &szNewString, UINT nResource)
  343. {
  344. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  345. CString strResource;
  346. VERIFY(strResource.LoadString(nResource));
  347. szNewString = CoTaskStrDup(strResource);
  348. if (szNewString == NULL) ::AfxThrowMemoryException();
  349. }