windows-nt/Source/XPSP1/NT/enduser/troubleshoot/msinfo/taskpad.cpp
2020-09-26 16:20:57 +08:00

409 lines
11 KiB
C++

/* Taskpad.cpp
*
* Code to handle the taskpad interface.
*
* Copyright (c) 1998-1999 Microsoft Corporation
*/
#include "StdAfx.h"
#include "DataObj.h"
#include "SysInfo.h"
#include "Taskpad.h"
#include <atlbase.h>
#ifndef IDS_TASK_TITLE
#include "resrc1.h"
#endif
static inline void GetMSInfoResourceName(LPOLESTR &, UINT);
static inline void GetMMCResourceName(LPOLESTR &, UINT);
static inline void LoadNewString(LPOLESTR &, UINT);
static inline LPOLESTR CoTaskStrDup(const CString &);
/*
* GetResultViewType - Set the Result view to the default.
*
* History: a-jsari 9/1/97 Initial version
*/
STDMETHODIMP CSystemInfo::GetResultViewType(MMC_COOKIE cookie, LPOLESTR *ppViewType, long *pViewOptions)
{
#ifdef _DEBUG
TRACE(_T("CSystemInfo::GetResultViewType(%lx, ViewType, ViewOptions)\n"), cookie);
#endif
ASSERT(ppViewType != NULL);
ASSERT(pViewOptions != NULL);
if (ppViewType == NULL || pViewOptions == NULL) return E_POINTER;
// Remove the default list menu items.
*pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
// Remove our taskpad view for now...
//
// if (cookie == ((CSystemInfoScope *)pComponentData())->RootCookie()) {
// GetMMCResourceName(*ppViewType, IDS_TASKPAD_DHTML);
// return S_OK;
// }
CViewObject * pDataCategory = reinterpret_cast<CViewObject *>(cookie);
if (pDataCategory)
{
CFolder * pFolder = pDataCategory->Category();
if (pFolder && pFolder->GetType() == CDataSource::OCX)
{
// Check to see if the OCX is present.
HKEY hkey;
CString strCLSID;
reinterpret_cast<COCXFolder *>(pFolder)->GetCLSIDString(strCLSID);
strCLSID = CString(_T("CLSID\\")) + strCLSID;
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CLASSES_ROOT, strCLSID, 0, KEY_QUERY_VALUE, &hkey))
{
RegCloseKey(hkey);
if ((reinterpret_cast<COCXFolder *>(pFolder))->GetCLSID(ppViewType))
return S_OK;
}
}
}
return S_FALSE;
}
// IExtendTaskpad interface in CSystemInfo
/*
* TaskNotify - The notify function for when the user selects a taskpad item.
*
* History: a-jsari 2/2/98 Initial version
*/
STDMETHODIMP CSystemInfo::TaskNotify(LPDATAOBJECT, VARIANT *pvarg, VARIANT *)
{
// ASSERT(lpDataObject != NULL);
ASSERT(pvarg != NULL);
// ASSERT(pvparam != NULL);
if (pvarg->vt == VT_I4) {
CString strPath;
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
switch(pvarg->lVal) {
case CTaskEnumPrimary::IDM_DISPLAY_BASIC:
VERIFY(strPath.LoadString(IDS_SUMMARY_PATH));
if (dynamic_cast<CSystemInfoScope *>(pComponentData())->SelectItem(strPath))
dynamic_cast<CSystemInfoScope *>(pComponentData())->SetView(BASIC);
break;
case CTaskEnumPrimary::IDM_DISPLAY_ADVANCED:
VERIFY(strPath.LoadString(IDS_SUMMARY_PATH));
if (dynamic_cast<CSystemInfoScope *>(pComponentData())->SelectItem(strPath))
dynamic_cast<CSystemInfoScope *>(pComponentData())->SetView(ADVANCED);
break;
case CTaskEnumPrimary::IDM_TASK_SAVE_FILE:
dynamic_cast<CSystemInfoScope *>(pComponentData())->SaveFile();
break;
case CTaskEnumPrimary::IDM_TASK_PRINT_REPORT:
OnPrint();
break;
case CTaskEnumPrimary::IDM_PROBLEM_DEVICES:
VERIFY(strPath.LoadString(IDS_PROBLEM_DEVICES_PATH));
dynamic_cast<CSystemInfoScope *>(pComponentData())->SelectItem(strPath);
break;
case CTaskEnumExtension::IDM_MSINFO32:
VERIFY(strPath.LoadString(IDS_INITIAL_PATH));
dynamic_cast<CSystemInfoScope *>(pComponentData())->SelectItem(strPath);
break;
default:
ASSERT(FALSE);
break;
}
}
return S_OK;
}
/*
* EnumTasks - Enumerate our available tasks.
*
* History: a-jsari 2/2/98 Initial version
*/
STDMETHODIMP CSystemInfo::EnumTasks(LPDATAOBJECT, LPOLESTR szGroup, LPENUMTASK *ppEnumTask)
{
ASSERT(ppEnumTask != NULL);
CString strTaskpadName;
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
VERIFY(strTaskpadName.LoadString(IDS_ROOT_TASKPAD));
if (!strTaskpadName.Compare(szGroup)) {
CComObject<CTaskEnumPrimary> *pEnumTask;
CComObject<CTaskEnumPrimary>::CreateInstance(&pEnumTask);
ASSERT(pEnumTask != NULL);
if (pEnumTask == NULL) ::AfxThrowMemoryException();
pEnumTask->AddRef();
HRESULT hr = pEnumTask->QueryInterface(IID_IEnumTASK, (void **)ppEnumTask);
ASSERT(hr == S_OK);
pEnumTask->Release();
} else {
CComObject<CTaskEnumExtension> *pEnumTask;
CComObject<CTaskEnumExtension>::CreateInstance(&pEnumTask);
ASSERT(pEnumTask != NULL);
if (pEnumTask == NULL) ::AfxThrowMemoryException();
pEnumTask->AddRef();
HRESULT hr = pEnumTask->QueryInterface(IID_IEnumTASK, (void **)ppEnumTask);
ASSERT(hr == S_OK);
pEnumTask->Release();
}
return S_OK;
}
/*
* GetListPadInfo - Return information about the list view version of the task pad.
*
* History: a-jsari 3/24/98 Initial version
*/
STDMETHODIMP CSystemInfo::GetListPadInfo(LPOLESTR, MMC_LISTPAD_INFO *lpListPadInfo)
{
const int LISTPAD_COMMAND = 1234;
// We don't distinguish between which way we're loaded for the data we display.
// If we need to, switch off of the first LPOLESTR parameter. Our taskpad group
// is IDS_ROOT_TASKPAD.
// Use our main title as the same title for the List view.
GetTitle((BSTR) 0, &lpListPadInfo->szTitle);
LoadNewString(lpListPadInfo->szButtonText, IDS_LISTPAD_BUTTON);
lpListPadInfo->nCommandID = LISTPAD_COMMAND;
return S_OK;
}
/*
* GetTitle - Return in pszTitle a pointer to the title for the taskpad.
*
* History: a-jsari 2/2/98 Initial version
*/
STDMETHODIMP CSystemInfo::GetTitle(BSTR, LPOLESTR *pszTitle)
{
ASSERT(pszTitle != NULL);
LoadNewString(*pszTitle, IDS_TASK_TITLE);
return S_OK;
}
/*
* GetBackground - Return the background resource.
*
* History: a-jsari 2/2/98 Initial version
*/
STDMETHODIMP CSystemInfo::GetBackground(BSTR, MMC_TASK_DISPLAY_OBJECT *)
{
// ASSERT(pszBackground != NULL);
// GetMSInfoResourceName(*pszBackground, IDS_BACKGROUND_RESPATH);
return S_OK;
}
STDMETHODIMP CSystemInfo::GetDescriptiveText(BSTR, LPOLESTR *)
{
return S_OK;
}
#if 0
/*
* OnListPad - Listpad notification. I don't expect we will receive this
* notification unless we implement listpads.
*
* History: a-jsari 3/24/98 Initial version
*/
STDMETHODIMP CSystemInfo::OnListPad()
{
return E_NOTIMPL;
}
#endif
/*
* Next - Get the next task. Since we have only one, this function is quite
* small.
*
* History: a-jsari 3/4/98 Initial version
*/
STDMETHODIMP CTaskEnumBase::Next(ULONG celt, MMC_TASK *rgelt, ULONG *pceltFetched)
{
ASSERT(rgelt != NULL);
ASSERT(!IsBadWritePtr(rgelt, celt * sizeof(MMC_TASK)));
ASSERT(pceltFetched != NULL);
ULONG i;
// According to the documentation, celt will always be 1.
::memset(rgelt, 0, celt * sizeof(MMC_TASK));
try {
for (i = 0 ; i < celt ; ++i, ++m_iTask, ++rgelt) {
// Increment our task value and test to see if they are fetching an invalid task.
if (m_iTask >= m_cTasks) {
*pceltFetched = i;
return S_FALSE;
}
// GetMSInfoResourceName(rgelt->szMouseOverBitmap, MouseOverResourceID());
// GetMSInfoResourceName(rgelt->szMouseOffBitmap, FirstMouseOffResourceID() + m_iTask);
// The resource IDs for these items must be sequential.
LoadNewString(rgelt->szText, FirstTaskTextResourceID() + m_iTask);
LoadNewString(rgelt->szHelpString, FirstTaskHelpResourceID() + m_iTask);
rgelt->eActionType = MMC_ACTION_ID;
// The Command IDs are in sorted order.
rgelt->nCommandID = FirstCommandID() + m_iTask;
}
}
catch (CMemoryException *) {
// if (rgelt->szMouseOverBitmap)
// ::CoTaskMemFree(rgelt->szMouseOverBitmap);
// if (rgelt->szMouseOffBitmap)
// ::CoTaskMemFree(rgelt->szMouseOffBitmap);
if (rgelt->szText)
::CoTaskMemFree(rgelt->szText);
if (rgelt->szHelpString)
::CoTaskMemFree(rgelt->szHelpString);
*pceltFetched = i;
return S_FALSE;
}
return S_OK;
}
/*
* Skip - Skip the next task. Will reportedly never be called.
*
* History: a-jsari 3/4/98 Initial version
*/
STDMETHODIMP CTaskEnumBase::Skip(ULONG celt)
{
m_iTask += celt;
if (m_iTask >= m_cTasks) {
m_iTask = m_cTasks;
return S_FALSE;
}
return S_OK;
}
/*
* Reset - Reset to the first task.
*
* History: a-jsari 3/4/98 Initial version.
*/
STDMETHODIMP CTaskEnumBase::Reset()
{
m_iTask = 0;
return S_OK;
}
/*
* Clone - Clone this task. Will reportedly never be called.
*
* History: a-jsari 3/4/98 Initial version
*/
STDMETHODIMP CTaskEnumBase::Clone(IEnumTASK **)
{
ASSERT(FALSE);
return E_NOTIMPL;
}
/*
* CoTaskStrDup - Copy the CString passed in as a LPOLESTR, allocating
* the memory to store the string using CoTaskMemAlloc.
*
* History: a-jsari 3/4/98 Initial version
*/
static inline LPOLESTR CoTaskStrDup(const CString &strCopy)
{
USES_CONVERSION;
LPOLESTR szDuplicate = (LPOLESTR) ::CoTaskMemAlloc((strCopy.GetLength() + 1)
* sizeof(OLECHAR));
ASSERT(szDuplicate != NULL);
if (szDuplicate != NULL) {
::lstrcpy(szDuplicate, T2CW((LPCTSTR)strCopy));
}
return szDuplicate;
}
/*
* GetMSInfoResourceName - Get the initial path to a resource in the currently
* loaded DLL.
*
* History: a-jsari 3/4/98 Initial version.
*/
static inline void GetMSInfoResourceName(LPOLESTR &szNewString, UINT nResource)
{
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
OLECHAR szExePath[MAX_PATH];
CString strResource;
strResource = _T("res://");
HINSTANCE hInstance = ::AfxGetInstanceHandle();
ASSERT(hInstance != NULL);
DWORD dwCount = ::GetModuleFileName(hInstance, szExePath, MAX_PATH);
ASSERT(dwCount != 0);
strResource += szExePath;
CString strResPath;
VERIFY(strResPath.LoadString(nResource));
strResource += strResPath;
szNewString = CoTaskStrDup(strResource);
if (szNewString == NULL) ::AfxThrowMemoryException();
}
/*
* GetMMCResourceName - Get the initial path to a resource in MMC.EXE.
*
* History: a-jsari 3/5/98 Initial version
*/
static inline void GetMMCResourceName(LPOLESTR &szNewString, UINT nResource)
{
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
OLECHAR szExePath[MAX_PATH];
CString strResource;
VERIFY(strResource.LoadString(IDS_MMCEXE));
HINSTANCE hInstance = ::GetModuleHandle(strResource);
ASSERT(hInstance != NULL);
DWORD dwCount = ::GetModuleFileName(hInstance, szExePath, MAX_PATH);
ASSERT(dwCount != 0);
strResource = _T("res://");
strResource += szExePath;
CString strResPath;
VERIFY(strResPath.LoadString(nResource));
strResource += strResPath;
szNewString = CoTaskStrDup(strResource);
if (szNewString == NULL) ::AfxThrowMemoryException();
}
/*
* LoadNewString - Load the string at nResource from the Resources, then
* allocate memory for the pointer and copy that string in.
*
* History: a-jsari 3/4/98 Initial version.
*/
static inline void LoadNewString(LPOLESTR &szNewString, UINT nResource)
{
AFX_MANAGE_STATE(::AfxGetStaticModuleState());
CString strResource;
VERIFY(strResource.LoadString(nResource));
szNewString = CoTaskStrDup(strResource);
if (szNewString == NULL) ::AfxThrowMemoryException();
}