2025-04-27 07:49:33 -04:00

5097 lines
118 KiB
C++

// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
// MultiViewCtl.cpp : Implementation of the CMultiViewCtrl OLE control class.
//
// 03, Jan, 1997 - Larry French
// Added code to the CMultiViewGrid class to fire the SelectionChanged event
// when the grids selection changed. Also added the code to check for the
// selection change.
//
// Please look for all the places marked with !!! Judy (to do)
#include "precomp.h"
#include <OBJIDL.H>
#include <wbemidl.h>
#include "olemsclient.h"
#include "grid.h"
#include "MultiView.h"
#include "MultiViewCtl.h"
#include "MultiViewPpg.h"
#include "SyncEnumDlg.h"
#include "AsyncEnumDialog.h"
#include "AsyncQueryDialog.h"
#include "ProgDlg.h"
#include "resource.h"
#include "logindlg.h"
#include <genlex.h>
#include <opathlex.h>
#include <objpath.h>
#include <WbemResource.h>
#define ENUM_TIMEOUT 500 // Half second timeout
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define SZ_MODULE_NAME "MultiView.ocx"
#define CX_SMALL_ICON 16
#define CY_SMALL_ICON 16
#define N_INSTANCES 20
enum {VIEW_DEFAULT=0, VIEW_CURRENT=1, VIEW_FIRST=2, VIEW_LAST=3};
enum {OBJECT_CURRENT=0, OBJECT_FIRST=1, OBJECT_LAST=2};
extern CMultiViewApp NEAR theApp;
IMPLEMENT_DYNCREATE(CMultiViewCtrl, COleControl)
/////////////////////////////////////////////////////////////////////////////
// Message map
BEGIN_MESSAGE_MAP(CMultiViewCtrl, COleControl)
ON_WM_CONTEXTMENU()
//{{AFX_MSG_MAP(CMultiViewCtrl)
ON_WM_CREATE()
ON_WM_SIZE()
ON_WM_DESTROY()
ON_WM_SHOWWINDOW()
ON_COMMAND(ID_MENUITEMGOTOSINGLE, OnMenuitemgotosingle)
ON_UPDATE_COMMAND_UI(ID_MENUITEMGOTOSINGLE, OnUpdateMenuitemgotosingle)
ON_WM_SETFOCUS()
ON_WM_KILLFOCUS()
//}}AFX_MSG_MAP
ON_OLEVERB(AFX_IDS_VERB_EDIT, OnEdit)
ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
ON_MESSAGE( ID_DISPLAYNOINSTANCES, DisplayNoInstances )
ON_MESSAGE( ID_INSTENUMDONE, InstEnumDone )
ON_MESSAGE( ID_QUERYDONE, QueryDone )
ON_MESSAGE( ID_GETASYNCINSTENUMSINK, GetEnumSink)
ON_MESSAGE( ID_GETASYNCQUERYSINK, GetQuerySink)
ON_MESSAGE( ID_ENUM_DOMODAL, EnumDoModalDialog)
ON_MESSAGE( ID_SYNC_ENUM_DOMODAL, SyncEnumDoModalDialog)
ON_MESSAGE( ID_SYNC_ENUM, SyncEnum)
ON_MESSAGE( ID_QUERY_DOMODAL, QueryDoModalDialog)
ON_MESSAGE( ID_ASYNCENUM_CANCEL , AsyncEnumCancelled)
ON_MESSAGE( ID_ASYNCQUERY_CANCEL , AsyncQueryCancelled)
ON_MESSAGE( ID_ASYNCQUERY_DISPLAY ,DisplayAsyncQueryInstances)
ON_MESSAGE( INITSERVICES, InitServices)
ON_MESSAGE( INITIALIZE_NAMESPACE, OpenNamespace)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Dispatch map
BEGIN_DISPATCH_MAP(CMultiViewCtrl, COleControl)
//{{AFX_DISPATCH_MAP(CMultiViewCtrl)
DISP_PROPERTY_EX(CMultiViewCtrl, "NameSpace", GetNameSpace, SetNameSpace, VT_BSTR)
DISP_PROPERTY_EX(CMultiViewCtrl, "PropertyFilter", GetPropertyFilter, SetPropertyFilter, VT_I4)
DISP_FUNCTION(CMultiViewCtrl, "ViewClassInstances", ViewClassInstances, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CMultiViewCtrl, "ForceRedraw", ForceRedraw, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "CreateInstance", CreateInstance, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "DeleteInstance", DeleteInstance, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "GetContext", GetContext, VT_I4, VTS_PI4)
DISP_FUNCTION(CMultiViewCtrl, "RestoreContext", RestoreContext, VT_I4, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "AddContextRef", AddContextRef, VT_I4, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "ReleaseContext", ReleaseContext, VT_I4, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "GetEditMode", GetEditMode, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "GetObjectPath", GetObjectPath, VT_BSTR, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "GetObjectTitle", GetObjectTitle, VT_BSTR, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "GetTitle", GetTitle, VT_I4, VTS_PBSTR VTS_PDISPATCH)
DISP_FUNCTION(CMultiViewCtrl, "GetViewTitle", GetViewTitle, VT_BSTR, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "NextViewTitle", NextViewTitle, VT_I4, VTS_I4 VTS_PBSTR)
DISP_FUNCTION(CMultiViewCtrl, "ExternInstanceCreated", ExternInstanceCreated, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CMultiViewCtrl, "ExternInstanceDeleted", ExternInstanceDeleted, VT_EMPTY, VTS_BSTR)
DISP_FUNCTION(CMultiViewCtrl, "NotifyWillShow", NotifyWillShow, VT_EMPTY, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "PrevViewTitle", PrevViewTitle, VT_I4, VTS_I4 VTS_PBSTR)
DISP_FUNCTION(CMultiViewCtrl, "QueryCanCreateInstance", QueryCanCreateInstance, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "QueryCanDeleteInstance", QueryCanDeleteInstance, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "QueryNeedsSave", QueryNeedsSave, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "QueryObjectSelected", QueryObjectSelected, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "RefreshView", RefreshView, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "SaveData", SaveData, VT_I4, VTS_NONE)
DISP_FUNCTION(CMultiViewCtrl, "SelectView", SelectView, VT_I4, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "SetEditMode", SetEditMode, VT_EMPTY, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "StartObjectEnumeration", StartObjectEnumeration, VT_I4, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "StartViewEnumeration", StartViewEnumeration, VT_I4, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "ViewInstances", ViewInstances, VT_I4, VTS_BSTR VTS_VARIANT)
DISP_FUNCTION(CMultiViewCtrl, "QueryViewInstances", QueryViewInstances, VT_EMPTY, VTS_BSTR VTS_BSTR VTS_BSTR VTS_BSTR)
DISP_FUNCTION(CMultiViewCtrl, "NextObject", NextObject, VT_I4, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "PrevObject", PrevObject, VT_I4, VTS_I4)
DISP_FUNCTION(CMultiViewCtrl, "SelectObjectByPath", SelectObjectByPath, VT_I4, VTS_BSTR)
DISP_FUNCTION(CMultiViewCtrl, "SelectObjectByPosition", SelectObjectByPosition, VT_I4, VTS_I4)
//}}AFX_DISPATCH_MAP
DISP_FUNCTION_ID(CMultiViewCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()
/////////////////////////////////////////////////////////////////////////////
// Event map
BEGIN_EVENT_MAP(CMultiViewCtrl, COleControl)
//{{AFX_EVENT_MAP(CMultiViewCtrl)
EVENT_CUSTOM("NotifyViewModified", FireNotifyViewModified, VTS_NONE)
EVENT_CUSTOM("NotifySelectionChanged", FireNotifySelectionChanged, VTS_NONE)
EVENT_CUSTOM("NotifySaveRequired", FireNotifySaveRequired, VTS_NONE)
EVENT_CUSTOM("NotifyViewObjectSelected", FireNotifyViewObjectSelected, VTS_BSTR)
EVENT_CUSTOM("GetIWbemServices", FireGetIWbemServices, VTS_BSTR VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT)
EVENT_CUSTOM("NotifyContextChanged", FireNotifyContextChanged, VTS_I4)
//}}AFX_EVENT_MAP
END_EVENT_MAP()
/////////////////////////////////////////////////////////////////////////////
// Property pages
// TODO: Add more property pages as needed. Remember to increase the count!
BEGIN_PROPPAGEIDS(CMultiViewCtrl, 1)
PROPPAGEID(CMultiViewPropPage::guid)
END_PROPPAGEIDS(CMultiViewCtrl)
/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid
IMPLEMENT_OLECREATE_EX(CMultiViewCtrl, "WBEM.MultiViewCtrl.1",
0xff371bf4, 0x213d, 0x11d0, 0x95, 0xf3, 0, 0xc0, 0x4f, 0xd9, 0xb1, 0x5b)
/////////////////////////////////////////////////////////////////////////////
// Type library ID and version
IMPLEMENT_OLETYPELIB(CMultiViewCtrl, _tlid, _wVerMajor, _wVerMinor)
/////////////////////////////////////////////////////////////////////////////
// Interface IDs
const IID BASED_CODE IID_DMultiView =
{ 0xff371bf2, 0x213d, 0x11d0, { 0x95, 0xf3, 0, 0xc0, 0x4f, 0xd9, 0xb1, 0x5b } };
const IID BASED_CODE IID_DMultiViewEvents =
{ 0xff371bf3, 0x213d, 0x11d0, { 0x95, 0xf3, 0, 0xc0, 0x4f, 0xd9, 0xb1, 0x5b } };
/////////////////////////////////////////////////////////////////////////////
// Control type information
static const DWORD BASED_CODE _dwMultiViewOleMisc =\
OLEMISC_SIMPLEFRAME |
OLEMISC_ACTIVATEWHENVISIBLE |
OLEMISC_SETCLIENTSITEFIRST |
OLEMISC_INSIDEOUT |
OLEMISC_CANTLINKINSIDE |
OLEMISC_RECOMPOSEONRESIZE;
IMPLEMENT_OLECTLTYPE(CMultiViewCtrl, IDS_MULTIVIEW, _dwMultiViewOleMisc)
STDMETHODIMP CMVContext::QueryInterface(REFIID riid, LPVOID* ppv)
{
if(riid == IID_IUnknown)
{
*ppv = this;
AddRef();
return S_OK;
}
else return E_NOINTERFACE;
}
ULONG CMVContext::AddRef()
{
return InterlockedIncrement(&m_lRef);
}
ULONG CMVContext::Release()
{
int lNewRef = InterlockedDecrement(&m_lRef);
if(lNewRef == 0)
{
delete this;
}
return lNewRef;
}
CMVContext::CMVContext(CMVContext &rhs)
: m_lRef(0),
m_bContextDrawn(FALSE)
{
GetType() = rhs.GetType();
GetClass()= rhs.GetClass();
GetQuery() = rhs.GetQuery();
GetQueryType() = rhs.GetQueryType();
GetLabel() = rhs.GetLabel();
GetNamespace() = rhs.GetNamespace();
for (int i = 0; i < rhs.GetInstances().GetSize(); i++)
{
GetInstances().Add(rhs.GetInstances().GetAt(i));
}
}
BOOL CMVContext::IsContextEqual(CMVContext &cmvcContext)
{
if(GetType() != cmvcContext.m_nContextType)
{
return FALSE;
}
if (GetClass().CompareNoCase(cmvcContext.m_csClass) != 0)
{
return FALSE;
}
if (GetQuery().CompareNoCase(cmvcContext.m_csQuery) != 0)
{
return FALSE;
}
if (GetQueryType().CompareNoCase(cmvcContext.m_csQueryType) != 0)
{
return FALSE;
}
if (GetLabel().CompareNoCase(cmvcContext.m_csLabel) != 0)
{
return FALSE;
}
if (GetNamespace().CompareNoCase(cmvcContext.m_csNamespace) != 0)
{
return FALSE;
}
if (GetInstances().GetSize() != cmvcContext.m_csaInstances.GetSize())
{
return FALSE;
}
for (int i = 0; i < cmvcContext.m_csaInstances.GetSize(); i++)
{
if (GetInstances().GetAt(i).CompareNoCase
(cmvcContext.m_csaInstances.GetAt(i)) != 0)
{
return FALSE;
}
}
return TRUE;
}
CMVContext &CMVContext::operator=(const CMVContext &rhs)
{
if (this == &rhs)
{
return *this;
}
this->~CMVContext();
m_lRef = 0;
IsDrawn() = FALSE;
GetType() = rhs.m_nContextType;
GetClass()= rhs.m_csClass;
GetQuery() = rhs.m_csQuery;
GetQueryType() = rhs.m_csQueryType;
GetLabel() = rhs.m_csLabel;
GetNamespace() = rhs.m_csNamespace;
for (int i = 0; i < rhs.m_csaInstances.GetSize(); i++)
{
GetInstances().Add(rhs.m_csaInstances.GetAt(i));
}
return *this;
}
STDMETHODIMP CAsyncQuerySink::QueryInterface(REFIID riid, LPVOID* ppv)
{
if(riid == IID_IUnknown || riid == IID_IWbemObjectSink)
{
*ppv = this;
AddRef();
return S_OK;
}
else return E_NOINTERFACE;
}
ULONG CAsyncQuerySink::AddRef()
{
return InterlockedIncrement(&m_lRef);
}
ULONG CAsyncQuerySink::Release()
{
int lNewRef = InterlockedDecrement(&m_lRef);
if(lNewRef == 0)
{
delete this;
}
return lNewRef;
}
STDMETHODIMP CAsyncQuerySink::Indicate
(LONG lObjectCount,IWbemClassObject FAR* FAR*ppObjArray)
{
BOOL bDone = FALSE;
CPtrArray cpaInstances;
int i;
for (i = 0; i < lObjectCount; i++)
{
IWbemClassObject *pInst = reinterpret_cast<IWbemClassObject*>(ppObjArray[i]);
CString csClass = GetIWbemClass
(m_pMultiViewCtrl->m_pServices,pInst);
CString csNotifyBase = _T("__NotifyStatus");
CString csDynasty = _T("__Dynasty");
csDynasty = ::GetProperty(m_pMultiViewCtrl->m_pServices,pInst,&csDynasty);
if (!csDynasty.CompareNoCase(csNotifyBase) == 0)
{
pInst->AddRef();
cpaInstances.Add(ppObjArray[i]);
m_pMultiViewCtrl->m_nInstances++;
}
else
{
m_lAsyncRequestHandle = 0;
if (m_pMultiViewCtrl->m_nInstances == 0)
{
m_pMultiViewCtrl->PostMessage(ID_DISPLAYNOINSTANCES,0,0);
}
bDone = TRUE;
}
}
if (lObjectCount > 0)
{
if (m_pMultiViewCtrl->m_csClassForAsyncSink.GetLength() > 0)
{
m_pMultiViewCtrl->AddToDisplay(&cpaInstances);
}
else
{
m_pMultiViewCtrl->m_cpaInstancesForQuery.Append(cpaInstances);
}
}
if (bDone)
{
if (m_pMultiViewCtrl->m_csClassForAsyncSink.GetLength() == 0)
{
m_pMultiViewCtrl->PostMessage(ID_ASYNCQUERY_DISPLAY,0,0);
}
m_pMultiViewCtrl->PostMessage(ID_QUERYDONE,0,0);
}
return S_OK;
}
CAsyncQuerySink::~CAsyncQuerySink()
{
if (m_lRef > 0)
{
}
}
void CAsyncQuerySink::ShutDownSink()
{
if (!m_lAsyncRequestHandle == 0)
{
AddRef();
SCODE sc =
m_pMultiViewCtrl->m_pServices->
CancelAsyncCall((IWbemObjectSink*) this);
Sleep(1000);
CoDisconnectObject(this,0);
m_lRef = 0;
CAsyncQuerySink::~CAsyncQuerySink();
} else if (m_lRef == 1)
{
m_lRef = 0;
CAsyncQuerySink::~CAsyncQuerySink();
}
else
{
CoDisconnectObject(this,0);
m_lRef = 0;
CAsyncQuerySink::~CAsyncQuerySink();
}
}
STDMETHODIMP CAsyncInstEnumSink::QueryInterface(REFIID riid, LPVOID* ppv)
{
if(riid == IID_IUnknown || riid == IID_IWbemObjectSink)
{
*ppv = this;
AddRef();
return S_OK;
}
else return E_NOINTERFACE;
}
ULONG CAsyncInstEnumSink::AddRef()
{
return InterlockedIncrement(&m_lRef);
}
ULONG CAsyncInstEnumSink::Release()
{
int lNewRef = InterlockedDecrement(&m_lRef);
if(lNewRef == 0)
{
delete this;
}
return lNewRef;
}
STDMETHODIMP CAsyncInstEnumSink::Indicate
(LONG lObjectCount,IWbemClassObject FAR* FAR*ppObjArray)
{
BOOL bDone;
#ifdef _DEBUG
// afxDump << _T("Entering Indicate\n");;
#endif
CPtrArray cpaInstances;
int i;
for (i = 0; i < lObjectCount; i++)
{
IWbemClassObject *pInst = reinterpret_cast<IWbemClassObject*>(ppObjArray[i]);
CString csClass = GetIWbemClass
(m_pMultiViewCtrl->m_pServices,pInst);
#ifdef _DEBUG
// afxDump << _T("Async enum class = ") << csClass << "\n";
#endif
CString csNotifyBase = _T("__NotifyStatus");
CString csDynasty = _T("__Dynasty");
csDynasty = ::GetProperty(m_pMultiViewCtrl->m_pServices,pInst,&csDynasty);
if (!csDynasty.CompareNoCase(csNotifyBase) == 0)
{
pInst->AddRef();
cpaInstances.Add(ppObjArray[i]);
m_pMultiViewCtrl->m_nInstances++;
}
else
{
m_lAsyncRequestHandle = 0;
if (m_pMultiViewCtrl->m_nInstances == 0)
{
m_pMultiViewCtrl->PostMessage(ID_DISPLAYNOINSTANCES,0,0);
}
bDone = TRUE;
}
}
if (lObjectCount > 0)
{
m_pMultiViewCtrl->AddToDisplay(&cpaInstances);
}
if (bDone)
{
m_pMultiViewCtrl->PostMessage(ID_INSTENUMDONE,0,0);
}
#ifdef _DEBUG
// afxDump << _T("Leaving Indicate\n");;
#endif
return S_OK;
}
CAsyncInstEnumSink::~CAsyncInstEnumSink()
{
if (m_lRef > 0)
{
}
}
void CAsyncInstEnumSink::ShutDownSink()
{
if (!m_lAsyncRequestHandle == 0)
{
AddRef();
SCODE sc =
m_pMultiViewCtrl->m_pServices->
CancelAsyncCall((IWbemObjectSink*) this);
Sleep(1000);
CoDisconnectObject(this,0);
m_lRef = 0;
CAsyncInstEnumSink::~CAsyncInstEnumSink();
} else if (m_lRef == 1)
{
m_lRef = 0;
CAsyncInstEnumSink::~CAsyncInstEnumSink();
}
else
{
CoDisconnectObject(this,0);
m_lRef = 0;
CAsyncInstEnumSink::~CAsyncInstEnumSink();
}
}
/////////////////////////////////////////////////////////////////////////////
// CMultiViewCtrl::CMultiViewCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CMultiViewCtrl
BOOL CMultiViewCtrl::CMultiViewCtrlFactory::UpdateRegistry(BOOL bRegister)
{
// TODO: Verify that your control follows apartment-model threading rules.
// Refer to MFC TechNote 64 for more information.
// If your control does not conform to the apartment-model rules, then
// you must modify the code below, changing the 6th parameter from
// afxRegInsertable | afxRegApartmentThreading to afxRegInsertable.
if (bRegister)
return AfxOleRegisterControlClass(
AfxGetInstanceHandle(),
m_clsid,
m_lpszProgID,
IDS_MULTIVIEW,
IDB_MULTIVIEW,
afxRegInsertable | afxRegApartmentThreading,
_dwMultiViewOleMisc,
_tlid,
_wVerMajor,
_wVerMinor);
else
return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}
/////////////////////////////////////////////////////////////////////////////
// CMultiViewCtrl::CMultiViewCtrl - Constructor
CMultiViewCtrl::CMultiViewCtrl()
{
InitializeIIDs(&IID_DMultiView, &IID_DMultiViewEvents);
EnableSimpleFrame();
m_pServices = NULL;
m_cgGrid.SetParent (this);
m_nClassOrInstances = CMultiViewCtrl::NONE;
m_pcsedDialog = NULL;
m_pcaedDialog = NULL;
m_pcaqdDialog = NULL;
m_pInstEnumObjectSink = NULL;
m_pAsyncQuerySink = NULL;
m_bInOnDraw = FALSE;
m_bInitServices = TRUE;
m_pcmvcCurrentContext = new CMVContext;
m_pcmvcCurrentContext->AddRef();
m_pProgressDlg = NULL;
m_cpRightUp.x = 0;
m_cpRightUp.y = 0;
m_lPropFilterFlags = PROPFILTER_SYSTEM | PROPFILTER_INHERITED | PROPFILTER_LOCAL;
m_bSelectionNotChanging = FALSE;
m_bCanEdit = FALSE;
m_bPropFilterFlagsChanged = FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CMultiViewCtrl::~CMultiViewCtrl - Destructor
CMultiViewCtrl::~CMultiViewCtrl()
{
m_csaProps.RemoveAll();
if (m_pServices)
{
m_pServices -> Release();
}
// Delete stored paths
int nRows = m_cgGrid.GetRows();
for (int i = 0; i < nRows; i++)
{
CString *pcsPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(i, 0).GetTagValue());
delete pcsPath;
}
m_pcmvcCurrentContext->Release();
}
/////////////////////////////////////////////////////////////////////////////
// CMultiViewCtrl::OnDraw - Drawing function
void CMultiViewCtrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (GetSafeHwnd() && !AmbientUserMode())
{
COLORREF crWhite = RGB(255,255,255);
CRect rcOutline(rcBounds);
CBrush cbBackGround;
cbBackGround.CreateSolidBrush(crWhite);
CBrush *cbSave = pdc -> SelectObject(&cbBackGround);
pdc ->FillRect(&rcOutline, &cbBackGround);
pdc -> SelectObject(cbSave);
return;
}
// TODO: Replace the following code with your own drawing code.
if (m_bInOnDraw)
{
return;
}
m_bInOnDraw = TRUE;
if (m_cgGrid.GetSafeHwnd())
{
m_cgGrid.ShowWindow(SW_SHOW);
}
if (m_csNamespaceToInit.GetLength() > 0)
{
PostMessage(INITIALIZE_NAMESPACE,0,0);
}
m_bInOnDraw = FALSE;
}
LRESULT CMultiViewCtrl::InitServices (WPARAM, LPARAM)
{
if (m_bInitServices)
{
m_pServices = InitServices(&m_csNameSpace);
m_bInitServices = FALSE;
}
return 0;
}
/////////////////////////////////////////////////////////////////////////////
// CMultiViewCtrl::DoPropExchange - Persistence support
void CMultiViewCtrl::DoPropExchange(CPropExchange* pPX)
{
ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
COleControl::DoPropExchange(pPX);
PX_String(pPX, _T("NameSpace"), m_csNameSpace, _T(""));
if (pPX->IsLoading() && m_csNameSpace.GetLength() > 0)
{
m_csNamespaceToInit = m_csNameSpace;
}
}
/////////////////////////////////////////////////////////////////////////////
// CMultiViewCtrl::OnResetState - Reset control to default state
void CMultiViewCtrl::OnResetState()
{
COleControl::OnResetState(); // Resets defaults found in DoPropExchange
// TODO: Reset any other control state here.
}
/////////////////////////////////////////////////////////////////////////////
// CMultiViewCtrl::AboutBox - Display an "About" box to the user
void CMultiViewCtrl::AboutBox()
{
CWnd* pwndFocus = GetFocus();
CDialog dlgAbout(IDD_ABOUTBOX_MULTIVIEW);
dlgAbout.DoModal();
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
}
/////////////////////////////////////////////////////////////////////////////
// CMultiViewCtrl message handlers
int CMultiViewCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (COleControl::OnCreate(lpCreateStruct) == -1)
return -1;
if (AmbientUserMode( ) && GetSafeHwnd())
{
// Create the grid window
UINT idWindow = 500;
BOOL bGridVisible = TRUE;
CRect rcGrid(0, 0, 0, 0);
m_cgGrid.Create(rcGrid, this, idWindow, bGridVisible);
m_pcsedDialog = new CSyncEnumDlg;
m_pcsedDialog->SetLocalParent(this);
m_pcaedDialog = new CAsyncEnumDialog;
m_pcaedDialog->SetLocalParent(this);
m_pcaqdDialog = new CAsyncQueryDialog;
m_pcaqdDialog->SetLocalParent(this);
m_pProgressDlg = new CProgressDlg;
}
return 0;
}
void CMultiViewCtrl::OnSize(UINT nType, int cx, int cy)
{
if (AmbientUserMode( ) && GetSafeHwnd())
{
COleControl::OnSize(nType, cx, cy);
// Make the grid window cover the entire client area.
if (m_cgGrid.m_hWnd) {
m_cgGrid.MoveWindow(0, 0, cx, cy, TRUE);
}
}
}
void CMultiViewCtrl::ViewClassInstances(LPCTSTR lpszClassName)
{
m_pcmvcCurrentContext->~CMVContext();
m_pcmvcCurrentContext->AddRef();
m_pcmvcCurrentContext->GetType() = CMVContext::Class;
m_pcmvcCurrentContext->GetClass() = lpszClassName;
m_pcmvcCurrentContext->GetNamespace() = m_csNameSpace;
m_nClassOrInstances = CMultiViewCtrl::CLASS;
if (IsWindowVisible())
{
NotifyWillShow();
}
}
void CMultiViewCtrl::ViewClassInstancesSync(LPCTSTR lpszClassName)
{
if (lpszClassName == NULL || lpszClassName[0] == '\0' || !m_pServices)
{
return;
}
m_csSyncEnumClass = lpszClassName;
// This is just to allow the message pump to run so we see the gird
// because the container will not actually show us until "VierInstances"
// returns??
// From PolyView.cpp:
// m_pmv->NotifyWillShow();
// m_pmv->ShowWindow(SW_SHOW);
// It would be nice to do these in the reverse order because as it now stands
// ViewClassInstances is not synchronous which is not good for programatic use.
PostMessage(ID_SYNC_ENUM , 0,0);
// Refresh repaints in line.
// Refresh();
// SyncEnum(0,0);
}
LRESULT CMultiViewCtrl::SyncEnum(WPARAM, LPARAM)
{
// CWaitCursor wait;
IWbemClassObject *pimcoClass = NULL;
IWbemClassObject *pErrorObject = NULL;
SCODE sc;
CString csPath;
if (m_pcmvcCurrentContext->GetType() == CMVContext::Class)
{
BSTR bstrTemp = m_csSyncEnumClass.AllocSysString();
m_sc = m_pServices ->
GetObject(bstrTemp,0, NULL, &pimcoClass,NULL);
::SysFreeString(bstrTemp);
}
else
{
csPath = m_csSyncEnumClass;
pimcoClass = GetClassFromAnyNamespace(csPath);
}
if (!pimcoClass)
{
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot get class object ") + csPath;
ErrorMsg
(&csUserMsg, m_sc,FALSE, FALSE, &csUserMsg, __FILE__,
__LINE__ - 9);
return 0;
}
if (csPath.IsEmpty())
{
csPath = GetIWbemClass(m_pServices,pimcoClass);
}
CString csClass;
BOOL bDiffNS =
ObjectInDifferentNamespace
(m_pServices, &m_csNameSpace, pimcoClass);
IWbemServices *pServices;
if (bDiffNS)
{
CString csNameSpace =
GetObjectNamespace (m_pServices, pimcoClass);
pServices = InitServices(&csNameSpace);
if (!pServices)
{
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot connect to namespace ") + csNameSpace;
ErrorMsg
(&csUserMsg, S_OK, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__ - 9);
pimcoClass->Release();
return 0;
}
csClass = GetIWbemClass(pServices ,pimcoClass);
}
else
{
csClass = GetIWbemClass(m_pServices ,pimcoClass);
}
CPtrArray *pcpaInstances = new CPtrArray;
IWbemClassObject *pInstanceEnumErrorObject = NULL;
int cInst;
BOOL bCancel = FALSE;
m_pAsyncEnumCancelled = FALSE;
m_pAsyncQueryCancelled = FALSE;
sc = SemiSyncClassInstancesIncrementalAddToDisplay
(bDiffNS? pServices: m_pServices, pimcoClass, &csClass ,
*pcpaInstances , cInst, bCancel);
if (cInst == 0 || bCancel)
{
m_nClassOrInstances = CMultiViewCtrl::ZERO_CLASS_INST;
CString csMessage;
if (bCancel)
{
csMessage = _T("Operation Canceled");
}
else
{
csMessage = _T("No Instances Available");
}
InitializeDisplay(NULL,NULL,NULL,&csMessage);
pimcoClass -> Release();
if (bDiffNS)
{
pServices->Release();
}
m_csClass = csPath;
delete pcpaInstances;
return 0;
}
pimcoClass -> Release();
if (bDiffNS)
{
pServices->Release();
}
delete pcpaInstances;
return 0;
}
SCODE CMultiViewCtrl::SemiSyncClassInstancesIncrementalAddToDisplay
(IWbemServices * pIWbemServices, IWbemClassObject *pimcoClass,
CString *pcsClass,
CPtrArray &cpaInstances,int &cInst, BOOL &bCancel)
{
m_bSelectionNotChanging = TRUE;
CString csMessage =
m_csSyncEnumClass + _T(" class instances.");
SetProgressDlgMessage(csMessage);
cInst = 0;
bCancel = 0;
SCODE sc;
IEnumWbemClassObject *pimecoInstanceEnum = NULL;
#ifdef _DEBUG
afxDump << "CreateInstanceEnum in SemiSyncClassInstancesIncrementalAddToDisplay for class " << *pcsClass << "\n";
#endif
BSTR bstrTemp = pcsClass -> AllocSysString();
sc = pIWbemServices->CreateInstanceEnum
(bstrTemp,
WBEM_FLAG_DEEP | WBEM_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY, NULL, &pimecoInstanceEnum);
::SysFreeString(bstrTemp);
if(sc != S_OK)
{
m_bSelectionNotChanging = FALSE;
m_cgGrid.CheckForSelectionChange();
return sc;
}
sc = SetEnumInterfaceSecurity(m_csNameSpace,pimecoInstanceEnum, pIWbemServices);
#ifdef _DEBUG
afxDump << "SetEnumInterfaceSecurityin SemiSyncClassInstancesIncrementalAddToDisplay for class " << sc << "\n";
#endif
// sc = pimecoInstanceEnum->Reset();
m_csaProps.RemoveAll();
int nProps = GetSortedPropNames (pimcoClass, m_csaProps, m_cmstpPropFlavors);
InitializeDisplay(NULL, NULL, &m_csaProps, NULL, &m_cmstpPropFlavors);
IWbemClassObject *pimcoInstances[N_INSTANCES];
IWbemClassObject **pInstanceArray =
reinterpret_cast<IWbemClassObject **> (&pimcoInstances);
int i;
for (i = 0; i < N_INSTANCES; i++)
{
pimcoInstances[i] = NULL;
}
IWbemClassObject *pimcoInstance = NULL;
ULONG uReturned = 0;
#ifdef _DEBUG
afxDump << "Next in SemiSyncClassInstancesIncrementalAddToDisplay number returned = ";
#endif
CString csPath = m_csSyncEnumClass;
m_csClass = csPath;
m_nClassOrInstances = CLASS;
if (!m_pProgressDlg->GetSafeHwnd())
{
CreateProgressDlgWindow();
}
BOOL bReportRetrievalError = FALSE;
HWND hwndFocus = ::GetFocus();
sc = pimecoInstanceEnum->Next(ENUM_TIMEOUT,N_INSTANCES,pInstanceArray, &uReturned);
if (FAILED(sc)) {
bReportRetrievalError = TRUE;
}
#ifdef _DEBUG
afxDump << uReturned << "\n";
#endif
while (sc == S_OK || sc == WBEM_S_TIMEDOUT || uReturned > 0)
{
bCancel = CheckCancelButtonProgressDlgWindow();
if (bCancel)
{
#pragma warning( disable :4018 )
for (int i = 0; i < uReturned; i++)
#pragma warning( default : 4018 )
{
pimcoInstances[i]->Release();
pimcoInstances[i] = NULL;
}
cInst = 0;
break;
}
#pragma warning( disable :4018 )
for (int i = 0; i < uReturned; i++)
#pragma warning( default : 4018 )
{
cpaInstances.Add(reinterpret_cast<void *>(pimcoInstances[i]));
pimcoInstances[i] = NULL;
}
if (uReturned > 0)
{
AddToDisplay(&cpaInstances);
}
cpaInstances.RemoveAll();
cInst += uReturned;
uReturned = 0;
#ifdef _DEBUG
afxDump << "Next in SemiSyncClassInstancesIncrementalAddToDisplay number returned = ";
#endif
sc = pimecoInstanceEnum->Next
(1,N_INSTANCES,pInstanceArray, &uReturned);
if (FAILED(sc)) {
bReportRetrievalError = TRUE;
}
#ifdef _DEBUG
afxDump << uReturned << "\n";
#endif
}
pimecoInstanceEnum -> Release();
DestroyProgressDlgWindow();
if (bReportRetrievalError) {
CString csUserMsg =
_T("An error occurred while attempting to retrieve the list of objects.");
ErrorMsg
(&csUserMsg, sc, TRUE,
TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
if (::IsWindow(hwndFocus) && ::IsWindowVisible(hwndFocus)) {
::SetFocus(hwndFocus);
}
}
m_bSelectionNotChanging = FALSE;
m_cgGrid.CheckForSelectionChange();
return sc;
}
void CMultiViewCtrl::SetProgressDlgMessage(CString &csMessage)
{
m_pProgressDlg->SetMessage(csMessage);
}
void CMultiViewCtrl::CreateProgressDlgWindow()
{
PreModalDialog();
m_pProgressDlg->Create(this);
}
BOOL CMultiViewCtrl::CheckCancelButtonProgressDlgWindow()
{
if (::IsWindow(m_pProgressDlg->m_hWnd) && m_pProgressDlg->GetSafeHwnd())
{
return m_pProgressDlg->CheckCancelButton();
}
return FALSE;
}
void CMultiViewCtrl::DestroyProgressDlgWindow()
{
if (::IsWindow(m_pProgressDlg->m_hWnd) && m_pProgressDlg->GetSafeHwnd())
{
m_pProgressDlg->DestroyWindow();
PostModalDialog();
}
}
void CMultiViewCtrl::PumpMessagesProgressDlgWindow()
{
if (::IsWindow(m_pProgressDlg->m_hWnd) && m_pProgressDlg->GetSafeHwnd())
{
m_pProgressDlg->PumpMessages();
}
}
void CMultiViewCtrl::ViewClassInstancesAsync(LPCTSTR lpszClassName)
{
if (lpszClassName == NULL || lpszClassName[0] == '\0' || !m_pServices)
{
return;
}
CString csPath = lpszClassName;
IWbemClassObject *pimcoClass = NULL;
SCODE sc;
pimcoClass = GetClassFromAnyNamespace(csPath);
if (!pimcoClass)
{
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot get class object ") + csPath;
ErrorMsg
(&csUserMsg, m_sc, FALSE, TRUE, &csUserMsg, __FILE__,
__LINE__ - 9);
return;
}
CString csClass;
BOOL bDiffNS =
ObjectInDifferentNamespace
(m_pServices, &m_csNameSpace, pimcoClass);
IWbemServices *pServices;
if (bDiffNS)
{
CString csNameSpace =
GetObjectNamespace (m_pServices, pimcoClass);
pServices = InitServices(&csNameSpace);
if (!pServices)
{
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot connect to namespace ") + csNameSpace;
ErrorMsg
(&csUserMsg, m_sc, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__ - 9);
pimcoClass->Release();
return;
}
csClass = GetIWbemClass(pServices ,pimcoClass);
}
else
{
csClass = GetIWbemClass(m_pServices ,pimcoClass);
}
m_csaProps.RemoveAll();
int nProps = GetSortedPropNames (pimcoClass, m_csaProps, m_cmstpPropFlavors);
pimcoClass -> Release();
m_csClass = csClass;
m_nClassOrInstances = CLASS;
InitializeDisplay(&csClass, NULL, &m_csaProps, NULL, &m_cmstpPropFlavors);
m_pcaedDialog->SetClass(&csClass);
BOOL bCancel = FALSE;
sc = GetInstancesAsync
(bDiffNS? pServices: m_pServices, &csClass);
if (bDiffNS)
{
pServices->Release();
}
}
SCODE CMultiViewCtrl::ViewInstances(LPCTSTR szTitle, const VARIANT FAR& varPathArray)
{
//
// There are two things that ViewInstances needs to do to work
// properly with the new view interface:
//
// 1. The container now passes the call to ViewInstances though immediately
// rather than waiting till the multiview is made visible. This means
// that CMultiViewCtrl needs to check to see if the multiview control
// is currently hidden. If so, ViewInstances should a) save the parameter values
// somewhere and b) set itself to an "empty" state, and c) when NotifyDidShow is
// called, load the instances into the multiview.
//
// 2. The container now passes the title though to the multiview. The multiview
// needs to make this available through the GetTitle method.
//
if (!((varPathArray.vt == (VT_ARRAY | VT_BSTR)) ||
(varPathArray.vt == (VT_VARIANT | VT_BYREF))))
{
return WBEM_E_INVALID_PARAMETER;
}
m_pcmvcCurrentContext->~CMVContext();
m_pcmvcCurrentContext->AddRef();
m_pcmvcCurrentContext->GetType() = CMVContext::Instances;
m_pcmvcCurrentContext->GetLabel() = szTitle;
m_pcmvcCurrentContext->GetNamespace() = m_csNameSpace;
CStringArray csaPaths;
CStringArray csaClasses;
CPtrArray cpaInstances;
SAFEARRAY *psaPaths = NULL;
if (varPathArray.vt == (VT_VARIANT | VT_BYREF))
{
if (varPathArray.pvarVal->vt == (VT_ARRAY | VT_VARIANT))
{
psaPaths = varPathArray.pvarVal->parray;
}
}
else
{
psaPaths = varPathArray.parray;
}
long ix[2] = {0,0};
long lLower, lUpper;
int iDim = SafeArrayGetDim(psaPaths );
int i;
SCODE sc = SafeArrayGetLBound(psaPaths,1,&lLower);
sc = SafeArrayGetUBound(psaPaths,1,&lUpper);
for(ix[0] = lLower, i = 0; ix[0] <= lUpper; ix[0]++, i++)
{
CString csPath;
BSTR bstrPath;
if (varPathArray.pvarVal->vt == (VT_ARRAY | VT_VARIANT))
{
VARIANT var;
VariantInit(&var);
sc = SafeArrayGetElement(psaPaths,ix,&var);
if (SUCCEEDED(sc))
{
VARIANTARG varChanged;
VariantInit(&varChanged);
sc = VariantChangeType(&varChanged, &var, 0, VT_BSTR);
VariantClear(&var);
if (SUCCEEDED(sc))
{
bstrPath = varChanged.bstrVal;
VariantClear(&varChanged);
}
}
}
else
{
sc = SafeArrayGetElement(psaPaths,ix,&bstrPath);
}
if (SUCCEEDED(sc))
{
csPath = bstrPath;
m_pcmvcCurrentContext->GetInstances().Add(csPath);
SysFreeString(bstrPath);
}
}
if (IsWindowVisible())
{
NotifyWillShow();
}
return S_OK;
}
SCODE CMultiViewCtrl::ViewInstancesInternal
(LPCTSTR szTitle, CStringArray &rcsaPathArray)
{
CString csTitle = szTitle;
// CWaitCursor wait;
CString csMessage =
csTitle + _T(" instances.");
SetProgressDlgMessage(csMessage);
if (!m_pProgressDlg->GetSafeHwnd())
{
CreateProgressDlgWindow();
}
CStringArray csaPaths;
CStringArray csaClasses;
CPtrArray cpaInstances;
IWbemClassObject *pimcoClass = NULL;
int i;
for (i = 1; i < rcsaPathArray.GetSize(); i++)
{
PumpMessagesProgressDlgWindow();
CString csPath = rcsaPathArray.GetAt(i);
IWbemClassObject *pimcoObject = NULL;
BSTR bstrTemp = csPath.AllocSysString();
#ifdef _DEBUG
// afxDump << "GetObject in ViewInstancesInternal for " << csPath << "\n";
#endif
SCODE sc;
if (csPath.GetLength() == 0)
{
sc = E_FAIL;
}
else
{
sc =
m_pServices -> GetObject(bstrTemp,0, NULL,
&pimcoObject,NULL);
}
::SysFreeString(bstrTemp);
CString csClass;
if (sc == S_OK)
{
PumpMessagesProgressDlgWindow();
csClass = GetIWbemClassPath(m_pServices ,pimcoObject);
csaPaths.Add(csPath);
cpaInstances.Add(pimcoObject);
if (!ClassInClasses(&csaClasses,&csClass))
{
csaClasses.Add(csClass);
}
}
else
{
PumpMessagesProgressDlgWindow();
}
}
if (csaClasses.GetSize() > 0)
{
pimcoClass = CommonParent(&csaClasses);
}
else
{
pimcoClass = NULL;
}
if (pimcoClass == NULL)
{
DestroyProgressDlgWindow();
m_nClassOrInstances = INSTANCES;
m_csClass.Empty();
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot get a common parent ");
PreModalDialog();
ErrorMsg
(&csUserMsg, S_OK, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__ - 13);
PostModalDialog();
CString csMessage = _T("No Instances Available");
m_nClassOrInstances = NONE;
m_csClass.Empty();
InitializeDisplay(NULL,NULL,NULL,&csMessage);
return S_OK;
}
m_csaProps.RemoveAll();
int nProps = GetSortedPropNames (pimcoClass, m_csaProps, m_cmstpPropFlavors);
CString csClass = GetIWbemClass(m_pServices,pimcoClass);
pimcoClass -> Release();
m_nClassOrInstances = INSTANCES;
m_csClass.Empty();
DestroyProgressDlgWindow();
InitializeDisplay(&csClass, &cpaInstances, &m_csaProps, NULL, &m_cmstpPropFlavors);
return S_OK;
}
BOOL CMultiViewCtrl::IsColVisible(long lFilter, long lFlavor)
{
BOOL bLocal = (lFilter & PROPFILTER_LOCAL) && (lFlavor == WBEM_FLAVOR_ORIGIN_LOCAL);
if (bLocal)
{
return TRUE;
}
BOOL bSystem = (lFilter & PROPFILTER_SYSTEM) && (lFlavor == WBEM_FLAVOR_ORIGIN_SYSTEM);
if (bSystem)
{
return TRUE;
}
BOOL bPropagated = (lFilter & PROPFILTER_INHERITED) && (lFlavor == WBEM_FLAVOR_ORIGIN_PROPAGATED);
if (bPropagated)
{
return TRUE;
}
else
{
return FALSE;
}
}
void CMultiViewCtrl::SetAllColVisibility( CStringArray *pcsaProps, CMapStringToPtr *pcmstpPropFlavors)
{
long *plFlavor;
BOOL bReturn;
for (int i = 0; i < pcsaProps->GetSize(); i++)
{
bReturn = m_cmstpPropFlavors.Lookup((LPCTSTR) pcsaProps->GetAt(i),(void *&) plFlavor);
// NOTE: Win64- the m_cmstpPropFlavors was really only using the lower 32 bits to store the flavor
long lFlavor = (DWORD)(DWORD_PTR)plFlavor;
BOOL bVisible;
if (bReturn)
{
bVisible = IsColVisible(m_lPropFilterFlags, lFlavor);
}
else
{
bVisible = TRUE;
}
m_cgGrid.SetColVisibility(i, bVisible);
}
}
void CMultiViewCtrl::InitializeDisplay
(CString *pcsClass, CPtrArray *pcpaInstances, CStringArray *pcsaProps,
CString *pcsMessage, CMapStringToPtr *pcmstpPropFlavors)
{
// CWaitCursor cwcWait;
int i;
// Delete stored paths
int nRows = m_cgGrid.GetRows();
for (i = 0; i < nRows; i++)
{
CString *pcsPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(i, 0).GetTagValue());
delete pcsPath;
}
int n = m_cgGrid.GetCols();
if (n > 1)
{
for (int i = 0; i < n; i++)
{
m_cgGrid.m_cwaColWidth.SetAtGrow(i,(WORD)m_cgGrid.ColWidthFromHeader(i));
}
}
// Clear the grid
m_cgGrid.Clear();
if (pcsaProps == NULL && pcsMessage == NULL)
{
InvalidateControl();
m_cgGrid.RedrawWindow();
return;
}
if (pcsMessage)
{
InitializeDisplayMessage(pcsMessage);
return;
}
int nCols = (int) pcsaProps -> GetSize();
nRows = pcpaInstances? (int) pcpaInstances -> GetSize(): 0;
// Row columns
int nColSave = (int) m_cgGrid.m_cwaColWidth.GetSize();
for (i = 0; i < nCols; i++)
{
int nColWidth = 100;
if ( i < nColSave)
{
nColWidth = m_cgGrid.m_cwaColWidth.GetAt(i);
}
m_cgGrid.AddColumn(nColWidth, pcsaProps -> GetAt(i));
}
SetAllColVisibility(pcsaProps,pcmstpPropFlavors);
for (i = 0; i < nRows; i++)
{
IWbemClassObject *pimcoInstance =
reinterpret_cast<IWbemClassObject *>
(pcpaInstances -> GetAt(i));
m_cgGrid.AddRow();
CString *pcsPath =
new CString(GetIWbemFullPath(m_pServices,pimcoInstance));
(m_cgGrid.GetAt(i, 0).SetTagValue
(reinterpret_cast<DWORD_PTR>(pcsPath)));
VARIANT var;
for (int k = 0; k < nCols; k++)
{
CIMTYPE cimtype;
GetPropertyAsVariant( pimcoInstance,&pcsaProps -> GetAt(k),var, cimtype);
m_cgGrid.GetAt(i,k).SetValue(CELLTYPE_VARIANT, var, cimtype);
m_cgGrid.GetAt(i,k).SetFlags(CELLFLAG_READONLY,CELLFLAG_READONLY);
VariantClear(&var);
}
pimcoInstance -> Release();
CString *pcsStoredPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(i, 0).GetTagValue());
}
m_cgGrid.CheckForSelectionChange();
SetModifiedFlag();
// 5-2-97 removed per Cori's usggestion.
// Sort the grid using column zero as the primary key.
//if (m_cgGrid.GetRows() > 0) {
// m_cgGrid.SortGrid(0, m_cgGrid.GetRows()-1, 0);
//}
InvalidateControl();
m_cgGrid.RedrawWindow();
}
LRESULT CMultiViewCtrl::DisplayAsyncQueryInstances(WPARAM, LPARAM)
{
if (m_cpaInstancesForQuery.GetSize() == 0)
{
return 0;
}
CStringArray csaPaths;
CStringArray csaClasses;
int i;
for (i = 0; i < m_cpaInstancesForQuery.GetSize(); i++)
{
IWbemClassObject *pObject =
reinterpret_cast<IWbemClassObject *>
(m_cpaInstancesForQuery.GetAt(i));
CString csClass = GetIWbemClass(m_pServices ,pObject);
if (!ClassInClasses(&csaClasses,&csClass))
{
csaClasses.Add(csClass);
}
}
IWbemClassObject *pClass = CommonParent(&csaClasses);
if (pClass == NULL)
{
m_nClassOrInstances = INSTANCES;
m_csClass.Empty();
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot get a common parent ");
ErrorMsg
(&csUserMsg, S_OK, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__ - 13);
return 0;
}
m_csaProps.RemoveAll();
int nProps = GetSortedPropNames (pClass, m_csaProps, m_cmstpPropFlavors);
CString csClass = GetIWbemClass(m_pServices,pClass);
pClass -> Release();
m_nClassOrInstances = INSTANCES;
m_csClass.Empty();
InitializeDisplay(NULL, &m_cpaInstancesForQuery, &m_csaProps, NULL, &m_cmstpPropFlavors);
m_cpaInstancesForQuery.RemoveAll();
return 0;
}
void CMultiViewCtrl::AddToDisplay(CPtrArray *pcpaInstances)
{
if (m_pAsyncEnumCancelled == TRUE || m_pAsyncQueryCancelled == TRUE)
{
return;
}
int nLastRow = m_cgGrid.GetRows();
int nNewRows = (int) pcpaInstances->GetSize();
int nCols = (int) m_csaProps.GetSize();
int i;
int n = nLastRow;
for (i = 0; i < nNewRows; i++)
{
IWbemClassObject *pimcoInstance =
reinterpret_cast<IWbemClassObject *>
(pcpaInstances -> GetAt(i));
if (pimcoInstance == NULL) {
continue;
}
m_cgGrid.AddRow();
int nNow = m_cgGrid.GetRows();
CString *pcsPath = new CString(GetIWbemFullPath (m_pServices,pimcoInstance));
m_cgGrid.GetAt(n, 0).SetTagValue (reinterpret_cast<DWORD_PTR>(pcsPath));
VARIANT var;
for (int k = 0; k < nCols; k++)
{
CIMTYPE cimtype;
GetPropertyAsVariant( pimcoInstance,&m_csaProps.GetAt(k),var, cimtype);
m_cgGrid.GetAt(n,k).SetValue(CELLTYPE_VARIANT, var, cimtype);
m_cgGrid.GetAt(n,k).SetFlags(CELLFLAG_READONLY,CELLFLAG_READONLY);
VariantClear(&var);
}
pimcoInstance -> Release();
CString *pcsStoredPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(n, 0).GetTagValue());
n++;
}
m_cgGrid.CheckForSelectionChange();
SetModifiedFlag();
// 5-2-97 removed per Cori's usggestion.
// Sort the grid using column zero as the primary key.
// if (m_cgGrid.GetRows() > 0) {
// m_cgGrid.SortGrid(0, m_cgGrid.GetRows()-1, 0);
// }
InvalidateControl();
m_cgGrid.RedrawWindow();
}
void CMultiViewCtrl::InitializeDisplayMessage
(CString *pcsMessage)
{
PumpMessagesProgressDlgWindow();
CString *pcsTitle = new CString(_T(" "));
m_cgGrid.AddColumn(500,*pcsTitle);
m_cgGrid.AddRow();
(m_cgGrid.GetAt(0, 0).SetTagValue
(reinterpret_cast<DWORD_PTR>(pcsTitle)));
VARIANT var;
VariantInit(&var);
var.vt = VT_BSTR;
var.bstrVal = pcsMessage->AllocSysString();
m_cgGrid.GetAt(0,0).SetValue(CELLTYPE_VARIANT, var, CIM_STRING);
m_cgGrid.GetAt(0,0).SetFlags(CELLFLAG_READONLY,CELLFLAG_READONLY);
VariantClear(&var);
SetModifiedFlag();
InvalidateControl();
m_cgGrid.RedrawWindow();
}
IWbemClassObject *CMultiViewCtrl::ParentFromDerivations(CStringArray **pcsaDerivation, int nDerivation)
{
//Search from the end of the derivations until they do not match.
// Make sure all the derivations end in the same class
int i;
int *nEndIndex = new int[nDerivation];
nEndIndex[0] = ((int) pcsaDerivation[0]->GetSize()) - 1;
CString csTest1 = pcsaDerivation[0]->GetAt(nEndIndex[0]);
int nMaxDerivation = (int) pcsaDerivation[0]->GetSize();
int nLongestDerivationIndex = 0;
for (i = 0; i < nDerivation; i++) //zina: changed to 0
{
int n = (int) pcsaDerivation[i]->GetSize();
if (n > nMaxDerivation)
{
nMaxDerivation = n;
nLongestDerivationIndex = i;
}
nEndIndex[i] = ((int) pcsaDerivation[i]->GetSize()) - 1;
if (csTest1.CompareNoCase(pcsaDerivation[i]->GetAt(nEndIndex[i])) != 0)
{
delete [] nEndIndex;
return FALSE;
}
}
// All derivations are length of one and must be the same if we are here.
if (nEndIndex[nLongestDerivationIndex] == 1)
{
BSTR bstrTemp = csTest1.AllocSysString();
IWbemClassObject *pObject = NULL;
SCODE sc =
m_pServices ->
GetObject(bstrTemp,0, NULL, &pObject,NULL);
::SysFreeString(bstrTemp);
if (!SUCCEEDED(sc))
{
delete [] nEndIndex;
return NULL;
}
else
{
delete [] nEndIndex;
return pObject;
}
}
BOOL bDone = FALSE;
CString csSave = csTest1;
while(!bDone)
{
if (nEndIndex[nLongestDerivationIndex] - 1 < 0)
{
bDone = TRUE;
break;
}
csSave = csTest1;
csTest1 = pcsaDerivation[nLongestDerivationIndex]->GetAt(nEndIndex[nLongestDerivationIndex] - 1);
for (i = 0; i < nDerivation; i++)
{
nEndIndex[i]--;
// Two things end the search
// 1) No more classes in a derivation
if (nEndIndex[i] < 0)
{
bDone = TRUE;
break;
}
// 2) The derivations do not match
if (csTest1.CompareNoCase(pcsaDerivation[i]->GetAt(nEndIndex[i])) != 0)
{
bDone = TRUE;
break;
}
}
}
BSTR bstrTemp = csSave.AllocSysString();
IWbemClassObject *pObject = NULL;
SCODE sc =
m_pServices ->
GetObject(bstrTemp,0, NULL, &pObject,NULL);
::SysFreeString(bstrTemp);
if (!SUCCEEDED(sc))
{
delete [] nEndIndex;
return NULL;
}
else
{
delete [] nEndIndex;
return pObject;
}
}
IWbemClassObject *CMultiViewCtrl::LowestCommonParent(CStringArray *pcsaPaths)
{
int n = (int) pcsaPaths->GetSize();
CStringArray **pcsaDerivation = new CStringArray *[n];
//try to get derivation array for each class
for (int i = 0, k = 0; i < n; i++)
{
pcsaDerivation[k] = NULL;
CStringArray * pDeriv = ClassDerivation(m_pServices, pcsaPaths->GetAt(i));
//if we could get derivation for this class:
if (pDeriv != NULL && pDeriv->GetSize() > 0) {
pcsaDerivation[k] = pDeriv;
k++;
}
}
IWbemClassObject *pParent = ParentFromDerivations(pcsaDerivation,k);
for (i = 0; i < k; i++)
{
delete pcsaDerivation[i];
}
delete [] pcsaDerivation;
return pParent;
}
IWbemClassObject * CMultiViewCtrl::CommonParent(CStringArray *pcsaPaths)
{
if (pcsaPaths -> GetSize() == 0)
{
return NULL;
}
if (pcsaPaths -> GetSize() == 1)
{
IWbemClassObject *pimcoClass = NULL;
pimcoClass = GetClassFromAnyNamespace(pcsaPaths -> GetAt(0));
if (pimcoClass)
{
return pimcoClass;
}
else
{
return NULL;
}
}
return LowestCommonParent(pcsaPaths);
}
BOOL CMultiViewCtrl::ClassInClasses(CStringArray *pcsaClasses, CString *pcsParent)
{
for (int i = 0; i < pcsaClasses -> GetSize();i++)
{
if (pcsParent -> CompareNoCase(pcsaClasses -> GetAt(i)) == 0)
{
return TRUE;
}
}
return FALSE;
}
void CMultiViewCtrl::ForceRedraw()
{
InvalidateControl();
}
SCODE CMultiViewCtrl::GetInstancesAsync
(IWbemServices * pIWbemServices, CString *pcsClass)
{
m_pServicesForAsyncSink = pIWbemServices;
m_csClassForAsyncSink = *pcsClass;
m_pAsyncEnumCancelled = FALSE;
m_pAsyncQueryCancelled = FALSE;
m_pAsyncEnumRunning = TRUE;
PostMessage(ID_ENUM_DOMODAL , 0,0);
PostMessage(ID_GETASYNCINSTENUMSINK,0,0);
return WBEM_NO_ERROR;
}
void CMultiViewGrid::OnCellDoubleClicked(int iRow, int iCol)
{
if (m_pParent -> m_nClassOrInstances == CMultiViewCtrl::NONE ||
m_pParent -> m_nClassOrInstances == CMultiViewCtrl::ZERO_CLASS_INST)
{
return;
}
CString *pcsPath =
reinterpret_cast<CString *>
(GetAt(iRow, 0).GetTagValue());
if (pcsPath)
{
CheckForSelectionChange();
m_pParent ->FireNotifyViewObjectSelected((LPCTSTR) *pcsPath);
}
}
void CMultiViewGrid::OnRequestUIActive()
{
m_pParent->OnRequestUIActive();
}
//************************************************************
// CMultiViewGrid::CheckForSelectionChange
//
// Check to see if the grid's row selection changed. If so,
// fire the SelectionChanged event.
//
// Parameters:
// None.
//
// Returns:
// Nothing.
//
//************************************************************
void CMultiViewGrid::CheckForSelectionChange()
{
int iRow;
if (m_pParent->m_bSelectionNotChanging)
{
return;
}
if (m_pParent -> m_nClassOrInstances == CMultiViewCtrl::NONE ||
m_pParent -> m_nClassOrInstances == CMultiViewCtrl::ZERO_CLASS_INST)
{
return;
}
iRow = GetSelectedRow();
m_pParent->FireNotifySelectionChanged();
m_iSelectedRow = iRow;
}
//***********************************************************
// CMultiViewGrid::OnRowHandleDoubleClicked
//
// The CGrid base class calls this method when a row handle
// is double clicked. When this happens, fire the "ViewObject"
// event.
//
// Parameters:
// [in] int iRow
//
// Returns:
// Nothing.
//
//************************************************************
void CMultiViewGrid::OnRowHandleDoubleClicked(int iRow)
{
if (m_pParent -> m_nClassOrInstances == CMultiViewCtrl::NONE ||
m_pParent -> m_nClassOrInstances == CMultiViewCtrl::ZERO_CLASS_INST)
{
return;
}
CString *pcsPath =
reinterpret_cast<CString *>
(GetAt(iRow, 0).GetTagValue());
if (pcsPath)
{
CheckForSelectionChange();
m_pParent -> FireNotifyViewObjectSelected((LPCTSTR) *pcsPath);
}
}
void CMultiViewGrid::SetRowEditFlag(int nRow, BOOL bEdit)
{
}
void CMultiViewGrid::OnCellClicked(int iRow, int iCol)
{
if(m_iSelectedRow != GetSelectedRow())
CheckForSelectionChange();
}
void CMultiViewGrid::OnSetToNoSelection()
{
m_pParent->FireNotifySelectionChanged();
SyncSelectionIndex();
}
void CMultiViewGrid::OnRowHandleClicked(int iRow)
{
SelectRow(iRow);
CheckForSelectionChange();
}
//**********************************************************************
// CMultiViewGrid::OnHeaderItemClick
//
// Catch the "header item clicked" notification message by overriding
// the base class' virtual method.
//
// Parameters:
// int iColumn
// The index of the column that was clicked.
//
// Returns:
// Nothing.
//
//***********************************************************************
void CMultiViewGrid::OnHeaderItemClick(int iColumn)
{
int iLastRow = GetRows()-1;
if (iLastRow > 0) {
SortGrid(0, iLastRow, iColumn);
BOOL bAscending = ColumnIsAscending(iColumn);
SetHeaderSortIndicator(iColumn, bAscending);
RedrawWindow();
}
}
//*******************************************************************
// CMultiViewGrid::CompareRows
//
// This is a virtual method override that compares two rows in the grid
// using the column index as the sort criteria.
//
// Parameters:
// int iRow1
// The index of the first row.
//
// int iRow2
// The index of the second row.
//
// int iSortColumn
// The column index.
//
// Returns:
// >0 if row 1 is greater than row 2
// 0 if row 1 equal zero
// <0 if row 1 is less than zero.
//
//********************************************************************
int CMultiViewGrid::CompareRows(int iRow1, int iRow2, int iSortColumn)
{
// First do a row comparison using the specified column as the
// primary key.
int iResult;
iResult = CompareCells(iRow1, iSortColumn, iRow2, iSortColumn);
if (iResult != 0) {
// The primary keys were not equal, so we have the result already.
return iResult;
}
// Control comes here if the primary keys were identical. Now we must
// compare the other columns to establish a sort order. To do this
// we iterate through all of the columns from left to right until
// we encounter a column that differentiates the two rows.
int nCols = GetCols();
for (int iCol=0; iCol < nCols; ++iCol) {
if (iCol == iSortColumn) {
// We already know these two columns are equal, so there is
// no sense in comparing them again.
continue;
}
iResult = CompareCells(iRow1, iCol, iRow2, iCol);
if (iResult != 0) {
break;
}
}
return iResult;
}
BSTR CMultiViewCtrl::GetNameSpace()
{
return m_csNameSpace.AllocSysString();
}
void CMultiViewCtrl::SetNameSpace(LPCTSTR lpszNewValue)
{
// TODO: Add your property handler here
if (GetSafeHwnd() && AmbientUserMode())
{
m_csNamespaceToInit = lpszNewValue;
OpenNamespace(0,0);
}
else if (GetSafeHwnd() && !AmbientUserMode())
{
m_csNameSpace = lpszNewValue;
SetModifiedFlag();
}
}
LRESULT CMultiViewCtrl::OpenNamespace(WPARAM, LPARAM)
{
CString csNameSpace = m_csNamespaceToInit;
m_csNamespaceToInit.Empty();
IWbemServices *pServices = InitServices(&csNameSpace);
if (pServices)
{
if (m_pServices)
{
m_pServices -> Release();
}
m_pServices = pServices;
m_csNameSpace = csNameSpace;
}
InitializeDisplay
(NULL, NULL, NULL);
SetModifiedFlag();
InvalidateControl();
return 0;
}
int CMultiViewCtrl::ObjectInGrid(CString *pcsPathIn)
{
int nNumRows = m_cgGrid.GetRows();
for (int i = 0; i < nNumRows; i++)
{
CString *pcsPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(i, 0).GetTagValue());
if (pcsPath->CompareNoCase(*pcsPathIn) == 0)
{
return i;
}
}
return -1;
}
long CMultiViewCtrl::SelectObjectByPath(LPCTSTR szObjectPath)
{
CString csPathIn = szObjectPath;
int nRow = ObjectInGrid(&csPathIn);
if (nRow > -1)
{
m_cgGrid.SelectRow(nRow);
m_cgGrid.CheckForSelectionChange();
InvalidateControl();
return S_OK;
}
else
{
return WBEM_E_NOT_FOUND;
}
}
//******************************************************
// CMultiViewGrid::IsNoInstanceRow
//
// This method checks to see if the specified row is
// the "No Instances Available" row. This special case
// occurs when the grid is logically empty, but this
// special row exists anyway so that the user sees that
// there are no instances.
//
// Parameters:
// [in] iRow
// The index of the row to test.
//
// Returns:
// TRUE if the specified row is the "No Instance Available"
// row, FALSE otherwise.
//
//*******************************************************
BOOL CMultiViewGrid::IsNoInstanceRow(int iRow)
{
if (iRow >= 0) {
CString *pcsPath =
reinterpret_cast<CString *>
(GetAt(iRow, 0).GetTagValue());
pcsPath->TrimRight();
if (pcsPath->IsEmpty())
{
return TRUE;
}
}
return FALSE;
}
BOOL CMultiViewGrid::OnRowKeyDown
(int iRow,UINT nChar, UINT nRepCnt, UINT nFlags)
{
CWnd* pwndFocus = GetFocus();
switch(nChar) {
case VK_DELETE:
{
if (!m_pParent->m_bCanEdit)
{
MessageBeep(MB_ICONEXCLAMATION);
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return TRUE;
}
int nRow = GetSelectedRow();
CString *pcsPath =
reinterpret_cast<CString *>
(GetAt(nRow, 0).GetTagValue());
pcsPath->TrimRight();
if (pcsPath->IsEmpty())
{
return TRUE;
}
long lPos;
CString sTitle;
lPos = m_pParent->StartObjectEnumeration(OBJECT_CURRENT);
if (lPos >= 0) {
sTitle = m_pParent->GetObjectTitle(lPos);
}
else {
ASSERT(FALSE);
sTitle = *pcsPath;
}
CString csPrompt;
csPrompt = _T("Do you want to delete \"") + sTitle;
csPrompt += _T("\"?");
int nReturn =
m_pParent -> MessageBox
(
csPrompt,
_T("Deleting an Instance"),
MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1 |
MB_APPLMODAL);
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
if (nReturn == IDYES)
{
SCODE sc;
BSTR bstrTemp = pcsPath -> AllocSysString();
sc = m_pParent->m_pServices ->
DeleteInstance(bstrTemp, NULL, 0, NULL);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
CString csUserMsg =
_T("Cannot delete instance ") + *pcsPath;
ErrorMsg
(&csUserMsg, sc, TRUE,
TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return TRUE;
}
m_pParent->ExternInstanceDeleted((LPCTSTR) *pcsPath);
}
}
return TRUE;
}
// We don't handle this event.
return FALSE;
}
LRESULT CMultiViewCtrl::DisplayNoInstances(WPARAM, LPARAM)
{
CString csMessage = _T("No Instances Available");
InitializeDisplay(NULL,NULL,NULL,&csMessage);
return 0;
}
LRESULT CMultiViewCtrl::InstEnumDone(WPARAM, LPARAM)
{
PostMessage(ID_ASYNCENUM_DONE,0,0);
m_pAsyncEnumRunning = FALSE;
return 0;
}
LRESULT CMultiViewCtrl::QueryDone(WPARAM, LPARAM)
{
PostMessage(ID_ASYNCQUERY_DONE,0,0);
m_pAsyncQueryRunning = FALSE;
return 0;
}
LRESULT CMultiViewCtrl::EnumDoModalDialog(WPARAM, LPARAM)
{
CWnd* pwndFocus = GetFocus();
m_pcaedDialog->DoModal();
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return 0;
}
LRESULT CMultiViewCtrl::SyncEnumDoModalDialog(WPARAM, LPARAM)
{
CWnd* pwndFocus = GetFocus();
m_pcsedDialog->DoModal();
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return 0;
}
LRESULT CMultiViewCtrl::QueryDoModalDialog(WPARAM, LPARAM)
{
CWnd* pwndFocus = GetFocus();
m_pcaqdDialog->DoModal();
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return 0;
}
LRESULT CMultiViewCtrl::AsyncEnumCancelled(WPARAM, LPARAM)
{
m_pAsyncEnumCancelled = TRUE;
if (m_pAsyncEnumRunning)
{
m_pAsyncEnumRunning = FALSE;
}
CString csMessage = _T("Instance retrieval operation cancelled");
InitializeDisplay(NULL,NULL,NULL,&csMessage);
theApp.DoWaitCursor(-1);
return 0;
}
LRESULT CMultiViewCtrl::AsyncQueryCancelled(WPARAM, LPARAM)
{
m_pAsyncQueryCancelled = TRUE;
if (m_pAsyncQueryRunning)
{
m_pAsyncQueryRunning = FALSE;
}
CString csMessage = _T("Instance retrieval operation cancelled");
InitializeDisplay(NULL,NULL,NULL,&csMessage);
for (int i = 0; i < m_cpaInstancesForQuery.GetSize(); i++)
{
IWbemClassObject *pObject =
reinterpret_cast<IWbemClassObject *>
(m_cpaInstancesForQuery.GetAt(i));
pObject->Release();
}
m_cpaInstancesForQuery.RemoveAll();
theApp.DoWaitCursor(-1);
return 0;
}
LRESULT CMultiViewCtrl::GetEnumSink(WPARAM, LPARAM)
{
CWnd* pwndFocus = GetFocus();
m_pInstEnumObjectSink = new CAsyncInstEnumSink(this);
#ifdef _DEBUG
ASSERT(m_pInstEnumObjectSink);
#endif
if (!m_pInstEnumObjectSink)
{
return FALSE;
}
m_pInstEnumObjectSink->AddRef();
m_nInstances = 0;
BSTR bstrTemp = m_csClass.AllocSysString();
SCODE sc = m_pServices->CreateInstanceEnumAsync
(bstrTemp,
WBEM_FLAG_DEEP | WBEM_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
NULL,
(IWbemObjectSink *) m_pInstEnumObjectSink );
::SysFreeString(bstrTemp);
#ifdef _DEBUG
ASSERT(sc == S_OK);
#endif
if(sc != S_OK)
{
CString csUserMsg;
csUserMsg = _T("Ascyronous instance enumeration failed for class: ") + m_csClass;
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__);
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
m_pInstEnumObjectSink->Release();
return FALSE;
}
return S_OK;
}
LRESULT CMultiViewCtrl::GetQuerySink(WPARAM, LPARAM)
{
CWnd* pwndFocus = GetFocus();
m_pAsyncQuerySink = new CAsyncQuerySink(this);
if (!m_pAsyncQuerySink)
{
return FALSE;
}
m_pAsyncQuerySink->AddRef();
m_nInstances = 0;
BSTR bstrTemp1 = m_csQueryTypeForAsyncSink.AllocSysString();
BSTR bstrTemp2 = m_csQueryForAsyncSink.AllocSysString();
SCODE sc = m_pServices->
ExecQueryAsync
( bstrTemp1,
bstrTemp2,
0,
NULL,
(IWbemObjectSink *) m_pAsyncQuerySink);
::SysFreeString(bstrTemp1);
::SysFreeString(bstrTemp2);
if(sc != S_OK)
{
CString csUserMsg;
csUserMsg = _T("Ascyronous query failed for query: ") + m_csQueryForAsyncSink;
ErrorMsg
(&csUserMsg, sc, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__);
m_pAsyncQuerySink->Release();
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return FALSE;
}
return S_OK;
}
BOOL CMultiViewCtrl::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if (pMsg->message == ID_DISPLAYNOINSTANCES)
{
DisplayNoInstances(0,0);
return TRUE;
}
if (pMsg->message == ID_INSTENUMDONE)
{
InstEnumDone(0,0);
return TRUE;
}
if (pMsg->message == ID_QUERYDONE)
{
QueryDone(0,0);
return TRUE;
}
return COleControl::PreTranslateMessage(pMsg);
}
void CMultiViewCtrl::OnDestroy()
{
delete m_pcsedDialog;
delete m_pcaedDialog;
delete m_pcaqdDialog;
delete m_pProgressDlg;
COleControl::OnDestroy();
}
void CMultiViewCtrl::QueryViewInstances
(LPCTSTR szTitle, LPCTSTR szQueryType, LPCTSTR szQuery, LPCTSTR szClass)
{
CString csQuery = szQuery;
// This really, really wants to return an scode.
//if (!szQuery || !szQueryType || !(csQuery.CompareNoCase("WQL")))
//{
// return;
//}
m_pcmvcCurrentContext->~CMVContext();
m_pcmvcCurrentContext->AddRef();
m_pcmvcCurrentContext->GetType() = CMVContext::Query;
m_pcmvcCurrentContext->GetLabel() = szTitle;
m_pcmvcCurrentContext->GetQuery() = szQuery;
m_pcmvcCurrentContext->GetQueryType() = szQueryType;
m_pcmvcCurrentContext->GetClass() = szClass;
m_pcmvcCurrentContext->GetNamespace() = m_csNameSpace;
if (IsWindowVisible())
{
NotifyWillShow();
}
DestroyProgressDlgWindow();
}
void CMultiViewCtrl::QueryViewInstancesSync
(LPCTSTR szTitle, LPCTSTR szQueryType, LPCTSTR szQuery, LPCTSTR szClass)
{
//
// There are two things that need to be done to QueryViewInstances.
//
// 1. The multiview control needs to implement delayed data loading if
// it is currently currently hidden.
//
// 2. The container now passes the title (label) though to the multiview
// control. The multiview control needs to make this title available
// via the GetTitle method.
//
// The delayed rendering is necessary because the container now passes
// calls to the multiview though immediately even if the multiview is
// hidden. Now the multiview is responsible for delaying the execution
// of these calls until it is made visible again.
//
// CWaitCursor wait;
CString csClass = szClass;
if (csClass.GetLength() > 0)
{
QueryViewInstancesSyncWithClass
(szTitle,szQueryType,szQuery,szClass);
}
else
{
QueryViewInstancesSyncWithoutClass
(szTitle,szQueryType,szQuery);
}
DestroyProgressDlgWindow();
}
void CMultiViewCtrl::QueryViewInstancesSyncWithoutClass
(LPCTSTR szTitle, LPCTSTR szQueryType, LPCTSTR szQuery)
{
//
// There are two things that need to be done to QueryViewInstances.
//
// 1. The multiview control needs to implement delayed data loading if
// it is currently currently hidden.
//
// 2. The container now passes the title (label) though to the multiview
// control. The multiview control needs to make this title available
// via the GetTitle method.
//
// The delayed rendering is necessary because the container now passes
// calls to the multiview though immediately even if the multiview is
// hidden. Now the multiview is responsible for delaying the execution
// of these calls until it is made visible again.
//
SCODE sc;
CString csQuery = szQuery;
CString csMessage =
_T("Executing query: ") + csQuery + _T(".");
SetProgressDlgMessage(csMessage);
if (!m_pProgressDlg->GetSafeHwnd())
{
CreateProgressDlgWindow();
}
CString csQueryType = szQueryType;
IWbemClassObject *pCommonParent = NULL;
m_csaProps.RemoveAll();
m_csClass = _T("");
m_nClassOrInstances = INSTANCES;
InitializeDisplay(NULL, NULL, NULL);
#ifdef _DEBUG
// afxDump << "ExecQuery in QueryViewInstancesSyncWithoutClass = " << csQuery << "\n";
#endif
IEnumWbemClassObject *pecoInstances =
ExecQuery(m_pServices, csQueryType, csQuery, m_csNameSpace);
BOOL bCancel = CheckCancelButtonProgressDlgWindow();
if (bCancel)
{
csMessage = _T("Operation Canceled");
InitializeDisplay(NULL,NULL,NULL,&csMessage);
if (pecoInstances)
{
pecoInstances->Release();
pecoInstances = NULL;
}
}
CPtrArray *pcpaInstances = NULL;
if (pecoInstances)
{
sc = SemiSyncQueryInstancesNonincrementalAddToDisplay
(pcpaInstances, pecoInstances, bCancel);
}
int nInstances = pcpaInstances? (int) pcpaInstances->GetSize() : 0;
if (nInstances == 0)
{
m_nClassOrInstances = CMultiViewCtrl::NONE;
CString csMessage;
if (bCancel)
{
csMessage = _T("Operation Canceled");
}
else
{
csMessage = _T("No Instances Available");
}
InitializeDisplay(NULL,NULL,NULL,&csMessage);
delete pcpaInstances;
return;
}
int i;
CStringArray csaClasses;
CString csClass;
if (nInstances > 0)
{
for (i = 0; i < nInstances; i++)
{
IWbemClassObject *pInstance =
reinterpret_cast<IWbemClassObject *>
(pcpaInstances->GetAt(i));
ASSERT (pInstance);
csClass = GetIWbemClassPath(m_pServices ,pInstance);
if (csClass.IsEmpty()) {
continue;
}
if (!ClassInClasses(&csaClasses,&csClass))
{
csaClasses.Add(csClass);
}
}
//if we could retrieve class names for some instances
if (csaClasses.GetSize() != 0) {
pCommonParent = CommonParent(&csaClasses);
}
m_csaProps.RemoveAll();
m_nClassOrInstances = INSTANCES;
if (!pCommonParent)
{
//get sorted properties for each instance, then find least common denominator
for (i = 0; i < nInstances; i++) {
IWbemClassObject *pInstance =
reinterpret_cast<IWbemClassObject *>(pcpaInstances->GetAt(i));
CStringArray csaProps;
int nProps = GetSortedPropNames (pInstance, csaProps, m_cmstpPropFlavors);
//initialize resulting property array
if (i == 0) {
m_csaProps.Copy(csaProps);
}
//intersect resulting array with the current one
IntersectInPlace(m_csaProps, csaProps);
}
m_csClass = _T("");
InitializeDisplay(NULL, NULL, &m_csaProps, NULL, &m_cmstpPropFlavors);
}
else
{
int nProps = GetSortedPropNames (pCommonParent, m_csaProps, m_cmstpPropFlavors);
pCommonParent -> Release();
m_csClass = _T("");
InitializeDisplay(NULL, NULL, &m_csaProps, NULL, &m_cmstpPropFlavors);
}
}
AddToDisplay(pcpaInstances);
delete pcpaInstances;
}
SCODE CMultiViewCtrl::SemiSyncQueryInstancesNonincrementalAddToDisplay
(CPtrArray *& pcpaObjects, IEnumWbemClassObject *pemcoObjects, BOOL &bCancel)
{
ASSERT(pcpaObjects == NULL);
if (!pemcoObjects)
return E_FAIL;
pcpaObjects = new CPtrArray;
pemcoObjects -> Reset();
IWbemClassObject *pObject = NULL;
ULONG uReturned = 0;
HRESULT hResult = S_OK;
IWbemClassObject *pimcoInstances[N_INSTANCES];
IWbemClassObject **pInstanceArray =
reinterpret_cast<IWbemClassObject **> (&pimcoInstances);
int i;
for (i = 0; i < N_INSTANCES; i++)
{
pimcoInstances[i] = NULL;
}
IWbemClassObject *pimcoInstance = NULL;
#ifdef _DEBUG
// afxDump << "Next in SemiSyncQueryInstancesNonincrementalAddToDisplay\n";
#endif
hResult =
pemcoObjects->Next(ENUM_TIMEOUT, N_INSTANCES,pInstanceArray, &uReturned);
int cInst = 0;
while(hResult == S_OK || hResult == WBEM_S_TIMEDOUT || uReturned > 0)
{
if (!m_pProgressDlg->GetSafeHwnd())
{
CreateProgressDlgWindow();
}
else
{
bCancel = CheckCancelButtonProgressDlgWindow();
}
if (bCancel)
{
int i;
#pragma warning( disable :4018 )
for (i = 0; i < uReturned; i++)
#pragma warning( default : 4018 )
{
pimcoInstances[i]->Release();
pimcoInstances[i] = NULL;
}
cInst = 0;
for (i = 0; i < pcpaObjects->GetSize(); i++)
{
IWbemClassObject *pObject =
reinterpret_cast<IWbemClassObject *>
(pcpaObjects->GetAt(i));
pObject->Release();
}
pcpaObjects->RemoveAll();
break;
}
#pragma warning( disable :4018 )
for (int i = 0; i < uReturned; i++)
#pragma warning( default : 4018 )
{
pcpaObjects->Add(reinterpret_cast<void *>(pimcoInstances[i]));
pimcoInstances[i] = NULL;
}
cInst += uReturned;
uReturned = 0;
#ifdef _DEBUG
// afxDump << "Next in SemiSyncQueryInstancesNonincrementalAddToDisplay\n";
#endif
hResult = pemcoObjects->Next
(0,N_INSTANCES,pInstanceArray, &uReturned);
}
pemcoObjects -> Release();
DestroyProgressDlgWindow();
if (FAILED(hResult)) {
CString csUserMsg =
_T("An error occurred while attempting to retrieve the list of objects.");
HWND hwndFocus = ::GetFocus();
ErrorMsg
(&csUserMsg, hResult, TRUE,
TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
if (::IsWindow(hwndFocus) && ::IsWindowVisible(hwndFocus)) {
::SetFocus(hwndFocus);
}
}
return S_OK;
}
void CMultiViewCtrl::QueryViewInstancesSyncWithClass
(LPCTSTR szTitle, LPCTSTR szQueryType, LPCTSTR szQuery, LPCTSTR szClass)
{
//
// There are two things that need to be done to QueryViewInstances.
//
// 1. The multiview control needs to implement delayed data loading if
// it is currently currently hidden.
//
// 2. The container now passes the title (label) though to the multiview
// control. The multiview control needs to make this title available
// via the GetTitle method.
//
// The delayed rendering is necessary because the container now passes
// calls to the multiview though immediately even if the multiview is
// hidden. Now the multiview is responsible for delaying the execution
// of these calls until it is made visible again.
//
// CWaitCursor wait;
CString csQuery = szQuery;
CString csMessage =
_T("Executing query: ") + csQuery + _T(".");
SetProgressDlgMessage(csMessage);
CString csClass = szClass;
CString csQueryType = szQueryType;
IWbemClassObject *pCommonParent = NULL;
SCODE sc;
pCommonParent = GetClassFromAnyNamespace(csClass);
if (!pCommonParent)
{
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot get class object ") + csClass;
ErrorMsg
(&csUserMsg, m_sc, FALSE,TRUE, &csUserMsg, __FILE__,
__LINE__ - 9);
return;
}
#ifdef _DEBUG
// afxDump << "ExecQuery in QueryViewInstancesSyncWithClass = " << csQuery << "\n";
#endif
IEnumWbemClassObject *pecoInstances =
ExecQuery(m_pServices, csQueryType, csQuery, m_csNameSpace);
if (pecoInstances == NULL)
{
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot get enumeration for ") + csQuery;
CWnd* pwndFocus = GetFocus();
ErrorMsg
(&csUserMsg, S_OK, FALSE,TRUE, &csUserMsg, __FILE__,
__LINE__ );
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return;
}
m_csaProps.RemoveAll();
int nProps = GetSortedPropNames (pCommonParent, m_csaProps, m_cmstpPropFlavors);
pCommonParent -> Release();
m_csClass = _T("");
m_nClassOrInstances = INSTANCES;
InitializeDisplay(NULL, NULL, &m_csaProps, NULL, &m_cmstpPropFlavors);
CPtrArray *pcpaInstances = new CPtrArray;
BOOL bCancel= FALSE;
int cInst = 0;
sc = SemiSyncQueryInstancesIncrementalAddToDisplay
(m_pServices, pecoInstances, *pcpaInstances, cInst, bCancel);
pecoInstances -> Release();
if (cInst == 0)
{
m_nClassOrInstances = CMultiViewCtrl::NONE;
CString csMessage = _T("No Instances Available");
InitializeDisplay(NULL,NULL,NULL,&csMessage);
delete pcpaInstances;
return;
}
delete pcpaInstances;
}
SCODE CMultiViewCtrl::SemiSyncQueryInstancesIncrementalAddToDisplay
(IWbemServices * pIWbemServices, IEnumWbemClassObject *pimecoInstanceEnum,
CPtrArray &cpaInstances,int &cInst, BOOL &bCancel)
{
cInst = 0;
bCancel = 0;
SCODE sc = S_OK;
if(pimecoInstanceEnum == NULL)
{
return sc;
}
sc = pimecoInstanceEnum->Reset();
IWbemClassObject *pimcoInstances[N_INSTANCES];
IWbemClassObject **pInstanceArray =
reinterpret_cast<IWbemClassObject **> (&pimcoInstances);
int i;
for (i = 0; i < N_INSTANCES; i++)
{
pimcoInstances[i] = NULL;
}
IWbemClassObject *pimcoInstance = NULL;
ULONG uReturned = 0;
#ifdef _DEBUG
// afxDump << "Next in SemiSyncQueryInstancesIncrementalAddToDisplay\n";
#endif
sc = pimecoInstanceEnum->Next(ENUM_TIMEOUT,N_INSTANCES,pInstanceArray, &uReturned);
CString csPath = m_csSyncEnumClass;
m_csClass = csPath;
m_nClassOrInstances = CLASS;
while (sc == S_OK || sc == WBEM_S_TIMEDOUT || uReturned > 0)
{
if (!m_pProgressDlg->GetSafeHwnd())
{
CreateProgressDlgWindow();
}
else
{
PumpMessagesProgressDlgWindow();
}
cpaInstances.RemoveAll();
#pragma warning( disable :4018 )
for (int i = 0; i < uReturned; i++)
#pragma warning( default : 4018 )
{
cpaInstances.Add(reinterpret_cast<void *>(pimcoInstances[i]));
pimcoInstances[i] = NULL;
}
if (uReturned > 0)
{
AddToDisplay(&cpaInstances);
}
cInst += uReturned;
uReturned = 0;
#ifdef _DEBUG
// afxDump << "Next in SemiSyncQueryInstancesIncrementalAddToDisplay\n";
#endif
sc = pimecoInstanceEnum->Next(ENUM_TIMEOUT, N_INSTANCES,pInstanceArray, &uReturned);
}
DestroyProgressDlgWindow();
if (FAILED(sc)) {
CString csUserMsg =
_T("An error occurred while attempting to retrieve the list of objects.");
ErrorMsg
(&csUserMsg, sc, TRUE,
TRUE, &csUserMsg, __FILE__, __LINE__ - 6);
}
return sc;
}
void CMultiViewCtrl::QueryViewInstancesAsync(LPCTSTR szTitle, LPCTSTR szQueryType, LPCTSTR szQuery, LPCTSTR szClass)
{
//
// There are two things that need to be done to QueryViewInstances.
//
// 1. The multiview control needs to implement delayed data loading if
// it is currently currently hidden.
//
// 2. The container now passes the title (label) though to the multiview
// control. The multiview control needs to make this title available
// via the GetTitle method.
//
// The delayed rendering is necessary because the container now passes
// calls to the multiview though immediately even if the multiview is
// hidden. Now the multiview is responsible for delaying the execution
// of these calls until it is made visible again.
//
CString csClass = szClass;
CString csQueryType = szQueryType;
CString csQuery = szQuery;
IWbemClassObject *pimcoClass = NULL;
if (csClass.GetLength() > 0)
{
//SCODE sc;
pimcoClass = GetClassFromAnyNamespace(csClass);
if (!pimcoClass)
{
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot get class object ") + csClass;
CWnd* pwndFocus = GetFocus();
ErrorMsg
(&csUserMsg, m_sc, FALSE,TRUE, &csUserMsg, __FILE__,
__LINE__ - 9);
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return;
}
m_csaProps.RemoveAll();
int nProps = GetSortedPropNames (pimcoClass, m_csaProps, m_cmstpPropFlavors);
pimcoClass -> Release();
m_csClass = _T("");
m_nClassOrInstances = INSTANCES;
InitializeDisplay(NULL, NULL, &m_csaProps, NULL, &m_cmstpPropFlavors);
}
else
{
m_csaProps.RemoveAll();
m_csClass = _T("");
m_nClassOrInstances = INSTANCES;
InitializeDisplay(NULL, NULL, NULL);
}
m_csClassForAsyncSink = csClass;
m_csQueryForAsyncSink = csQuery;
m_csQueryTypeForAsyncSink = csQueryType;
m_pcaqdDialog->SetClass(&csClass);
m_pcaqdDialog->SetQueryType(&csQueryType);
m_pcaqdDialog->SetQuery(&csQuery);
GetQueryInstancesAsync
(m_pServices, &csQueryType, &csQuery);
}
//*************************************************************
// CMultiViewCtrl::CreateInstance
//
// Create an instance of the current class.
//
//
// Parameters:
// None.
//
// Returns:
// SCODE
// S_OK if the operation was successful, E_FAIL otherwise.
//
//**************************************************************
SCODE CMultiViewCtrl::CreateInstance()
{
//
// Please send your comments to me regarding the design
// of the interface for "Create" and "Delete".
//
// I am not yet clear on how the multiview should handle
// CreateInstance. This is because of goals:
// 1. The multiview should be able to work in the absence
// of the single view. In this case what does CreateInstance
// mean since the single view will not be available for
// editing the newly created instance.
//
// 2. The views have the greatest flexibility if they are
// in control of "creation" and "deletion" as it allows
// the view to attach their own semantics to these actions.
//
// 3. When using the multiview as a stand-alone control, it
// would make the multiview more powerful and easy to use
// if it could handle instance creation/deletion.
//
// 4. Create and delete can originate from within the multiview
// though keyboard events that are sent to the multiview
// control.
//
return E_NOTIMPL;
}
//*************************************************************
// CMultiViewCtrl::DeleteInstance
//
// Delete the currently selected object.
//
//
// Parameters:
// None.
//
// Returns:
// SCODE
// S_OK if the operation was successful, E_FAIL otherwise.
//
//**************************************************************
SCODE CMultiViewCtrl::DeleteInstance()
{
//
// I am not yet satisfied with the interface for create and delete.
// Please review the my comments in CMultiViewCtrl::CreateInstance and
// send your comments to me regarding any improvements to this design.
//
// The container calls this method when the "Delete Instance" button
// is clicked and the multiview is visible. The multiview is now
// responsible for deleting whatever it is that it wants to delete.
// This will typically be an instance of the current class.
//
// The container will call this method only if the QueryCanDeleteInstance
// method returns TRUE. The container checks this when the multiview is
// first made visible and whenever it gets a FireNotifyViewModified event.
long lPosition = StartObjectEnumeration(OBJECT_CURRENT);
CString csPath;
if (lPosition > -1)
{
csPath = GetObjectPath(lPosition);
}
else
{
return WBEM_E_FAILED;
}
if (csPath.GetLength() > 0)
{
SCODE sc;
IWbemClassObject *pObject = NULL;
BSTR bstrTemp = csPath.AllocSysString();
sc =
m_pServices ->
DeleteInstance(bstrTemp,0, NULL,NULL);
::SysFreeString(bstrTemp);
if (sc == S_OK)
{
CString *pcsPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(lPosition, 0).GetTagValue());
delete pcsPath;
m_cgGrid.DeleteRowAt(lPosition);
if (m_cgGrid.GetRows() == 0) {
NotifyWillShow();
}
m_cgGrid.CheckForSelectionChange();
InvalidateControl();
return S_OK;
}
else
{
CString *pcsPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(lPosition, 0).GetTagValue());
CString csUserMsg;
csUserMsg = _T("Cannot delete object ") + *pcsPath;
CWnd* pwndFocus = GetFocus();
ErrorMsg
(&csUserMsg, sc, TRUE, TRUE, &csUserMsg, __FILE__,
__LINE__ - 7);
if (pwndFocus && ::IsWindow(pwndFocus->m_hWnd)) {
pwndFocus->SetFocus();
}
return sc;
}
}
else
{
return WBEM_E_FAILED;
}
}
//*************************************************************
// CMultiViewCtrl::GetContext
//
// Get a handle to the current multiview context by allocating
// a multiview context object, storing a snapshot of the current
// state in the context object, and returning a handle to the
// newly created context object.
//
// The container may use this handle later to restore the multivew
// to a previous state.
//
// Parameters:
// [out] long FAR* pCtxHandle
// The place to return the context handle.
//
// Returns:
// SCODE
// S_OK if the operation was successful, E_FAIL otherwise.
//
//**************************************************************
SCODE CMultiViewCtrl::GetContext(long FAR* pCtxHandle)
{
// The container calls this method to save the current state of the
// multiview in a context object. When this method is called, a new
// context handle needs to be created, the current state is saved in
// it and a handle to the context object is returned. The intial
// reference count on the context object is assumed to be 1.
//
// I expect that the context handles will actually be a pointer
// to some context object of your own design that has been cast to a
// long. To the container the context handles are just long integers.
//if (m_pcmvcCurrentContext->GetType() == CMVContext::Unitialized)
//{
// A NULL handle means restore to the uninitialized state.
// *pCtxHandle = NULL;
// return S_OK;
//}
CMVContext *pNewContext;
if (m_pcmvcCurrentContext)
{
pNewContext = new CMVContext(*m_pcmvcCurrentContext);
}
else
{
pNewContext = new CMVContext;
}
if (!pNewContext)
{
return WBEM_E_FAILED;
}
pNewContext->AddRef();
// BUGBUG: HACK: WE SHOULD NOT BE PASSING A POINTER THROUGH AN AUTOMATION INTERFACE!!!
#ifdef _WIN64
ASSERT(FALSE);
*pCtxHandle = NULL;
#else
*pCtxHandle = reinterpret_cast<long>(pNewContext);
#endif
return S_OK;
}
//*************************************************************
// CMultiViewCtrl::AddContextRef
//
// Restore the multiview's context to the state specified by the
// given view context handle.
//
// Parameters:
// [in] long lCtxtHandle
// The view context handle.
//
// Returns:
// SCODE
// S_OK if the operation was successful, E_FAIL otherwise.
//
//**************************************************************
SCODE CMultiViewCtrl::RestoreContext(long lCtxtHandle)
{
// The container calls this method to restore the
// multiview to a previously saved state. The state is stored in
// an object identified by the context handle.
//
// I expect that the context handles will actually be a pointer
// to some context object of your own design that has been cast to a
// long. To the container the context handles are just long integers.
CMVContext *pNewContext;
if (lCtxtHandle == 0)
{
pNewContext = new CMVContext;
}
else
{
pNewContext = reinterpret_cast<CMVContext*>(lCtxtHandle);
}
if (!pNewContext)
{
return WBEM_E_FAILED;
}
if (m_pcmvcCurrentContext->IsContextEqual(*pNewContext))
{
if (IsWindowVisible())
{
NotifyWillShow();
}
return S_OK;
}
*m_pcmvcCurrentContext = *pNewContext;
m_pcmvcCurrentContext->AddRef();
if (m_pcmvcCurrentContext->GetNamespace().GetLength() > 0 &&
m_pcmvcCurrentContext->GetNamespace().CompareNoCase(m_csNameSpace))
{
SetNameSpace(m_pcmvcCurrentContext->GetNamespace());
}
if (IsWindowVisible())
{
NotifyWillShow();
}
return S_OK;
}
//*************************************************************
// CMultiViewCtrl::AddContextRef
//
// Increment the reference count on the specified context handle.
//
// Parameters:
// [in] long lCtxtHandle
// The view context handle.
//
// Returns:
// SCODE
// S_OK if the operation was successful, E_FAIL otherwise.
//
//**************************************************************
SCODE CMultiViewCtrl::AddContextRef(long lCtxtHandle)
{
// The container calls this method to increment the reference count
// of the specified context object.
//
// I expect that the context handles will actually be a pointer
// to some context object of your own design that has been cast to a
// long. To the container the context handles are just long integers.
CMVContext *pContext = reinterpret_cast<CMVContext*>(lCtxtHandle);
if (!pContext)
{
return WBEM_E_FAILED;
}
pContext->AddRef();
return S_OK;
}
//*************************************************************
// CMultiViewCtrl::ReleaseContext
//
// Decrement the reference count on the specified view context handle.
// If the reference count goes to zero, delete the corresponding
// view context.
//
// Parameters:
// [in] long lCtxtHandle
// The view context handle.
//
// Returns:
// SCODE
// S_OK if the operation was successful, E_FAIL otherwise.
//
//**************************************************************
SCODE CMultiViewCtrl::ReleaseContext(long lCtxtHandle)
{
if (lCtxtHandle == 0) {
// !!!Judy: A null context handle corresponds to "uninitialized:
return S_OK;
}
// The container calls this method to release the specified
// context handle. When the context handle's reference count
// goes to zero, the context can be deleted.
//
// I expect that the context handles will actually be a pointer
// to some context object of your own design that has been cast to a
// long. To the container the context handles are just long integers.
CMVContext *pContext = reinterpret_cast<CMVContext*>(lCtxtHandle);
pContext->Release();
return S_OK;
}
//*********************************************************
// CMultiViewCtrl::SetEditMode
//
// Set the edit mode flag.
//
// Parameters:
// [in] BOOL bCanEdit
// TRUE if the view can be edited (studio mode),
// FALSE if the data can not be edited (browser mode).
//
// Returns:
// Nothing.
//
//*********************************************************
void CMultiViewCtrl::SetEditMode(long bCanEdit)
{
// The container passes the "studio mode" flag to you here.
// bCanEdit will be TRUE if the container is in studio mode,
// and FALSE if it is in browse mode.
m_bCanEdit = bCanEdit;
}
//*************************************************************
// CMultiViewCtrl::GetEditMode
//
// Get the current edit mode.
//
// Parameters:
// None.
//
// Returns:
// BOOL
// TRUE if editing is enabled (studio mode).
// FALSE if editing is disabled (browser mode).
//
//**************************************************************
long CMultiViewCtrl::GetEditMode()
{
return m_bCanEdit;
}
//*************************************************************
// CMultiViewCtrl::GetTitle
//
// Get the multiview's title and picture that will be displayed
// in the container's titlebar. This title and picture should
// correspond to the currently selected object.
//
// Parameters:
// [out] BSTR FAR* pbstrTitle
// The place to return the title.
//
// [out] LPDISPATCH FAR* lpPictDisp
// The place to return the picture to be displayed as the
// object's icon in the container's titlebar.
//
//**************************************************************
SCODE CMultiViewCtrl::GetTitle(BSTR FAR* pbstrTitle, LPDISPATCH FAR* lpPictDisp)
{ //
// This is the method that the container calls to get the title and
// icon that appear in the container's titlebar. The title and icon
// should correspond to the currently selected instance, class, and
// so on.
//
// You can see how this is done in the SingleView by looking at the
// following methods:
//
// CSingleViewCtrl::GetTitle SingleView\SingleViewCtl.cpp
// CSelection::GetObjectDescription SingleView\Path.cpp
// CSelection::GetPictureDispatch SingleView\Path.cpp
//
if (m_pcmvcCurrentContext->GetLabel().GetLength() > 0)
{
*pbstrTitle = m_pcmvcCurrentContext->GetLabel().AllocSysString();
CString csLabel = *pbstrTitle;
BOOL bGroup;
if (csLabel.Right(5).CompareNoCase(_T("Group")) == 0)
{
bGroup = TRUE;
}
else
{
bGroup = FALSE;
}
CPictureHolder *pPicture = new CPictureHolder;
HICON hIcon;
if (bGroup)
{
hIcon = theApp.LoadIcon(IDI_ICONOJBG);
}
else
{
hIcon = theApp.LoadIcon(IDI_ICONASSOCROLE);
}
if (hIcon)
{
pPicture->CreateFromIcon(hIcon,TRUE);
*lpPictDisp = pPicture->GetPictureDispatch();
}
else
{
*lpPictDisp = NULL;
}
return S_OK;
}
else
{
// Get Class Icon
*pbstrTitle = m_pcmvcCurrentContext->GetClass().AllocSysString();
CString csClass = *pbstrTitle;
IWbemClassObject *pClass = NULL;
if (!m_pServices)
{
*lpPictDisp = NULL;
return S_OK;
}
BSTR bstrTemp = csClass.AllocSysString();
#ifdef _DEBUG
// afxDump << "GetObject in GetTitle for " << csClass << "\n";
#endif
SCODE sc =
m_pServices ->
GetObject(bstrTemp,0, NULL, &pClass, NULL);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
*lpPictDisp = NULL;
return sc;
}
CString csAttribName = _T("Icon");
CString csIconPath = GetBSTRAttrib(pClass, NULL , &csAttribName);
if (csIconPath.GetLength() == 0)
{
csIconPath = csClass;
}
CPictureHolder *pPicture = new CPictureHolder;
HICON hIcon = NULL;
if (csIconPath.GetLength() > 0)
{
hIcon = ::WBEMGetIcon((LPCTSTR)csIconPath);
}
if (hIcon)
{
pPicture->CreateFromIcon(hIcon,TRUE);
*lpPictDisp = pPicture->GetPictureDispatch();
}
else
{
hIcon = theApp.LoadIcon(IDI_ICONPLACEH);
if (hIcon)
{
pPicture->CreateFromIcon(hIcon,TRUE);
*lpPictDisp = pPicture->GetPictureDispatch();
}
else
{
delete pPicture;
*lpPictDisp = NULL;
}
}
return S_OK;
}
}
HICON CMultiViewCtrl::LoadIcon(CString pcsFile)
{
SIZE size;
size.cx = CX_SMALL_ICON;
size.cy = CY_SMALL_ICON;
HICON hIcon = (HICON) ::LoadImage(NULL, pcsFile, IMAGE_ICON,
size.cx, size.cy, LR_LOADFROMFILE);
return hIcon;
}
//*****************************************************************
// CMultiViewCtrl::ExternInstanceCreated
//
// The container calls this method to notify the multiview control
// that the container deleted an object instance. This gives the
// multiview a chance to remove the instance from its list if necessary.
//
// Parameters:
// [in] LPCTSTR szObjectPath
// The HMOM object path of the instance that was Created (wouldn't
// a uniform object identifier be nice here?)
//
// Returns:
// Nothing.
//
//********************************************************************
void CMultiViewCtrl::ExternInstanceCreated(LPCTSTR szObjectPath)
{
if (m_nClassOrInstances != CMultiViewCtrl::CLASS &&
m_nClassOrInstances != CMultiViewCtrl::ZERO_CLASS_INST)
{
return;
}
CString csPath = szObjectPath;
IWbemClassObject *pimcoObject = NULL;
BSTR bstrTemp = csPath.AllocSysString();
#ifdef _DEBUG
// afxDump << "GetObject in ExternInstanceCreated for " << csPath << "\n";
#endif
SCODE sc =
m_pServices ->
GetObject(bstrTemp,0, NULL, &pimcoObject, NULL);
::SysFreeString(bstrTemp);
if(sc != S_OK)
{
CString csUserMsg;
csUserMsg = _T("Cannot get object ") + csPath;
ErrorMsg
(&csUserMsg, sc, TRUE, TRUE, &csUserMsg, __FILE__,
__LINE__ - 7);
return;
}
CString csClassPath =
GetIWbemFullPath(m_pServices, pimcoObject);
CString csClass =
GetIWbemClass(m_pServices, pimcoObject);
pimcoObject->Release();
if (m_csClass.CompareNoCase(m_csClass) == 0)
{
ViewClassInstances((LPCTSTR) csClass);
}
InvalidateControl();
return;
}
//************************************************************
// CMultiViewCtrl::ExternInstanceDeleted
//
// The container calls this method when an instance is deleted.
//
// Parameters:
// None.
//
// Returns:
// Nothing.
//
//*************************************************************
void CMultiViewCtrl::ExternInstanceDeleted(LPCTSTR szObjectPath)
{
if (m_nClassOrInstances == CMultiViewCtrl::NONE ||
m_nClassOrInstances == CMultiViewCtrl::ZERO_CLASS_INST)
{
return;
}
int nRows = m_cgGrid.GetRows();
if (nRows == 0)
{
return;
}
CString csPath = szObjectPath;
int nRow = ObjectInGrid(&csPath);
if (nRow == -1)
{
return;
}
CString *pcsPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(nRow, 0).GetTagValue());
delete pcsPath;
m_cgGrid.DeleteRowAt(nRow);
nRows = m_cgGrid.GetRows();
if (nRows == 0 && GetSafeHwnd() && (IsWindowVisible()))
{
CString csMessage = _T("No Instances Available");
InitializeDisplay(NULL,NULL,NULL,&csMessage);
}
InvalidateControl();
}
//************************************************************
// CMultiViewCtrl::NotifyWillShow
//
// The container calls this method just prior to performing
// a ShowWindow(SW_SHOW) on the multiview window.
//
// Parameters:
// None.
//
// Returns:
// Nothing.
//
//************************************************************
void CMultiViewCtrl::NotifyWillShow()
{
//
// Now the container passes though calls to the multiview
// immediately even if the multiview is currently hidden. To avoid
// the performance hits we experienced in the past, the multiview
// will be responsible for implementing "delayed" loading where the
// data is loaded at the time the multiview becomes visible.
//
// The container calls NotifyWillShow just prior to making the
// multiview visible. This is the multiview's chance to do any
// data loading that might have been delayed.
//
// Of course it would be nice if multiview could do its data loading
// asyncrhonously in the backgound even if it is currenly hidden so long
// as the user wouldn't experience a big performance hit.
if (m_pcmvcCurrentContext->IsDrawn() == FALSE || m_bPropFilterFlagsChanged)
{
if ((m_pcmvcCurrentContext->GetNamespace().IsEmpty() || m_csNameSpace.IsEmpty())
&& m_pcmvcCurrentContext->GetType() != CMVContext::Unitialized)
{
CString csUserMsg;
csUserMsg = _T("A namespace must be opened before you can view instances.");
ErrorMsg
(&csUserMsg, S_OK, FALSE, TRUE, &csUserMsg, __FILE__,
__LINE__ );
return;
}
m_pcmvcCurrentContext->IsDrawn() = TRUE;
m_bPropFilterFlagsChanged = FALSE;
if (m_pcmvcCurrentContext->GetType() == CMVContext::Class)
{
ViewClassInstancesSync(m_pcmvcCurrentContext->GetClass());
}
else if (m_pcmvcCurrentContext->GetType() == CMVContext::Instances)
{
ViewInstancesInternal(m_pcmvcCurrentContext->GetLabel(),
m_pcmvcCurrentContext->GetInstances());
}
else if(m_pcmvcCurrentContext->GetType() == CMVContext::Query)
{
QueryViewInstancesSync
(m_pcmvcCurrentContext->GetLabel(),
m_pcmvcCurrentContext->GetQueryType(),
m_pcmvcCurrentContext->GetQuery(),
m_pcmvcCurrentContext->GetClass());
}
else
{
InitializeDisplay(NULL,NULL,NULL);
}
}
else
{
int nRows = m_cgGrid.GetRows();
if (nRows == 0 && GetSafeHwnd())
{
CString csMessage = _T("No Instances Available");
InitializeDisplay(NULL,NULL,NULL,&csMessage);
}
InvalidateControl();
}
}
//************************************************************
// CMultiViewCtrl::QueryCanCreateInstance
//
// The container calls this method to determine whether or not
// a "CreateInstance" can be done.
//
// Parameters:
// None.
//
// Returns:
// TRUE if a "create instance" can be done, FALSE otherwise.
//
//************************************************************
long CMultiViewCtrl::QueryCanCreateInstance()
{
// Return TRUE if it is OK to create and instance. Please see the
// CSelection::UpdateCreateDeleteFlags method that I have placed
// near the end of this file to see how I did determined whether
// instance creation/deletion could be done in the "SingleView".
// You can find related code in the SingleView's
// "path.cpp, and hmomutil.cpp" files.
return FALSE;
}
//************************************************************
// CMultiViewCtrl::QueryCanDeleteInstance
//
// The container calls this method to determine whether or not it
// is OK to delete the currently selected instance.
//
// Parameters:
// None.
//
// Returns:
// TRUE if it is OK to delete the currently selected instance,
// FALSE otherwise.
//
//*************************************************************
long CMultiViewCtrl::QueryCanDeleteInstance()
{
// Return TRUE if there is an instance selected and it is
// OK to delete it. Please see the CSelection::UpdateCreateDeleteFlags
// method that I have placed near the end of this file to see how
// I did determined whether instance creation/deletion could be
// done in the "SingleView". You can find related code in the SingleView's
// "path.cpp, and hmomutil.cpp" files.
long lPosition = StartObjectEnumeration(OBJECT_CURRENT);
CString csPath;
if (lPosition > -1)
{
csPath = GetObjectPath(lPosition);
}
else
{
return FALSE;
}
if (csPath.GetLength() > 0)
{
SCODE sc;
IWbemClassObject *pObject = NULL;
BSTR bstrTemp = csPath.AllocSysString();
#ifdef _DEBUG
// afxDump << "GetObject in QueryCanDeleteInstance for " << csPath << "\n";
#endif
sc =
m_pServices ->
GetObject(bstrTemp,0, NULL, &pObject, NULL);
::SysFreeString(bstrTemp);
if (sc == S_OK)
{
BOOL bObjectIsDynamic = ObjectIsDynamic(sc, pObject);
if (sc == S_OK && !bObjectIsDynamic)
{
pObject->Release();
return TRUE;
}
else
{
if (sc == S_OK)
{
pObject->Release();
}
return FALSE;
}
}
else
{
return FALSE;
}
}
else
{
return FALSE;
}
}
//***********************************************************
// CMultiViewCtrl::QueryNeedsSave
//
// Query to determine whether a save needs to be done.
//
// Parameters:
// None.
//
// Returns:
// TRUE if a save needs to be done, FALSE otherwise.
//
//************************************************************
long CMultiViewCtrl::QueryNeedsSave()
{
// Return TRUE if the user has edited something and a
// save needs to be done. Perhaps this is redundant since
// the container could use the control's modified flag, but
// right now the container calls QueryNeedSave anyway to
// determine whether or not a save needs to be done.
return FALSE;
}
//***********************************************************
// CMultiViewCtrl::QueryObjectSelected
//
// Query to determine where any object in the object list is
// currently selected. (ie. is there a current object?)
//
// Parameters:
// None.
//
// Returns:
// TRUE if there is an object is selected, FALSE otherwise.
//
//***********************************************************
long CMultiViewCtrl::QueryObjectSelected()
{
int nRow = m_cgGrid.GetSelectedRow();
if (nRow == -1)
{
return FALSE;
}
else
{
return TRUE;
}
}
//***********************************************************
// CMultiViewCtrl::RefreshView
//
// Refresh the view data from the HMOM database.
//
// Parameters:
// None.
//
// Returns:
// SCODE
// S_OK if successful, otherwise a failure code.
//
//***********************************************************
SCODE CMultiViewCtrl::RefreshView()
{
// This should work like the obsolete "RefreshData" method
// except that now the multiview is responsible for keeping
// track of what to refresh. Previously the container passed
// a list of object paths to "RefreshData"
//
// Note that the code for RefreshData is at the bottom of the
// file in the obsolete code section that has been ifdefed out.
if (m_pcmvcCurrentContext->GetType() != CMVContext::Unitialized)
{
m_pcmvcCurrentContext->IsDrawn() = FALSE;
if (IsWindowVisible())
{
NotifyWillShow();
}
return S_OK;
}
else
{
return WBEM_E_FAILED;
}
}
//**********************************************************
// CMultiViewCtrl::SaveData
//
// Execute a "Save" operation corresponding to click on the
// "Save" button in the container.
//
// Parameters:
// None.
//
// Returns:
// SCODE
// S_OK if successful, otherwise E_FAIL.
//
//**********************************************************
SCODE CMultiViewCtrl::SaveData()
{
// The container calls this method when the "Save" button
// is clicked.
//
// To enable the container's "Save" button, the multiview
// must fire the FireNotifySaveRequired() event. This
// will be necessary only if the user edits the data directly
// in the multiview.
return E_NOTIMPL;
}
//*********************************************************
// CMultiViewCtrl::StartObjectEnumeration
//
// Start enumerating the object paths.
//
// Parameters:
// [in] long lWhere
// enum {OBJECT_CURRENT=0, OBJECT_FIRST=1, OBJECT_LAST=2};
//
// Returns:
// long
// The position of the object in the object list.
// -1 if the object list is empty, or a failure occurs.
//
//***********************************************************
long CMultiViewCtrl::StartObjectEnumeration(long lWhere)
{
// This method needs to return an index into the instance
// list corresponding to the "lWhere" selector as described
// in the parameter list.
int nNumRows = m_cgGrid.GetRows();
if (nNumRows == 0) {
return -1;
}
// Check to see if this row is the "No instances available" row.
if (nNumRows == 1) {
if (m_cgGrid.IsNoInstanceRow(0)) {
return -1;
}
}
int iRow;
switch(lWhere) {
case OBJECT_CURRENT:
iRow = m_cgGrid.GetSelectedRow();
return iRow;
break;
case OBJECT_FIRST:
return 0;
break;
case OBJECT_LAST:
return nNumRows - 1;
break;
default:
// Invalid input parameter.
return -1;
}
}
//*********************************************************
// CMultiViewCtrl::NextObject
//
// Get the position of the next HMOM object in the object
// list. The container uses this method to enumerate the
// object instances in multiview's instance list.
//
// Parameters:
// [in] long lPosition
// The position of the reference object (the
// position of the next object after this one is returned).
//
// Retuturns:
// long
// The position of the object that logically follows
// the reference object or -1 if no "next" object
// is available.
//
//**********************************************************
long CMultiViewCtrl::NextObject(long lPosition)
{
// This method needs to return the index of the next
// object instance in the instance list.
int nNumRows = m_cgGrid.GetRows();
if (lPosition < nNumRows - 1 && lPosition >= 0)
{
return lPosition + 1;
}
else
{
return -1;
}
}
//*********************************************************
// CMultiViewCtrl::PrevObject
//
// Get the position of the previous HMOM object in the object
// list. The container uses this method to enumerate the
// object instances in multiview's instance list.
//
// Parameters:
// [in] long lPosition
// The position of the reference object (the
// position of the object preceding this one is returned).
//
// Retuturns:
// long
// The position of the object that logically follows
// the reference object or -1 if no "previous" object
// is available.
//
//**********************************************************
long CMultiViewCtrl::PrevObject(long lPosition)
{
// This method needs to return the index of the previous
// object instance in the instance list.
int nNumRows = m_cgGrid.GetRows();
if (lPosition < nNumRows - 1 && lPosition >= 1)
{
return lPosition - 1;
}
else
{
return -1;
}
}
//*************************************************************
// CMultiViewCtrl::GetObjectPath
//
// Get the HMOM object path of the specified class-object.
//
// Parameters:
// [in] long lPosition
// The position of the object.
//
// Returns:
// BSTR
// The title of the specified class-object.
//
//**************************************************************
BSTR CMultiViewCtrl::GetObjectPath(long lPosition)
{
// Return the HMOM object path for the specified object.
CString csReturn = _T("");
int nNumRows = m_cgGrid.GetRows();
if (lPosition >= 0 && lPosition < nNumRows)
{
CString *pcsPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(lPosition, 0).GetTagValue());
if (pcsPath)
{
csReturn = *pcsPath;
}
}
return csReturn.AllocSysString();
}
//*************************************************************
// CMultiViewCtrl::GetObjectTitle
//
// Get the title of the specified class-object.
//
// Parameters:
// [in] long lPosition
// The position of the object.
//
// Returns:
// BSTR
// The title of the specified class-object.
//
//**************************************************************
BSTR CMultiViewCtrl::GetObjectTitle(long lPosition)
{
// The container calls this method to get the title of the
// specified object instance. The container uses this title
// in message boxes and so on when it needs to display a message
// containing a reference to an object.
//
// It would have been possible for the container to generate the
// title from the object path, however this API provides a convenient
// way for applications to get the object title when the multiview
// control is used separately from the container.
//
// Note: This is the title of a specific object and not that of
// the entire view.
CString csReturn = _T("");
CString csPath;
if (lPosition > -1)
{
csPath = GetObjectPath(lPosition);
if (csPath.GetLength() == 0)
{
return csReturn.AllocSysString();
}
}
else
{
return csReturn.AllocSysString();
}
SCODE sc;
IWbemClassObject *pObject = NULL;
BSTR bstrTemp = csPath.AllocSysString();
#ifdef _DEBUG
// afxDump << "GetObject in GetObjectTitle for " << csPath << "\n";
#endif
sc =
m_pServices ->
GetObject(bstrTemp,0, NULL, &pObject, NULL);
::SysFreeString(bstrTemp);
if (sc != S_OK)
{
return csReturn.AllocSysString();
}
BOOL bDiffNS =
ObjectInDifferentNamespace
(m_pServices, &m_csNameSpace, pObject);
csPath = GetIWbemFullPath(m_pServices,pObject);
CString csRelPath = GetIWbemRelPath(m_pServices,pObject);
pObject->Release();
if (bDiffNS)
{
return csPath.AllocSysString();
}
else
{
return csRelPath.AllocSysString();
}
}
//*********************************************************
// CMultiViewCtrl::SelectObjectByPosition
//
// Select the specified HMOM class object.
//
// Parameters:
// [in] long lPosition
// The position of the HMOM object to select.
//
// Returns:
// S_OK if the specified object was selected,
// E_FAIL if the object was not selected.
//
//***********************************************************
SCODE CMultiViewCtrl::SelectObjectByPosition(long lPosition)
{
// Select the specified instance in the instance list.
// lPosition is an index into the instance list.
int nNumRows = m_cgGrid.GetRows();
if (lPosition >= 0 && lPosition < nNumRows)
{
m_cgGrid.SelectRow(lPosition);
m_cgGrid.CheckForSelectionChange();
InvalidateControl();
return S_OK;
}
else
{
return WBEM_E_NOT_FOUND;
}
}
//********************************************************
// CMultiViewCtrl::StartViewEnumeration
//
// Start enumerating the alternate views (custom views) that
// the multiview supports (none currently).
//
// Parameters:
// [in] long lWhere
// The place to start the enumeration.
// enum {VIEW_DEFAULT=0, VIEW_CURRENT=1, VIEW_FIRST=2, VIEW_LAST=3};
//
// Returns:
// long
// The position of the view in the view list,
// or -1 if there are no alternate views.
//
//********************************************************
long CMultiViewCtrl::StartViewEnumeration(long lWhere)
{
// Currently, there are no alternate (custom) views, so return
// -1 to indicate that there are none.
return -1;
}
//*********************************************************
// CMultiViewCtrl::SelectView
//
// Select an alternate view (custom view).
//
// Parameters:
// [in] long lPosition
// The position of the view in the alternate view list.
//
// Returns:
// SCODE
// S_OK if the view was successfully selected, E_FAIL
// if it was not selected.
//
//***********************************************************
SCODE CMultiViewCtrl::SelectView(long lPosition)
{
// Currently there are no alternate (custom) views, so it
// doesn't make any sense to try to select one.
return E_FAIL;
}
//************************************************************
// CMultiViewCtrl::NextViewTitle
//
// Get the title o the next alternate (custom) view.
//
// Parameters:
// [in] long lPosition
// The position of the view that preceeds the desired
// view in the view list.
//
// [out] BSTR FAR* pbstrTitle
// A pointer to the place to return the view's title.
//
// Returns:
// long
// The position of the next view (the view who's title
// is returned). -1 if the end of the view list
// is reached.
//****************************************************************
long CMultiViewCtrl::NextViewTitle(long lPosition, BSTR FAR* pbstrTitle)
{
// Currently there are no alternate (custom) views, so just
// return -1.
return -1;
}
//************************************************************
// CMultiViewCtrl::GetViewTitle
//
// Get the title o the specified alternate (custom) view.
//
// Parameters:
// [in] long lPosition
// The position of the view in the view list.
//
// Returns:
// BSTR
// The view title.
//
//****************************************************************
BSTR CMultiViewCtrl::GetViewTitle(long lPosition)
{
// Currently there are no alternate (custom) views, so just
// return an empty string for the view titles just in case
// someone calls this method.
CString strResult;
return strResult.AllocSysString();
}
//************************************************************
// CMultiViewCtrl::PrevViewTitle
//
// Get the title o the previous alternate (custom) view.
//
// Parameters:
// [in] long lPosition
// The position of the view that follows the desired
// view in the view list.
//
// [out] BSTR FAR* pbstrTitle
// A pointer to the place to return the view's title.
//
// Returns:
// long
// The position of the previous view (the view who's title
// is returned). -1 if the beginning of the view list
// is reached.
//****************************************************************
long CMultiViewCtrl::PrevViewTitle(long lPosition, BSTR FAR* pbstrTitle)
{
// Currently there are no alternate (custom) views, so just
// return -1.
return -1;
}
IWbemServices *CMultiViewCtrl::InitServices
(CString *pcsNameSpace)
{
IWbemServices *pSession = 0;
IWbemServices *pChild = 0;
CString csObjectPath;
// hook up to default namespace
if (pcsNameSpace == NULL)
{
csObjectPath = _T("root\\cimv2");
}
else
{
csObjectPath = *pcsNameSpace;
}
CString csUser = _T("");
pSession = GetIWbemServices(csObjectPath);
return pSession;
}
IWbemServices *CMultiViewCtrl::GetIWbemServices
(CString &rcsNamespace)
{
IUnknown *pServices = NULL;
BOOL bUpdatePointer= FALSE;
m_sc = S_OK;
m_bUserCancel = FALSE;
VARIANT varUpdatePointer;
VariantInit(&varUpdatePointer);
varUpdatePointer.vt = VT_I4;
if (bUpdatePointer == TRUE)
{
varUpdatePointer.lVal = 1;
}
else
{
varUpdatePointer.lVal = 0;
}
VARIANT varService;
VariantInit(&varService);
VARIANT varSC;
VariantInit(&varSC);
VARIANT varUserCancel;
VariantInit(&varUserCancel);
FireGetIWbemServices
((LPCTSTR)rcsNamespace, &varUpdatePointer, &varService, &varSC,
&varUserCancel);
if (varService.vt & VT_UNKNOWN)
{
pServices = reinterpret_cast<IWbemServices*>(varService.punkVal);
}
varService.punkVal = NULL;
VariantClear(&varService);
if (varSC.vt == VT_I4)
{
m_sc = varSC.lVal;
}
else
{
m_sc = WBEM_E_FAILED;
}
VariantClear(&varSC);
if (varUserCancel.vt == VT_BOOL)
{
m_bUserCancel = varUserCancel.boolVal;
}
VariantClear(&varUserCancel);
VariantClear(&varUpdatePointer);
IWbemServices *pRealServices = NULL;
if (m_sc == S_OK && !m_bUserCancel)
{
pRealServices = reinterpret_cast<IWbemServices *>(pServices);
}
return pRealServices;
}
void CMultiViewCtrl::OnShowWindow(BOOL bShow, UINT nStatus)
{
if (GetSafeHwnd() && AmbientUserMode())
{
COleControl::OnShowWindow(bShow, nStatus);
if (bShow == TRUE)
{
NotifyWillShow();
}
}
}
IWbemClassObject *CMultiViewCtrl::GetClassFromAnyNamespace(CString &csClass)
{
IWbemClassObject *pimcoClass = NULL;
IWbemClassObject *pErrorObject = NULL;
CString csNameSpace = GetPathNamespace(csClass);
BOOL bDiffNS =
csNameSpace.CompareNoCase(m_csNameSpace) != 0;
IWbemServices *pServices;
if (bDiffNS)
{
pServices = InitServices(&csNameSpace);
if (!pServices)
{
InitializeDisplay(NULL,NULL,NULL);
CString csUserMsg;
csUserMsg = _T("Cannot connect to namespace ") + csNameSpace;
ErrorMsg
(&csUserMsg, S_OK, NULL, TRUE, &csUserMsg, __FILE__,
__LINE__ - 9);
return 0;
}
BSTR bstrTemp = csClass.AllocSysString();
#ifdef _DEBUG
// afxDump << "GetObject in GetClassFromAnyNamespace for " << csClass << "\n";
#endif
pServices ->
GetObject(bstrTemp,0,NULL, &pimcoClass,NULL);
::SysFreeString(bstrTemp);
pServices->Release();
}
else
{
BSTR bstrTemp = csClass.AllocSysString();
#ifdef _DEBUG
// afxDump << "GetObject in GetClassFromAnyNamespace for " << csClass << "\n";
#endif
m_sc =
m_pServices ->
GetObject(bstrTemp,0,NULL, &pimcoClass,NULL);
::SysFreeString(bstrTemp);
}
return pimcoClass;
}
//***************************************************************************
//
// GetIWbemClassPath
//
// Purpose: Returns the path of the class of the object.
//
//***************************************************************************
CString CMultiViewCtrl::GetIWbemClassPath(IWbemServices *pProv, IWbemClassObject *pimcoObject)
{
CString csProp = _T("__Path");
CString csPath = ::GetProperty(pProv,pimcoObject,&csProp);
CString csClassPath = GetClassFromPath(csPath);
return csClassPath;
}
//******************************************************
// CMultiViewCtrl::GetPropertyFilter
//
// Get the value of the property filter flags. The flags
// indicate which type of properties should be displayed
// on the properties tab.
//
// Parameters:
// None.
//
// Returns:
// long
// A long value that is composed of bitflags to
// indicate which type of properties to show on
// the properties tab.
//
// The following values are valid:
//
// PROPFILTER_SYSTEM
// PROPFILTER_INHERITED
// PROPFILTER_LOCAL
//
//*******************************************************
long CMultiViewCtrl::GetPropertyFilter()
{
return m_lPropFilterFlags;
}
//******************************************************
// CMultiViewCtrl::SetPropertyFilter
//
// Set the value of the property filter flags. The flags
// indicate which type of properties should be displayed
// on the properties tab.
//
// Parameters:
// [in] long lPropertyFilter
// A long value that is composed of bitflags to
// indicate which type of properties to show on
// the properties tab.
//
// The following values are valid:
//
// PROPFILTER_SYSTEM
// PROPFILTER_INHERITED
// PROPFILTER_LOCAL
//
// Returns:
// Nothing.
//
//*******************************************************
void CMultiViewCtrl::SetPropertyFilter(long lPropFilterFlags)
{
// Make sure only the flags that we know about are set.
long lPropFilterFlagsSave = m_lPropFilterFlags;
m_lPropFilterFlags = lPropFilterFlags & (PROPFILTER_SYSTEM | PROPFILTER_INHERITED | PROPFILTER_LOCAL);
if (IsWindowVisible())
{
SetAllColVisibility(&m_csaProps,&m_cmstpPropFlavors);
m_cgGrid.CheckForSelectionChange();
SetModifiedFlag();
InvalidateControl();
m_cgGrid.RedrawWindow();
m_bPropFilterFlagsChanged = FALSE;
}
else
{
if (lPropFilterFlagsSave != m_lPropFilterFlags)
{
m_bPropFilterFlagsChanged = TRUE;
}
}
#if 0
// Make sure only the flags that we know about are set.
m_lPropFilterFlags = lPropFilterFlags & (PROPFILTER_SYSTEM | PROPFILTER_INHERITED | PROPFILTER_LOCAL);
// Verify that the caller did not try to set any bits that we don't understand.
ASSERT(m_lPropFilterFlags == lPropFilterFlags);
if (m_lPropFilterFlags != lPrevValue) {
IWbemClassObject* pco = (IWbemClassObject*) *m_psel;
if (pco != NULL) {
m_bSelectingObject = TRUE;
Refresh();
m_bSelectingObject = FALSE;
InvalidateControl();
}
}
#endif //0
}
void CMultiViewCtrl::OnUpdateMenuitemgotosingle(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
// m_cpRightUp;
int iRow;
int iCol;
BOOL bClickedCell = m_cgGrid.PointToCell(m_cpRightUp, iRow, iCol);
if (!bClickedCell)
{
iCol = NULL_INDEX;
BOOL bClickedRowHandle = m_cgGrid.PointToRowHandle(m_cpRightUp, iRow);
if (!bClickedRowHandle)
{
iRow = NULL_INDEX;
}
}
m_iContextRow = iRow;
if ((iRow == NULL_INDEX) || m_cgGrid.IsNoInstanceRow(iRow))
{
pCmdUI->Enable(FALSE);
}
else
{
pCmdUI->Enable(TRUE);
}
}
void CMultiViewCtrl::OnContextMenu(CWnd*, CPoint point)
{
m_cpRightUp = point;
ScreenToClient(&m_cpRightUp);
// CG: This block was added by the Pop-up Menu component
{
if (point.x == -1 && point.y == -1){
//keystroke invocation
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
point = rect.TopLeft();
point.Offset(5, 5);
}
CMenu menu;
VERIFY(menu.LoadMenu(CG_IDR_POPUP_MULTI_VIEW_CTRL));
CMenu* pPopup = menu.GetSubMenu(0);
#ifdef _DEBUG
ASSERT(pPopup != NULL);
#endif
CWnd* pWndPopupOwner = this;
pPopup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y,
pWndPopupOwner);
}
}
void CMultiViewCtrl::OnMenuitemgotosingle()
{
// TODO: Add your command handler code here
CString *pcsPath =
reinterpret_cast<CString *>
(m_cgGrid.GetAt(m_iContextRow, 0).GetTagValue());
if (pcsPath)
{
FireNotifyViewObjectSelected((LPCTSTR) *pcsPath);
}
}
SCODE CMultiViewCtrl::GetQueryInstancesAsync
(IWbemServices * pIWbemServices, CString *pcsQueryType, CString *pcsQuery)
{
m_cpaInstancesForQuery.RemoveAll();
m_pServicesForAsyncSink = pIWbemServices;
m_csQueryTypeForAsyncSink = *pcsQueryType;
m_csQueryForAsyncSink = *pcsQuery;
m_pAsyncQueryCancelled = FALSE;
m_pAsyncEnumCancelled = FALSE;
m_pAsyncQueryRunning = TRUE;
PostMessage(ID_QUERY_DOMODAL , 0,0);
PostMessage(ID_GETASYNCQUERYSINK,0,0);
return WBEM_NO_ERROR;
}
void CMultiViewCtrl::OnSetFocus(CWnd* pOldWnd)
{
COleControl::OnSetFocus(pOldWnd);
OnActivateInPlace(TRUE,NULL);
m_cgGrid.SetFocus();
// TODO: Add your message handler code here
}
void CMultiViewCtrl::OnKillFocus(CWnd* pNewWnd)
{
COleControl::OnKillFocus(pNewWnd);
// TODO: Add your message handler code here
}
void CMultiViewCtrl::OnRequestUIActive()
{
OnActivateInPlace(TRUE,NULL);
FireRequestUIActive();
}