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.

1471 lines
48 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // BasePage.cpp
  7. //
  8. // Description:
  9. // Implementation of the CBasePropertyPage class.
  10. //
  11. // Author:
  12. // <name> (<e-mail name>) Mmmm DD, 2002
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "VSSTaskEx.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. // nIDTemplate [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 nIDTemplate,
  111. IN const DWORD * pdwHelpMap,
  112. IN const DWORD * pdwWizardHelpMap,
  113. IN UINT nIDCaption
  114. )
  115. : CPropertyPage( nIDTemplate, nIDCaption )
  116. , m_dlghelp( pdwHelpMap, nIDTemplate )
  117. {
  118. CommonConstruct();
  119. m_pdwWizardHelpMap = pdwWizardHelpMap;
  120. } //*** CBasePropertyPage::CBasePropertyPage(UINT, DWORD *, DWORD *, 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 = NOERROR;
  173. CWaitCursor _wc;
  174. do
  175. {
  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. } // if: adding page to wizard
  190. else
  191. {
  192. ASSERT( IddPropertyPage() != NULL );
  193. Construct( IddPropertyPage(), IdsCaption() );
  194. } // else: adding page to property sheet
  195. // Read the properties private to this resource and parse them.
  196. {
  197. DWORD _sc = ERROR_SUCCESS;
  198. CClusPropList _cpl;
  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. break;
  268. } // if: error parsing getting or parsing properties
  269. } // Read the properties private to this resource and parse them
  270. } while ( 0 );
  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( reinterpret_cast< LPPROPSHEETPAGEW >( &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 ) // can not use != NULL because overloading tries to do a string compare!
  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.pcb = rcpl.CbhCurrentValue().pBinaryValue->cbLength;
  391. *_pprop->m_value.ppb = new BYTE[ *_pprop->m_value.pcb ];
  392. CopyMemory( *_pprop->m_value.ppb, rcpl.CbhCurrentValue().pBinaryValue->rgb, *_pprop->m_value.pcb );
  393. *_pprop->m_valuePrev.pcb = rcpl.CbhCurrentValue().pBinaryValue->cbLength;
  394. *_pprop->m_valuePrev.ppb = new BYTE[ *_pprop->m_value.pcb ];
  395. CopyMemory( *_pprop->m_valuePrev.ppb, rcpl.CbhCurrentValue().pBinaryValue->rgb, *_pprop->m_value.pcb );
  396. break;
  397. default:
  398. ASSERT(0); // don't know how to deal with this type
  399. } // switch: property format
  400. // Exit the loop since we found the parameter.
  401. break;
  402. }// if: found a type match
  403. } // if: found a string match
  404. } // for: each property that we know about
  405. //
  406. // If the property wasn't known, ask the derived class to parse it.
  407. //
  408. if ( _cprop == 0 )
  409. {
  410. _sc = ScParseUnknownProperty(
  411. rcpl.CbhCurrentPropertyName().pName->sz,
  412. rcpl.CbhCurrentValue(),
  413. rcpl.RPvlPropertyValue().CbDataLeft()
  414. );
  415. if ( _sc != ERROR_SUCCESS )
  416. {
  417. return _sc;
  418. } // if: error parsing the unknown property
  419. } // if: property not parsed
  420. //
  421. // Advance the buffer pointer past the value in the value list.
  422. //
  423. _sc = rcpl.ScMoveToNextProperty();
  424. } // while: more properties to parse
  425. //
  426. // If we reached the end of the properties, fix the return code.
  427. //
  428. if ( _sc == ERROR_NO_MORE_ITEMS )
  429. {
  430. _sc = ERROR_SUCCESS;
  431. } // if: ended loop after parsing all properties
  432. return _sc;
  433. } //*** CBasePropertyPage::ScParseProperties()
  434. /////////////////////////////////////////////////////////////////////////////
  435. //++
  436. //
  437. // CBasePropertyPage::OnCreate
  438. //
  439. // Description:
  440. // Handler for the WM_CREATE message.
  441. //
  442. // Arguments:
  443. // lpCreateStruct [IN OUT] Window create structure.
  444. //
  445. // Return Value:
  446. // -1 Error.
  447. // 0 Success.
  448. //
  449. //--
  450. /////////////////////////////////////////////////////////////////////////////
  451. int CBasePropertyPage::OnCreate( LPCREATESTRUCT lpCreateStruct )
  452. {
  453. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  454. // Attach the window to the property page structure.
  455. // This has been done once already in the main application, since the
  456. // main application owns the property sheet. It needs to be done here
  457. // so that the window handle can be found in the DLL's handle map.
  458. if ( FromHandlePermanent( m_hWnd ) == NULL ) // is the window handle already in the handle map
  459. {
  460. HWND _hWnd = m_hWnd;
  461. m_hWnd = NULL;
  462. Attach( _hWnd );
  463. m_bDoDetach = TRUE;
  464. } // if: is the window handle in the handle map
  465. return CPropertyPage::OnCreate( lpCreateStruct );
  466. } //*** CBasePropertyPage::OnCreate()
  467. /////////////////////////////////////////////////////////////////////////////
  468. //++
  469. //
  470. // CBasePropertyPage::OnDestroy
  471. //
  472. // Description:
  473. // Handler for the WM_DESTROY message.
  474. //
  475. // Arguments:
  476. // None.
  477. //
  478. // Return Value:
  479. // None.
  480. //
  481. //--
  482. /////////////////////////////////////////////////////////////////////////////
  483. void CBasePropertyPage::OnDestroy( void )
  484. {
  485. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  486. // Detach the window from the property page structure.
  487. // This will be done again by the main application, since it owns the
  488. // property sheet. It needs to be done here so that the window handle
  489. // can be removed from the DLL's handle map.
  490. if ( m_bDoDetach )
  491. {
  492. if ( m_hWnd != NULL )
  493. {
  494. HWND _hWnd = m_hWnd;
  495. Detach();
  496. m_hWnd = _hWnd;
  497. } // if: do we have a window handle?
  498. } // if: do we need to balance the attach we did with a detach?
  499. CPropertyPage::OnDestroy();
  500. } //*** CBasePropertyPage::OnDestroy()
  501. /////////////////////////////////////////////////////////////////////////////
  502. //++
  503. //
  504. // CBasePropertyPage::DoDataExchange
  505. //
  506. // Description:
  507. // Do data exchange between the dialog and the class.
  508. //
  509. // Arguments:
  510. // pDX [IN OUT] Data exchange object
  511. //
  512. // Return Value:
  513. // None.
  514. //
  515. //--
  516. /////////////////////////////////////////////////////////////////////////////
  517. void CBasePropertyPage::DoDataExchange( CDataExchange * pDX )
  518. {
  519. if ( ! pDX->m_bSaveAndValidate || ! BSaved() )
  520. {
  521. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  522. //{{AFX_DATA_MAP(CBasePropertyPage)
  523. // NOTE: the ClassWizard will add DDX and DDV calls here
  524. //}}AFX_DATA_MAP
  525. DDX_Control( pDX, IDC_PP_ICON, m_staticIcon );
  526. DDX_Control( pDX, IDC_PP_TITLE, m_staticTitle );
  527. if ( pDX->m_bSaveAndValidate )
  528. {
  529. if ( ! BBackPressed() )
  530. {
  531. CWaitCursor _wc;
  532. // Validate the data.
  533. if ( ! BSetPrivateProps( TRUE /*bValidateOnly*/ ) )
  534. {
  535. pDX->Fail();
  536. } // if: error setting private properties
  537. } // if: Back button not pressed
  538. } // if: saving data from dialog
  539. else
  540. {
  541. // Set the title.
  542. DDX_Text( pDX, IDC_PP_TITLE, m_strTitle );
  543. } // if: not saving data
  544. } // if: not saving or haven't saved yet
  545. // Call the base class method.
  546. CPropertyPage::DoDataExchange( pDX );
  547. } //*** CBasePropertyPage::DoDataExchange()
  548. /////////////////////////////////////////////////////////////////////////////
  549. //++
  550. //
  551. // CBasePropertyPage::OnInitDialog
  552. //
  553. // Description:
  554. // Handler for the WM_INITDIALOG message.
  555. //
  556. // Arguments:
  557. // None.
  558. //
  559. // Return Value:
  560. // TRUE We need the focus to be set for us.
  561. // FALSE We already set the focus to the proper control.
  562. //
  563. //--
  564. /////////////////////////////////////////////////////////////////////////////
  565. BOOL CBasePropertyPage::OnInitDialog( void )
  566. {
  567. ASSERT( Peo() != NULL );
  568. ASSERT( Peo()->PodObjData() != NULL );
  569. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  570. // Set the title string.
  571. m_strTitle = Peo()->PodObjData()->m_strName;
  572. // Call the base class method.
  573. CPropertyPage::OnInitDialog();
  574. // Display an icon for the object.
  575. if ( Peo()->Hicon() != NULL )
  576. {
  577. m_staticIcon.SetIcon( Peo()->Hicon() );
  578. } // if: an icon was specified
  579. return TRUE; // return TRUE unless you set the focus to a control
  580. // EXCEPTION: OCX Property Pages should return FALSE
  581. } //*** CBasePropertyPage::OnInitDialog()
  582. /////////////////////////////////////////////////////////////////////////////
  583. //++
  584. //
  585. // CBasePropertyPage::OnSetActive
  586. //
  587. // Description:
  588. // Handler for the PSN_SETACTIVE message.
  589. //
  590. // Arguments:
  591. // None.
  592. //
  593. // Return Value:
  594. // TRUE Page successfully initialized.
  595. // FALSE Page not initialized.
  596. //
  597. //--
  598. /////////////////////////////////////////////////////////////////////////////
  599. BOOL CBasePropertyPage::OnSetActive( void )
  600. {
  601. HRESULT _hr;
  602. ASSERT( Peo() != NULL);
  603. ASSERT( Peo()->PodObjData() != NULL );
  604. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  605. // Reread the data.
  606. _hr = Peo()->HrGetObjectInfo();
  607. if ( _hr != NOERROR )
  608. {
  609. return FALSE;
  610. } // if: error getting object info
  611. // Set the title string.
  612. m_strTitle = Peo()->PodObjData()->m_strName;
  613. m_bBackPressed = FALSE;
  614. m_bSaved = FALSE;
  615. return CPropertyPage::OnSetActive();
  616. } //*** CBasePropertyPage::OnSetActive()
  617. /////////////////////////////////////////////////////////////////////////////
  618. //++
  619. //
  620. // CBasePropertyPage::OnApply
  621. //
  622. // Description:
  623. // Handler for the PSM_APPLY message.
  624. //
  625. // Arguments:
  626. // None.
  627. //
  628. // Return Value:
  629. // TRUE Page successfully applied.
  630. // FALSE Error applying page.
  631. //
  632. //--
  633. /////////////////////////////////////////////////////////////////////////////
  634. BOOL CBasePropertyPage::OnApply( void )
  635. {
  636. ASSERT( ! BWizard() );
  637. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  638. CWaitCursor _wc;
  639. if ( ! BApplyChanges() )
  640. {
  641. return FALSE;
  642. } // if: error applying changes
  643. return CPropertyPage::OnApply();
  644. } //*** CBasePropertyPage::OnApply()
  645. /////////////////////////////////////////////////////////////////////////////
  646. //++
  647. //
  648. // CBasePropertyPage::OnWizardBack
  649. //
  650. // Description:
  651. // Handler for the PSN_WIZBACK message.
  652. //
  653. // Arguments:
  654. // None.
  655. //
  656. // Return Value:
  657. // -1 Don't change the page.
  658. // 0 Change the page.
  659. //
  660. //--
  661. /////////////////////////////////////////////////////////////////////////////
  662. LRESULT CBasePropertyPage::OnWizardBack( void )
  663. {
  664. LRESULT _lResult;
  665. ASSERT( BWizard() );
  666. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  667. _lResult = CPropertyPage::OnWizardBack();
  668. if ( _lResult != -1 )
  669. {
  670. m_bBackPressed = TRUE;
  671. } // if: no error occurred
  672. return _lResult;
  673. } //*** CBasePropertyPage::OnWizardBack()
  674. /////////////////////////////////////////////////////////////////////////////
  675. //++
  676. //
  677. // CBasePropertyPage::OnWizardNext
  678. //
  679. // Description:
  680. // Handler for the PSN_WIZNEXT message.
  681. //
  682. // Arguments:
  683. // None.
  684. //
  685. // Return Value:
  686. // -1 Don't change the page.
  687. // 0 Change the page.
  688. //
  689. //--
  690. /////////////////////////////////////////////////////////////////////////////
  691. LRESULT CBasePropertyPage::OnWizardNext( void )
  692. {
  693. ASSERT( BWizard() );
  694. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  695. CWaitCursor _wc;
  696. // Update the data in the class from the page.
  697. // This necessary because, while OnKillActive() will call UpdateData(),
  698. // it is called after this method is called, and we need to be sure that
  699. // data has been saved before we apply them.
  700. if ( ! UpdateData( TRUE /*bSaveAndValidate*/ ) )
  701. {
  702. return -1;
  703. } // if: error updating data
  704. // Save the data in the sheet.
  705. if ( ! BApplyChanges() )
  706. {
  707. return -1;
  708. } // if: error applying changes
  709. // Create the object.
  710. return CPropertyPage::OnWizardNext();
  711. } //*** CBasePropertyPage::OnWizardNext()
  712. /////////////////////////////////////////////////////////////////////////////
  713. //++
  714. //
  715. // CBasePropertyPage::OnWizardFinish
  716. //
  717. // Description:
  718. // Handler for the PSN_WIZFINISH message.
  719. //
  720. // Arguments:
  721. // None.
  722. //
  723. // Return Value:
  724. // FALSE Don't change the page.
  725. // TRUE Change the page.
  726. //
  727. //--
  728. /////////////////////////////////////////////////////////////////////////////
  729. BOOL CBasePropertyPage::OnWizardFinish( void )
  730. {
  731. ASSERT( BWizard() );
  732. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  733. CWaitCursor _wc;
  734. // BUG! There should be no need to call UpdateData in this function.
  735. // See BUG: Finish Button Fails Data Transfer from Page to Variables
  736. // KB Article ID: Q150349
  737. // Update the data in the class from the page.
  738. if ( ! UpdateData( TRUE /*bSaveAndValidate*/ ) )
  739. {
  740. return FALSE;
  741. } // if: error updating data
  742. // Save the data in the sheet.
  743. if ( ! BApplyChanges() )
  744. {
  745. return FALSE;
  746. } // if: error applying changes
  747. return CPropertyPage::OnWizardFinish();
  748. } //*** CBasePropertyPage::OnWizardFinish()
  749. /////////////////////////////////////////////////////////////////////////////
  750. //++
  751. //
  752. // CBasePropertyPage::OnChangeCtrl
  753. //
  754. // Description:
  755. // Handler for the messages sent when a control is changed. This
  756. // method can be specified in a message map if all that needs to be
  757. // done is enable the Apply button.
  758. //
  759. // Arguments:
  760. // None.
  761. //
  762. // Return Value:
  763. // None.
  764. //
  765. //--
  766. /////////////////////////////////////////////////////////////////////////////
  767. void CBasePropertyPage::OnChangeCtrl( void )
  768. {
  769. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  770. SetModified( TRUE );
  771. } //*** CBasePropertyPage::OnChangeCtrl()
  772. /////////////////////////////////////////////////////////////////////////////
  773. //++
  774. //
  775. // CBasePropertyPage::EnableNext
  776. //
  777. // Description:
  778. // Enables or disables the NEXT or FINISH button.
  779. //
  780. // Arguments:
  781. // bEnable [IN] TRUE = enable the button, FALSE = disable the button.
  782. //
  783. // Return Value:
  784. // None.
  785. //
  786. //--
  787. /////////////////////////////////////////////////////////////////////////////
  788. void CBasePropertyPage::EnableNext( IN BOOL bEnable /*TRUE*/ )
  789. {
  790. ASSERT( BWizard() );
  791. ASSERT( PiWizardCallback() );
  792. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  793. PiWizardCallback()->EnableNext( reinterpret_cast< LONG * >( Hpage() ), bEnable );
  794. } //*** CBasePropertyPage::EnableNext()
  795. /////////////////////////////////////////////////////////////////////////////
  796. //++
  797. //
  798. // CBasePropertyPage::BApplyChanges
  799. //
  800. // Description:
  801. // Apply changes made on the page.
  802. //
  803. // Arguments:
  804. // None.
  805. //
  806. // Return Value:
  807. // TRUE Page successfully applied.
  808. // FALSE Error applying page.
  809. //
  810. //--
  811. /////////////////////////////////////////////////////////////////////////////
  812. BOOL CBasePropertyPage::BApplyChanges( void )
  813. {
  814. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  815. CWaitCursor _wc;
  816. // Save data.
  817. return BSetPrivateProps();
  818. } //*** CBasePropertyPage::BApplyChanges()
  819. /////////////////////////////////////////////////////////////////////////////
  820. //++
  821. //
  822. // CBasePropertyPage::BBuildPropList
  823. //
  824. // Description:
  825. // Build the property list.
  826. //
  827. // Arguments:
  828. // rcpl [IN OUT] Cluster property list.
  829. // bNoNewProps [IN] TRUE = exclude properties marked with opfNew.
  830. //
  831. // Return Value:
  832. // TRUE Property list built successfully.
  833. // FALSE Error building property list.
  834. //
  835. // Exceptions Thrown:
  836. // Any exceptions thrown by CClusPropList::AddProp().
  837. //
  838. //--
  839. /////////////////////////////////////////////////////////////////////////////
  840. BOOL CBasePropertyPage::BBuildPropList(
  841. IN OUT CClusPropList & rcpl,
  842. IN BOOL bNoNewProps // = FALSE
  843. )
  844. {
  845. BOOL _bNewPropsFound = FALSE;
  846. DWORD _cprop;
  847. const CObjectProperty * _pprop;
  848. for ( _pprop = Pprops(), _cprop = Cprops() ; _cprop > 0 ; _pprop++, _cprop-- )
  849. {
  850. if ( bNoNewProps && (_pprop->m_fFlags & CObjectProperty::opfNew) )
  851. {
  852. _bNewPropsFound = TRUE;
  853. continue;
  854. } // if: no new props allowed and this is a new property
  855. switch ( _pprop->m_propFormat )
  856. {
  857. case CLUSPROP_FORMAT_SZ:
  858. rcpl.ScAddProp(
  859. _pprop->m_pwszName,
  860. *_pprop->m_value.pstr,
  861. *_pprop->m_valuePrev.pstr
  862. );
  863. break;
  864. case CLUSPROP_FORMAT_EXPAND_SZ:
  865. rcpl.ScAddExpandSzProp(
  866. _pprop->m_pwszName,
  867. *_pprop->m_value.pstr,
  868. *_pprop->m_valuePrev.pstr
  869. );
  870. break;
  871. case CLUSPROP_FORMAT_DWORD:
  872. rcpl.ScAddProp(
  873. _pprop->m_pwszName,
  874. *_pprop->m_value.pdw,
  875. *_pprop->m_valuePrev.pdw
  876. );
  877. break;
  878. case CLUSPROP_FORMAT_LONG:
  879. rcpl.ScAddProp(
  880. _pprop->m_pwszName,
  881. *_pprop->m_value.pl,
  882. *_pprop->m_valuePrev.pl
  883. );
  884. break;
  885. case CLUSPROP_FORMAT_BINARY:
  886. case CLUSPROP_FORMAT_MULTI_SZ:
  887. rcpl.ScAddProp(
  888. _pprop->m_pwszName,
  889. *_pprop->m_value.ppb,
  890. *_pprop->m_value.pcb,
  891. *_pprop->m_valuePrev.ppb,
  892. *_pprop->m_valuePrev.pcb
  893. );
  894. break;
  895. default:
  896. ASSERT( 0 ); // don't know how to deal with this type
  897. return FALSE;
  898. } // switch: property format
  899. } // for: each property
  900. return ( ! bNoNewProps || _bNewPropsFound );
  901. } //*** CBasePropertyPage::BBuildPropList()
  902. /////////////////////////////////////////////////////////////////////////////
  903. //++
  904. //
  905. // CBasePropertyPage::BSetPrivateProps
  906. //
  907. // Description:
  908. // Set the private properties for this object.
  909. //
  910. // Arguments:
  911. // bValidateOnly [IN] TRUE = only validate the data.
  912. // bNoNewProps [IN] TRUE = exclude properties marked with opfNew.
  913. //
  914. // Return Value:
  915. // ERROR_SUCCESS The operation was completed successfully.
  916. // !0 Failure.
  917. //
  918. //--
  919. /////////////////////////////////////////////////////////////////////////////
  920. BOOL CBasePropertyPage::BSetPrivateProps(
  921. IN BOOL bValidateOnly, // = FALSE
  922. IN BOOL bNoNewProps // = FALSE
  923. )
  924. {
  925. BOOL _bSuccess = TRUE;
  926. CClusPropList _cpl( BWizard() /*bAlwaysAddProp*/ );
  927. ASSERT( Peo() != NULL );
  928. ASSERT( Peo()->PrdResData() );
  929. ASSERT( Peo()->PrdResData()->m_hresource );
  930. // Build the property list.
  931. try
  932. {
  933. _bSuccess = BBuildPropList( _cpl, bNoNewProps );
  934. } // try
  935. catch ( CException * pe )
  936. {
  937. pe->ReportError();
  938. pe->Delete();
  939. _bSuccess = FALSE;
  940. } // catch: CException
  941. // Set the data.
  942. if ( _bSuccess )
  943. {
  944. if ( (_cpl.PbPropList() != NULL) && (_cpl.CbPropList() > 0) )
  945. {
  946. DWORD _sc = ERROR_SUCCESS;
  947. DWORD _dwControlCode;
  948. DWORD _cbProps;
  949. switch ( Cot() )
  950. {
  951. case CLUADMEX_OT_NODE:
  952. ASSERT( Peo()->PndNodeData() != NULL );
  953. ASSERT( Peo()->PndNodeData()->m_hnode != NULL );
  954. // Determine which control code to use.
  955. if ( bValidateOnly )
  956. {
  957. _dwControlCode = CLUSCTL_NODE_VALIDATE_PRIVATE_PROPERTIES;
  958. } // if: only validating data
  959. else
  960. {
  961. _dwControlCode = CLUSCTL_NODE_SET_PRIVATE_PROPERTIES;
  962. } // else: setting data
  963. // Set private properties.
  964. _sc = ClusterNodeControl(
  965. Peo()->PndNodeData()->m_hnode,
  966. NULL, // hNode
  967. _dwControlCode,
  968. _cpl.PbPropList(),
  969. _cpl.CbPropList(),
  970. NULL, // lpOutBuffer
  971. 0, // nOutBufferSize
  972. &_cbProps
  973. );
  974. break;
  975. case CLUADMEX_OT_GROUP:
  976. ASSERT( Peo()->PgdGroupData() != NULL );
  977. ASSERT( Peo()->PgdGroupData()->m_hgroup != NULL );
  978. // Determine which control code to use.
  979. if ( bValidateOnly )
  980. {
  981. _dwControlCode = CLUSCTL_GROUP_VALIDATE_PRIVATE_PROPERTIES;
  982. } // if: only validating data
  983. else
  984. {
  985. _dwControlCode = CLUSCTL_GROUP_SET_PRIVATE_PROPERTIES;
  986. } // else: setting data
  987. // Set private properties.
  988. _sc = ClusterGroupControl(
  989. Peo()->PgdGroupData()->m_hgroup,
  990. NULL, // hNode
  991. _dwControlCode,
  992. _cpl.PbPropList(),
  993. _cpl.CbPropList(),
  994. NULL, // lpOutBuffer
  995. 0, // nOutBufferSize
  996. &_cbProps
  997. );
  998. break;
  999. case CLUADMEX_OT_RESOURCE:
  1000. ASSERT( Peo()->PrdResData() != NULL );
  1001. ASSERT( Peo()->PrdResData()->m_hresource != NULL );
  1002. // Determine which control code to use.
  1003. if ( bValidateOnly )
  1004. {
  1005. _dwControlCode = CLUSCTL_RESOURCE_VALIDATE_PRIVATE_PROPERTIES;
  1006. } // if: only validating data
  1007. else
  1008. {
  1009. _dwControlCode = CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES;
  1010. } // else: setting data
  1011. // Set private properties.
  1012. _sc = ClusterResourceControl(
  1013. Peo()->PrdResData()->m_hresource,
  1014. NULL, // hNode
  1015. _dwControlCode,
  1016. _cpl.PbPropList(),
  1017. _cpl.CbPropList(),
  1018. NULL, // lpOutBuffer
  1019. 0, // nOutBufferSize
  1020. &_cbProps
  1021. );
  1022. break;
  1023. case CLUADMEX_OT_RESOURCETYPE:
  1024. ASSERT( Peo()->PodObjData() != NULL );
  1025. ASSERT( Peo()->PodObjData()->m_strName.GetLength() > 0 );
  1026. // Determine which control code to use.
  1027. if ( bValidateOnly )
  1028. {
  1029. _dwControlCode = CLUSCTL_RESOURCE_TYPE_VALIDATE_PRIVATE_PROPERTIES;
  1030. } // if: only validating data
  1031. else
  1032. {
  1033. _dwControlCode = CLUSCTL_RESOURCE_TYPE_SET_PRIVATE_PROPERTIES;
  1034. } // else: setting data
  1035. // Set private properties.
  1036. _sc = ClusterResourceTypeControl(
  1037. Hcluster(),
  1038. Peo()->PodObjData()->m_strName,
  1039. NULL, // hNode
  1040. _dwControlCode,
  1041. _cpl.PbPropList(),
  1042. _cpl.CbPropList(),
  1043. NULL, // lpOutBuffer
  1044. 0, // nOutBufferSize
  1045. &_cbProps
  1046. );
  1047. break;
  1048. case CLUADMEX_OT_NETWORK:
  1049. ASSERT( Peo()->PndNetworkData() != NULL );
  1050. ASSERT( Peo()->PndNetworkData()->m_hnetwork != NULL );
  1051. // Determine which control code to use.
  1052. if ( bValidateOnly )
  1053. {
  1054. _dwControlCode = CLUSCTL_NETWORK_VALIDATE_PRIVATE_PROPERTIES;
  1055. } // if: only validating data
  1056. else
  1057. {
  1058. _dwControlCode = CLUSCTL_NETWORK_SET_PRIVATE_PROPERTIES;
  1059. } // else: setting data
  1060. // Set private properties.
  1061. _sc = ClusterNetworkControl(
  1062. Peo()->PndNetworkData()->m_hnetwork,
  1063. NULL, // hNode
  1064. _dwControlCode,
  1065. _cpl.PbPropList(),
  1066. _cpl.CbPropList(),
  1067. NULL, // lpOutBuffer
  1068. 0, // nOutBufferSize
  1069. &_cbProps
  1070. );
  1071. break;
  1072. case CLUADMEX_OT_NETINTERFACE:
  1073. ASSERT( Peo()->PndNetInterfaceData() != NULL );
  1074. ASSERT( Peo()->PndNetInterfaceData()->m_hnetinterface != NULL );
  1075. // Determine which control code to use.
  1076. if ( bValidateOnly )
  1077. {
  1078. _dwControlCode = CLUSCTL_NETINTERFACE_VALIDATE_PRIVATE_PROPERTIES;
  1079. } // if: only validating data
  1080. else
  1081. {
  1082. _dwControlCode = CLUSCTL_NETINTERFACE_SET_PRIVATE_PROPERTIES;
  1083. } // else: setting data
  1084. // Set private properties.
  1085. _sc = ClusterNetInterfaceControl(
  1086. Peo()->PndNetInterfaceData()->m_hnetinterface,
  1087. NULL, // hNode
  1088. _dwControlCode,
  1089. _cpl.PbPropList(),
  1090. _cpl.CbPropList(),
  1091. NULL, // lpOutBuffer
  1092. 0, // nOutBufferSize
  1093. &_cbProps
  1094. );
  1095. break;
  1096. default:
  1097. ASSERT( 0 );
  1098. } // switch: object type
  1099. // Handle errors.
  1100. if ( _sc != ERROR_SUCCESS )
  1101. {
  1102. if ( _sc == ERROR_INVALID_PARAMETER )
  1103. {
  1104. if ( ! bNoNewProps )
  1105. {
  1106. _bSuccess = BSetPrivateProps( bValidateOnly, TRUE /*bNoNewProps*/ );
  1107. } // if: new props are allowed
  1108. else
  1109. _bSuccess = FALSE;
  1110. } // if: invalid parameter error occurred
  1111. else
  1112. {
  1113. _bSuccess = FALSE;
  1114. } // else: some other error occurred
  1115. //
  1116. // If an error occurred, display an error message.
  1117. //
  1118. if ( ! _bSuccess )
  1119. {
  1120. DisplaySetPropsError( _sc, bValidateOnly ? IDS_ERROR_VALIDATING_PROPERTIES : IDS_ERROR_SETTING_PROPERTIES );
  1121. if ( _sc == ERROR_RESOURCE_PROPERTIES_STORED )
  1122. {
  1123. _bSuccess = TRUE;
  1124. } // if: properties only stored
  1125. } // if: error occurred
  1126. } // if: error setting/validating data
  1127. } // if: there is data to set
  1128. } // if: no errors building the property list
  1129. // Save data locally.
  1130. if ( ! bValidateOnly && _bSuccess )
  1131. {
  1132. // Save new values as previous values.
  1133. try
  1134. {
  1135. DWORD _cprop;
  1136. const CObjectProperty * _pprop;
  1137. for ( _pprop = Pprops(), _cprop = Cprops() ; _cprop > 0 ; _pprop++, _cprop-- )
  1138. {
  1139. switch ( _pprop->m_propFormat )
  1140. {
  1141. case CLUSPROP_FORMAT_SZ:
  1142. case CLUSPROP_FORMAT_EXPAND_SZ:
  1143. ASSERT(_pprop->m_value.pstr != NULL);
  1144. ASSERT(_pprop->m_valuePrev.pstr != NULL);
  1145. *_pprop->m_valuePrev.pstr = *_pprop->m_value.pstr;
  1146. break;
  1147. case CLUSPROP_FORMAT_DWORD:
  1148. case CLUSPROP_FORMAT_LONG:
  1149. ASSERT( _pprop->m_value.pdw != NULL );
  1150. ASSERT( _pprop->m_valuePrev.pdw != NULL );
  1151. *_pprop->m_valuePrev.pdw = *_pprop->m_value.pdw;
  1152. break;
  1153. case CLUSPROP_FORMAT_BINARY:
  1154. case CLUSPROP_FORMAT_MULTI_SZ:
  1155. ASSERT( _pprop->m_value.ppb != NULL );
  1156. ASSERT( *_pprop->m_value.ppb != NULL );
  1157. ASSERT( _pprop->m_value.pcb != NULL );
  1158. ASSERT( _pprop->m_valuePrev.ppb != NULL );
  1159. ASSERT( *_pprop->m_valuePrev.ppb != NULL );
  1160. ASSERT( _pprop->m_valuePrev.pcb != NULL );
  1161. delete [] *_pprop->m_valuePrev.ppb;
  1162. *_pprop->m_valuePrev.ppb = new BYTE[ *_pprop->m_value.pcb ];
  1163. CopyMemory( *_pprop->m_valuePrev.ppb, *_pprop->m_value.ppb, *_pprop->m_value.pcb );
  1164. *_pprop->m_valuePrev.pcb = *_pprop->m_value.pcb;
  1165. break;
  1166. default:
  1167. ASSERT( 0 ); // don't know how to deal with this type
  1168. } // switch: property format
  1169. } // for: each property
  1170. } // try
  1171. catch ( CException * _pe )
  1172. {
  1173. _pe->ReportError();
  1174. _pe->Delete();
  1175. _bSuccess = FALSE;
  1176. } // catch: CException
  1177. } // if: not just validating and successful so far
  1178. //
  1179. // Indicate we successfully saved the properties.
  1180. //
  1181. if ( ! bValidateOnly && _bSuccess )
  1182. {
  1183. m_bSaved = TRUE;
  1184. } // if: successfully saved data
  1185. return _bSuccess;
  1186. } //*** CBasePropertyPage::BSetPrivateProps()
  1187. /////////////////////////////////////////////////////////////////////////////
  1188. //++
  1189. //
  1190. // CBasePropertyPage::DisplaySetPropsError
  1191. //
  1192. // Routine Description:
  1193. // Display an error caused by setting or validating properties.
  1194. //
  1195. // Arguments:
  1196. // sc [IN] Status to display error on.
  1197. // idsOper [IN] Operation message.
  1198. //
  1199. // Return Value:
  1200. // nStatus ERROR_SUCCESS = success, !0 = failure
  1201. //
  1202. //--
  1203. /////////////////////////////////////////////////////////////////////////////
  1204. void CBasePropertyPage::DisplaySetPropsError(
  1205. IN DWORD sc,
  1206. IN UINT idsOper
  1207. ) const
  1208. {
  1209. CString _strErrorMsg;
  1210. CString _strOperMsg;
  1211. CString _strMsgIdFmt;
  1212. CString _strMsgId;
  1213. CString _strMsg;
  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()