2025-11-28 00:35:46 +09:00

1178 lines
33 KiB
C++

// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.
#include "stdafx.h"
#include "VCExplore.h"
#include "VCExploreDlg.h"
#include "AppExportDlg.h"
#include "AppInstallDlg.h"
#include "AppUtilDlg.h"
#include "CompImportDlg.h"
#include "CompInstallDlg.h"
#include "ConnectDlg.h"
#include "UtilitiesDlg.h"
#include <comdef.h>
#include "comadmin.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define RELEASE_ALL_PARENT_OBJECTS 0
#define DLG_APP_EXPORT 1
#define DLG_APP_INSTALL 2
#define DLG_APP_UTIL_START 3
#define DLG_APP_UTIL_STOP 4
#define DLG_COMPONENT_IMPORT 5
#define DLG_COMPONENT_INSTALL 6
#define DLG_CONNECT 7
#define DLG_UTILITIES 8
#define DLG_ABOUT 9
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
virtual BOOL OnInitDialog();
afx_msg void OnEasterEgg();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
ON_BN_CLICKED(IDC_APPLICATION_ICON, OnEasterEgg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CAboutDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CAboutDlg::OnEasterEgg()
{
MessageBox("Built By:\tAllen Herring\n\tApplication Developer Consultant\n\tMicrosoft Corporation\n\n\tFebruary 1999",
"Party On!",
(MB_OK | MB_ICONINFORMATION));
}
/////////////////////////////////////////////////////////////////////////////
// CVCExploreDlg dialog
CVCExploreDlg::CVCExploreDlg(CWnd* pParent /*=NULL*/)
: CDialog(CVCExploreDlg::IDD)
{
UNREFERENCED_PARAMETER(pParent);
//{{AFX_DATA_INIT(CVCExploreDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDI_APP_ICON);
// Pointer Initialization
m_pCatalog = NULL;
m_pCurrCollection = NULL;
m_bChangesArePending = FALSE;
}
void CVCExploreDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CVCExploreDlg)
DDX_Control(pDX, IDC_BUTTON_SET_PROPERTY, m_btnSetProperty);
DDX_Control(pDX, IDC_EDIT_PROPERTY_VALUE, m_edtPropertyValue);
DDX_Control(pDX, IDC_LIST_RELATED_COLLECTIONS, m_lstRelatedCollections);
DDX_Control(pDX, IDC_LIST_PROPERTIES, m_lstProperties);
DDX_Control(pDX, IDC_LIST_PARENT_COLLECTIONS, m_lstParentCollections);
DDX_Control(pDX, IDC_LIST_OBJECTS, m_lstObjects);
DDX_Control(pDX, IDC_LABEL_COMPUTER_NAME_VALUE, m_lblComputerName);
DDX_Control(pDX, IDC_LABEL_COLLECTION_NAME_VALUE, m_lblCollectionName);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CVCExploreDlg, CDialog)
//{{AFX_MSG_MAP(CVCExploreDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_COMMAND(ID_TBTN_ABOUT, OnTBtnAbout)
ON_COMMAND(ID_TBTN_CONNECT, OnTBtnConnect)
ON_COMMAND(ID_TBTN_DELETE, OnTBtnDelete)
ON_COMMAND(ID_TBTN_EXPORT_APP, OnTBtnExportApp)
ON_COMMAND(ID_TBTN_IMPORT_COMPONENT, OnTBtnImportComponent)
ON_COMMAND(ID_TBTN_INSTALL_APP, OnTBtnInstallApp)
ON_COMMAND(ID_TBTN_INSTALL_COMPONENT, OnTBtnInstallComponent)
ON_COMMAND(ID_TBTN_NEW, OnTBtnNew)
ON_COMMAND(ID_TBTN_REFRESH, OnTBtnRefresh)
ON_COMMAND(ID_TBTN_SAVE, OnTBtnSave)
ON_COMMAND(ID_TBTN_START_APP, OnTBtnStartApp)
ON_COMMAND(ID_TBTN_STOP_APP, OnTBtnStopApp)
ON_COMMAND(ID_TBTN_UTILITY, OnTBtnUtility)
ON_WM_CLOSE()
ON_LBN_SELCHANGE(IDC_LIST_RELATED_COLLECTIONS, OnSelChangeRelatedCollections)
ON_LBN_SELCHANGE(IDC_LIST_PARENT_COLLECTIONS, OnSelChangeParentCollections)
ON_LBN_SELCHANGE(IDC_LIST_OBJECTS, OnSelChangeObjects)
ON_LBN_SELCHANGE(IDC_LIST_PROPERTIES, OnSelChangeProperties)
ON_BN_CLICKED(IDC_BUTTON_SET_PROPERTY, OnSetProperty)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CVCExploreDlg message handlers
BOOL CVCExploreDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
if (strAboutMenu.LoadString(IDS_ABOUTBOX) && !strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Create the button structure
TBBUTTON tbButtons[] = {
{0, ID_TBTN_CONNECT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, (UCHAR)-1},
{1, ID_TBTN_REFRESH, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, (UCHAR)-1},
{2, ID_TBTN_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{3, ID_TBTN_SAVE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{4, ID_TBTN_DELETE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, (UCHAR)-1},
{5, ID_TBTN_START_APP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{6, ID_TBTN_STOP_APP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{7, ID_TBTN_INSTALL_APP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{8, ID_TBTN_EXPORT_APP, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, (UCHAR)-1},
{9, ID_TBTN_INSTALL_COMPONENT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{10, ID_TBTN_IMPORT_COMPONENT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, (UCHAR)-1},
{11, ID_TBTN_UTILITY, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, (UCHAR)-1},
{12, ID_TBTN_ABOUT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}
};
// Create the bitmap structure that represents the toolbar
TBADDBITMAP tbBitmap;
tbBitmap.hInst = AfxGetApp()->m_hInstance;
tbBitmap.nID = IDR_TOOLBAR_MAIN;
// Create the toolbar
m_hwndToolBar = CreateToolbarEx(this->m_hWnd, // HWND of the toolbar's parent
WS_CHILD | WS_BORDER | WS_VISIBLE | TBSTYLE_TOOLTIPS, // Toolbar style
IDR_TOOLBAR_MAIN, // Toolbar Command ID
13, // Number of bitmaps
AfxGetApp()->m_hInstance, // HINST of the module that contains the resource
IDR_TOOLBAR_MAIN, // Toolbar Resoure ID
(LPCTBBUTTON) &tbButtons, // Toolbar button structure
19, // Number of buttons (including seperators)
16, 16, // Button width & height
16, 16, // Bitmap width & height
sizeof(TBBUTTON)); // Size of single TBBUTTON structure (i.e., individual button)
if (NULL != m_hwndToolBar)
{
CWnd* pToolBar = GetDlgItem(IDR_TOOLBAR_MAIN);
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_NEW, MAKELONG(false, 0));
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_SAVE, MAKELONG(false, 0));
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_DELETE, MAKELONG(false, 0));
}
else
MessageBox("Failed to create toolbar.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
// Enable the tooltip window for this CWnd object
this->EnableToolTips(true);
// Load the COM libraries
HRESULT hr = CoInitialize(NULL);
if SUCCEEDED(hr)
{
hr = CreateCatalog();
if SUCCEEDED(hr)
hr = NavigateTo(m_pCurrCollection);
}
// Display the computer name
_bstr_t bstrComputerName = "( Local )";
set_ComputerName(bstrComputerName);
return TRUE; // return TRUE unless you set the focus to a control
}
void CVCExploreDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CVCExploreDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CVCExploreDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CVCExploreDlg::OnTBtnAbout()
{
// Continue only if we have a valid reference to a Catalog object
if (NULL != GetCatalog())
{
CAboutDlg dlg;
// Display the "About" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnTBtnConnect()
{
if (NULL != GetCatalog())
{
CConnectDlg dlg;
// Set the dialog's catalog reference...
dlg.set_Catalog(GetCatalog());
//... and set the "child" dialog's parent (i.e., communication channel)
dlg.set_ParentDlg(this);
// Display the "Connect" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnTBtnDelete()
{
// Get the current object selected
int nObjectIndex = m_lstObjects.GetCurSel();
// Continue only if an object is selected
if (LB_ERR == nObjectIndex)
return;
// Attempt to remove the item from the collection
HRESULT hr = m_pCurrCollection->Remove(nObjectIndex);
if (SUCCEEDED(hr))
{
CWnd* pToolBar = GetDlgItem(IDR_TOOLBAR_MAIN);
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_SAVE, MAKELONG(true, 0));
m_bChangesArePending = TRUE;
}
else
{
MessageBox("Failed to delete the specified object from the current collection.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
}
}
void CVCExploreDlg::OnTBtnExportApp()
{
if (NULL != GetCatalog())
{
CAppExportDlg dlg;
// Set the dialog's catalog reference... ONLY if we aren't invoking the Connect dialog
dlg.set_Catalog(GetCatalog());
// Display the "App Export" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnTBtnImportComponent()
{
if (NULL != GetCatalog())
{
CCompImportDlg dlg;
// Set the dialog's catalog reference... ONLY if we aren't invoking the Connect dialog
dlg.set_Catalog(GetCatalog());
// Display the "Import Component" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnTBtnInstallApp()
{
if (NULL != GetCatalog())
{
CAppInstallDlg dlg;
// Set the dialog's catalog reference... ONLY if we aren't invoking the Connect dialog
dlg.set_Catalog(GetCatalog());
// Display the "Import Component" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnTBtnInstallComponent()
{
if (NULL != GetCatalog())
{
CCompInstallDlg dlg;
// Set the dialog's catalog reference... ONLY if we aren't invoking the Connect dialog
dlg.set_Catalog(GetCatalog());
// Display the "Import Component" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnTBtnNew()
{
ICatalogObject* pCatalogObject = NULL;
// Attempt to add a new item to the current collection
HRESULT hr = m_pCurrCollection->Add((IDispatch**) &pCatalogObject);
// Validate success/fail of the requested operation
if SUCCEEDED(hr)
{
// Toggle the toolbar save button
CWnd* pToolBar = GetDlgItem(IDR_TOOLBAR_MAIN);
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_SAVE, MAKELONG(true, 0));
m_bChangesArePending = TRUE;
// Release the new CatalogObject reference
pCatalogObject->Release();
}
else
MessageBox("Failed to add the new object to the current collection.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
// Refresh the UI
NavigateTo(m_pCurrCollection, FALSE);
}
void CVCExploreDlg::OnTBtnRefresh()
{
// Refresh the UI with the current collection
NavigateTo(m_pCurrCollection);
}
void CVCExploreDlg::OnTBtnSave()
{
// Attempt to save the requested changes
long lRetValue = 0;
HRESULT hr = m_pCurrCollection->SaveChanges(&lRetValue);
if FAILED(hr)
{
MessageBox("Failed to save changes to the current collection.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
}
// Turn off the toolbar save button
CWnd* pToolBar = GetDlgItem(IDR_TOOLBAR_MAIN);
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_SAVE, MAKELONG(false, 0));
m_bChangesArePending = FALSE;
// Refresh the UI with the current collection
NavigateTo(m_pCurrCollection);
}
void CVCExploreDlg::OnTBtnStartApp()
{
if (NULL != GetCatalog())
{
CAppUtilDlg dlg;
// Set the dialog's catalog reference... ONLY if we aren't invoking the Connect dialog
dlg.set_Catalog(GetCatalog());
// Set the dialog "type"
dlg.set_UtilityType(UTILITY_TYPE_START_APP);
// Display the "Import Component" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnTBtnStopApp()
{
if (NULL != GetCatalog())
{
CAppUtilDlg dlg;
// Set the dialog's catalog reference... ONLY if we aren't invoking the Connect dialog
dlg.set_Catalog(GetCatalog());
// Set the dialog "type"
dlg.set_UtilityType(UTILITY_TYPE_STOP_APP);
// Display the "Import Component" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnTBtnUtility()
{
if (NULL != GetCatalog())
{
CUtilitiesDlg dlg;
// Set the dialog's catalog reference... ONLY if we aren't invoking the Connect dialog
dlg.set_Catalog(GetCatalog());
// Display the "Import Component" dialog
dlg.DoModal();
}
}
void CVCExploreDlg::OnClose()
{
// Release the pointers to out objects and unload the COM libraries
RemoveParent(RELEASE_ALL_PARENT_OBJECTS);
DestroyCatalog();
CoUninitialize();
CDialog::OnClose();
}
HRESULT CVCExploreDlg::CreateCatalog()
{
// Close any previous Catalog instances
DestroyCatalog();
IUnknown* pUnknown = NULL;
// Attempt to get a reference to the objects IUnknown pointer
HRESULT hr = CoCreateInstance(CLSID_COMAdminCatalog,
NULL,
CLSCTX_INPROC_SERVER,
IID_IUnknown,
(void**) &pUnknown);
// Continue only if successful
if SUCCEEDED(hr)
{
// Attempt to get a reference to the object's ICOMAdminCatalog interface
hr = pUnknown->QueryInterface(IID_ICOMAdminCatalog,
(void**) &m_pCatalog);
// Release the IUnknown pointer
pUnknown->Release();
// Continue only if successful
if SUCCEEDED(hr)
{
_bstr_t bstrRootCollection = "Root";
// Attempt to connect to "Root" of the Catalog object
hr = m_pCatalog->GetCollection(bstrRootCollection,
(IDispatch**) &m_pCurrCollection);
// Continue only if successful
if SUCCEEDED(hr)
{
// Attempt to load the "Root" collection objects
hr = m_pCurrCollection->Populate();
// Continue only if successful
if SUCCEEDED(hr)
return S_OK;
else
MessageBox("Failed to populate the current Catalog objects root collection.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
}
else
MessageBox("Failed to obtain a reference to the current Catalog objects root collection.\n\nNo processing will be performed.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
}
else
MessageBox("ICOMAdminCatalog interface is not supported.\n\nNo processing will be performed.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
}
else
MessageBox("Failed to instantiate the COMAdmin object.\n\nNo processing will be performed.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
// Default return value
return hr;
}
void CVCExploreDlg::DestroyCatalog()
{
if (NULL != m_pCurrCollection)
{
m_pCurrCollection->Release();
m_pCurrCollection = NULL;
}
if (NULL != m_pCatalog)
{
m_pCatalog->Release();
m_pCatalog = NULL;
}
}
HRESULT CVCExploreDlg::NavigateTo(ICatalogCollection *pCatalogCollection, BOOL bPopulate)
{
long lObjCount = 0;
_bstr_t bstrRelatedCollectionInfo = "RelatedCollectionInfo";
_bstr_t bstrPropertyInfo = "PropertyInfo";
_variant_t vtRelatedCollInfoKey = "RelatedCollectionInfo";
_variant_t vtPropertyInfoKey = "PropertyInfo";
_variant_t vtKey = "";
_variant_t vtName = "";
ICatalogObject* pCatalogObject = NULL;
ICatalogCollection* pRelatedCollInfo = NULL;
ICatalogCollection* pPropertyInfo = NULL;
// Make sure the current CatalogCollection object has been populated
HRESULT hr;
if (bPopulate)
hr = pCatalogCollection->Populate();
////////////////////////////////////////////////////////////////////////////////////////
// FIRST...
// Display the current CatalogCollection's name
hr = pCatalogCollection->get_Name(&vtName);
if SUCCEEDED(hr)
m_lblCollectionName.SetWindowText(_bstr_t(vtName));
////////////////////////////////////////////////////////////////////////////////////////
// SECOND...
// Enumerate "RelatedCollectionInfo" for the current collection
//
// Clear the listbox control
m_lstRelatedCollections.ResetContent();
hr = pCatalogCollection->GetCollection(bstrRelatedCollectionInfo,
vtRelatedCollInfoKey,
(IDispatch**) &pRelatedCollInfo);
if SUCCEEDED(hr)
{
// Attempt to populate the RelatedCollectionInfo
hr = pRelatedCollInfo->Populate();
if SUCCEEDED(hr)
{
// Output the number of RelatedCollectionInfo objects in the collection
long lCount = 0;
hr = pRelatedCollInfo->get_Count(&lCount);
for (long lIndex = 0; lIndex < lCount; lIndex++)
{
hr = pRelatedCollInfo->get_Item(lIndex,
(IDispatch**) &pCatalogObject);
if SUCCEEDED(hr)
{
// Display the current CatalogObject's Key and Name
pCatalogObject->get_Key(&vtKey);
pCatalogObject->get_Name(&vtName);
// Add the RelatedCollection's name to the listbox control
m_lstRelatedCollections.AddString(_bstr_t(vtName));
// Release the ICatalogObject pointer
pCatalogObject->Release();
}
}
}
// Release the ICatalogCollection pointer
pRelatedCollInfo->Release();
}
////////////////////////////////////////////////////////////////////////////////////////
// THIRD...
// Enumerate "PropertyInfo" for the current collection
//
// Clear the listbox control
m_lstProperties.ResetContent();
hr = pCatalogCollection->GetCollection(bstrPropertyInfo,
vtPropertyInfoKey,
(IDispatch**) &pPropertyInfo);
if SUCCEEDED(hr)
{
// Populate the collection
hr = pPropertyInfo->Populate();
if SUCCEEDED(hr)
{
// Display the number of PropertyInfo objects in the collection
long lPropCnt = 0;
pPropertyInfo->get_Count(&lPropCnt);
for (int lIndex = 0; lIndex < lPropCnt; lIndex++)
{
hr = pPropertyInfo->get_Item(lIndex,
(IDispatch**) &pCatalogObject);
if SUCCEEDED(hr)
{
// Display the current CatalogObject's Key and Name
pCatalogObject->get_Key(&vtKey);
pCatalogObject->get_Name(&vtName);
// Add property names to the listbox control
m_lstProperties.AddString(_bstr_t(vtName));
// Release the ICatalogObject pointer
pCatalogObject->Release();
}
}
}
// Release the ICatalogCollection pointer
pPropertyInfo->Release();
}
////////////////////////////////////////////////////////////////////////////////////////
// FORTH...
// Enumerate the current collection's objects
//
// Clear the listbox control
m_lstObjects.ResetContent();
// Get the number of objects available in this CatalogCollection
hr = pCatalogCollection->get_Count(&lObjCount);
// Output each objects (i.e., CatalogObject) properties in the current collection
for (long lIndex = 0; lIndex < lObjCount; lIndex++)
{
hr = pCatalogCollection->get_Item(lIndex,
(IDispatch**) &pCatalogObject);
if SUCCEEDED(hr)
{
// Get the current CatalogObject's Name
pCatalogObject->get_Name(&vtName);
// Add the Object names to the listbox control
m_lstObjects.AddString(_bstr_t(vtName));
// Release the temporary ICatalogObject pointer
pCatalogObject->Release();
}
}
////////////////////////////////////////////////////////////////////////////////////////
// FIFTH...
// Set the state of the persistence (i.e., new & delete) toolbar buttons
//
// Set the persistence toolbar buttons state depending upon the current collections
// properties (i.e., whether or not save & delete are permitted
short sSaveEnabled = 0;
short sRemoveEnabled = 0;
CWnd* pToolBar = GetDlgItem(IDR_TOOLBAR_MAIN);
hr = pCatalogCollection->get_AddEnabled(&sSaveEnabled);
if (sSaveEnabled && SUCCEEDED(hr))
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_NEW, MAKELONG(true, 0));
hr = pCatalogCollection->get_RemoveEnabled(&sRemoveEnabled);
if (sRemoveEnabled && SUCCEEDED(hr))
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_DELETE, MAKELONG(true, 0));
////////////////////////////////////////////////////////////////////////////////////////
// SIXTH...
// Clear any existing property value
//
m_edtPropertyValue.SetSel(0, -1, false);
m_edtPropertyValue.Clear();
m_lstObjects.SetCurSel(0);
m_lstProperties.SetCurSel(0);
return hr;
}
void CVCExploreDlg::OnSelChangeRelatedCollections()
{
TryToSaveChanges();
// Get the index of the currently selected listbox item
int nCurrSelection = m_lstRelatedCollections.GetCurSel();
// Get the currently selected items text (i.e., new collection name)
int nBufSize = m_lstRelatedCollections.GetTextLen(nCurrSelection) + 1;
char* pBuf = new char[nBufSize];
int nRetVal = m_lstRelatedCollections.GetText(nCurrSelection, pBuf);
// Attempt to get a reference to the new CatalogCollection object
_bstr_t bstrCollectionName = pBuf;
_variant_t vtCollectionKey;
ICatalogCollection* pCatalogCollection = NULL;
// We might need an object key, depending on which related collection was
// selected
HRESULT hr = E_UNEXPECTED;
if (!lstrcmpW(bstrCollectionName, L"RolesForMethod") ||
!lstrcmpW(bstrCollectionName, L"MethodsForInterface") ||
!lstrcmpW(bstrCollectionName, L"InterfacesForComponent") ||
!lstrcmpW(bstrCollectionName, L"RolesForComponent") ||
!lstrcmpW(bstrCollectionName, L"Roles") ||
!lstrcmpW(bstrCollectionName, L"SubscriptionsForComponent") ||
!lstrcmpW(bstrCollectionName, L"UsersInRole") ||
!lstrcmpW(bstrCollectionName, L"Components") )
{
// Need to get the object key
int nObjectCurrSelection = m_lstObjects.GetCurSel();
int nObjectBufSize = m_lstObjects.GetTextLen(nObjectCurrSelection) + 1;
char* pObjectBuf = new char[nObjectBufSize];
nRetVal = m_lstObjects.GetText(nObjectCurrSelection, pObjectBuf);
long lCollectionCount;
int iLoopIndex;
ICatalogObject* pCatalogObject = NULL;
m_pCurrCollection->get_Count(&lCollectionCount);
_bstr_t bstrSelObjName = pObjectBuf;
for (iLoopIndex = 0; iLoopIndex < lCollectionCount; iLoopIndex++)
{
hr = m_pCurrCollection->get_Item(iLoopIndex, (IDispatch**)&pCatalogObject);
if (SUCCEEDED(hr))
{
_variant_t vtName;
hr = pCatalogObject->get_Name(&vtName);
if (SUCCEEDED(hr) && !lstrcmp(bstrSelObjName, (_bstr_t)vtName))
{
// Found it
break;
}
pCatalogObject->Release();
pCatalogObject = NULL;
}
}
if (pCatalogObject)
{
hr = pCatalogObject->get_Key(&vtCollectionKey);
pCatalogObject->Release();
}
delete [] pObjectBuf;
}
else
{
// No key needed
vtCollectionKey = bstrCollectionName;
}
hr = m_pCurrCollection->GetCollection(bstrCollectionName,
vtCollectionKey,
(IDispatch**) &pCatalogCollection);
if SUCCEEDED(hr)
{
// Navigate to the new collection
hr = NavigateTo(pCatalogCollection);
if SUCCEEDED(hr)
{
// Increment the reference count to the current CatalogCollection
// before caching its value
m_pCurrCollection->AddRef();
// Add the current CatalogCollection to the ParentCollection
// listbox (i.e., cache the current CatalogCollection object)
AddParent(m_pCurrCollection);
// Increment the reference count to the temporary CatalogCollection
// object before setting/copying it as the currenct CatalogCollection
pCatalogCollection->AddRef();
// Set the "new" current CatalogCollection to the user's selection
m_pCurrCollection = pCatalogCollection;
}
// Release the temporary ICatalogCollection pointer
pCatalogCollection->Release();
}
// Cleanup
delete [] pBuf;
}
void CVCExploreDlg::OnSelChangeParentCollections()
{
TryToSaveChanges();
// Determine which item is selected
int nIndex = m_lstParentCollections.GetCurSel();
// Remove the strings from the listbox and release the un-needed objects (i.e., un-wind/pop values off the stack)
RemoveParent(nIndex);
// Navigate to the "new" currrent CatalogCollection
NavigateTo(m_pCurrCollection);
}
int CVCExploreDlg::AddParent(ICatalogCollection *pCatalogCollection)
{
_variant_t vtName;
int nIndex = -1;
// Add the CatalogCollections name to the ParentCollection listbox
HRESULT hr = pCatalogCollection->get_Name(&vtName);
if SUCCEEDED(hr)
{
// Attempt to dd the name to the ParentCollections listbox
nIndex = m_lstParentCollections.AddString(_bstr_t(vtName));
// If successful, store/cache the ICatalogCollection pointer
if ((LB_ERR != nIndex) && (LB_ERRSPACE != nIndex))
m_lstParentCollections.SetItemDataPtr(nIndex, pCatalogCollection);
}
return nIndex;
}
void CVCExploreDlg::RemoveParent(int nNewCurrIndex)
{
// Remove the strings from the listbox and release the un-needed objects (i.e., un-wind/pop values off the stack)
for (int nPtr = (m_lstParentCollections.GetCount() - 1); nPtr >= nNewCurrIndex; nPtr--)
{
// Get the current listbox item's cached ICatalogCollection pointer
ICatalogCollection* pCatalogCollection = (ICatalogCollection*) m_lstParentCollections.GetItemDataPtr(nPtr);
// If we are on the item the user selected...
if (nNewCurrIndex == nPtr)
{
//... release the CatalogCollection we are currently pointing to...
m_pCurrCollection->Release();
//... increment the number of references to the CatalogCollection we are currently using...
pCatalogCollection->AddRef();
//... set the "new" current CatalogCollection
m_pCurrCollection = pCatalogCollection;
}
// Remove the current listbox item
m_lstParentCollections.DeleteString(nPtr);
// Release the temporary CatalogCollection object
pCatalogCollection->Release();
}
}
void CVCExploreDlg::DisplayPropertyValue()
{
// Clear the current contents of the edit control
m_edtPropertyValue.SetSel(0, -1, false);
m_edtPropertyValue.Clear();
// Determine which (if any) CatalogObject is selected
int nObjectIndex = m_lstObjects.GetCurSel();
int nPropertyIndex = m_lstProperties.GetCurSel();
// Bail if no CatalogObject OR Property selected
if ((LB_ERR == nObjectIndex) || (LB_ERR == nPropertyIndex))
return;
// Attempt to get a reference to the currently selected CatalogObject
ICatalogObject* pCatalogObject = NULL;
HRESULT hr = m_pCurrCollection->get_Item(nObjectIndex,
(IDispatch**) &pCatalogObject);
if SUCCEEDED(hr)
{
// Get the Properties name
int nTextLength = m_lstProperties.GetTextLen(nPropertyIndex);
char* pBuf = new char[nTextLength + 1];
m_lstProperties.GetText(nPropertyIndex, pBuf);
// Attempt to get the actual properties value
_bstr_t bstrPropertyName = pBuf;
delete [] pBuf;
_variant_t vtPropertyValue = "";
hr = pCatalogObject->get_Value(bstrPropertyName, &vtPropertyValue);
// Set the text if successful
if SUCCEEDED(hr)
{
short sFlag = 0;
// Read only check (i.e., enable update only if allowed)
hr = pCatalogObject->IsPropertyReadOnly(bstrPropertyName, &sFlag);
if (sFlag || FAILED(hr))
m_btnSetProperty.EnableWindow(false);
else
m_btnSetProperty.EnableWindow(true);
// Write only check (i.e., display the value only if allowed)
hr = pCatalogObject->IsPropertyWriteOnly(bstrPropertyName, &sFlag);
if (!sFlag && SUCCEEDED(hr))
{
// Set the new edit control text
try
{
m_edtPropertyValue.SetWindowText(_bstr_t(vtPropertyValue));
// Select the text
m_edtPropertyValue.SetSel(0, -1, false);
}
catch (...)
{
m_btnSetProperty.EnableWindow(false);
vtPropertyValue = "";
m_edtPropertyValue.SetWindowText(_bstr_t(vtPropertyValue));
}
}
}
// Release the temporary CatalogObject
pCatalogObject->Release();
}
}
void CVCExploreDlg::OnSelChangeObjects()
{
DisplayPropertyValue();
}
void CVCExploreDlg::OnSelChangeProperties()
{
DisplayPropertyValue();
}
ICOMAdminCatalog* CVCExploreDlg::GetCatalog()
{
// Increment the reference count on the Catalog object only if it's valid
if (NULL != m_pCatalog)
m_pCatalog->AddRef();
// Return a reference to the current Catalog object
return m_pCatalog;
}
void CVCExploreDlg::set_CurrentCollection(ICatalogCollection* pCollection)
{
// Clear the Object and Property listbox contents, if any
m_lstObjects.ResetContent();
m_lstProperties.ResetContent();
// Release all of the parent Collection objects, if any
RemoveParent(RELEASE_ALL_PARENT_OBJECTS);
// Release the current Collection
if (NULL != m_pCurrCollection)
m_pCurrCollection->Release();
// Assign the new Catalog
m_pCurrCollection = pCollection;
// Populate the collection
HRESULT hr = m_pCurrCollection->Populate();
if SUCCEEDED(hr)
// Navigate to the new collection (i.e., fill in the UI)
NavigateTo(m_pCurrCollection);
}
void CVCExploreDlg::set_ComputerName(_bstr_t bstrComputerName)
{
m_lblComputerName.SetWindowText(bstrComputerName);
}
void CVCExploreDlg::OnSetProperty()
{
// Continue only if we have a valid reference to a Catalog object
if (NULL != m_pCatalog)
{
ICatalogObject* pCatalogObject = NULL;
int nObjectIndex = m_lstObjects.GetCurSel();
int nPropertyIndex = m_lstProperties.GetCurSel();
// Only try to set a property value if a property of an object has actually
// been selected
if ((LB_ERR == nObjectIndex) || (LB_ERR == nPropertyIndex))
return;
// Attempt to get a reference to the current CatalogObject selected
HRESULT hr = m_pCurrCollection->get_Item(nObjectIndex,
(IDispatch**) &pCatalogObject);
if SUCCEEDED(hr)
{
// Get the currently selected Properties name
int nTextLength = m_lstProperties.GetTextLen(nPropertyIndex);
char* pBuf = new char[nTextLength + 1];
m_lstProperties.GetText(nPropertyIndex, pBuf);
_bstr_t bstrPropertyName = pBuf;
delete [] pBuf;
// Extract the new value from the UI
int nNewValueLength = m_edtPropertyValue.GetWindowTextLength() + 1;
char* pNewValueBuf = new char[nNewValueLength];
m_edtPropertyValue.GetWindowText(pNewValueBuf, nNewValueLength);
_bstr_t bstrNewValue = pNewValueBuf;
delete [] pNewValueBuf;
_variant_t vtPropertyValue = bstrNewValue;
// Attempt to update the Properties value
hr = pCatalogObject->put_Value(bstrPropertyName, vtPropertyValue);
// Validate success/fail of the operation
if SUCCEEDED(hr)
{
CWnd* pToolbar = GetDlgItem(IDR_TOOLBAR_MAIN);
pToolbar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_SAVE, MAKELONG(true, 0));
m_bChangesArePending = TRUE;
}
else
MessageBox("Failed to save the selected CatalogObject's property value.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
// Release the temporary CatalogObject
pCatalogObject->Release();
}
else
MessageBox("Failed to obtain a reference to the selected CatalogObject.\n\nNo Processing will be performed.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
}
else
MessageBox("Invalid Catalog object.\n\nNo Processing will be performed.\n\nPress OK to continue.",
"Error",
(MB_OK | MB_ICONERROR));
}
void CVCExploreDlg::TryToSaveChanges()
{
if (!m_bChangesArePending)
{
// nothing to do
return;
}
int iMBRet = MessageBox("Do you wish to save your changes before continuing?", "Changes may be lost!", MB_ICONWARNING | MB_YESNO);
if (iMBRet == IDYES)
{
long lCount;
m_pCurrCollection->SaveChanges(&lCount);
}
CWnd* pToolBar = GetDlgItem(IDR_TOOLBAR_MAIN);
pToolBar->SendMessage(TB_ENABLEBUTTON, ID_TBTN_SAVE, MAKELONG(false, 0));
m_bChangesArePending = FALSE;
}