// // relation.cpp : Implementation of ClassRelationshipPage // // Jon Newman // Copyright (c) Microsoft Corporation 1997 // #include "stdafx.h" #include "macros.h" USE_HANDLE_MACROS("SCHMMGMT(relation.cpp)") #include "compdata.h" #include "schmutil.h" #include "relation.h" #include "select.h" const CDialogControlsInfo ctrls[] = { { IDC_CLASS_REL_AUX_CLASSES, g_AuxiliaryClass, FALSE }, { IDC_CLASS_REL_AUX_ADD, g_AuxiliaryClass, FALSE }, { IDC_CLASS_REL_SUPER_CLASSES, g_Superiors, FALSE }, { IDC_CLASS_REL_SUPER_ADD, g_Superiors, FALSE }, } ; const DWORD ClassRelationshipPage::help_map[] = { IDI_CLASS, NO_HELP, IDC_CLASS_REL_NAME_STATIC, NO_HELP, IDC_CLASS_REL_PARENT_EDIT, IDH_CLASS_REL_PARENT_EDIT, IDC_CLASS_REL_AUX_CLASSES, IDH_CLASS_REL_AUX_CLASSES, IDC_STATIC_SYSTEMONLY_AUXILIARY, NO_HELP, IDC_CLASS_REL_AUX_ADD, IDH_CLASS_REL_AUX_ADD, IDC_CLASS_REL_AUX_REMOVE, IDH_CLASS_REL_AUX_REMOVE, IDC_CLASS_REL_SUPER_CLASSES, IDH_CLASS_REL_SUPER_CLASSES, IDC_STATIC_SYSTEMONLY_SUPERIOR, NO_HELP, IDC_CLASS_REL_SUPER_ADD, IDH_CLASS_REL_SUPER_ADD, IDC_CLASS_REL_SUPER_REMOVE, IDH_CLASS_REL_SUPER_REMOVE, IDC_CLASS_REL_SYSCLASS_STATIC, NO_HELP, 0,0 }; ClassRelationshipPage::ClassRelationshipPage( ComponentData *pScope, LPDATAOBJECT lpDataObject ) : CPropertyPage(ClassRelationshipPage::IDD) , m_pIADsObject( NULL ) , fSystemClass( FALSE ) , m_pSchemaObject( NULL ) , m_pScopeControl( pScope ) , m_lpScopeDataObj( lpDataObject ) { ASSERT( NULL != m_pScopeControl ); ASSERT( NULL != lpDataObject ); } ClassRelationshipPage::~ClassRelationshipPage() { if (NULL != m_pIADsObject) m_pIADsObject->Release(); if (NULL != m_pSchemaObject) { m_pScopeControl->g_SchemaCache.ReleaseRef( m_pSchemaObject ); } } void ClassRelationshipPage::Load( Cookie& CookieRef ) { // // Store the cookie object pointer. // m_pCookie = &CookieRef; return; } BOOL ClassRelationshipPage::OnInitDialog() { HRESULT hr = S_OK; ASSERT( NULL == m_pIADsObject && m_szAdsPath.IsEmpty() ); // // Get the schema cache object and the actual ADS object. // m_pSchemaObject = m_pScopeControl->g_SchemaCache.LookupSchemaObjectByCN( m_pCookie->strSchemaObject, SCHMMGMT_CLASS ); if ( m_pSchemaObject ) { m_pScopeControl->GetSchemaObjectPath( m_pSchemaObject->commonName, m_szAdsPath ); if ( !m_szAdsPath.IsEmpty() ) { hr = ADsGetObject( (LPWSTR)(LPCWSTR)m_szAdsPath, IID_IADs, (void **)&m_pIADsObject ); ASSERT( SUCCEEDED(hr) ); } } // // If we have no ADS object, we should error out! // if ( !m_pIADsObject ) { DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_NO_SCHEMA_OBJECT ); ASSERT(FALSE); return TRUE; } // // get the current values. // VARIANT AdsResult; VariantInit( &AdsResult ); // // ObjectName // hr = m_pIADsObject->Get( const_cast((LPCTSTR)g_DisplayName), &AdsResult ); if ( SUCCEEDED( hr ) ) { ASSERT( AdsResult.vt == VT_BSTR ); ObjectName = AdsResult.bstrVal; VariantClear( &AdsResult ); } // // Parent Class. // hr = m_pIADsObject->Get( const_cast((LPCTSTR)g_SubclassOf), &AdsResult ); if ( SUCCEEDED( hr ) ) { ASSERT( AdsResult.vt == VT_BSTR ); ParentClass = AdsResult.bstrVal; VariantClear( &AdsResult ); } // // SysClass // hr = m_pIADsObject->Get( const_cast((LPCTSTR)g_SystemOnly), &AdsResult ); if ( SUCCEEDED( hr ) ) { ASSERT( AdsResult.vt == VT_BOOL ); fSystemClass = AdsResult.boolVal; if ( fSystemClass ) { SysClassString = g_SysClassString; } else { SysClassString = L""; } VariantClear( &AdsResult ); } else { SysClassString = L""; } // // Determine the auxiliary classes // VARIANT varClasses; VariantInit( &varClasses ); hr = m_pIADsObject->GetEx( g_AuxiliaryClass, &varClasses ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); if( SUCCEEDED(hr) ) { hr = VariantToStringList( varClasses, strlistAuxiliary ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); } VariantClear( &varClasses ); hr = m_pIADsObject->GetEx( g_SystemAuxiliaryClass, &varClasses ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); if( SUCCEEDED(hr) ) { hr = VariantToStringList( varClasses, strlistSystemAuxiliary ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); } VariantClear( &varClasses ); // // Determine the superior classes // hr = m_pIADsObject->GetEx( g_Superiors, &varClasses ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); if( SUCCEEDED(hr) ) { hr = VariantToStringList( varClasses, strlistSuperior ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); } VariantClear( &varClasses ); hr = m_pIADsObject->GetEx( g_SystemSuperiors, &varClasses ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); if( SUCCEEDED(hr) ) { hr = VariantToStringList( varClasses, strlistSystemSuperior ); ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr ); } VariantClear( &varClasses ); hr = DissableReadOnlyAttributes( this, m_pIADsObject, ctrls, sizeof(ctrls)/sizeof(ctrls[0]) ); ASSERT( SUCCEEDED(hr) ); // shouldn't fail, but unimportant, so ignore error // This calls must be done before DDX binding m_listboxAuxiliary.InitType( m_pScopeControl, SELECT_AUX_CLASSES, IDC_CLASS_REL_AUX_REMOVE, &strlistSystemAuxiliary, IDC_STATIC_SYSTEMONLY_AUXILIARY ); m_listboxSuperior.InitType( m_pScopeControl, SELECT_CLASSES, IDC_CLASS_REL_SUPER_REMOVE, &strlistSystemSuperior, IDC_STATIC_SYSTEMONLY_SUPERIOR ); CPropertyPage::OnInitDialog(); return TRUE; } BOOL ClassRelationshipPage::OnSetActive() { // always enable the Apply button SetModified(TRUE); return TRUE; } void ClassRelationshipPage::DoDataExchange( CDataExchange *pDX ) { HRESULT hr = S_OK; CPropertyPage::DoDataExchange( pDX ); //{{AFX_DATA_MAP(ClassRelationshipPage) DDX_Control(pDX, IDC_CLASS_REL_PARENT_EDIT, m_staticParent ); DDX_Control(pDX, IDC_CLASS_REL_AUX_CLASSES, m_listboxAuxiliary); DDX_Control(pDX, IDC_CLASS_REL_SUPER_CLASSES, m_listboxSuperior); DDX_Text( pDX, IDC_CLASS_REL_NAME_STATIC, ObjectName ); DDX_Text( pDX, IDC_CLASS_REL_PARENT_EDIT, ParentClass ); DDX_Text( pDX, IDC_CLASS_REL_SYSCLASS_STATIC, SysClassString ); //}}AFX_DATA_MAP if ( !pDX->m_bSaveAndValidate ) { // // Fill the auxiliary classes list box. // m_listboxAuxiliary.ResetContent(); hr = InsertEditItems( m_listboxAuxiliary, strlistAuxiliary ); ASSERT( SUCCEEDED(hr) ); hr = InsertEditItems( m_listboxAuxiliary, strlistSystemAuxiliary ); ASSERT( SUCCEEDED(hr) ); // // Fill the possible superiors list box. // m_listboxSuperior.ResetContent(); hr = InsertEditItems( m_listboxSuperior, strlistSuperior ); ASSERT( SUCCEEDED(hr) ); hr = InsertEditItems( m_listboxSuperior, strlistSystemSuperior ); ASSERT( SUCCEEDED(hr) ); m_listboxAuxiliary.OnSelChange(); m_listboxSuperior.OnSelChange(); } else { // // All changes that we save are tied to button control routines. // strlistAuxiliary.RemoveAll(); hr = RetrieveEditItemsWithExclusions( m_listboxAuxiliary, strlistAuxiliary, &strlistSystemAuxiliary ); ASSERT( SUCCEEDED(hr) ); strlistSuperior.RemoveAll(); hr = RetrieveEditItemsWithExclusions( m_listboxSuperior, strlistSuperior, &strlistSystemSuperior ); ASSERT( SUCCEEDED(hr) ); } } BEGIN_MESSAGE_MAP(ClassRelationshipPage, CPropertyPage) ON_BN_CLICKED(IDC_CLASS_REL_AUX_ADD, OnButtonAuxiliaryClassAdd) ON_BN_CLICKED(IDC_CLASS_REL_AUX_REMOVE, OnButtonAuxiliaryClassRemove) ON_BN_CLICKED(IDC_CLASS_REL_SUPER_ADD, OnButtonSuperiorClassAdd) ON_BN_CLICKED(IDC_CLASS_REL_SUPER_REMOVE, OnButtonSuperiorClassRemove) ON_LBN_SELCHANGE(IDC_CLASS_REL_AUX_CLASSES, OnAuxiliarySelChange) ON_LBN_SELCHANGE(IDC_CLASS_REL_SUPER_CLASSES, OnSuperiorSelChange) ON_MESSAGE(WM_HELP, OnHelp) ON_MESSAGE(WM_CONTEXTMENU, OnContextHelp) END_MESSAGE_MAP() BOOL ClassRelationshipPage::OnApply( ) // // Revisions: // CoryWest - 10/1/97 - Changes new additions to be listed by oid. // Add cache freshening to improve performance. // { ASSERT( NULL != m_pIADsObject); HRESULT hr = S_OK; HRESULT flush_result; ListEntry *pNewList = NULL; BOOL fApplyAbort = FALSE; // stop later saves BOOL fApplyFailed = FALSE; // should not close the box if ( m_listboxAuxiliary.IsModified() ) { // // Update the auxiliary classes // VARIANT AdsValue; VariantInit( &AdsValue ); hr = StringListToVariant( AdsValue, strlistAuxiliary ); ASSERT( SUCCEEDED(hr) ); hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, g_AuxiliaryClass, AdsValue ); ASSERT( SUCCEEDED(hr) ); VariantClear( &AdsValue ); hr = m_pIADsObject->SetInfo(); if ( SUCCEEDED( hr )) { // // Update the aux class list in the cache. // hr = StringListToColumnList( m_pScopeControl, strlistAuxiliary, &pNewList ); if ( SUCCEEDED( hr )) { m_pScopeControl->g_SchemaCache.FreeColumnList( m_pSchemaObject->auxiliaryClass ); m_pSchemaObject->auxiliaryClass = pNewList; // // Refresh the display! // m_pScopeControl->QueryConsole()->UpdateAllViews( m_lpScopeDataObj, SCHMMGMT_CLASS, SCHMMGMT_UPDATEVIEW_REFRESH ); } // // Continue with the directory operation even if // we couldn't update the display. // hr = S_OK; } else { // // Flush the IADS property cache so future // operations won't fail because of this one. // IADsPropertyList *pPropertyList; flush_result = m_pIADsObject->QueryInterface( IID_IADsPropertyList, reinterpret_cast(&pPropertyList) ); if ( SUCCEEDED( flush_result ) ) { pPropertyList->PurgePropertyList(); pPropertyList->Release(); } } } if ( SUCCEEDED(hr) && m_listboxSuperior.IsModified() ) { // // Update the superior classes // VARIANT AdsValue; VariantInit( &AdsValue ); hr = StringListToVariant( AdsValue, strlistSuperior ); ASSERT( SUCCEEDED(hr) ); hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, g_Superiors, AdsValue ); ASSERT( SUCCEEDED(hr) ); VariantClear( &AdsValue ); hr = m_pIADsObject->SetInfo(); } if ( hr == ADS_EXTENDED_ERROR ) { DoExtErrMsgBox(); } else if ( FAILED(hr) ) { if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) ) { fApplyFailed = TRUE; DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_CHANGE_REJECT ); } else { fApplyAbort = TRUE; DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) ); } } else { // page is no longer "dirty" m_listboxAuxiliary.SetModified( FALSE ); m_listboxSuperior.SetModified( FALSE ); // Update comboBox status OnAuxiliarySelChange(); OnSuperiorSelChange(); SetModified( FALSE ); } return !fApplyAbort && !fApplyFailed ; // return TRUE if nothing happened } void ClassRelationshipPage::OnAuxiliarySelChange() { m_listboxAuxiliary.OnSelChange(); } void ClassRelationshipPage::OnSuperiorSelChange() { m_listboxSuperior.OnSelChange(); } void ClassRelationshipPage::OnButtonAuxiliaryClassRemove() { if( m_listboxAuxiliary.RemoveListBoxItem() ) SetModified( TRUE ); } void ClassRelationshipPage::OnButtonSuperiorClassRemove() { if( m_listboxSuperior.RemoveListBoxItem() ) SetModified( TRUE ); } void ClassRelationshipPage::OnButtonAuxiliaryClassAdd() { if( m_listboxAuxiliary.AddNewObjectToList() ) SetModified( TRUE ); } void ClassRelationshipPage::OnButtonSuperiorClassAdd() { if( m_listboxSuperior.AddNewObjectToList() ) SetModified( TRUE ); }