Leaked source code of windows server 2003
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.

1473 lines
48 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // BasePage.cpp
  7. //
  8. // Description:
  9. // Implementation of the CBasePropertyPage class.
  10. //
  11. // Author:
  12. // David Potter (DavidP) March 24, 1999
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "ClNetResEx.h"
  21. #include "ExtObj.h"
  22. #include "BasePage.h"
  23. #include "BasePage.inl"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CBasePropertyPage property page
  31. /////////////////////////////////////////////////////////////////////////////
  32. IMPLEMENT_DYNCREATE( CBasePropertyPage, CPropertyPage )
  33. /////////////////////////////////////////////////////////////////////////////
  34. // Message Maps
  35. BEGIN_MESSAGE_MAP( CBasePropertyPage, CPropertyPage )
  36. //{{AFX_MSG_MAP(CBasePropertyPage)
  37. ON_WM_CREATE()
  38. ON_WM_DESTROY()
  39. ON_WM_HELPINFO()
  40. ON_WM_CONTEXTMENU()
  41. ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
  42. //}}AFX_MSG_MAP
  43. END_MESSAGE_MAP()
  44. /////////////////////////////////////////////////////////////////////////////
  45. //++
  46. //
  47. // CBasePropertyPage::CBasePropertyPage
  48. //
  49. // Description:
  50. // Default constructor.
  51. //
  52. // Arguments:
  53. // None.
  54. //
  55. // Return Value:
  56. // None.
  57. //
  58. //--
  59. /////////////////////////////////////////////////////////////////////////////
  60. CBasePropertyPage::CBasePropertyPage( void )
  61. {
  62. CommonConstruct();
  63. } //*** CBasePropertyPage::CBasePropertyPage()
  64. /////////////////////////////////////////////////////////////////////////////
  65. //++
  66. //
  67. // CBasePropertyPage::CBasePropertyPage
  68. //
  69. // Routine Description:
  70. // Default constructor.
  71. //
  72. // Arguments:
  73. // pdwHelpMap [IN] Control-to-help ID map.
  74. // pdwWizardHelpMap [IN] Control-to-help ID map if this is a wizard page.
  75. //
  76. // Return Value:
  77. // None.
  78. //
  79. //--
  80. /////////////////////////////////////////////////////////////////////////////
  81. CBasePropertyPage::CBasePropertyPage(
  82. IN const DWORD * pdwHelpMap,
  83. IN const DWORD * pdwWizardHelpMap
  84. )
  85. : m_dlghelp( pdwHelpMap, 0 )
  86. {
  87. CommonConstruct();
  88. m_pdwWizardHelpMap = pdwWizardHelpMap;
  89. } //*** CBasePropertyPage::CBasePropertyPage()
  90. /////////////////////////////////////////////////////////////////////////////
  91. //++
  92. //
  93. // CBasePropertyPage::CBasePropertyPage
  94. //
  95. // Routine Description:
  96. // Default constructor.
  97. //
  98. // Arguments:
  99. // idd [IN] Dialog template resource ID.
  100. // pdwHelpMap [IN] Control-to-help ID map.
  101. // pdwWizardHelpMap [IN] Control-to-help ID map if this is a wizard page.
  102. // nIDCaption [IN] Caption string resource ID.
  103. //
  104. // Return Value:
  105. // None.
  106. //
  107. //--
  108. /////////////////////////////////////////////////////////////////////////////
  109. CBasePropertyPage::CBasePropertyPage(
  110. IN UINT idd,
  111. IN const DWORD * pdwHelpMap,
  112. IN const DWORD * pdwWizardHelpMap,
  113. IN UINT nIDCaption
  114. )
  115. : CPropertyPage( idd, nIDCaption )
  116. , m_dlghelp( pdwHelpMap, idd )
  117. {
  118. CommonConstruct();
  119. m_pdwWizardHelpMap = pdwWizardHelpMap;
  120. } //*** CBasePropertyPage::CBasePropertyPage( UINT, UINT )
  121. /////////////////////////////////////////////////////////////////////////////
  122. //++
  123. //
  124. // CBasePropertyPage::CommonConstruct
  125. //
  126. // Description:
  127. // Common construction.
  128. //
  129. // Arguments:
  130. // None.
  131. //
  132. // Return Value:
  133. // None.
  134. //
  135. //--
  136. /////////////////////////////////////////////////////////////////////////////
  137. void CBasePropertyPage::CommonConstruct( void )
  138. {
  139. //{{AFX_DATA_INIT(CBasePropertyPage)
  140. //}}AFX_DATA_INIT
  141. m_peo = NULL;
  142. m_hpage = NULL;
  143. m_bBackPressed = FALSE;
  144. m_bSaved = FALSE;
  145. m_iddPropertyPage = NULL;
  146. m_iddWizardPage = NULL;
  147. m_idsCaption = NULL;
  148. m_pdwWizardHelpMap = NULL;
  149. m_bDoDetach = FALSE;
  150. } //*** CBasePropertyPage::CommonConstruct()
  151. /////////////////////////////////////////////////////////////////////////////
  152. //++
  153. //
  154. // CBasePropertyPage::HrInit
  155. //
  156. // Description:
  157. // Initialize the page.
  158. //
  159. // Arguments:
  160. // peo [IN OUT] Pointer to the extension object.
  161. //
  162. // Return Value:
  163. // S_OK Page initialized successfully.
  164. // hr Page failed to initialize.
  165. //
  166. //--
  167. /////////////////////////////////////////////////////////////////////////////
  168. HRESULT CBasePropertyPage::HrInit( IN OUT CExtObject * peo )
  169. {
  170. ASSERT( peo != NULL );
  171. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  172. HRESULT _hr = S_FALSE;
  173. CWaitCursor _wc;
  174. DWORD _sc = ERROR_SUCCESS;
  175. CClusPropList _cpl;
  176. m_peo = peo;
  177. // Change the help map if this is a wizard page.
  178. if ( Peo()->BWizard() )
  179. {
  180. m_dlghelp.SetMap( m_pdwWizardHelpMap );
  181. } // if: in a wizard
  182. // Don't display a help button.
  183. m_psp.dwFlags &= ~PSP_HASHELP;
  184. // Construct the property page.
  185. if ( Peo()->BWizard() )
  186. {
  187. ASSERT( IddWizardPage() != NULL);
  188. Construct( IddWizardPage(), IdsCaption() );
  189. m_dlghelp.SetHelpMask( IddWizardPage() );
  190. } // if: adding page to wizard
  191. else
  192. {
  193. ASSERT( IddPropertyPage() != NULL );
  194. Construct( IddPropertyPage(), IdsCaption() );
  195. m_dlghelp.SetHelpMask( IddPropertyPage() );
  196. } // else: adding page to property sheet
  197. // Read the properties private to this resource and parse them.
  198. {
  199. ASSERT( Peo() != NULL );
  200. ASSERT( Peo()->PodObjData() );
  201. // Read the properties.
  202. switch ( Cot() )
  203. {
  204. case CLUADMEX_OT_NODE:
  205. ASSERT( Peo()->PndNodeData()->m_hnode != NULL );
  206. _sc = _cpl.ScGetNodeProperties(
  207. Peo()->PndNodeData()->m_hnode,
  208. CLUSCTL_NODE_GET_PRIVATE_PROPERTIES
  209. );
  210. break;
  211. case CLUADMEX_OT_GROUP:
  212. ASSERT( Peo()->PgdGroupData()->m_hgroup != NULL );
  213. _sc = _cpl.ScGetGroupProperties(
  214. Peo()->PgdGroupData()->m_hgroup,
  215. CLUSCTL_GROUP_GET_PRIVATE_PROPERTIES
  216. );
  217. break;
  218. case CLUADMEX_OT_RESOURCE:
  219. ASSERT( Peo()->PrdResData()->m_hresource != NULL );
  220. _sc = _cpl.ScGetResourceProperties(
  221. Peo()->PrdResData()->m_hresource,
  222. CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES
  223. );
  224. break;
  225. case CLUADMEX_OT_RESOURCETYPE:
  226. ASSERT( Peo()->PodObjData()->m_strName.GetLength() > 0 );
  227. _sc = _cpl.ScGetResourceTypeProperties(
  228. Hcluster(),
  229. Peo()->PodObjData()->m_strName,
  230. CLUSCTL_RESOURCE_TYPE_GET_PRIVATE_PROPERTIES
  231. );
  232. break;
  233. case CLUADMEX_OT_NETWORK:
  234. ASSERT( Peo()->PndNetworkData()->m_hnetwork != NULL );
  235. _sc = _cpl.ScGetNetworkProperties(
  236. Peo()->PndNetworkData()->m_hnetwork,
  237. CLUSCTL_NETWORK_GET_PRIVATE_PROPERTIES
  238. );
  239. break;
  240. case CLUADMEX_OT_NETINTERFACE:
  241. ASSERT( Peo()->PndNetInterfaceData()->m_hnetinterface != NULL );
  242. _sc = _cpl.ScGetNetInterfaceProperties(
  243. Peo()->PndNetInterfaceData()->m_hnetinterface,
  244. CLUSCTL_NETINTERFACE_GET_PRIVATE_PROPERTIES
  245. );
  246. break;
  247. default:
  248. ASSERT( 0 );
  249. } // switch: object type
  250. // Parse the properties.
  251. if ( _sc == ERROR_SUCCESS )
  252. {
  253. // Parse the properties.
  254. try
  255. {
  256. _sc = ScParseProperties( _cpl );
  257. } // try
  258. catch ( CMemoryException * _pme )
  259. {
  260. _hr = E_OUTOFMEMORY;
  261. _pme->Delete();
  262. } // catch: CMemoryException
  263. } // if: properties read successfully
  264. if ( _sc != ERROR_SUCCESS )
  265. {
  266. _hr = HRESULT_FROM_WIN32( _sc );
  267. goto Cleanup;
  268. } // if: error parsing getting or parsing properties
  269. } // Read the properties private to this resource and parse them
  270. Cleanup:
  271. return _hr;
  272. } //*** CBasePropertyPage::HrInit()
  273. /////////////////////////////////////////////////////////////////////////////
  274. //++
  275. //
  276. // CBasePropertyPage::HrCreatePage
  277. //
  278. // Description:
  279. // Create the page.
  280. //
  281. // Arguments:
  282. // None.
  283. //
  284. // Return Value:
  285. // S_OK Page created successfully.
  286. // hr Error creating the page.
  287. //
  288. //--
  289. /////////////////////////////////////////////////////////////////////////////
  290. HRESULT CBasePropertyPage::HrCreatePage( void )
  291. {
  292. ASSERT( m_hpage == NULL );
  293. HRESULT _hr = S_OK;
  294. m_hpage = CreatePropertySheetPage( &m_psp );
  295. if ( m_hpage == NULL )
  296. {
  297. _hr = HRESULT_FROM_WIN32( GetLastError() );
  298. } // if: error creating the page
  299. return _hr;
  300. } //*** CBasePropertyPage::HrCreatePage()
  301. /////////////////////////////////////////////////////////////////////////////
  302. //++
  303. //
  304. // CBasePropertyPage::ScParseProperties
  305. //
  306. // Description:
  307. // Parse the properties of the resource. This is in a separate function
  308. // from HrInit so that the optimizer can do a better job.
  309. //
  310. // Arguments:
  311. // rcpl [IN] Cluster property list to parse.
  312. //
  313. // Return Values:
  314. // ERROR_SUCCESS Properties were parsed successfully.
  315. // Any error returns from ScParseUnknownProperty().
  316. //
  317. // Exceptions Thrown:
  318. // Any exceptions from CString::operator=().
  319. //
  320. //--
  321. /////////////////////////////////////////////////////////////////////////////
  322. DWORD CBasePropertyPage::ScParseProperties( IN CClusPropList & rcpl )
  323. {
  324. DWORD _sc;
  325. DWORD _cprop;
  326. const CObjectProperty * _pprop;
  327. ASSERT( rcpl.PbPropList() != NULL );
  328. _sc = rcpl.ScMoveToFirstProperty();
  329. while ( _sc == ERROR_SUCCESS )
  330. {
  331. //
  332. // Parse known properties.
  333. //
  334. for ( _pprop = Pprops(), _cprop = Cprops() ; _cprop > 0 ; _pprop++, _cprop-- )
  335. {
  336. if ( lstrcmpiW( rcpl.PszCurrentPropertyName(), _pprop->m_pwszName ) == 0 )
  337. {
  338. if ( rcpl.CpfCurrentValueFormat() == _pprop->m_propFormat )
  339. {
  340. switch ( _pprop->m_propFormat )
  341. {
  342. case CLUSPROP_FORMAT_SZ:
  343. case CLUSPROP_FORMAT_EXPAND_SZ:
  344. ASSERT( (rcpl.CbCurrentValueLength() == (lstrlenW( rcpl.CbhCurrentValue().pStringValue->sz ) + 1) * sizeof( WCHAR ))
  345. || ( (rcpl.CbCurrentValueLength() == 0)
  346. && (rcpl.CbhCurrentValue().pStringValue->sz[ 0 ] == L'\0') ) );
  347. *_pprop->m_value.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  348. *_pprop->m_valuePrev.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  349. // See if we need to find an expanded version
  350. if ( _pprop->m_valueEx.pstr != NULL )
  351. {
  352. // Copy the non-expanded one just in case there isn't an expanded version
  353. *_pprop->m_valueEx.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  354. // See if they included an expanded version
  355. rcpl.ScMoveToNextPropertyValue( );
  356. if ( rcpl.CpfCurrentValueFormat( ) == CLUSPROP_FORMAT_EXPANDED_SZ )
  357. {
  358. *_pprop->m_valueEx.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  359. } // if: found expanded version
  360. } // if: *_pprop->m_valueEx.pstr is present
  361. break;
  362. case CLUSPROP_FORMAT_EXPANDED_SZ:
  363. ASSERT( (rcpl.CbCurrentValueLength() == (lstrlenW( rcpl.CbhCurrentValue().pStringValue->sz ) + 1) * sizeof( WCHAR ))
  364. || ( (rcpl.CbCurrentValueLength() == 0)
  365. && (rcpl.CbhCurrentValue().pStringValue->sz[ 0 ] == L'\0') ) );
  366. *_pprop->m_value.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  367. *_pprop->m_valuePrev.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  368. // See if we need to find an expanded version
  369. if ( _pprop->m_valueEx.pstr != NULL )
  370. {
  371. // Copy the expanded version
  372. *_pprop->m_valueEx.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  373. // See if they included a non-expanded version
  374. rcpl.ScMoveToNextPropertyValue( );
  375. if ( rcpl.CpfCurrentValueFormat( ) == CLUSPROP_FORMAT_SZ )
  376. {
  377. *_pprop->m_value.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  378. *_pprop->m_valuePrev.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  379. } // if: found non-expanded version
  380. } // if: *_pprop->m_valueEx.pstr is present
  381. break;
  382. case CLUSPROP_FORMAT_DWORD:
  383. case CLUSPROP_FORMAT_LONG:
  384. ASSERT( rcpl.CbCurrentValueLength() == sizeof( DWORD ) );
  385. *_pprop->m_value.pdw = rcpl.CbhCurrentValue().pDwordValue->dw;
  386. *_pprop->m_valuePrev.pdw = rcpl.CbhCurrentValue().pDwordValue->dw;
  387. break;
  388. case CLUSPROP_FORMAT_BINARY:
  389. case CLUSPROP_FORMAT_MULTI_SZ:
  390. *_pprop->m_value.ppb = rcpl.CbhCurrentValue().pBinaryValue->rgb;
  391. *_pprop->m_value.pcb = rcpl.CbhCurrentValue().pBinaryValue->cbLength;
  392. *_pprop->m_valuePrev.ppb = rcpl.CbhCurrentValue().pBinaryValue->rgb;
  393. *_pprop->m_valuePrev.pcb = rcpl.CbhCurrentValue().pBinaryValue->cbLength;
  394. break;
  395. default:
  396. ASSERT(0); // don't know how to deal with this type
  397. } // switch: property format
  398. // Exit the loop since we found the parameter.
  399. break;
  400. }// if: found a type match
  401. } // if: found a string match
  402. } // for: each property that we know about
  403. //
  404. // If the property wasn't known, ask the derived class to parse it.
  405. //
  406. if ( _cprop == 0 )
  407. {
  408. _sc = ScParseUnknownProperty(
  409. rcpl.CbhCurrentPropertyName().pName->sz,
  410. rcpl.CbhCurrentValue(),
  411. static_cast< DWORD >( rcpl.RPvlPropertyValue().CbDataLeft() )
  412. );
  413. if ( _sc != ERROR_SUCCESS )
  414. {
  415. return _sc;
  416. } // if: error parsing the unknown property
  417. } // if: property not parsed
  418. //
  419. // Advance the buffer pointer past the value in the value list.
  420. //
  421. _sc = rcpl.ScMoveToNextProperty();
  422. } // while: more properties to parse
  423. //
  424. // If we reached the end of the properties, fix the return code.
  425. //
  426. if ( _sc == ERROR_NO_MORE_ITEMS )
  427. {
  428. _sc = ERROR_SUCCESS;
  429. } // if: ended loop after parsing all properties
  430. return _sc;
  431. } //*** CBasePropertyPage::ScParseProperties()
  432. /////////////////////////////////////////////////////////////////////////////
  433. //++
  434. //
  435. // CBasePropertyPage::OnCreate
  436. //
  437. // Description:
  438. // Handler for the WM_CREATE message.
  439. //
  440. // Arguments:
  441. // lpCreateStruct [IN OUT] Window create structure.
  442. //
  443. // Return Value:
  444. // -1 Error.
  445. // 0 Success.
  446. //
  447. //--
  448. /////////////////////////////////////////////////////////////////////////////
  449. int CBasePropertyPage::OnCreate( LPCREATESTRUCT lpCreateStruct )
  450. {
  451. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  452. // Attach the window to the property page structure.
  453. // This has been done once already in the main application, since the
  454. // main application owns the property sheet. It needs to be done here
  455. // so that the window handle can be found in the DLL's handle map.
  456. if ( FromHandlePermanent( m_hWnd ) == NULL ) // is the window handle already in the handle map
  457. {
  458. HWND _hWnd = m_hWnd;
  459. m_hWnd = NULL;
  460. Attach( _hWnd );
  461. m_bDoDetach = TRUE;
  462. } // if: is the window handle in the handle map
  463. return CPropertyPage::OnCreate( lpCreateStruct );
  464. } //*** CBasePropertyPage::OnCreate()
  465. /////////////////////////////////////////////////////////////////////////////
  466. //++
  467. //
  468. // CBasePropertyPage::OnDestroy
  469. //
  470. // Description:
  471. // Handler for the WM_DESTROY message.
  472. //
  473. // Arguments:
  474. // None.
  475. //
  476. // Return Value:
  477. // None.
  478. //
  479. //--
  480. /////////////////////////////////////////////////////////////////////////////
  481. void CBasePropertyPage::OnDestroy( void )
  482. {
  483. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  484. // Detach the window from the property page structure.
  485. // This will be done again by the main application, since it owns the
  486. // property sheet. It needs to be done here so that the window handle
  487. // can be removed from the DLL's handle map.
  488. if ( m_bDoDetach )
  489. {
  490. if ( m_hWnd != NULL )
  491. {
  492. HWND _hWnd = m_hWnd;
  493. Detach();
  494. m_hWnd = _hWnd;
  495. } // if: do we have a window handle?
  496. } // if: do we need to balance the attach we did with a detach?
  497. CPropertyPage::OnDestroy();
  498. } //*** CBasePropertyPage::OnDestroy()
  499. /////////////////////////////////////////////////////////////////////////////
  500. //++
  501. //
  502. // CBasePropertyPage::DoDataExchange
  503. //
  504. // Description:
  505. // Do data exchange between the dialog and the class.
  506. //
  507. // Arguments:
  508. // pDX [IN OUT] Data exchange object
  509. //
  510. // Return Value:
  511. // None.
  512. //
  513. //--
  514. /////////////////////////////////////////////////////////////////////////////
  515. void CBasePropertyPage::DoDataExchange( CDataExchange * pDX )
  516. {
  517. if ( ! pDX->m_bSaveAndValidate || ! BSaved() )
  518. {
  519. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  520. //{{AFX_DATA_MAP(CBasePropertyPage)
  521. // NOTE: the ClassWizard will add DDX and DDV calls here
  522. //}}AFX_DATA_MAP
  523. DDX_Control( pDX, IDC_PP_ICON, m_staticIcon );
  524. DDX_Control( pDX, IDC_PP_TITLE, m_staticTitle );
  525. if ( pDX->m_bSaveAndValidate )
  526. {
  527. if ( ! BBackPressed() )
  528. {
  529. CWaitCursor _wc;
  530. // Validate the data.
  531. if ( ! BSetPrivateProps( TRUE /*bValidateOnly*/ ) )
  532. {
  533. pDX->Fail();
  534. } // if: error setting private properties
  535. } // if: Back button not pressed
  536. } // if: saving data from dialog
  537. else
  538. {
  539. // Set the title.
  540. DDX_Text( pDX, IDC_PP_TITLE, m_strTitle );
  541. } // if: not saving data
  542. } // if: not saving or haven't saved yet
  543. // Call the base class method.
  544. CPropertyPage::DoDataExchange( pDX );
  545. } //*** CBasePropertyPage::DoDataExchange()
  546. /////////////////////////////////////////////////////////////////////////////
  547. //++
  548. //
  549. // CBasePropertyPage::OnInitDialog
  550. //
  551. // Description:
  552. // Handler for the WM_INITDIALOG message.
  553. //
  554. // Arguments:
  555. // None.
  556. //
  557. // Return Value:
  558. // TRUE We need the focus to be set for us.
  559. // FALSE We already set the focus to the proper control.
  560. //
  561. //--
  562. /////////////////////////////////////////////////////////////////////////////
  563. BOOL CBasePropertyPage::OnInitDialog( void )
  564. {
  565. ASSERT( Peo() != NULL );
  566. ASSERT( Peo()->PodObjData() != NULL );
  567. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  568. // Set the title string.
  569. m_strTitle = Peo()->PodObjData()->m_strName;
  570. // Call the base class method.
  571. CPropertyPage::OnInitDialog();
  572. // Display an icon for the object.
  573. if ( Peo()->Hicon() != NULL )
  574. {
  575. m_staticIcon.SetIcon( Peo()->Hicon() );
  576. } // if: an icon was specified
  577. return TRUE; // return TRUE unless you set the focus to a control
  578. // EXCEPTION: OCX Property Pages should return FALSE
  579. } //*** CBasePropertyPage::OnInitDialog()
  580. /////////////////////////////////////////////////////////////////////////////
  581. //++
  582. //
  583. // CBasePropertyPage::OnSetActive
  584. //
  585. // Description:
  586. // Handler for the PSN_SETACTIVE message.
  587. //
  588. // Arguments:
  589. // None.
  590. //
  591. // Return Value:
  592. // TRUE Page successfully initialized.
  593. // FALSE Page not initialized.
  594. //
  595. //--
  596. /////////////////////////////////////////////////////////////////////////////
  597. BOOL CBasePropertyPage::OnSetActive( void )
  598. {
  599. HRESULT _hr;
  600. ASSERT( Peo() != NULL);
  601. ASSERT( Peo()->PodObjData() != NULL );
  602. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  603. // Reread the data.
  604. _hr = Peo()->HrGetObjectInfo();
  605. if ( _hr != NOERROR )
  606. {
  607. return FALSE;
  608. } // if: error getting object info
  609. // Set the title string.
  610. m_strTitle = Peo()->PodObjData()->m_strName;
  611. m_bBackPressed = FALSE;
  612. m_bSaved = FALSE;
  613. return CPropertyPage::OnSetActive();
  614. } //*** CBasePropertyPage::OnSetActive()
  615. /////////////////////////////////////////////////////////////////////////////
  616. //++
  617. //
  618. // CBasePropertyPage::OnApply
  619. //
  620. // Description:
  621. // Handler for the PSM_APPLY message.
  622. //
  623. // Arguments:
  624. // None.
  625. //
  626. // Return Value:
  627. // TRUE Page successfully applied.
  628. // FALSE Error applying page.
  629. //
  630. //--
  631. /////////////////////////////////////////////////////////////////////////////
  632. BOOL CBasePropertyPage::OnApply( void )
  633. {
  634. ASSERT( ! BWizard() );
  635. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  636. CWaitCursor _wc;
  637. if ( ! BApplyChanges() )
  638. {
  639. return FALSE;
  640. } // if: error applying changes
  641. return CPropertyPage::OnApply();
  642. } //*** CBasePropertyPage::OnApply()
  643. /////////////////////////////////////////////////////////////////////////////
  644. //++
  645. //
  646. // CBasePropertyPage::OnWizardBack
  647. //
  648. // Description:
  649. // Handler for the PSN_WIZBACK message.
  650. //
  651. // Arguments:
  652. // None.
  653. //
  654. // Return Value:
  655. // -1 Don't change the page.
  656. // 0 Change the page.
  657. //
  658. //--
  659. /////////////////////////////////////////////////////////////////////////////
  660. LRESULT CBasePropertyPage::OnWizardBack( void )
  661. {
  662. LRESULT _lResult;
  663. ASSERT( BWizard() );
  664. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  665. _lResult = CPropertyPage::OnWizardBack();
  666. if ( _lResult != -1 )
  667. {
  668. m_bBackPressed = TRUE;
  669. } // if: no error occurred
  670. return _lResult;
  671. } //*** CBasePropertyPage::OnWizardBack()
  672. /////////////////////////////////////////////////////////////////////////////
  673. //++
  674. //
  675. // CBasePropertyPage::OnWizardNext
  676. //
  677. // Description:
  678. // Handler for the PSN_WIZNEXT message.
  679. //
  680. // Arguments:
  681. // None.
  682. //
  683. // Return Value:
  684. // -1 Don't change the page.
  685. // 0 Change the page.
  686. //
  687. //--
  688. /////////////////////////////////////////////////////////////////////////////
  689. LRESULT CBasePropertyPage::OnWizardNext( void )
  690. {
  691. ASSERT( BWizard() );
  692. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  693. CWaitCursor _wc;
  694. // Update the data in the class from the page.
  695. // This necessary because, while OnKillActive() will call UpdateData(),
  696. // it is called after this method is called, and we need to be sure that
  697. // data has been saved before we apply them.
  698. if ( ! UpdateData( TRUE /*bSaveAndValidate*/ ) )
  699. {
  700. return -1;
  701. } // if: error updating data
  702. // Save the data in the sheet.
  703. if ( ! BApplyChanges() )
  704. {
  705. return -1;
  706. } // if: error applying changes
  707. // Create the object.
  708. return CPropertyPage::OnWizardNext();
  709. } //*** CBasePropertyPage::OnWizardNext()
  710. /////////////////////////////////////////////////////////////////////////////
  711. //++
  712. //
  713. // CBasePropertyPage::OnWizardFinish
  714. //
  715. // Description:
  716. // Handler for the PSN_WIZFINISH message.
  717. //
  718. // Arguments:
  719. // None.
  720. //
  721. // Return Value:
  722. // FALSE Don't change the page.
  723. // TRUE Change the page.
  724. //
  725. //--
  726. /////////////////////////////////////////////////////////////////////////////
  727. BOOL CBasePropertyPage::OnWizardFinish( void )
  728. {
  729. ASSERT( BWizard() );
  730. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  731. CWaitCursor _wc;
  732. // BUG! There should be no need to call UpdateData in this function.
  733. // See BUG: Finish Button Fails Data Transfer from Page to Variables
  734. // KB Article ID: Q150349
  735. // Update the data in the class from the page.
  736. if ( ! UpdateData( TRUE /*bSaveAndValidate*/ ) )
  737. {
  738. return FALSE;
  739. } // if: error updating data
  740. // Save the data in the sheet.
  741. if ( ! BApplyChanges() )
  742. {
  743. return FALSE;
  744. } // if: error applying changes
  745. return CPropertyPage::OnWizardFinish();
  746. } //*** CBasePropertyPage::OnWizardFinish()
  747. /////////////////////////////////////////////////////////////////////////////
  748. //++
  749. //
  750. // CBasePropertyPage::OnChangeCtrl
  751. //
  752. // Description:
  753. // Handler for the messages sent when a control is changed. This
  754. // method can be specified in a message map if all that needs to be
  755. // done is enable the Apply button.
  756. //
  757. // Arguments:
  758. // None.
  759. //
  760. // Return Value:
  761. // None.
  762. //
  763. //--
  764. /////////////////////////////////////////////////////////////////////////////
  765. void CBasePropertyPage::OnChangeCtrl( void )
  766. {
  767. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  768. SetModified( TRUE );
  769. } //*** CBasePropertyPage::OnChangeCtrl()
  770. /////////////////////////////////////////////////////////////////////////////
  771. //++
  772. //
  773. // CBasePropertyPage::EnableNext
  774. //
  775. // Description:
  776. // Enables or disables the NEXT or FINISH button.
  777. //
  778. // Arguments:
  779. // bEnable [IN] TRUE = enable the button, FALSE = disable the button.
  780. //
  781. // Return Value:
  782. // None.
  783. //
  784. //--
  785. /////////////////////////////////////////////////////////////////////////////
  786. void CBasePropertyPage::EnableNext( IN BOOL bEnable /*TRUE*/ )
  787. {
  788. ASSERT( BWizard() );
  789. ASSERT( PiWizardCallback() );
  790. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  791. PiWizardCallback()->EnableNext( reinterpret_cast< LONG * >( Hpage() ), bEnable );
  792. } //*** CBasePropertyPage::EnableNext()
  793. /////////////////////////////////////////////////////////////////////////////
  794. //++
  795. //
  796. // CBasePropertyPage::BApplyChanges
  797. //
  798. // Description:
  799. // Apply changes made on the page.
  800. //
  801. // Arguments:
  802. // None.
  803. //
  804. // Return Value:
  805. // TRUE Page successfully applied.
  806. // FALSE Error applying page.
  807. //
  808. //--
  809. /////////////////////////////////////////////////////////////////////////////
  810. BOOL CBasePropertyPage::BApplyChanges( void )
  811. {
  812. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  813. CWaitCursor _wc;
  814. // Save data.
  815. return BSetPrivateProps();
  816. } //*** CBasePropertyPage::BApplyChanges()
  817. /////////////////////////////////////////////////////////////////////////////
  818. //++
  819. //
  820. // CBasePropertyPage::BBuildPropList
  821. //
  822. // Description:
  823. // Build the property list.
  824. //
  825. // Arguments:
  826. // rcpl [IN OUT] Cluster property list.
  827. // bNoNewProps [IN] TRUE = exclude properties marked with opfNew.
  828. //
  829. // Return Value:
  830. // TRUE Property list built successfully.
  831. // FALSE Error building property list.
  832. //
  833. // Exceptions Thrown:
  834. // Any exceptions thrown by CClusPropList::AddProp().
  835. //
  836. //--
  837. /////////////////////////////////////////////////////////////////////////////
  838. BOOL CBasePropertyPage::BBuildPropList(
  839. IN OUT CClusPropList & rcpl,
  840. IN BOOL bNoNewProps // = FALSE
  841. )
  842. {
  843. BOOL _bNewPropsFound = FALSE;
  844. DWORD _cprop;
  845. const CObjectProperty * _pprop;
  846. for ( _pprop = Pprops(), _cprop = Cprops() ; _cprop > 0 ; _pprop++, _cprop-- )
  847. {
  848. if ( bNoNewProps && (_pprop->m_fFlags & CObjectProperty::opfNew) )
  849. {
  850. _bNewPropsFound = TRUE;
  851. continue;
  852. } // if: no new props allowed and this is a new property
  853. switch ( _pprop->m_propFormat )
  854. {
  855. case CLUSPROP_FORMAT_SZ:
  856. rcpl.ScAddProp(
  857. _pprop->m_pwszName,
  858. *_pprop->m_value.pstr,
  859. *_pprop->m_valuePrev.pstr
  860. );
  861. break;
  862. case CLUSPROP_FORMAT_EXPAND_SZ:
  863. rcpl.ScAddExpandSzProp(
  864. _pprop->m_pwszName,
  865. *_pprop->m_value.pstr,
  866. *_pprop->m_valuePrev.pstr
  867. );
  868. break;
  869. case CLUSPROP_FORMAT_DWORD:
  870. rcpl.ScAddProp(
  871. _pprop->m_pwszName,
  872. *_pprop->m_value.pdw,
  873. *_pprop->m_valuePrev.pdw
  874. );
  875. break;
  876. case CLUSPROP_FORMAT_LONG:
  877. rcpl.ScAddProp(
  878. _pprop->m_pwszName,
  879. *_pprop->m_value.pl,
  880. *_pprop->m_valuePrev.pl
  881. );
  882. break;
  883. case CLUSPROP_FORMAT_BINARY:
  884. case CLUSPROP_FORMAT_MULTI_SZ:
  885. rcpl.ScAddProp(
  886. _pprop->m_pwszName,
  887. *_pprop->m_value.ppb,
  888. *_pprop->m_value.pcb,
  889. *_pprop->m_valuePrev.ppb,
  890. *_pprop->m_valuePrev.pcb
  891. );
  892. break;
  893. default:
  894. ASSERT( 0 ); // don't know how to deal with this type
  895. return FALSE;
  896. } // switch: property format
  897. } // for: each property
  898. return ( ! bNoNewProps || _bNewPropsFound );
  899. } //*** CBasePropertyPage::BBuildPropList()
  900. /////////////////////////////////////////////////////////////////////////////
  901. //++
  902. //
  903. // CBasePropertyPage::BSetPrivateProps
  904. //
  905. // Description:
  906. // Set the private properties for this object.
  907. //
  908. // Arguments:
  909. // bValidateOnly [IN] TRUE = only validate the data.
  910. // bNoNewProps [IN] TRUE = exclude properties marked with opfNew.
  911. //
  912. // Return Value:
  913. // ERROR_SUCCESS The operation was completed successfully.
  914. // !0 Failure.
  915. //
  916. //--
  917. /////////////////////////////////////////////////////////////////////////////
  918. BOOL CBasePropertyPage::BSetPrivateProps(
  919. IN BOOL bValidateOnly, // = FALSE
  920. IN BOOL bNoNewProps // = FALSE
  921. )
  922. {
  923. BOOL _fSuccess = TRUE;
  924. CClusPropList _cpl( BWizard() /*bAlwaysAddProp*/ );
  925. ASSERT( Peo() != NULL );
  926. ASSERT( Peo()->PrdResData() );
  927. ASSERT( Peo()->PrdResData()->m_hresource );
  928. // Build the property list.
  929. try
  930. {
  931. _fSuccess = BBuildPropList( _cpl, bNoNewProps );
  932. } // try
  933. catch ( CException * pe )
  934. {
  935. pe->ReportError();
  936. pe->Delete();
  937. _fSuccess = FALSE;
  938. } // catch: CException
  939. // Set the data.
  940. if ( _fSuccess )
  941. {
  942. if ( (_cpl.PbPropList() != NULL) && (_cpl.CbPropList() > 0) )
  943. {
  944. DWORD _sc = ERROR_SUCCESS;
  945. DWORD _dwControlCode;
  946. DWORD _cbProps;
  947. switch ( Cot() )
  948. {
  949. case CLUADMEX_OT_NODE:
  950. ASSERT( Peo()->PndNodeData() != NULL );
  951. ASSERT( Peo()->PndNodeData()->m_hnode != NULL );
  952. // Determine which control code to use.
  953. if ( bValidateOnly )
  954. {
  955. _dwControlCode = CLUSCTL_NODE_VALIDATE_PRIVATE_PROPERTIES;
  956. } // if: only validating data
  957. else
  958. {
  959. _dwControlCode = CLUSCTL_NODE_SET_PRIVATE_PROPERTIES;
  960. } // else: setting data
  961. // Set private properties.
  962. _sc = ClusterNodeControl(
  963. Peo()->PndNodeData()->m_hnode,
  964. NULL, // hNode
  965. _dwControlCode,
  966. _cpl.PbPropList(),
  967. static_cast< DWORD >( _cpl.CbPropList() ),
  968. NULL, // lpOutBuffer
  969. 0, // nOutBufferSize
  970. &_cbProps
  971. );
  972. break;
  973. case CLUADMEX_OT_GROUP:
  974. ASSERT( Peo()->PgdGroupData() != NULL );
  975. ASSERT( Peo()->PgdGroupData()->m_hgroup != NULL );
  976. // Determine which control code to use.
  977. if ( bValidateOnly )
  978. {
  979. _dwControlCode = CLUSCTL_GROUP_VALIDATE_PRIVATE_PROPERTIES;
  980. } // if: only validating data
  981. else
  982. {
  983. _dwControlCode = CLUSCTL_GROUP_SET_PRIVATE_PROPERTIES;
  984. } // else: setting data
  985. // Set private properties.
  986. _sc = ClusterGroupControl(
  987. Peo()->PgdGroupData()->m_hgroup,
  988. NULL, // hNode
  989. _dwControlCode,
  990. _cpl.PbPropList(),
  991. static_cast< DWORD >( _cpl.CbPropList() ),
  992. NULL, // lpOutBuffer
  993. 0, // nOutBufferSize
  994. &_cbProps
  995. );
  996. break;
  997. case CLUADMEX_OT_RESOURCE:
  998. ASSERT( Peo()->PrdResData() != NULL );
  999. ASSERT( Peo()->PrdResData()->m_hresource != NULL );
  1000. // Determine which control code to use.
  1001. if ( bValidateOnly )
  1002. {
  1003. _dwControlCode = CLUSCTL_RESOURCE_VALIDATE_PRIVATE_PROPERTIES;
  1004. } // if: only validating data
  1005. else
  1006. {
  1007. _dwControlCode = CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES;
  1008. } // else: setting data
  1009. // Set private properties.
  1010. _sc = ClusterResourceControl(
  1011. Peo()->PrdResData()->m_hresource,
  1012. NULL, // hNode
  1013. _dwControlCode,
  1014. _cpl.PbPropList(),
  1015. static_cast< DWORD >( _cpl.CbPropList() ),
  1016. NULL, // lpOutBuffer
  1017. 0, // nOutBufferSize
  1018. &_cbProps
  1019. );
  1020. break;
  1021. case CLUADMEX_OT_RESOURCETYPE:
  1022. ASSERT( Peo()->PodObjData() != NULL );
  1023. ASSERT( Peo()->PodObjData()->m_strName.GetLength() > 0 );
  1024. // Determine which control code to use.
  1025. if ( bValidateOnly )
  1026. {
  1027. _dwControlCode = CLUSCTL_RESOURCE_TYPE_VALIDATE_PRIVATE_PROPERTIES;
  1028. } // if: only validating data
  1029. else
  1030. {
  1031. _dwControlCode = CLUSCTL_RESOURCE_TYPE_SET_PRIVATE_PROPERTIES;
  1032. } // else: setting data
  1033. // Set private properties.
  1034. _sc = ClusterResourceTypeControl(
  1035. Hcluster(),
  1036. Peo()->PodObjData()->m_strName,
  1037. NULL, // hNode
  1038. _dwControlCode,
  1039. _cpl.PbPropList(),
  1040. static_cast< DWORD >( _cpl.CbPropList() ),
  1041. NULL, // lpOutBuffer
  1042. 0, // nOutBufferSize
  1043. &_cbProps
  1044. );
  1045. break;
  1046. case CLUADMEX_OT_NETWORK:
  1047. ASSERT( Peo()->PndNetworkData() != NULL );
  1048. ASSERT( Peo()->PndNetworkData()->m_hnetwork != NULL );
  1049. // Determine which control code to use.
  1050. if ( bValidateOnly )
  1051. {
  1052. _dwControlCode = CLUSCTL_NETWORK_VALIDATE_PRIVATE_PROPERTIES;
  1053. } // if: only validating data
  1054. else
  1055. {
  1056. _dwControlCode = CLUSCTL_NETWORK_SET_PRIVATE_PROPERTIES;
  1057. } // else: setting data
  1058. // Set private properties.
  1059. _sc = ClusterNetworkControl(
  1060. Peo()->PndNetworkData()->m_hnetwork,
  1061. NULL, // hNode
  1062. _dwControlCode,
  1063. _cpl.PbPropList(),
  1064. static_cast< DWORD >( _cpl.CbPropList() ),
  1065. NULL, // lpOutBuffer
  1066. 0, // nOutBufferSize
  1067. &_cbProps
  1068. );
  1069. break;
  1070. case CLUADMEX_OT_NETINTERFACE:
  1071. ASSERT( Peo()->PndNetInterfaceData() != NULL );
  1072. ASSERT( Peo()->PndNetInterfaceData()->m_hnetinterface != NULL );
  1073. // Determine which control code to use.
  1074. if ( bValidateOnly )
  1075. {
  1076. _dwControlCode = CLUSCTL_NETINTERFACE_VALIDATE_PRIVATE_PROPERTIES;
  1077. } // if: only validating data
  1078. else
  1079. {
  1080. _dwControlCode = CLUSCTL_NETINTERFACE_SET_PRIVATE_PROPERTIES;
  1081. } // else: setting data
  1082. // Set private properties.
  1083. _sc = ClusterNetInterfaceControl(
  1084. Peo()->PndNetInterfaceData()->m_hnetinterface,
  1085. NULL, // hNode
  1086. _dwControlCode,
  1087. _cpl.PbPropList(),
  1088. static_cast< DWORD >( _cpl.CbPropList() ),
  1089. NULL, // lpOutBuffer
  1090. 0, // nOutBufferSize
  1091. &_cbProps
  1092. );
  1093. break;
  1094. default:
  1095. ASSERT( 0 );
  1096. } // switch: object type
  1097. // Handle errors.
  1098. if ( _sc != ERROR_SUCCESS )
  1099. {
  1100. if ( _sc == ERROR_INVALID_PARAMETER )
  1101. {
  1102. if ( ! bNoNewProps )
  1103. {
  1104. _fSuccess = BSetPrivateProps( bValidateOnly, TRUE /*bNoNewProps*/ );
  1105. } // if: new props are allowed
  1106. else
  1107. _fSuccess = FALSE;
  1108. } // if: invalid parameter error occurred
  1109. else if ( bValidateOnly
  1110. || (_sc != ERROR_RESOURCE_PROPERTIES_STORED) )
  1111. {
  1112. _fSuccess = FALSE;
  1113. } // else if: only validating and error other than properties only stored
  1114. //
  1115. // If an error occurred, display an error message.
  1116. //
  1117. if ( ! _fSuccess )
  1118. {
  1119. DisplaySetPropsError( _sc, bValidateOnly ? IDS_ERROR_VALIDATING_PROPERTIES : IDS_ERROR_SETTING_PROPERTIES );
  1120. if ( _sc == ERROR_RESOURCE_PROPERTIES_STORED )
  1121. {
  1122. _fSuccess = TRUE;
  1123. } // if: properties only stored
  1124. } // if: error occurred
  1125. } // if: error setting/validating data
  1126. } // if: there is data to set
  1127. } // if: no errors building the property list
  1128. // Save data locally.
  1129. if ( ! bValidateOnly && _fSuccess )
  1130. {
  1131. // Save new values as previous values.
  1132. try
  1133. {
  1134. DWORD _cprop;
  1135. const CObjectProperty * _pprop;
  1136. for ( _pprop = Pprops(), _cprop = Cprops() ; _cprop > 0 ; _pprop++, _cprop-- )
  1137. {
  1138. switch ( _pprop->m_propFormat )
  1139. {
  1140. case CLUSPROP_FORMAT_SZ:
  1141. case CLUSPROP_FORMAT_EXPAND_SZ:
  1142. ASSERT(_pprop->m_value.pstr != NULL);
  1143. ASSERT(_pprop->m_valuePrev.pstr != NULL);
  1144. *_pprop->m_valuePrev.pstr = *_pprop->m_value.pstr;
  1145. break;
  1146. case CLUSPROP_FORMAT_DWORD:
  1147. case CLUSPROP_FORMAT_LONG:
  1148. ASSERT( _pprop->m_value.pdw != NULL );
  1149. ASSERT( _pprop->m_valuePrev.pdw != NULL );
  1150. *_pprop->m_valuePrev.pdw = *_pprop->m_value.pdw;
  1151. break;
  1152. case CLUSPROP_FORMAT_BINARY:
  1153. case CLUSPROP_FORMAT_MULTI_SZ:
  1154. ASSERT( _pprop->m_value.ppb != NULL );
  1155. ASSERT( *_pprop->m_value.ppb != NULL );
  1156. ASSERT( _pprop->m_value.pcb != NULL );
  1157. ASSERT( _pprop->m_valuePrev.ppb != NULL );
  1158. ASSERT( *_pprop->m_valuePrev.ppb != NULL );
  1159. ASSERT( _pprop->m_valuePrev.pcb != NULL );
  1160. delete [] *_pprop->m_valuePrev.ppb;
  1161. *_pprop->m_valuePrev.ppb = new BYTE[ *_pprop->m_value.pcb ];
  1162. CopyMemory( *_pprop->m_valuePrev.ppb, *_pprop->m_value.ppb, *_pprop->m_value.pcb );
  1163. *_pprop->m_valuePrev.pcb = *_pprop->m_value.pcb;
  1164. break;
  1165. default:
  1166. ASSERT( 0 ); // don't know how to deal with this type
  1167. } // switch: property format
  1168. } // for: each property
  1169. } // try
  1170. catch ( CException * _pe )
  1171. {
  1172. _pe->ReportError();
  1173. _pe->Delete();
  1174. _fSuccess = FALSE;
  1175. } // catch: CException
  1176. } // if: not just validating and successful so far
  1177. //
  1178. // Indicate we successfully saved the properties.
  1179. //
  1180. if ( ! bValidateOnly && _fSuccess )
  1181. {
  1182. m_bSaved = TRUE;
  1183. } // if: successfully saved data
  1184. return _fSuccess;
  1185. } //*** CBasePropertyPage::BSetPrivateProps()
  1186. /////////////////////////////////////////////////////////////////////////////
  1187. //++
  1188. //
  1189. // CBasePropertyPage::DisplaySetPropsError
  1190. //
  1191. // Routine Description:
  1192. // Display an error caused by setting or validating properties.
  1193. //
  1194. // Arguments:
  1195. // sc [IN] Status to display error on.
  1196. // idsOper [IN] Operation message.
  1197. //
  1198. // Return Value:
  1199. // nStatus ERROR_SUCCESS = success, !0 = failure
  1200. //
  1201. //--
  1202. /////////////////////////////////////////////////////////////////////////////
  1203. void CBasePropertyPage::DisplaySetPropsError(
  1204. IN DWORD sc,
  1205. IN UINT idsOper
  1206. ) const
  1207. {
  1208. CString _strErrorMsg;
  1209. CString _strOperMsg;
  1210. CString _strMsgIdFmt;
  1211. CString _strMsgId;
  1212. CString _strMsg;
  1213. UNREFERENCED_PARAMETER( idsOper );
  1214. _strOperMsg.LoadString( IDS_ERROR_SETTING_PROPERTIES );
  1215. FormatError( _strErrorMsg, sc );
  1216. _strMsgIdFmt.LoadString( IDS_ERROR_MSG_ID );
  1217. _strMsgId.Format( _strMsgIdFmt, sc, sc );
  1218. _strMsg.Format( _T("%s\n\n%s%s"), _strOperMsg, _strErrorMsg, _strMsgId );
  1219. AfxMessageBox( _strMsg );
  1220. } //*** CBasePropertyPage::DisplaySetPropsError()
  1221. /////////////////////////////////////////////////////////////////////////////
  1222. //++
  1223. //
  1224. // CBasePropertyPage::OnContextMenu
  1225. //
  1226. // Routine Description:
  1227. // Handler for the WM_CONTEXTMENU message.
  1228. //
  1229. // Arguments:
  1230. // pWnd Window in which user clicked the right mouse button.
  1231. // point Position of the cursor, in screen coordinates.
  1232. //
  1233. // Return Value:
  1234. // TRUE Help processed.
  1235. // FALSE Help not processed.
  1236. //
  1237. //--
  1238. /////////////////////////////////////////////////////////////////////////////
  1239. void CBasePropertyPage::OnContextMenu( CWnd * pWnd, CPoint point )
  1240. {
  1241. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  1242. m_dlghelp.OnContextMenu( pWnd, point );
  1243. } //*** CBasePropertyPage::OnContextMenu()
  1244. /////////////////////////////////////////////////////////////////////////////
  1245. //++
  1246. //
  1247. // CBasePropertyPage::OnHelpInfo
  1248. //
  1249. // Routine Description:
  1250. // Handler for the WM_HELPINFO message.
  1251. //
  1252. // Arguments:
  1253. // pHelpInfo Structure containing info about displaying help.
  1254. //
  1255. // Return Value:
  1256. // TRUE Help processed.
  1257. // FALSE Help not processed.
  1258. //
  1259. //--
  1260. /////////////////////////////////////////////////////////////////////////////
  1261. BOOL CBasePropertyPage::OnHelpInfo( HELPINFO * pHelpInfo )
  1262. {
  1263. BOOL _bProcessed;
  1264. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  1265. _bProcessed = m_dlghelp.OnHelpInfo( pHelpInfo );
  1266. if ( ! _bProcessed )
  1267. {
  1268. _bProcessed = CPropertyPage::OnHelpInfo( pHelpInfo );
  1269. } // if: message not processed yet
  1270. return _bProcessed;
  1271. } //*** CBasePropertyPage::OnHelpInfo()
  1272. /////////////////////////////////////////////////////////////////////////////
  1273. //++
  1274. //
  1275. // CBasePropertyPage::OnCommandHelp
  1276. //
  1277. // Routine Description:
  1278. // Handler for the WM_COMMANDHELP message.
  1279. //
  1280. // Arguments:
  1281. // wParam [IN] WPARAM.
  1282. // lParam [IN] LPARAM.
  1283. //
  1284. // Return Value:
  1285. // TRUE Help processed.
  1286. // FALSE Help not processed.
  1287. //
  1288. //--
  1289. /////////////////////////////////////////////////////////////////////////////
  1290. LRESULT CBasePropertyPage::OnCommandHelp( WPARAM wParam, LPARAM lParam )
  1291. {
  1292. LRESULT _bProcessed;
  1293. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  1294. _bProcessed = m_dlghelp.OnCommandHelp( wParam, lParam );
  1295. if ( ! _bProcessed )
  1296. {
  1297. _bProcessed = CPropertyPage::OnCommandHelp( wParam, lParam );
  1298. } // if: message not processed yet
  1299. return _bProcessed;
  1300. } //*** CBasePropertyPage::OnCommandHelp()