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

1138 lines
33 KiB
C++

//=--------------------------------------------------------------------------------------
// psextend.cpp
//=--------------------------------------------------------------------------------------
//
// Copyright (c) 1999, Microsoft Corporation.
// All Rights Reserved.
//
// Information Contained Herein Is Proprietary and Confidential.
//
//=------------------------------------------------------------------------------------=
//
// Snap-In Property Sheet implementation
//=-------------------------------------------------------------------------------------=
#include "pch.h"
#include "common.h"
#include "psextend.h"
// for ASSERT and FAIL
//
SZTHISFILE
const int kMaxBuffer = 1024;
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//
// Holder for available MMC Node Types
//
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//=--------------------------------------------------------------------------------------
// CMMCNodeType::CMMCNodeType(const char *pszName, const char *pszGuid)
//=--------------------------------------------------------------------------------------
//
// Notes
//
CMMCNodeType::CMMCNodeType
(
const char *pszName,
const char *pszGuid
)
: CCheckedListItem(false), m_pszName(0), m_pszGuid(0)
{
m_pszName = reinterpret_cast<char *>(CtlAlloc(::strlen(pszName) + 1));
if (NULL != m_pszName)
{
::strcpy(m_pszName, pszName);
}
m_pszGuid = reinterpret_cast<char *>(CtlAlloc(::strlen(pszGuid) + 1));
if (NULL != m_pszGuid)
{
::strcpy(m_pszGuid, pszGuid);
}
}
//=--------------------------------------------------------------------------------------
// CMMCNodeType::~CMMCNodeType()
//=--------------------------------------------------------------------------------------
//
// Notes
//
CMMCNodeType::~CMMCNodeType()
{
if (NULL != m_pszName)
CtlFree(m_pszName);
if (NULL != m_pszGuid)
CtlFree(m_pszGuid);
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//
// SnapIn Property Page "Available Nodes"
//
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
//=--------------------------------------------------------------------------------------
// IUnknown *CSnapInAvailNodesPage::Create(IUnknown *pUnkOuter)
//=--------------------------------------------------------------------------------------
//
// Notes
//
IUnknown *CSnapInAvailNodesPage::Create(IUnknown *pUnkOuter)
{
CSnapInAvailNodesPage *pNew = New CSnapInAvailNodesPage(pUnkOuter);
return pNew->PrivateUnknown();
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::CSnapInAvailNodesPage(IUnknown *pUnkOuter)
//=--------------------------------------------------------------------------------------
//
// Notes
//
CSnapInAvailNodesPage::CSnapInAvailNodesPage
(
IUnknown *pUnkOuter
)
: CSIPropertyPage(pUnkOuter, OBJECT_TYPE_PPGSNAPINAVAILNO),
m_piSnapInDesignerDef(0), m_piSnapInDef(0), m_pCheckList(0), m_pMMCNodeType(0), m_bEnabled(false)
{
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::~CSnapInAvailNodesPage()
//=--------------------------------------------------------------------------------------
//
// Notes
//
CSnapInAvailNodesPage::~CSnapInAvailNodesPage()
{
RELEASE(m_piSnapInDef);
RELEASE(m_piSnapInDesignerDef);
if (NULL != m_pCheckList)
{
m_pCheckList->Detach();
delete m_pCheckList;
}
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnInitializeDialog()
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnInitializeDialog()
{
HRESULT hr = S_OK;
m_pCheckList = New CCheckList(IDC_LIST_AVAILABLE_NODES);
if (NULL == m_pCheckList)
{
hr = SID_E_OUTOFMEMORY;
EXCEPTION_CHECK_GO(hr);
}
hr = m_pCheckList->Attach(::GetDlgItem(m_hwnd, IDC_LIST_AVAILABLE_NODES));
IfFailGo(hr);
Error:
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnNewObjects()
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnNewObjects()
{
HRESULT hr = S_OK;
IUnknown *pUnk = NULL;
DWORD dwDummy = 0;
IObjectModel *piObjectModel = NULL;
ISnapInDef *piSnapInDef = NULL;
SnapInTypeConstants sitc = siStandAlone;
TCHAR szBuffer[kMaxBuffer + 1];
if (NULL != m_piSnapInDef)
goto Error; // Handle only one object
pUnk = FirstControl(&dwDummy);
if (NULL == pUnk)
{
hr = SID_E_INTERNAL;
EXCEPTION_CHECK_GO(hr);
}
hr = pUnk->QueryInterface(IID_ISnapInDef, reinterpret_cast<void **>(&m_piSnapInDef));
if (FAILED(hr))
{
hr = SID_E_INTERNAL;
EXCEPTION_CHECK_GO(hr);
}
hr = pUnk->QueryInterface(IID_IObjectModel, reinterpret_cast<void **>(&piObjectModel));
if (FAILED(hr))
{
hr = SID_E_INTERNAL;
EXCEPTION_CHECK_GO(hr);
}
hr = piObjectModel->GetSnapInDesignerDef(&m_piSnapInDesignerDef);
IfFailGo(hr);
hr = m_piSnapInDesignerDef->get_SnapInDef(&piSnapInDef);
IfFailGo(hr);
hr = piSnapInDef->get_Type(&sitc);
IfFailGo(hr);
if (siStandAlone != sitc)
{
hr = PopulateAvailNodesDialog();
IfFailGo(hr);
::EnableWindow(::GetDlgItem(m_hwnd, IDC_BUTTON_PROPERTIES), FALSE);
::SendMessage(::GetDlgItem(m_hwnd, IDC_LIST_AVAILABLE_NODES), LB_SETCURSEL, 0, 0);
m_bEnabled = true;
}
else
{
::EnableWindow(::GetDlgItem(m_hwnd, IDC_BUTTON_ADD), FALSE);
::EnableWindow(::GetDlgItem(m_hwnd, IDC_BUTTON_PROPERTIES), FALSE);
hr = GetResourceString(IDS_TT_EXTEND_INSTRUCTIONS, szBuffer, kMaxBuffer);
IfFailGo(hr);
::SetWindowText(::GetDlgItem(m_hwnd, IDC_STATIC_EXTEND_INSTRUCTIONS), szBuffer);
}
Error:
RELEASE(piSnapInDef);
RELEASE(piObjectModel);
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInGeneralPage::OnApply()
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnApply()
{
HRESULT hr = S_OK;
int iCount = 0;
int iIndex = 0;
CMMCNodeType *pNodeType = NULL;
VARIANT_BOOL bCheck = VARIANT_FALSE;
BSTR bstrNodeTypeGUID = NULL;
IExtendedSnapIn *piExtendedSnapIn = NULL;
ASSERT(NULL != m_piSnapInDef, "OnApply: m_piSnapInDef is NULL");
m_pCheckList->GetNumberOfItems(&iCount);
IfFailGo(hr);
for (iIndex = 0; iIndex < iCount; ++iIndex)
{
hr = m_pCheckList->GetItemData(iIndex, reinterpret_cast<void **>(&pNodeType));
IfFailGo(hr);
if (NULL == pNodeType)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
hr = m_pCheckList->GetItemCheck(iIndex, &bCheck);
IfFailGo(hr);
hr = BSTRFromANSI(pNodeType->m_pszGuid, &bstrNodeTypeGUID);
IfFailGo(hr);
if (VARIANT_TRUE == bCheck)
{
hr = FindSnapIn(bstrNodeTypeGUID, &piExtendedSnapIn);
IfFailGo(hr);
if (S_FALSE == hr)
{
hr = AddSnapIn(pNodeType);
IfFailGo(hr);
}
}
else
{
hr = FindSnapIn(bstrNodeTypeGUID, &piExtendedSnapIn);
IfFailGo(hr);
if (S_OK == hr)
{
hr = RemoveSnapIn(pNodeType);
IfFailGo(hr);
}
}
FREESTRING(bstrNodeTypeGUID);
RELEASE(piExtendedSnapIn);
}
Error:
FREESTRING(bstrNodeTypeGUID);
RELEASE(piExtendedSnapIn);
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnCtlSelChange(int dlgItemID)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnCtlSelChange
(
int dlgItemID
)
{
HRESULT hr = S_OK;
long lIndex = 0;
DebugPrintf("OnCtlSelChange() m_bEnabled=%d\r\n", m_bEnabled);
if (true == m_bEnabled)
{
lIndex = ::SendMessage(::GetDlgItem(m_hwnd, IDC_LIST_AVAILABLE_NODES), LB_GETCURSEL, 0, 0);
if (LB_ERR == lIndex)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
if (LB_ERR != lIndex)
{
hr = m_pCheckList->GetItemData(lIndex, reinterpret_cast<void **>(&m_pMMCNodeType));
IfFailGo(hr);
if (NULL == m_pMMCNodeType)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
::EnableWindow(::GetDlgItem(m_hwnd, IDC_BUTTON_PROPERTIES), TRUE);
}
}
Error:
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnCtlSetFocus(int dlgItemID)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnCtlSetFocus
(
int dlgItemID
)
{
HRESULT hr = S_OK;
long lIndex = 0;
DebugPrintf("OnCtlSetFocus() m_bEnabled=%d\r\n", m_bEnabled);
if (true == m_bEnabled)
{
lIndex = ::SendMessage(::GetDlgItem(m_hwnd, IDC_LIST_AVAILABLE_NODES), LB_GETCURSEL, 0, 0);
if (lIndex == LB_ERR)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
if (LB_ERR != lIndex)
{
hr = m_pCheckList->GetItemData(lIndex, reinterpret_cast<void **>(&m_pMMCNodeType));
IfFailGo(hr);
if (NULL == m_pMMCNodeType)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
::EnableWindow(::GetDlgItem(m_hwnd, IDC_BUTTON_PROPERTIES), TRUE);
}
}
Error:
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnButtonClicked(int dlgItemID)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnButtonClicked
(
int dlgItemID
)
{
HRESULT hr = S_OK;
switch (dlgItemID)
{
case IDC_BUTTON_ADD:
hr = OnNewAvailNode();
IfFailGo(hr);
break;
case IDC_BUTTON_PROPERTIES:
if (NULL != m_pMMCNodeType)
{
hr = OnProperties(m_pMMCNodeType);
IfFailGo(hr);
}
break;
}
::SetFocus(::GetDlgItem(m_hwnd, IDC_LIST_AVAILABLE_NODES));
Error:
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnMeasureItem(MEASUREITEMSTRUCT *pMeasureItemStruct)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnMeasureItem
(
MEASUREITEMSTRUCT *pMeasureItemStruct
)
{
HRESULT hr = S_OK;
HDC hdc = NULL;
BOOL bResult = FALSE;
TEXTMETRIC tm;
DebugPrintf("OnMeasureItem() m_bEnabled=%d\r\n", m_bEnabled);
if (true == m_bEnabled)
{
hdc = ::GetDC(m_hwnd);
if (NULL == hdc)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
bResult = ::GetTextMetrics(hdc, &tm);
if (FALSE == bResult)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
pMeasureItemStruct->itemWidth = 0;
pMeasureItemStruct->itemHeight = tm.tmHeight;
}
Error:
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnDrawItem(DRAWITEMSTRUCT *pDrawItemStruct)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnDrawItem
(
DRAWITEMSTRUCT *pDrawItemStruct
)
{
HRESULT hr = S_OK;
CCheckedListItem *pCheckedListItem = NULL;
ASSERT(NULL != m_pCheckList, "OnDrawItem: m_pCheckList is NULL");
DebugPrintf("OnDrawItem() m_bEnabled=%d\r\n", m_bEnabled);
if (true == m_bEnabled)
{
hr = m_pCheckList->GetItemData(pDrawItemStruct->itemID, reinterpret_cast<void **>(&pCheckedListItem));
IfFailGo(hr);
hr = m_pCheckList->DrawItem(pDrawItemStruct, pCheckedListItem->m_bSelected);
IfFailGo(hr);
}
Error:
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnDestroy()
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnDestroy()
{
HRESULT hr = S_OK;
long lCount = 0;
long lIndex = 0;
CCheckedListItem *pCheckedListItem = NULL;
if (NULL != m_pCheckList)
{
lCount = ::SendMessage(m_pCheckList->Window(), LB_GETCOUNT, 0, 0);
if (LB_ERR != lCount)
{
for (lIndex = 0; lIndex < lCount; ++lIndex)
{
hr = m_pCheckList->GetItemData(lIndex, reinterpret_cast<void **>(&pCheckedListItem));
if (NULL != pCheckedListItem)
delete pCheckedListItem;
}
}
m_pCheckList->Detach();
delete m_pCheckList;
m_pCheckList = NULL;
}
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::AddSnapInToList(HKEY hkeyNodeTypes, const TCHAR *pszKeyName)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::AddSnapInToList
(
HKEY hkeyNodeTypes,
const TCHAR *pszKeyName
)
{
HRESULT hr = S_OK;
long lResult = 0;
HKEY hkeyRegisteredSnapIn = NULL;
unsigned long lBufSize = kSIMaxBuffer;
TCHAR pszName[kSIMaxBuffer + 1];
CMMCNodeType *pMMCNodeType = NULL;
int iIndex = 0;
BSTR bstrNodeTypeGUID = NULL;
IExtendedSnapIn *piExtendedSnapIn = NULL;
lResult = RegOpenKeyEx(hkeyNodeTypes, pszKeyName, 0, KEY_READ, &hkeyRegisteredSnapIn);
if (ERROR_SUCCESS != lResult)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
lResult = RegQueryValue(hkeyRegisteredSnapIn, NULL, pszName, reinterpret_cast<long *>(&lBufSize));
if (ERROR_SUCCESS != lResult)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
pMMCNodeType = New CMMCNodeType(pszName, pszKeyName);
if (NULL == pMMCNodeType)
{
hr = SID_E_OUTOFMEMORY;
EXCEPTION_CHECK_GO(hr);
}
if (0 == _tcslen(pszName))
{
hr = m_pCheckList->AddString(pszKeyName, &iIndex);
IfFailGo(hr);
}
else
{
hr = m_pCheckList->AddString(pszName, &iIndex);
IfFailGo(hr);
}
hr = m_pCheckList->SetItemData(iIndex, pMMCNodeType);
IfFailGo(hr);
hr = BSTRFromANSI(pszKeyName, &bstrNodeTypeGUID);
IfFailGo(hr);
hr = FindSnapIn(bstrNodeTypeGUID, &piExtendedSnapIn);
IfFailGo(hr);
if (S_OK == hr)
{
hr = m_pCheckList->SetItemCheck(iIndex, VARIANT_TRUE);
IfFailGo(hr);
}
Error:
RELEASE(piExtendedSnapIn);
FREESTRING(bstrNodeTypeGUID);
if (NULL != hkeyRegisteredSnapIn)
RegCloseKey(hkeyRegisteredSnapIn);
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::PopulateAvailNodesDialog()
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::PopulateAvailNodesDialog()
{
HRESULT hr = S_OK;
long lResult = 0;
HKEY hkeyNodeTypes = 0;
DWORD dwIndex = 0;
TCHAR pszKeyName[kSIMaxBuffer + 1];
TCHAR pszClass[kSIMaxBuffer + 1];
unsigned long lBufSize = kSIMaxBuffer;
FILETIME fileTime;
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\MMC\\NodeTypes"), 0, KEY_READ, &hkeyNodeTypes);
if (ERROR_SUCCESS != lResult)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
while (1)
{
lResult = RegEnumKeyEx(hkeyNodeTypes,
dwIndex,
pszKeyName,
&lBufSize,
0,
pszClass,
&lBufSize,
&fileTime);
if (ERROR_NO_MORE_ITEMS == lResult)
break;
if (ERROR_SUCCESS != lResult)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
hr = AddSnapInToList(hkeyNodeTypes, pszKeyName);
IfFailGo(hr);
pszKeyName[0] = '\0';
pszClass[0] = '\0';
lBufSize = kSIMaxBuffer;
++dwIndex;
}
Error:
if (NULL != hkeyNodeTypes)
RegCloseKey(hkeyNodeTypes);
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnNewAvailNode()
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnNewAvailNode()
{
HRESULT hr = S_OK;
CMMCNodeType *pMMCNodeType = NULL;
int iResult = 0;
int iIndex = 0;
pMMCNodeType = New CMMCNodeType("", "");
if (NULL == pMMCNodeType)
{
hr = SID_E_OUTOFMEMORY;
EXCEPTION_CHECK_GO(hr);
}
iResult = ::DialogBoxParam(GetResourceHandle(),
MAKEINTRESOURCE(IDD_DIALOG_ADD_TO_AVAILABLE),
m_hwnd,
reinterpret_cast<DLGPROC>(NodeTypeDialogProc),
reinterpret_cast<LPARAM>(pMMCNodeType));
if (-1 == iResult)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
if (1 == iResult)
{
if (0 != ::strlen(pMMCNodeType->m_pszName))
{
hr = m_pCheckList->AddString(pMMCNodeType->m_pszName, &iIndex);
IfFailGo(hr);
}
else
{
hr = m_pCheckList->AddString(pMMCNodeType->m_pszGuid, &iIndex);
IfFailGo(hr);
}
hr = m_pCheckList->SetItemData(iIndex, pMMCNodeType);
IfFailGo(hr);
// Select this node-type.
hr = m_pCheckList->SetItemCheck(iIndex, VARIANT_TRUE);
IfFailGo(hr);
}
Error:
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnProperties(CMMCNodeType *pMMCNodeType)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnProperties
(
CMMCNodeType *pMMCNodeType
)
{
HRESULT hr = S_OK;
int iResult = 0;
iResult = ::DialogBoxParam(GetResourceHandle(),
MAKEINTRESOURCE(IDD_DIALOG_ADD_TO_AVAILABLE),
m_hwnd,
reinterpret_cast<DLGPROC>(NodeTypeDialogProc),
reinterpret_cast<LPARAM>(pMMCNodeType));
if (-1 == iResult)
{
hr = HRESULT_FROM_WIN32(::GetLastError());
EXCEPTION_CHECK_GO(hr);
}
Error:
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::NodeTypeDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
//=--------------------------------------------------------------------------------------
//
// Notes
//
BOOL CALLBACK CSnapInAvailNodesPage::NodeTypeDialogProc
(
HWND hwndDlg,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
CMMCNodeType *pMMCNodeType = NULL;
TCHAR pszBuffer[kSIMaxBuffer + 1];
HRESULT hr = S_OK;
WCHAR *pwszGUID = NULL;
int nRet = 0;
if (WM_INITDIALOG == uMsg)
{
pMMCNodeType = reinterpret_cast<CMMCNodeType *>(lParam);
::SetWindowLong(hwndDlg, DWL_USER, reinterpret_cast<LONG>(pMMCNodeType));
if (NULL != pMMCNodeType)
{
::SetDlgItemText(hwndDlg, IDC_EDIT_AVAIL_NODE_GUID, pMMCNodeType->m_pszGuid);
::SetDlgItemText(hwndDlg, IDC_EDIT_AVAIL_NODE_NAME, pMMCNodeType->m_pszName);
// If we are showing properties for an existing node type then disable
// the edit controls and hide the Cancel button
if (::strlen(pMMCNodeType->m_pszGuid) > 0)
{
::EnableWindow(::GetDlgItem(hwndDlg, IDC_EDIT_AVAIL_NODE_NAME), FALSE);
::EnableWindow(::GetDlgItem(hwndDlg, IDC_EDIT_AVAIL_NODE_GUID), FALSE);
::ShowWindow(::GetDlgItem(hwndDlg, IDCANCEL), SW_HIDE);
}
else
{
// The user has asked to add a new node type. Disable the OK
// button until something has been typed in.
::EnableWindow(::GetDlgItem(hwndDlg, IDOK), FALSE);
}
}
return TRUE;
}
pMMCNodeType = reinterpret_cast<CMMCNodeType *>(::GetWindowLong(hwndDlg, DWL_USER));
switch (uMsg)
{
case WM_HELP:
g_GlobalHelp.ShowHelp(HID_mssnapd_AddToAvailableNodes);
return TRUE;
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
// Get the node type string entered by the user
::GetDlgItemText(hwndDlg, IDC_EDIT_AVAIL_NODE_GUID, reinterpret_cast<LPTSTR>(pszBuffer), kSIMaxBuffer);
// Convert to wide char
hr = ::WideStrFromANSI(pszBuffer, &pwszGUID);
if (FAILED(hr))
{
//UNDONE: generate error message here
GLOBAL_EXCEPTION_CHECK(hr);
::EndDialog(hwndDlg, 0);
}
// Check that the GUID string entered is indeed a GUID
CLSID clsid = CLSID_NULL;
hr = ::CLSIDFromString(pwszGUID, &clsid);
CtlFree(pwszGUID);
if (CO_E_CLASSSTRING == hr)
{
hr = ::SDU_DisplayMessage(IDS_INVALID_GUID,
MB_OK | MB_ICONHAND,
HID_mssnapd_InvalidGuid, 0,
DontAppendErrorInfo, &nRet);
if (FAILED(hr))
{
GLOBAL_EXCEPTION_CHECK(hr);
}
if ( FAILED(hr) || (IDCANCEL == nRet) )
{
::EndDialog(hwndDlg, 0);
}
else
{
return TRUE;
}
}
if (NULL != pMMCNodeType->m_pszGuid)
CtlFree(pMMCNodeType->m_pszGuid);
pMMCNodeType->m_pszGuid = reinterpret_cast<char *>(CtlAlloc(::strlen(pszBuffer) + 1));
if (NULL == pMMCNodeType->m_pszGuid)
{
//UNDONE: generate error message here
GLOBAL_EXCEPTION_CHECK(SID_E_OUTOFMEMORY);
::EndDialog(hwndDlg, 0);
return TRUE;
}
::strcpy(pMMCNodeType->m_pszGuid, pszBuffer);
::GetDlgItemText(hwndDlg, IDC_EDIT_AVAIL_NODE_NAME, reinterpret_cast<LPTSTR>(pszBuffer), kSIMaxBuffer);
if (NULL != pMMCNodeType->m_pszName)
CtlFree(pMMCNodeType->m_pszName);
pMMCNodeType->m_pszName = reinterpret_cast<char *>(CtlAlloc(::strlen(pszBuffer) + 1));
if (NULL == pMMCNodeType->m_pszName)
{
//UNDONE: generate error message here
GLOBAL_EXCEPTION_CHECK(SID_E_OUTOFMEMORY);
::EndDialog(hwndDlg, 0);
}
::strcpy(pMMCNodeType->m_pszName, pszBuffer);
// return 1 to indicate user entered valid data
::EndDialog(hwndDlg, 1);
return TRUE;
break;
}
case IDCANCEL:
::EndDialog(hwndDlg, 0);
return TRUE;
break;
case IDHELP:
g_GlobalHelp.ShowHelp(HID_mssnapd_AddToAvailableNodes);
return TRUE;
break;
case IDC_EDIT_AVAIL_NODE_GUID:
if (EN_CHANGE == HIWORD(wParam))
{
// If the GUID edit field is empty then disable the OK button
if (0 == ::GetDlgItemText(hwndDlg, IDC_EDIT_AVAIL_NODE_GUID,
pszBuffer, kSIMaxBuffer))
{
::EnableWindow(::GetDlgItem(hwndDlg, IDOK), FALSE);
}
else
{
::EnableWindow(::GetDlgItem(hwndDlg, IDOK), TRUE);
}
}
break;
}
break;
}
return FALSE;
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::OnDefault(UINT uiMsg, WPARAM wParam, LPARAM lParam)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::OnDefault(UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
HRESULT hr = S_FALSE;
switch (uiMsg)
{
case kCheckBoxChanged:
hr = S_OK; // message was handled
MakeDirty();
break;
}
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::FindSnapIn(BSTR bstrNodeTypeGUID, IExtendedSnapIn **ppiExtendedSnapIn)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::FindSnapIn(BSTR bstrNodeTypeGUID, IExtendedSnapIn **ppiExtendedSnapIn)
{
HRESULT hr = S_FALSE;
IExtensionDefs *piExtensionDefs = NULL;
IExtendedSnapIns *piExtendedSnapIns = NULL;
long lCount = 0;
long lIndex = 0;
VARIANT vtIndex;
IExtendedSnapIn *piExtendedSnapIn = NULL;
BSTR bstrThisNodeGUID = NULL;
::VariantInit(&vtIndex);
hr = m_piSnapInDesignerDef->get_ExtensionDefs(&piExtensionDefs);
IfFailGo(hr);
hr = piExtensionDefs->get_ExtendedSnapIns(&piExtendedSnapIns);
IfFailGo(hr);
hr = piExtendedSnapIns->get_Count(&lCount);
IfFailGo(hr);
for (lIndex = 1; lIndex <= lCount; ++lIndex)
{
vtIndex.vt = VT_I4;
vtIndex.lVal = lIndex;
hr = piExtendedSnapIns->get_Item(vtIndex, &piExtendedSnapIn);
IfFailGo(hr);
hr = piExtendedSnapIn->get_NodeTypeGUID(&bstrThisNodeGUID);
IfFailGo(hr);
if (0 == ::wcscmp(bstrNodeTypeGUID, bstrThisNodeGUID))
{
*ppiExtendedSnapIn = piExtendedSnapIn;
piExtendedSnapIn->AddRef();
hr = S_OK;
goto Error;
}
FREESTRING(bstrThisNodeGUID);
RELEASE(piExtendedSnapIn);
}
hr = S_FALSE;
Error:
FREESTRING(bstrThisNodeGUID);
::VariantClear(&vtIndex);
RELEASE(piExtendedSnapIn);
RELEASE(piExtendedSnapIns);
RELEASE(piExtensionDefs);
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::AddSnapIn(CMMCNodeType *pCMMCNodeType)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::AddSnapIn(CMMCNodeType *pCMMCNodeType)
{
HRESULT hr = S_OK;
BSTR bstrNodeTypeGUID = NULL;
IExtendedSnapIn *piExtendedSnapIn = NULL;
IExtensionDefs *piExtensionDefs = NULL;
IExtendedSnapIns *piExtendedSnapIns = NULL;
VARIANT vtIndex;
VARIANT vtKey;
BSTR bstrNodeTypeName = NULL;
ASSERT(NULL != pCMMCNodeType, "AddSnapIn: pCMMCNodeType is NULL");
::VariantInit(&vtIndex);
::VariantInit(&vtKey);
hr = ::BSTRFromANSI(pCMMCNodeType->m_pszGuid, &bstrNodeTypeGUID);
IfFailGo(hr);
hr = m_piSnapInDesignerDef->get_ExtensionDefs(&piExtensionDefs);
IfFailGo(hr);
hr = piExtensionDefs->get_ExtendedSnapIns(&piExtendedSnapIns);
IfFailGo(hr);
vtIndex.vt = VT_ERROR;
vtIndex.scode = DISP_E_PARAMNOTFOUND;
vtKey.vt = VT_BSTR;
vtKey.bstrVal = ::SysAllocString(bstrNodeTypeGUID);
if (NULL == vtKey.bstrVal)
{
hr = SID_E_OUTOFMEMORY;
EXCEPTION_CHECK(hr);
}
hr = piExtendedSnapIns->Add(vtIndex, vtKey, &piExtendedSnapIn);
IfFailGo(hr);
hr = piExtendedSnapIn->put_NodeTypeGUID(bstrNodeTypeGUID);
IfFailGo(hr);
hr = BSTRFromANSI(pCMMCNodeType->m_pszName, &bstrNodeTypeName);
IfFailGo(hr);
hr = piExtendedSnapIn->put_NodeTypeName(bstrNodeTypeName);
IfFailGo(hr);
Error:
::VariantClear(&vtIndex);
::VariantClear(&vtKey);
FREESTRING(bstrNodeTypeName);
FREESTRING(bstrNodeTypeGUID);
RELEASE(piExtendedSnapIn);
RELEASE(piExtendedSnapIns);
RELEASE(piExtensionDefs);
FREESTRING(bstrNodeTypeGUID);
RRETURN(hr);
}
//=--------------------------------------------------------------------------------------
// CSnapInAvailNodesPage::RemoveSnapIn(CMMCNodeType *pCMMCNodeType)
//=--------------------------------------------------------------------------------------
//
// Notes
//
HRESULT CSnapInAvailNodesPage::RemoveSnapIn(CMMCNodeType *pCMMCNodeType)
{
HRESULT hr = S_OK;
BSTR bstrNodeTypeGUID = NULL;
IExtensionDefs *piExtensionDefs = NULL;
IExtendedSnapIns *piExtendedSnapIns = NULL;
VARIANT vtKey;
ASSERT(NULL != pCMMCNodeType, "RemoveSnapIn: pCMMCNodeType is NULL");
::VariantInit(&vtKey);
hr = BSTRFromANSI(pCMMCNodeType->m_pszGuid, &bstrNodeTypeGUID);
IfFailGo(hr);
hr = m_piSnapInDesignerDef->get_ExtensionDefs(&piExtensionDefs);
IfFailGo(hr);
hr = piExtensionDefs->get_ExtendedSnapIns(&piExtendedSnapIns);
IfFailGo(hr);
vtKey.vt = VT_BSTR;
vtKey.bstrVal = ::SysAllocString(bstrNodeTypeGUID);
if (NULL == vtKey.bstrVal)
{
hr = SID_E_OUTOFMEMORY;
EXCEPTION_CHECK(hr);
}
hr = piExtendedSnapIns->Remove(vtKey);
IfFailGo(hr);
Error:
::VariantClear(&vtKey);
RELEASE(piExtendedSnapIns);
RELEASE(piExtensionDefs);
FREESTRING(bstrNodeTypeGUID);
RRETURN(hr);
}