Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

447 lines
11 KiB

  1. //
  2. // attrpage.cpp : Implementation of ClassAttributePage
  3. //
  4. // Jon Newman <[email protected]>
  5. // Copyright (c) Microsoft Corporation 1997
  6. //
  7. // templated from relation.cpp JonN 8/8/97
  8. //
  9. #include "stdafx.h"
  10. #include "macros.h"
  11. USE_HANDLE_MACROS("SCHMMGMT(attrpage.cpp)")
  12. #include "compdata.h"
  13. #include "schmutil.h"
  14. #include "select.h"
  15. #include "attrpage.h"
  16. const CDialogControlsInfo ctrls[] =
  17. {
  18. // { IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, g_MustContain, FALSE },
  19. // { IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, g_MayContain, FALSE },
  20. { IDC_CLASS_MMB_OPTIONAL_ADD, g_MayContain, FALSE },
  21. { IDC_CLASS_MMB_OPTIONAL_REMOVE, g_MayContain, FALSE },
  22. } ;
  23. const DWORD ClassAttributePage::help_map[] =
  24. {
  25. IDI_CLASS, NO_HELP,
  26. IDC_CLASS_MMB_NAME_STATIC, NO_HELP,
  27. IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, IDH_CLASS_MMB_MANDATORY_ATTRIBUTES,
  28. IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, IDH_CLASS_MMB_OPTIONAL_ATTRIBUTES,
  29. IDC_CLASS_MMB_SYSCLASS_STATIC, NO_HELP,
  30. IDC_CLASS_MMB_OPTIONAL_ADD, IDH_CLASS_MMB_OPTIONAL_ADD,
  31. IDC_CLASS_MMB_OPTIONAL_REMOVE, IDH_CLASS_MMB_OPTIONAL_REMOVE,
  32. 0,0
  33. };
  34. ClassAttributePage::ClassAttributePage(
  35. ComponentData *pScope,
  36. LPDATAOBJECT lpDataObject )
  37. :
  38. CPropertyPage(ClassAttributePage::IDD),
  39. m_pIADsObject( NULL ),
  40. fSystemClass( FALSE ),
  41. m_pSchemaObject( NULL ),
  42. pScopeControl( pScope ),
  43. lpScopeDataObj( lpDataObject )
  44. {
  45. ASSERT(pScopeControl);
  46. ASSERT(lpDataObject);
  47. }
  48. ClassAttributePage::~ClassAttributePage()
  49. {
  50. if (NULL != m_pIADsObject)
  51. {
  52. m_pIADsObject->Release();
  53. }
  54. if (NULL != m_pSchemaObject)
  55. {
  56. pScopeControl->g_SchemaCache.ReleaseRef( m_pSchemaObject );
  57. }
  58. }
  59. void
  60. ClassAttributePage::Load(
  61. Cookie& CookieRef
  62. ) {
  63. //
  64. // Store the cookie object pointer.
  65. //
  66. m_pCookie = &CookieRef;
  67. return;
  68. }
  69. BOOL
  70. ClassAttributePage::OnSetActive()
  71. {
  72. // always enable the Apply button
  73. SetModified(TRUE);
  74. return TRUE;
  75. }
  76. BOOL
  77. ClassAttributePage::OnInitDialog()
  78. {
  79. HRESULT hr = S_OK;
  80. ASSERT( NULL == m_pIADsObject && m_szAdsPath.IsEmpty() );
  81. //
  82. // Get the schema cache object and the actual ADS object.
  83. //
  84. m_pSchemaObject = pScopeControl->g_SchemaCache.LookupSchemaObjectByCN(
  85. (PCWSTR)m_pCookie->strSchemaObject,
  86. SCHMMGMT_CLASS );
  87. if ( m_pSchemaObject ) {
  88. pScopeControl->GetSchemaObjectPath( m_pSchemaObject->commonName, m_szAdsPath );
  89. if ( !m_szAdsPath.IsEmpty() ) {
  90. hr = ADsGetObject( (LPWSTR)(LPCWSTR)m_szAdsPath,
  91. IID_IADs,
  92. (void **)&m_pIADsObject );
  93. ASSERT( SUCCEEDED(hr) );
  94. }
  95. }
  96. //
  97. // If we have no ADS object, we should error out!
  98. //
  99. if ( !m_pIADsObject ) {
  100. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_NO_SCHEMA_OBJECT );
  101. ASSERT(FALSE);
  102. return TRUE;
  103. }
  104. //
  105. // get the current values.
  106. //
  107. VARIANT AdsResult;
  108. VariantInit( &AdsResult );
  109. //
  110. // ObjectName
  111. //
  112. hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_DisplayName),
  113. &AdsResult );
  114. if ( SUCCEEDED( hr ) ) {
  115. ASSERT( AdsResult.vt == VT_BSTR );
  116. ObjectName = AdsResult.bstrVal;
  117. VariantClear( &AdsResult );
  118. }
  119. //
  120. // SysClass
  121. //
  122. hr = m_pIADsObject->Get( const_cast<BSTR>((LPCTSTR)g_SystemOnly),
  123. &AdsResult );
  124. if ( SUCCEEDED( hr ) ) {
  125. ASSERT( AdsResult.vt == VT_BOOL );
  126. fSystemClass = AdsResult.boolVal;
  127. if ( fSystemClass ) {
  128. SysClassString = g_SysClassString;
  129. } else {
  130. SysClassString = L"";
  131. }
  132. VariantClear( &AdsResult );
  133. } else {
  134. SysClassString = L"";
  135. }
  136. //
  137. // Determine the mandatory attributes
  138. //
  139. VARIANT varAttributes;
  140. VariantInit( &varAttributes );
  141. hr = m_pIADsObject->GetEx( g_MustContain, &varAttributes );
  142. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  143. if( SUCCEEDED(hr) )
  144. {
  145. hr = VariantToStringList( varAttributes, strlistMandatory );
  146. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  147. }
  148. VariantClear( &varAttributes );
  149. hr = m_pIADsObject->GetEx( g_SystemMustContain, &varAttributes );
  150. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  151. if( SUCCEEDED(hr) )
  152. {
  153. hr = VariantToStringList( varAttributes, strlistSystemMandatory );
  154. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  155. }
  156. VariantClear( &varAttributes );
  157. //
  158. // Determine the optional attributes
  159. //
  160. hr = m_pIADsObject->GetEx( g_MayContain, &varAttributes );
  161. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  162. if( SUCCEEDED(hr) )
  163. {
  164. hr = VariantToStringList( varAttributes, strlistOptional );
  165. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  166. }
  167. VariantClear( &varAttributes );
  168. hr = m_pIADsObject->GetEx( g_SystemMayContain, &varAttributes );
  169. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  170. if( SUCCEEDED(hr) )
  171. {
  172. hr = VariantToStringList( varAttributes, strlistSystemOptional );
  173. ASSERT( SUCCEEDED(hr) || E_ADS_PROPERTY_NOT_FOUND == hr );
  174. }
  175. VariantClear( &varAttributes );
  176. hr = DissableReadOnlyAttributes( this, m_pIADsObject, ctrls, sizeof(ctrls)/sizeof(ctrls[0]) );
  177. ASSERT( SUCCEEDED(hr) ); // shouldn't fail, but unimportant, so ignore error
  178. // This call must be done before DDX binding
  179. m_listboxOptional.InitType( pScopeControl,
  180. SELECT_ATTRIBUTES,
  181. IDC_CLASS_MMB_OPTIONAL_REMOVE,
  182. &strlistSystemOptional
  183. );
  184. CPropertyPage::OnInitDialog();
  185. return TRUE;
  186. }
  187. void
  188. ClassAttributePage::DoDataExchange(
  189. CDataExchange *pDX
  190. ) {
  191. HRESULT hr = S_OK;
  192. CPropertyPage::DoDataExchange( pDX );
  193. //{{AFX_DATA_MAP(ClassAttributePage)
  194. DDX_Control(pDX, IDC_CLASS_MMB_MANDATORY_ATTRIBUTES, m_listboxMandatory);
  195. DDX_Control(pDX, IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, m_listboxOptional);
  196. DDX_Text( pDX, IDC_CLASS_MMB_NAME_STATIC, ObjectName );
  197. DDX_Text( pDX, IDC_CLASS_MMB_SYSCLASS_STATIC, SysClassString );
  198. //}}AFX_DATA_MAP
  199. if ( !pDX->m_bSaveAndValidate )
  200. {
  201. //
  202. // Fill the mandatory attributes list box.
  203. //
  204. m_listboxMandatory.ResetContent();
  205. hr = InsertEditItems( m_listboxMandatory, strlistMandatory );
  206. ASSERT( SUCCEEDED(hr) );
  207. hr = InsertEditItems( m_listboxMandatory, strlistSystemMandatory );
  208. ASSERT( SUCCEEDED(hr) );
  209. //
  210. // Fill the possible optionals list box.
  211. //
  212. m_listboxOptional.ResetContent();
  213. hr = InsertEditItems( m_listboxOptional, strlistOptional );
  214. ASSERT( SUCCEEDED(hr) );
  215. hr = InsertEditItems( m_listboxOptional, strlistSystemOptional );
  216. ASSERT( SUCCEEDED(hr) );
  217. m_listboxOptional.OnSelChange();
  218. }
  219. else
  220. {
  221. //
  222. // All changes that we save are tied to button control routines.
  223. //
  224. strlistMandatory.RemoveAll();
  225. hr = RetrieveEditItemsWithExclusions(
  226. m_listboxMandatory,
  227. strlistMandatory,
  228. &strlistSystemMandatory
  229. );
  230. ASSERT( SUCCEEDED(hr) );
  231. strlistOptional.RemoveAll();
  232. hr = RetrieveEditItemsWithExclusions(
  233. m_listboxOptional,
  234. strlistOptional,
  235. &strlistSystemOptional
  236. );
  237. ASSERT( SUCCEEDED(hr) );
  238. }
  239. }
  240. BEGIN_MESSAGE_MAP(ClassAttributePage, CPropertyPage)
  241. ON_BN_CLICKED(IDC_CLASS_MMB_OPTIONAL_ADD, OnButtonOptionalAttributeAdd)
  242. ON_BN_CLICKED(IDC_CLASS_MMB_OPTIONAL_REMOVE, OnButtonOptionalAttributeRemove)
  243. ON_LBN_SELCHANGE(IDC_CLASS_MMB_OPTIONAL_ATTRIBUTES, OnOptionalSelChange)
  244. ON_MESSAGE(WM_HELP, OnHelp)
  245. ON_MESSAGE(WM_CONTEXTMENU, OnContextHelp)
  246. END_MESSAGE_MAP()
  247. BOOL
  248. ClassAttributePage::OnApply()
  249. {
  250. ASSERT( NULL != m_pIADsObject);
  251. ASSERT( NULL != m_pSchemaObject);
  252. HRESULT hr = S_OK;
  253. BOOL fApplyAbort = FALSE; // stop later saves
  254. BOOL fApplyFailed = FALSE; // should not close the box
  255. ListEntry *pNewList;
  256. if ( m_listboxOptional.IsModified() )
  257. {
  258. //
  259. // Update the optional attributes
  260. //
  261. VARIANT AdsValue;
  262. VariantInit( &AdsValue );
  263. hr = StringListToVariant( AdsValue, strlistOptional );
  264. ASSERT( SUCCEEDED(hr) );
  265. hr = m_pIADsObject->PutEx( ADS_PROPERTY_UPDATE, g_MayContain, AdsValue );
  266. ASSERT( SUCCEEDED(hr) );
  267. VariantClear( &AdsValue );
  268. hr = m_pIADsObject->SetInfo();
  269. if ( SUCCEEDED( hr )) {
  270. //
  271. // Update the cached data.
  272. //
  273. hr = StringListToColumnList( pScopeControl,
  274. strlistOptional,
  275. &pNewList );
  276. if ( SUCCEEDED( hr )) {
  277. pScopeControl->g_SchemaCache.FreeColumnList( m_pSchemaObject->mayContain );
  278. m_pSchemaObject->mayContain = pNewList;
  279. }
  280. //
  281. // Continue with the directory operation even if
  282. // we couldn't update the cache.
  283. //
  284. hr = S_OK;
  285. }
  286. }
  287. if ( hr == ADS_EXTENDED_ERROR ) {
  288. DoExtErrMsgBox();
  289. }
  290. else if ( FAILED(hr) )
  291. {
  292. if( ERROR_DS_UNWILLING_TO_PERFORM == HRESULT_CODE(hr) )
  293. {
  294. fApplyFailed = TRUE;
  295. DoErrMsgBox( ::GetActiveWindow(), TRUE, IDS_ERR_CHANGE_REJECT );
  296. }
  297. else
  298. {
  299. fApplyAbort = TRUE;
  300. DoErrMsgBox( ::GetActiveWindow(), TRUE, GetErrorMessage(hr,TRUE) );
  301. }
  302. }
  303. else
  304. {
  305. m_listboxOptional.SetModified( FALSE );
  306. SetModified( FALSE );
  307. //
  308. // Refresh the display!
  309. //
  310. pScopeControl->QueryConsole()->UpdateAllViews(
  311. lpScopeDataObj, SCHMMGMT_CLASS, SCHMMGMT_UPDATEVIEW_REFRESH );
  312. }
  313. return !fApplyAbort && !fApplyFailed ; // return TRUE if nothing happened
  314. }
  315. void ClassAttributePage::OnOptionalSelChange()
  316. {
  317. m_listboxOptional.OnSelChange();
  318. }
  319. void ClassAttributePage::OnButtonOptionalAttributeRemove()
  320. {
  321. if( m_listboxOptional.RemoveListBoxItem() )
  322. SetModified( TRUE );
  323. }
  324. void
  325. ClassAttributePage::OnButtonOptionalAttributeAdd()
  326. {
  327. if( m_listboxOptional.AddNewObjectToList() )
  328. SetModified( TRUE );
  329. }