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.

1061 lines
26 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-1999 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // BasePage.cpp
  7. //
  8. // Abstract:
  9. // Implementation of the CBasePropertyPage class.
  10. //
  11. // Author:
  12. // David Potter (davidp) June 28, 1996
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "IISClEx3.h"
  21. #include "ExtObj.h"
  22. #include "BasePage.h"
  23. #include "BasePage.inl"
  24. #include "PropList.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CBasePropertyPage property page
  32. /////////////////////////////////////////////////////////////////////////////
  33. IMPLEMENT_DYNCREATE(CBasePropertyPage, CPropertyPage)
  34. /////////////////////////////////////////////////////////////////////////////
  35. // Message Maps
  36. BEGIN_MESSAGE_MAP(CBasePropertyPage, CPropertyPage)
  37. //{{AFX_MSG_MAP(CBasePropertyPage)
  38. ON_WM_CREATE()
  39. ON_WM_DESTROY()
  40. ON_WM_HELPINFO()
  41. ON_WM_CONTEXTMENU()
  42. ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
  43. //}}AFX_MSG_MAP
  44. END_MESSAGE_MAP()
  45. /////////////////////////////////////////////////////////////////////////////
  46. //++
  47. //
  48. // CBasePropertyPage::CBasePropertyPage
  49. //
  50. // Routine Description:
  51. // Default constructor.
  52. //
  53. // Arguments:
  54. // None.
  55. //
  56. // Return Value:
  57. // None.
  58. //
  59. //--
  60. /////////////////////////////////////////////////////////////////////////////
  61. CBasePropertyPage::CBasePropertyPage(void)
  62. {
  63. CommonConstruct();
  64. } //*** CBasePropertyPage::CBasePropertyPage()
  65. /////////////////////////////////////////////////////////////////////////////
  66. //++
  67. //
  68. // CBasePropertyPage::CBasePropertyPage
  69. //
  70. // Routine Description:
  71. // Default constructor.
  72. //
  73. // Arguments:
  74. // pdwHelpMap [IN] Control-to-help ID map.
  75. // pdwWizardHelpMap [IN] Control-to-help ID map if this is a wizard page.
  76. //
  77. // Return Value:
  78. // None.
  79. //
  80. //--
  81. /////////////////////////////////////////////////////////////////////////////
  82. CBasePropertyPage::CBasePropertyPage(
  83. IN const DWORD * pdwHelpMap,
  84. IN const DWORD * pdwWizardHelpMap
  85. )
  86. : m_dlghelp(pdwHelpMap, 0)
  87. {
  88. CommonConstruct();
  89. m_pdwWizardHelpMap = pdwWizardHelpMap;
  90. } //*** CBasePropertyPage::CBasePropertyPage()
  91. /////////////////////////////////////////////////////////////////////////////
  92. //++
  93. //
  94. // CBasePropertyPage::CBasePropertyPage
  95. //
  96. // Routine Description:
  97. // Default constructor.
  98. //
  99. // Arguments:
  100. // idd [IN] Dialog template resource ID.
  101. // pdwHelpMap [IN] Control-to-help ID map.
  102. // pdwWizardHelpMap [IN] Control-to-help ID map if this is a wizard page.
  103. // nIDCaption [IN] Caption string resource ID.
  104. //
  105. // Return Value:
  106. // None.
  107. //
  108. //--
  109. /////////////////////////////////////////////////////////////////////////////
  110. CBasePropertyPage::CBasePropertyPage(
  111. IN UINT idd,
  112. IN const DWORD * pdwHelpMap,
  113. IN const DWORD * pdwWizardHelpMap,
  114. IN UINT nIDCaption
  115. )
  116. : CPropertyPage(idd, nIDCaption)
  117. , m_dlghelp(pdwHelpMap, idd)
  118. {
  119. CommonConstruct();
  120. m_pdwWizardHelpMap = pdwWizardHelpMap;
  121. } //*** CBasePropertyPage::CBasePropertyPage(UINT, UINT)
  122. /////////////////////////////////////////////////////////////////////////////
  123. //++
  124. //
  125. // CBasePropertyPage::CommonConstruct
  126. //
  127. // Routine Description:
  128. // Common construction.
  129. //
  130. // Arguments:
  131. // None.
  132. //
  133. // Return Value:
  134. // None.
  135. //
  136. //--
  137. /////////////////////////////////////////////////////////////////////////////
  138. void CBasePropertyPage::CommonConstruct(void)
  139. {
  140. //{{AFX_DATA_INIT(CBasePropertyPage)
  141. //}}AFX_DATA_INIT
  142. m_peo = NULL;
  143. m_hpage = NULL;
  144. m_bBackPressed = 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::BInit
  155. //
  156. // Routine Description:
  157. // Initialize the page.
  158. //
  159. // Arguments:
  160. // peo [IN OUT] Pointer to the extension object.
  161. //
  162. // Return Value:
  163. // TRUE Page initialized successfully.
  164. // FALSE Page failed to initialize.
  165. //
  166. //--
  167. /////////////////////////////////////////////////////////////////////////////
  168. BOOL CBasePropertyPage::BInit(IN OUT CExtObject * peo)
  169. {
  170. ASSERT(peo != NULL);
  171. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  172. CWaitCursor wc;
  173. m_peo = peo;
  174. // Change the help map if this is a wizard page.
  175. if (Peo()->BWizard())
  176. m_dlghelp.SetMap(m_pdwWizardHelpMap);
  177. // Don't display a help button.
  178. m_psp.dwFlags &= ~PSP_HASHELP;
  179. // Construct the property page.
  180. if (Peo()->BWizard())
  181. {
  182. ASSERT(IddWizardPage() != NULL);
  183. Construct(IddWizardPage(), IdsCaption());
  184. m_dlghelp.SetHelpMask(IddWizardPage());
  185. } // if: adding page to wizard
  186. else
  187. {
  188. ASSERT(IddPropertyPage() != NULL);
  189. Construct(IddPropertyPage(), IdsCaption());
  190. m_dlghelp.SetHelpMask(IddPropertyPage());
  191. } // else: adding page to property sheet
  192. // Read the properties private to this resource and parse them.
  193. {
  194. DWORD dwStatus;
  195. CClusPropList cpl;
  196. ASSERT(Peo() != NULL);
  197. ASSERT(Peo()->PrdResData() != NULL);
  198. ASSERT(Peo()->PrdResData()->m_hresource != NULL);
  199. // Read the properties.
  200. dwStatus = cpl.ScGetResourceProperties(
  201. Peo()->PrdResData()->m_hresource,
  202. CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES
  203. );
  204. // Parse the properties.
  205. if (dwStatus == ERROR_SUCCESS)
  206. {
  207. // Parse the properties.
  208. try
  209. {
  210. dwStatus = DwParseProperties(cpl);
  211. } // try
  212. catch (CMemoryException * pme)
  213. {
  214. dwStatus = ERROR_NOT_ENOUGH_MEMORY;
  215. pme->Delete();
  216. } // catch: CMemoryException
  217. } // if: properties read successfully
  218. if (dwStatus != ERROR_SUCCESS)
  219. {
  220. return FALSE;
  221. } // if: error parsing getting or parsing properties
  222. } // Read the properties private to this resource and parse them
  223. return TRUE;
  224. } //*** CBasePropertyPage::BInit()
  225. /////////////////////////////////////////////////////////////////////////////
  226. //++
  227. //
  228. // CBasePropertyPage::DwParseProperties
  229. //
  230. // Routine Description:
  231. // Parse the properties of the resource. This is in a separate function
  232. // from BInit so that the optimizer can do a better job.
  233. //
  234. // Arguments:
  235. // rcpl [IN] Cluster property list to parse.
  236. //
  237. // Return Value:
  238. // ERROR_SUCCESS Properties were parsed successfully.
  239. //
  240. // Exceptions Thrown:
  241. // Any exceptions from CString::operator=().
  242. //
  243. //--
  244. /////////////////////////////////////////////////////////////////////////////
  245. DWORD CBasePropertyPage::DwParseProperties(IN CClusPropList & rcpl)
  246. {
  247. DWORD _sc;
  248. DWORD _cprop;
  249. const CObjectProperty * _pprop;
  250. ASSERT( rcpl.PbPropList() != NULL );
  251. _sc = rcpl.ScMoveToFirstProperty();
  252. while ( _sc == ERROR_SUCCESS )
  253. {
  254. //
  255. // Parse known properties.
  256. //
  257. for ( _pprop = Pprops(), _cprop = Cprops() ; _cprop > 0 ; _pprop++, _cprop-- )
  258. {
  259. if ( lstrcmpiW( rcpl.PszCurrentPropertyName(), _pprop->m_pwszName ) == 0 )
  260. {
  261. ASSERT( rcpl.CpfCurrentValueFormat() == _pprop->m_propFormat );
  262. switch ( _pprop->m_propFormat )
  263. {
  264. case CLUSPROP_FORMAT_SZ:
  265. case CLUSPROP_FORMAT_EXPAND_SZ:
  266. ASSERT( (rcpl.CbCurrentValueLength() == (lstrlenW( rcpl.CbhCurrentValue().pStringValue->sz ) + 1) * sizeof( WCHAR ))
  267. || ( (rcpl.CbCurrentValueLength() == 0)
  268. && (rcpl.CbhCurrentValue().pStringValue->sz[ 0 ] == L'\0') ) );
  269. *_pprop->m_value.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  270. *_pprop->m_valuePrev.pstr = rcpl.CbhCurrentValue().pStringValue->sz;
  271. break;
  272. case CLUSPROP_FORMAT_DWORD:
  273. case CLUSPROP_FORMAT_LONG:
  274. ASSERT( rcpl.CbCurrentValueLength() == sizeof( DWORD ) );
  275. *_pprop->m_value.pdw = rcpl.CbhCurrentValue().pDwordValue->dw;
  276. *_pprop->m_valuePrev.pdw = rcpl.CbhCurrentValue().pDwordValue->dw;
  277. break;
  278. case CLUSPROP_FORMAT_BINARY:
  279. case CLUSPROP_FORMAT_MULTI_SZ:
  280. *_pprop->m_value.ppb = rcpl.CbhCurrentValue().pBinaryValue->rgb;
  281. *_pprop->m_value.pcb = rcpl.CbhCurrentValue().pBinaryValue->cbLength;
  282. *_pprop->m_valuePrev.ppb = rcpl.CbhCurrentValue().pBinaryValue->rgb;
  283. *_pprop->m_valuePrev.pcb = rcpl.CbhCurrentValue().pBinaryValue->cbLength;
  284. break;
  285. default:
  286. ASSERT(0); // don't know how to deal with this type
  287. } // switch: property format
  288. // Exit the loop since we found the parameter.
  289. break;
  290. } // if: found a match
  291. } // for: each property that we know about
  292. //
  293. // If the property wasn't known, ask the derived class to parse it.
  294. //
  295. if ( _cprop == 0 )
  296. {
  297. _sc = DwParseUnknownProperty(
  298. rcpl.CbhCurrentPropertyName().pName->sz,
  299. rcpl.CbhCurrentValue(),
  300. rcpl.RPvlPropertyValue().CbDataLeft()
  301. );
  302. if ( _sc != ERROR_SUCCESS )
  303. {
  304. return _sc;
  305. } // if: error parsing the unknown property
  306. } // if: property not parsed
  307. //
  308. // Advance the buffer pointer past the value in the value list.
  309. //
  310. _sc = rcpl.ScMoveToNextProperty();
  311. } // while: more properties to parse
  312. //
  313. // If we reached the end of the properties, fix the return code.
  314. //
  315. if ( _sc == ERROR_NO_MORE_ITEMS )
  316. {
  317. _sc = ERROR_SUCCESS;
  318. } // if: ended loop after parsing all properties
  319. return _sc;
  320. } //*** CBasePropertyPage::DwParseProperties()
  321. /////////////////////////////////////////////////////////////////////////////
  322. //++
  323. //
  324. // CBasePropertyPage::OnCreate
  325. //
  326. // Routine Description:
  327. // Handler for the WM_CREATE message.
  328. //
  329. // Arguments:
  330. // lpCreateStruct [IN OUT] Window create structure.
  331. //
  332. // Return Value:
  333. // -1 Error.
  334. // 0 Success.
  335. //
  336. //--
  337. /////////////////////////////////////////////////////////////////////////////
  338. int CBasePropertyPage::OnCreate(LPCREATESTRUCT lpCreateStruct)
  339. {
  340. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  341. // Attach the window to the property page structure.
  342. // This has been done once already in the main application, since the
  343. // main application owns the property sheet. It needs to be done here
  344. // so that the window handle can be found in the DLL's handle map.
  345. if (FromHandlePermanent(m_hWnd) == NULL) // is the window handle already in the handle map
  346. {
  347. HWND _hWnd = m_hWnd;
  348. m_hWnd = NULL;
  349. Attach(_hWnd);
  350. m_bDoDetach = TRUE;
  351. } // if: is the window handle in the handle map
  352. return CPropertyPage::OnCreate(lpCreateStruct);
  353. } //*** CBasePropertyPage::OnCreate()
  354. /////////////////////////////////////////////////////////////////////////////
  355. //++
  356. //
  357. // CBasePropertyPage::OnDestroy
  358. //
  359. // Routine Description:
  360. // Handler for the WM_DESTROY message.
  361. //
  362. // Arguments:
  363. // None.
  364. //
  365. // Return Value:
  366. // None.
  367. //
  368. //--
  369. /////////////////////////////////////////////////////////////////////////////
  370. void CBasePropertyPage::OnDestroy(void)
  371. {
  372. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  373. // Detach the window from the property page structure.
  374. // This will be done again by the main application, since it owns the
  375. // property sheet. It needs to be done here so that the window handle
  376. // can be removed from the DLL's handle map.
  377. if (m_bDoDetach)
  378. {
  379. if (m_hWnd != NULL)
  380. {
  381. HWND hWnd = m_hWnd;
  382. Detach();
  383. m_hWnd = hWnd;
  384. } // if: do we have a window handle?
  385. } // if: do we need to balance the attach we did with a detach?
  386. CPropertyPage::OnDestroy();
  387. } //*** CBasePropertyPage::OnDestroy()
  388. /////////////////////////////////////////////////////////////////////////////
  389. //++
  390. //
  391. // CBasePropertyPage::DoDataExchange
  392. //
  393. // Routine Description:
  394. // Do data exchange between the dialog and the class.
  395. //
  396. // Arguments:
  397. // pDX [IN OUT] Data exchange object
  398. //
  399. // Return Value:
  400. // None.
  401. //
  402. //--
  403. /////////////////////////////////////////////////////////////////////////////
  404. void CBasePropertyPage::DoDataExchange(CDataExchange * pDX)
  405. {
  406. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  407. //{{AFX_DATA_MAP(CBasePropertyPage)
  408. // NOTE: the ClassWizard will add DDX and DDV calls here
  409. //}}AFX_DATA_MAP
  410. DDX_Control(pDX, IDC_PP_ICON, m_staticIcon);
  411. DDX_Control(pDX, IDC_PP_TITLE, m_staticTitle);
  412. if (pDX->m_bSaveAndValidate)
  413. {
  414. if (!BBackPressed())
  415. {
  416. CWaitCursor wc;
  417. // Validate the data.
  418. if (!BSetPrivateProps(TRUE /*bValidateOnly*/))
  419. pDX->Fail();
  420. } // if: Back button not pressed
  421. } // if: saving data from dialog
  422. else
  423. {
  424. // Set the title.
  425. DDX_Text(pDX, IDC_PP_TITLE, m_strTitle);
  426. } // if: not saving data
  427. CPropertyPage::DoDataExchange(pDX);
  428. } //*** CBasePropertyPage::DoDataExchange()
  429. /////////////////////////////////////////////////////////////////////////////
  430. //++
  431. //
  432. // CBasePropertyPage::OnInitDialog
  433. //
  434. // Routine Description:
  435. // Handler for the WM_INITDIALOG message.
  436. //
  437. // Arguments:
  438. // None.
  439. //
  440. // Return Value:
  441. // TRUE We need the focus to be set for us.
  442. // FALSE We already set the focus to the proper control.
  443. //
  444. //--
  445. /////////////////////////////////////////////////////////////////////////////
  446. BOOL CBasePropertyPage::OnInitDialog(void)
  447. {
  448. ASSERT(Peo() != NULL);
  449. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  450. // Set the title string.
  451. m_strTitle = Peo()->RrdResData().m_strName;
  452. // Call the base class method.
  453. CPropertyPage::OnInitDialog();
  454. // Display an icon for the object.
  455. if (Peo()->Hicon() != NULL)
  456. m_staticIcon.SetIcon(Peo()->Hicon());
  457. return TRUE; // return TRUE unless you set the focus to a control
  458. // EXCEPTION: OCX Property Pages should return FALSE
  459. } //*** CBasePropertyPage::OnInitDialog()
  460. /////////////////////////////////////////////////////////////////////////////
  461. //++
  462. //
  463. // CBasePropertyPage::OnSetActive
  464. //
  465. // Routine Description:
  466. // Handler for the PSN_SETACTIVE message.
  467. //
  468. // Arguments:
  469. // None.
  470. //
  471. // Return Value:
  472. // TRUE Page successfully initialized.
  473. // FALSE Page not initialized.
  474. //
  475. //--
  476. /////////////////////////////////////////////////////////////////////////////
  477. BOOL CBasePropertyPage::OnSetActive(void)
  478. {
  479. HRESULT hr;
  480. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  481. // Reread the data.
  482. hr = Peo()->HrGetObjectInfo();
  483. if (hr != NOERROR)
  484. return FALSE;
  485. // Set the title string.
  486. m_strTitle = Peo()->RrdResData().m_strName;
  487. m_bBackPressed = FALSE;
  488. return CPropertyPage::OnSetActive();
  489. } //*** CBasePropertyPage::OnSetActive()
  490. /////////////////////////////////////////////////////////////////////////////
  491. //++
  492. //
  493. // CBasePropertyPage::OnApply
  494. //
  495. // Routine Description:
  496. // Handler for the PSM_APPLY message.
  497. //
  498. // Arguments:
  499. // None.
  500. //
  501. // Return Value:
  502. // TRUE Page successfully applied.
  503. // FALSE Error applying page.
  504. //
  505. //--
  506. /////////////////////////////////////////////////////////////////////////////
  507. BOOL CBasePropertyPage::OnApply(void)
  508. {
  509. ASSERT(!BWizard());
  510. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  511. CWaitCursor wc;
  512. // Update the data in the class from the page.
  513. if (!UpdateData(TRUE /*bSaveAndValidate*/))
  514. return FALSE;
  515. if (!BApplyChanges())
  516. return FALSE;
  517. return CPropertyPage::OnApply();
  518. } //*** CBasePropertyPage::OnApply()
  519. /////////////////////////////////////////////////////////////////////////////
  520. //++
  521. //
  522. // CBasePropertyPage::OnWizardBack
  523. //
  524. // Routine Description:
  525. // Handler for the PSN_WIZBACK message.
  526. //
  527. // Arguments:
  528. // None.
  529. //
  530. // Return Value:
  531. // -1 Don't change the page.
  532. // 0 Change the page.
  533. //
  534. //--
  535. /////////////////////////////////////////////////////////////////////////////
  536. LRESULT CBasePropertyPage::OnWizardBack(void)
  537. {
  538. LRESULT lResult;
  539. ASSERT(BWizard());
  540. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  541. lResult = CPropertyPage::OnWizardBack();
  542. if (lResult != -1)
  543. m_bBackPressed = TRUE;
  544. return lResult;
  545. } //*** CBasePropertyPage::OnWizardBack()
  546. /////////////////////////////////////////////////////////////////////////////
  547. //++
  548. //
  549. // CBasePropertyPage::OnWizardNext
  550. //
  551. // Routine Description:
  552. // Handler for the PSN_WIZNEXT message.
  553. //
  554. // Arguments:
  555. // None.
  556. //
  557. // Return Value:
  558. // -1 Don't change the page.
  559. // 0 Change the page.
  560. //
  561. //--
  562. /////////////////////////////////////////////////////////////////////////////
  563. LRESULT CBasePropertyPage::OnWizardNext(void)
  564. {
  565. ASSERT(BWizard());
  566. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  567. CWaitCursor wc;
  568. // Update the data in the class from the page.
  569. if (!UpdateData(TRUE /*bSaveAndValidate*/))
  570. return -1;
  571. // Save the data in the sheet.
  572. if (!BApplyChanges())
  573. return -1;
  574. // Create the object.
  575. return CPropertyPage::OnWizardNext();
  576. } //*** CBasePropertyPage::OnWizardNext()
  577. /////////////////////////////////////////////////////////////////////////////
  578. //++
  579. //
  580. // CBasePropertyPage::OnWizardFinish
  581. //
  582. // Routine Description:
  583. // Handler for the PSN_WIZFINISH message.
  584. //
  585. // Arguments:
  586. // None.
  587. //
  588. // Return Value:
  589. // FALSE Don't change the page.
  590. // TRUE Change the page.
  591. //
  592. //--
  593. /////////////////////////////////////////////////////////////////////////////
  594. BOOL CBasePropertyPage::OnWizardFinish(void)
  595. {
  596. ASSERT(BWizard());
  597. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  598. CWaitCursor wc;
  599. // Update the data in the class from the page.
  600. if (!UpdateData(TRUE /*bSaveAndValidate*/))
  601. return FALSE;
  602. // Save the data in the sheet.
  603. if (!BApplyChanges())
  604. return FALSE;
  605. return CPropertyPage::OnWizardFinish();
  606. } //*** CBasePropertyPage::OnWizardFinish()
  607. /////////////////////////////////////////////////////////////////////////////
  608. //++
  609. //
  610. // CBasePropertyPage::OnChangeCtrl
  611. //
  612. // Routine Description:
  613. // Handler for the messages sent when a control is changed. This
  614. // method can be specified in a message map if all that needs to be
  615. // done is enable the Apply button.
  616. //
  617. // Arguments:
  618. // None.
  619. //
  620. // Return Value:
  621. // None.
  622. //
  623. //--
  624. /////////////////////////////////////////////////////////////////////////////
  625. void CBasePropertyPage::OnChangeCtrl(void)
  626. {
  627. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  628. SetModified(TRUE);
  629. } //*** CBasePropertyPage::OnChangeCtrl()
  630. /////////////////////////////////////////////////////////////////////////////
  631. //++
  632. //
  633. // CBasePropertyPage::EnableNext
  634. //
  635. // Routine Description:
  636. // Enables or disables the NEXT or FINISH button.
  637. //
  638. // Arguments:
  639. // bEnable [IN] TRUE = enable the button, FALSE = disable the button.
  640. //
  641. // Return Value:
  642. // None.
  643. //
  644. //--
  645. /////////////////////////////////////////////////////////////////////////////
  646. void CBasePropertyPage::EnableNext(IN BOOL bEnable /*TRUE*/)
  647. {
  648. ASSERT(BWizard());
  649. ASSERT(PiWizardCallback());
  650. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  651. PiWizardCallback()->EnableNext((LONG *) Hpage(), bEnable);
  652. } //*** CBasePropertyPage::EnableNext()
  653. /////////////////////////////////////////////////////////////////////////////
  654. //++
  655. //
  656. // CBasePropertyPage::BApplyChanges
  657. //
  658. // Routine Description:
  659. // Apply changes made on the page.
  660. //
  661. // Arguments:
  662. // None.
  663. //
  664. // Return Value:
  665. // TRUE Page successfully applied.
  666. // FALSE Error applying page.
  667. //
  668. //--
  669. /////////////////////////////////////////////////////////////////////////////
  670. BOOL CBasePropertyPage::BApplyChanges(void)
  671. {
  672. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  673. CWaitCursor wc;
  674. // Save data.
  675. return BSetPrivateProps();
  676. } //*** CBasePropertyPage::BApplyChanges()
  677. /////////////////////////////////////////////////////////////////////////////
  678. //++
  679. //
  680. // CBasePropertyPage::BuildPropList
  681. //
  682. // Routine Description:
  683. // Build the property list.
  684. //
  685. // Arguments:
  686. // rcpl [IN OUT] Cluster property list.
  687. //
  688. // Return Value:
  689. // None.
  690. //
  691. // Exceptions Thrown:
  692. // Any exceptions thrown by CClusPropList::AddProp().
  693. //
  694. //--
  695. /////////////////////////////////////////////////////////////////////////////
  696. void CBasePropertyPage::BuildPropList(
  697. IN OUT CClusPropList & rcpl
  698. )
  699. {
  700. DWORD cprop;
  701. const CObjectProperty * pprop;
  702. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--)
  703. {
  704. switch (pprop->m_propFormat)
  705. {
  706. case CLUSPROP_FORMAT_SZ:
  707. rcpl.ScAddProp(
  708. pprop->m_pwszName,
  709. *pprop->m_value.pstr,
  710. *pprop->m_valuePrev.pstr
  711. );
  712. break;
  713. case CLUSPROP_FORMAT_DWORD:
  714. rcpl.ScAddProp(
  715. pprop->m_pwszName,
  716. *pprop->m_value.pdw,
  717. *pprop->m_valuePrev.pdw
  718. );
  719. break;
  720. case CLUSPROP_FORMAT_BINARY:
  721. case CLUSPROP_FORMAT_MULTI_SZ:
  722. rcpl.ScAddProp(
  723. pprop->m_pwszName,
  724. *pprop->m_value.ppb,
  725. *pprop->m_value.pcb,
  726. *pprop->m_valuePrev.ppb,
  727. *pprop->m_valuePrev.pcb
  728. );
  729. break;
  730. default:
  731. ASSERT(0); // don't know how to deal with this type
  732. return;
  733. } // switch: property format
  734. } // for: each property
  735. } //*** CBasePropertyPage::BuildPropList()
  736. /////////////////////////////////////////////////////////////////////////////
  737. //++
  738. //
  739. // CBasePropertyPage::BSetPrivateProps
  740. //
  741. // Routine Description:
  742. // Set the private properties for this object.
  743. //
  744. // Arguments:
  745. // bValidateOnly [IN] TRUE = only validate the data.
  746. //
  747. // Return Value:
  748. // ERROR_SUCCESS The operation was completed successfully.
  749. // !0 Failure.
  750. //
  751. //--
  752. /////////////////////////////////////////////////////////////////////////////
  753. BOOL CBasePropertyPage::BSetPrivateProps(IN BOOL bValidateOnly)
  754. {
  755. BOOL bSuccess = TRUE;
  756. CClusPropList cpl(BWizard() /*bAlwaysAddProp*/);
  757. ASSERT(Peo() != NULL);
  758. ASSERT(Peo()->PrdResData());
  759. ASSERT(Peo()->PrdResData()->m_hresource);
  760. // Build the property list.
  761. try
  762. {
  763. BuildPropList(cpl);
  764. } // try
  765. catch (CException * pe)
  766. {
  767. pe->ReportError();
  768. pe->Delete();
  769. bSuccess = FALSE;
  770. } // catch: CException
  771. // Set the data.
  772. if (bSuccess)
  773. {
  774. if ((cpl.PbPropList() != NULL) && (cpl.CbPropList() > 0))
  775. {
  776. DWORD dwStatus;
  777. DWORD dwControlCode;
  778. DWORD cbProps;
  779. // Determine which control code to use.
  780. if (bValidateOnly)
  781. dwControlCode = CLUSCTL_RESOURCE_VALIDATE_PRIVATE_PROPERTIES;
  782. else
  783. dwControlCode = CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES;
  784. // Set private properties.
  785. dwStatus = ClusterResourceControl(
  786. Peo()->PrdResData()->m_hresource,
  787. NULL, // hNode
  788. dwControlCode,
  789. cpl.PbPropList(),
  790. cpl.CbPropList(),
  791. NULL, // lpOutBuffer
  792. 0, // nOutBufferSize
  793. &cbProps
  794. );
  795. if (dwStatus != ERROR_SUCCESS)
  796. {
  797. CString strMsg;
  798. FormatError(strMsg, dwStatus);
  799. AfxMessageBox(strMsg);
  800. if (bValidateOnly
  801. || (dwStatus != ERROR_RESOURCE_PROPERTIES_STORED))
  802. bSuccess = FALSE;
  803. } // if: error setting/validating data
  804. } // if: there is data to set
  805. } // if: no errors building the property list
  806. // Save data locally.
  807. if (!bValidateOnly && bSuccess)
  808. {
  809. // Save new values as previous values.
  810. try
  811. {
  812. DWORD cprop;
  813. const CObjectProperty * pprop;
  814. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--)
  815. {
  816. switch (pprop->m_propFormat)
  817. {
  818. case CLUSPROP_FORMAT_SZ:
  819. ASSERT(pprop->m_value.pstr != NULL);
  820. ASSERT(pprop->m_valuePrev.pstr != NULL);
  821. *pprop->m_valuePrev.pstr = *pprop->m_value.pstr;
  822. break;
  823. case CLUSPROP_FORMAT_DWORD:
  824. ASSERT(pprop->m_value.pdw != NULL);
  825. ASSERT(pprop->m_valuePrev.pdw != NULL);
  826. *pprop->m_valuePrev.pdw = *pprop->m_value.pdw;
  827. break;
  828. case CLUSPROP_FORMAT_BINARY:
  829. case CLUSPROP_FORMAT_MULTI_SZ:
  830. ASSERT(pprop->m_value.ppb != NULL);
  831. ASSERT(*pprop->m_value.ppb != NULL);
  832. ASSERT(pprop->m_value.pcb != NULL);
  833. ASSERT(pprop->m_valuePrev.ppb != NULL);
  834. ASSERT(*pprop->m_valuePrev.ppb != NULL);
  835. ASSERT(pprop->m_valuePrev.pcb != NULL);
  836. delete [] *pprop->m_valuePrev.ppb;
  837. *pprop->m_valuePrev.ppb = new BYTE[*pprop->m_value.pcb];
  838. CopyMemory(*pprop->m_valuePrev.ppb, *pprop->m_value.ppb, *pprop->m_value.pcb);
  839. *pprop->m_valuePrev.pcb = *pprop->m_value.pcb;
  840. break;
  841. default:
  842. ASSERT(0); // don't know how to deal with this type
  843. } // switch: property format
  844. } // for: each property
  845. } // try
  846. catch (CException * pe)
  847. {
  848. pe->ReportError();
  849. pe->Delete();
  850. bSuccess = FALSE;
  851. } // catch: CException
  852. } // if: not just validating and successful so far
  853. return bSuccess;
  854. } //*** CBasePropertyPage::BSetPrivateProps()
  855. /////////////////////////////////////////////////////////////////////////////
  856. //++
  857. //
  858. // CBasePropertyPage::OnContextMenu
  859. //
  860. // Routine Description:
  861. // Handler for the WM_CONTEXTMENU message.
  862. //
  863. // Arguments:
  864. // pWnd Window in which user clicked the right mouse button.
  865. // point Position of the cursor, in screen coordinates.
  866. //
  867. // Return Value:
  868. // TRUE Help processed.
  869. // FALSE Help not processed.
  870. //
  871. //--
  872. /////////////////////////////////////////////////////////////////////////////
  873. void CBasePropertyPage::OnContextMenu(CWnd * pWnd, CPoint point)
  874. {
  875. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  876. m_dlghelp.OnContextMenu(pWnd, point);
  877. } //*** CBasePropertyPage::OnContextMenu()
  878. /////////////////////////////////////////////////////////////////////////////
  879. //++
  880. //
  881. // CBasePropertyPage::OnHelpInfo
  882. //
  883. // Routine Description:
  884. // Handler for the WM_HELPINFO message.
  885. //
  886. // Arguments:
  887. // pHelpInfo Structure containing info about displaying help.
  888. //
  889. // Return Value:
  890. // TRUE Help processed.
  891. // FALSE Help not processed.
  892. //
  893. //--
  894. /////////////////////////////////////////////////////////////////////////////
  895. BOOL CBasePropertyPage::OnHelpInfo(HELPINFO * pHelpInfo)
  896. {
  897. BOOL bProcessed;
  898. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  899. bProcessed = m_dlghelp.OnHelpInfo(pHelpInfo);
  900. if (!bProcessed)
  901. bProcessed = CPropertyPage::OnHelpInfo(pHelpInfo);
  902. return bProcessed;
  903. } //*** CBasePropertyPage::OnHelpInfo()
  904. /////////////////////////////////////////////////////////////////////////////
  905. //++
  906. //
  907. // CBasePropertyPage::OnCommandHelp
  908. //
  909. // Routine Description:
  910. // Handler for the WM_COMMANDHELP message.
  911. //
  912. // Arguments:
  913. // wParam [IN] WPARAM.
  914. // lParam [IN] LPARAM.
  915. //
  916. // Return Value:
  917. // TRUE Help processed.
  918. // FALSE Help not processed.
  919. //
  920. //--
  921. /////////////////////////////////////////////////////////////////////////////
  922. LRESULT CBasePropertyPage::OnCommandHelp(WPARAM wParam, LPARAM lParam)
  923. {
  924. BOOL bProcessed;
  925. bProcessed = (BOOL) m_dlghelp.OnCommandHelp(wParam, lParam);
  926. if (!bProcessed)
  927. bProcessed = (BOOL) CPropertyPage::OnCommandHelp(wParam, lParam);
  928. return bProcessed;
  929. } //*** CBasePropertyPage::OnCommandHelp()