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.

820 lines
17 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. defws.cpp
  5. Abstract:
  6. Default Web Site Dialog
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Sergei Antonov (sergeia)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. --*/
  14. //
  15. // Include Files
  16. //
  17. #include "stdafx.h"
  18. #include "resource.h"
  19. #include "common.h"
  20. #include "inetmgrapp.h"
  21. #include "inetprop.h"
  22. #include "shts.h"
  23. #include "w3sht.h"
  24. #include "defws.h"
  25. #include "mime.h"
  26. #ifdef _DEBUG
  27. #define new DEBUG_NEW
  28. #undef THIS_FILE
  29. static char THIS_FILE[] = __FILE__;
  30. #endif
  31. //
  32. // Directory Size Units
  33. //
  34. #define DS_UNITS MEGABYTE
  35. //
  36. // Default Web Site Property Page
  37. //
  38. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  39. IMPLEMENT_DYNCREATE(CDefWebSitePage, CInetPropertyPage)
  40. CDefWebSitePage::CDefWebSitePage(
  41. IN CInetPropertySheet * pSheet
  42. )
  43. /*++
  44. Routine Description:
  45. Constructor for WWW Default Web Site page
  46. Arguments:
  47. CInetPropertySheet * pSheet : Sheet object
  48. Return Value:
  49. N/A
  50. --*/
  51. : CInetPropertyPage(CDefWebSitePage::IDD, pSheet),
  52. m_ppropCompression(NULL),
  53. m_ppropMimeTypes(NULL),
  54. m_fFilterPathFound(FALSE),
  55. m_fCompressionDirectoryChanged(FALSE),
  56. m_fCompatMode(FALSE)
  57. {
  58. #if 0 // Keep Class Wizard happy
  59. //{{AFX_DATA_INIT(CDefWebSitePage)
  60. m_fEnableDynamic = FALSE;
  61. m_fEnableStatic = FALSE;
  62. m_fCompatMode = FALSE;
  63. m_strDirectory = _T("");
  64. m_nUnlimited = -1;
  65. m_ilSize = 0L;
  66. //}}AFX_DATA_INIT
  67. #endif // 0
  68. m_fInitCompatMode = m_fCompatMode;
  69. }
  70. CDefWebSitePage::~CDefWebSitePage()
  71. /*++
  72. Routine Description:
  73. Destructor
  74. Arguments:
  75. N/A
  76. Return Value:
  77. N/A
  78. --*/
  79. {
  80. }
  81. void
  82. CDefWebSitePage::DoDataExchange(
  83. IN CDataExchange * pDX
  84. )
  85. /*++
  86. Routine Description:
  87. Initialise/Store control data
  88. Arguments:
  89. CDataExchange * pDX - DDX/DDV control structure
  90. Return Value:
  91. None
  92. --*/
  93. {
  94. CInetPropertyPage::DoDataExchange(pDX);
  95. //{{AFX_DATA_MAP(CDefWebSitePage)
  96. DDX_Control(pDX, IDC_EDIT_COMPRESS_DIRECTORY, m_edit_Directory);
  97. DDX_Control(pDX, IDC_BUTTON_BROWSE, m_button_Browse);
  98. DDX_Control(pDX, IDC_STATIC_COMPRESS_MB, m_static_MB);
  99. DDX_Control(pDX, IDC_EDIT_COMPRESS_DIRECTORY_SIZE, m_edit_DirectorySize);
  100. DDX_Check(pDX, IDC_CHECK_DYNAMIC_COMPRESSION, m_fEnableDynamic);
  101. DDX_Check(pDX, IDC_CHECK_STATIC_COMPRESSION, m_fEnableStatic);
  102. DDX_Check(pDX, IDC_COMPAT_MODE, m_fCompatMode);
  103. DDX_Radio(pDX, IDC_RADIO_COMPRESS_UNLIMITED, m_nUnlimited);
  104. //}}AFX_DATA_MAP
  105. if (HasCompression())
  106. {
  107. if (!pDX->m_bSaveAndValidate || m_fEnableStatic)
  108. {
  109. DDX_Text(pDX, IDC_EDIT_COMPRESS_DIRECTORY, m_strDirectory);
  110. DDV_MaxChars(pDX, m_strDirectory, _MAX_PATH);
  111. }
  112. if (pDX->m_bSaveAndValidate && m_fEnableStatic)
  113. {
  114. if (!PathIsValid(m_strDirectory) || !IsFullyQualifiedPath(m_strDirectory))
  115. {
  116. ::AfxMessageBox(IDS_ERR_INVALID_PATH);
  117. pDX->Fail();
  118. }
  119. //
  120. // Perform some additional smart checking on the compression
  121. // directory if the current machine is local, and the
  122. // directory has changed
  123. //
  124. if (IsLocal() && m_fCompressionDirectoryChanged)
  125. {
  126. //
  127. // Should exist on the local machine.
  128. //
  129. DWORD dwAttr = GetFileAttributes(m_strDirectory);
  130. if (dwAttr == 0xffffffff
  131. || (dwAttr & FILE_ATTRIBUTE_DIRECTORY) == 0
  132. || IsNetworkPath(m_strDirectory)
  133. )
  134. {
  135. ::AfxMessageBox(IDS_ERR_COMPRESS_DIRECTORY);
  136. pDX->Fail();
  137. }
  138. //
  139. // Now check to make sure the volume is of the correct
  140. // type.
  141. //
  142. DWORD dwFileSystemFlags;
  143. if (::GetVolumeInformationSystemFlags(
  144. m_strDirectory,
  145. &dwFileSystemFlags
  146. ))
  147. {
  148. if (!(dwFileSystemFlags & FS_PERSISTENT_ACLS))
  149. {
  150. //
  151. // No ACLS
  152. //
  153. if (!NoYesMessageBox(IDS_NO_ACL_WARNING))
  154. {
  155. pDX->Fail();
  156. }
  157. }
  158. if (dwFileSystemFlags & FS_VOL_IS_COMPRESSED
  159. || dwAttr & FILE_ATTRIBUTE_COMPRESSED)
  160. {
  161. //
  162. // Compression cache directory is itself compressed
  163. //
  164. if (!NoYesMessageBox(IDS_COMPRESS_WARNING))
  165. {
  166. pDX->Fail();
  167. }
  168. }
  169. }
  170. }
  171. }
  172. if (!pDX->m_bSaveAndValidate || (m_fEnableLimiting && m_fEnableStatic))
  173. {
  174. DDX_Text(pDX, IDC_EDIT_COMPRESS_DIRECTORY_SIZE, m_ilSize);
  175. DDV_MinMaxLong(pDX, m_ilSize, 1, 1024L);
  176. }
  177. }
  178. }
  179. //
  180. // Message Map
  181. //
  182. BEGIN_MESSAGE_MAP(CDefWebSitePage, CInetPropertyPage)
  183. //{{AFX_MSG_MAP(CDefWebSitePage)
  184. ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnButtonBrowse)
  185. ON_BN_CLICKED(IDC_RADIO_COMPRESS_LIMITED, OnRadioLimited)
  186. ON_BN_CLICKED(IDC_RADIO_COMPRESS_UNLIMITED, OnRadioUnlimited)
  187. ON_BN_CLICKED(IDC_CHECK_DYNAMIC_COMPRESSION, OnCheckDynamicCompression)
  188. ON_BN_CLICKED(IDC_CHECK_STATIC_COMPRESSION, OnCheckStaticCompression)
  189. ON_BN_CLICKED(IDC_BUTTON_FILE_TYPES, OnButtonFileTypes)
  190. ON_BN_CLICKED(IDC_COMPAT_MODE, OnCheckCompatMode)
  191. ON_EN_CHANGE(IDC_EDIT_COMPRESS_DIRECTORY, OnChangeEditCompressDirectory)
  192. ON_WM_DESTROY()
  193. //}}AFX_MSG_MAP
  194. ON_EN_CHANGE(IDC_EDIT_COMPRESS_DIRECTORY, OnItemChanged)
  195. ON_EN_CHANGE(IDC_EDIT_COMPRESS_DIRECTORY_SIZE, OnItemChanged)
  196. END_MESSAGE_MAP()
  197. void
  198. CDefWebSitePage::SetControlStates()
  199. /*++
  200. Routine Description:
  201. Enable/disable control states depending on the state of
  202. the dialog.
  203. Arguments:
  204. None
  205. Return Value:
  206. None
  207. --*/
  208. {
  209. GetDlgItem(IDC_STATIC_COMPRESS_DIRECTORY)->EnableWindow(m_fEnableStatic);
  210. m_edit_Directory.EnableWindow(m_fEnableStatic);
  211. m_edit_DirectorySize.EnableWindow(m_fEnableStatic && m_fEnableLimiting);
  212. m_static_MB.EnableWindow(m_fEnableStatic&& m_fEnableLimiting);
  213. GetDlgItem(IDC_RADIO_COMPRESS_LIMITED)->EnableWindow(m_fEnableStatic);
  214. GetDlgItem(IDC_RADIO_COMPRESS_UNLIMITED)->EnableWindow(m_fEnableStatic);
  215. GetDlgItem(IDC_STATIC_MAX_COMPRESS_SIZE)->EnableWindow(m_fEnableStatic);
  216. //
  217. // Browse on the local machine only
  218. //
  219. m_button_Browse.EnableWindow(IsLocal() && m_fEnableStatic);
  220. }
  221. /* virtual */
  222. HRESULT
  223. CDefWebSitePage::FetchLoadedValues()
  224. /*++
  225. Routine Description:
  226. Move configuration data from sheet to dialog controls
  227. Arguments:
  228. None
  229. Return Value:
  230. HRESULT
  231. --*/
  232. {
  233. CError err;
  234. ASSERT(m_ppropCompression == NULL);
  235. m_ppropCompression = new CIISCompressionProps(QueryAuthInfo());
  236. if (m_ppropCompression)
  237. {
  238. err = m_ppropCompression->LoadData();
  239. m_fFilterPathFound = err.Succeeded();
  240. if (err.Succeeded())
  241. {
  242. m_fEnableDynamic = m_ppropCompression->m_fEnableDynamicCompression;
  243. m_fEnableStatic = m_ppropCompression->m_fEnableStaticCompression;
  244. m_fEnableLimiting = m_ppropCompression->m_fLimitDirectorySize;
  245. {
  246. TCHAR buf[MAX_PATH];
  247. ExpandEnvironmentStrings(m_ppropCompression->m_strDirectory, buf, MAX_PATH);
  248. m_strDirectory = buf;
  249. }
  250. m_nUnlimited = m_fEnableLimiting ? RADIO_LIMITED : RADIO_UNLIMITED;
  251. if (m_ppropCompression->m_dwDirectorySize == 0xffffffff)
  252. {
  253. m_ilSize = DEF_MAX_COMPDIR_SIZE / DS_UNITS;
  254. }
  255. else
  256. {
  257. m_ilSize = m_ppropCompression->m_dwDirectorySize / DS_UNITS;
  258. }
  259. }
  260. else if (err.Win32Error() == ERROR_PATH_NOT_FOUND)
  261. {
  262. //
  263. // Fail quietly
  264. //
  265. TRACEEOLID("No compression filters installed");
  266. err.Reset();
  267. }
  268. }
  269. else
  270. {
  271. err = ERROR_NOT_ENOUGH_MEMORY;
  272. }
  273. ASSERT(m_ppropMimeTypes == NULL);
  274. if (err.Succeeded())
  275. {
  276. if (NULL != (m_ppropMimeTypes = new CMimeTypes(
  277. QueryAuthInfo(), CMetabasePath(TRUE, SZ_MBN_MIMEMAP))))
  278. {
  279. err = m_ppropMimeTypes->LoadData();
  280. }
  281. else
  282. {
  283. err = ERROR_NOT_ENOUGH_MEMORY;
  284. }
  285. if (err.Succeeded())
  286. {
  287. m_strlMimeTypes = m_ppropMimeTypes->m_strlMimeTypes;
  288. if (GetSheet()->QueryMajorVersion() >= 6)
  289. {
  290. CMetaKey mk(QueryAuthInfo(), QueryMetaPath(), METADATA_PERMISSION_READ);
  291. err = mk.QueryResult();
  292. if (err.Succeeded())
  293. {
  294. err = mk.QueryValue(MD_GLOBAL_STANDARD_APP_MODE_ENABLED, m_fCompatMode);
  295. if (err.Succeeded())
  296. {
  297. m_fInitCompatMode = m_fCompatMode;
  298. }
  299. }
  300. }
  301. else
  302. {
  303. m_fInitCompatMode = m_fCompatMode = TRUE;
  304. }
  305. }
  306. }
  307. return err;
  308. }
  309. HRESULT
  310. CDefWebSitePage::SaveInfo()
  311. /*++
  312. Routine Description:
  313. Save the information on this property page
  314. Arguments:
  315. None
  316. Return Value:
  317. Error return code
  318. --*/
  319. {
  320. ASSERT(IsDirty());
  321. TRACEEOLID("Saving W3 default web site page now...");
  322. CError err;
  323. BeginWaitCursor();
  324. if (HasCompression())
  325. {
  326. ASSERT(m_ppropCompression);
  327. DWORD dwSize = m_ilSize * DS_UNITS;
  328. m_ppropCompression->m_fEnableDynamicCompression = m_fEnableDynamic;
  329. m_ppropCompression->m_fEnableStaticCompression = m_fEnableStatic;
  330. m_ppropCompression->m_fLimitDirectorySize = m_fEnableLimiting;
  331. // TODO: Replace back %WINDIR% or another system settings in path
  332. m_ppropCompression->m_strDirectory = m_strDirectory;
  333. m_ppropCompression->m_dwDirectorySize = dwSize;
  334. err = m_ppropCompression->WriteDirtyProps();
  335. if (err.Succeeded())
  336. {
  337. m_fCompressionDirectoryChanged = FALSE;
  338. }
  339. }
  340. if (err.Succeeded())
  341. {
  342. m_ppropMimeTypes->m_strlMimeTypes = m_strlMimeTypes;
  343. err = m_ppropMimeTypes->WriteDirtyProps();
  344. if (err.Succeeded() && GetSheet()->QueryMajorVersion() >= 6)
  345. {
  346. CMetaKey mk(QueryAuthInfo(), QueryMetaPath(), METADATA_PERMISSION_WRITE);
  347. err = mk.QueryResult();
  348. if (err.Succeeded())
  349. {
  350. err = mk.SetValue(MD_GLOBAL_STANDARD_APP_MODE_ENABLED, m_fCompatMode);
  351. if (err.Succeeded() && m_fCompatMode != m_fInitCompatMode)
  352. {
  353. GetSheet()->SetRestartRequired(TRUE);
  354. // We don't need to save this parameter to sheet,
  355. // it is important to App Protection combo only, and
  356. // this combo is disabled for Master props, so it doesn't matter.
  357. }
  358. }
  359. }
  360. }
  361. EndWaitCursor();
  362. return err;
  363. }
  364. //
  365. // Message Handlers
  366. //
  367. // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  368. BOOL
  369. CDefWebSitePage::OnInitDialog()
  370. /*++
  371. Routine Description:
  372. WM_INITDIALOG handler. Initialize the dialog.
  373. Arguments:
  374. None.
  375. Return Value:
  376. TRUE if focus is to be set automatically, FALSE if the focus
  377. is already set.
  378. --*/
  379. {
  380. CInetPropertyPage::OnInitDialog();
  381. //
  382. // Check to make sure compression is supported
  383. //
  384. GetDlgItem(IDC_STATIC_COMPRESS_GROUP)->EnableWindow(HasCompression());
  385. GetDlgItem(IDC_CHECK_DYNAMIC_COMPRESSION)->EnableWindow(HasCompression());
  386. GetDlgItem(IDC_CHECK_STATIC_COMPRESSION)->EnableWindow(HasCompression());
  387. GetDlgItem(IDC_RADIO_COMPRESS_UNLIMITED)->EnableWindow(HasCompression());
  388. GetDlgItem(IDC_RADIO_COMPRESS_LIMITED)->EnableWindow(HasCompression());
  389. GetDlgItem(IDC_EDIT_COMPRESS_DIRECTORY)->EnableWindow(HasCompression());
  390. GetDlgItem(IDC_STATIC_MAX_COMPRESS_SIZE)->EnableWindow(HasCompression());
  391. GetDlgItem(IDC_STATIC_COMPRESS_DIRECTORY)->EnableWindow(HasCompression());
  392. GetDlgItem(IDC_STATIC_COMPRESS_MB)->EnableWindow(HasCompression());
  393. GetDlgItem(IDC_EDIT_COMPRESS_DIRECTORY_SIZE)->EnableWindow(HasCompression());
  394. GetDlgItem(IDC_COMPAT_MODE)->EnableWindow(GetSheet()->QueryMajorVersion() >= 6);
  395. SetControlStates();
  396. return TRUE;
  397. }
  398. void
  399. CDefWebSitePage::OnItemChanged()
  400. /*++
  401. Routine Description:
  402. Handle change in control data
  403. Arguments:
  404. None
  405. Return Value:
  406. None
  407. --*/
  408. {
  409. SetModified(TRUE);
  410. SetControlStates();
  411. }
  412. static int CALLBACK
  413. FileChooserCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
  414. {
  415. CDefWebSitePage * pThis = (CDefWebSitePage *)lpData;
  416. ASSERT(pThis != NULL);
  417. return pThis->BrowseForFolderCallback(hwnd, uMsg, lParam);
  418. }
  419. int
  420. CDefWebSitePage::BrowseForFolderCallback(HWND hwnd, UINT uMsg, LPARAM lParam)
  421. {
  422. switch (uMsg)
  423. {
  424. case BFFM_INITIALIZED:
  425. ASSERT(m_pPathTemp != NULL);
  426. if (::PathIsNetworkPath(m_pPathTemp))
  427. return 0;
  428. while (!::PathIsDirectory(m_pPathTemp))
  429. {
  430. if (0 == ::PathRemoveFileSpec(m_pPathTemp) && !::PathIsRoot(m_pPathTemp))
  431. {
  432. return 0;
  433. }
  434. DWORD attr = GetFileAttributes(m_pPathTemp);
  435. if ((attr & FILE_ATTRIBUTE_READONLY) == 0)
  436. break;
  437. }
  438. ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)m_pPathTemp);
  439. break;
  440. case BFFM_SELCHANGED:
  441. {
  442. LPITEMIDLIST pidl = (LPITEMIDLIST)lParam;
  443. TCHAR path[MAX_PATH];
  444. if (SHGetPathFromIDList(pidl, path))
  445. {
  446. ::SendMessage(hwnd, BFFM_ENABLEOK, 0, !PathIsNetworkPath(path));
  447. }
  448. }
  449. break;
  450. case BFFM_VALIDATEFAILED:
  451. break;
  452. }
  453. return 0;
  454. }
  455. void
  456. CDefWebSitePage::OnButtonBrowse()
  457. {
  458. ASSERT(IsLocal());
  459. BOOL bRes = FALSE;
  460. HRESULT hr;
  461. CString str;
  462. m_edit_Directory.GetWindowText(str);
  463. if (SUCCEEDED(hr = CoInitialize(NULL)))
  464. {
  465. LPITEMIDLIST pidl = NULL;
  466. if (SUCCEEDED(SHGetFolderLocation(NULL, CSIDL_DRIVES, NULL, 0, &pidl)))
  467. {
  468. LPITEMIDLIST pidList = NULL;
  469. BROWSEINFO bi;
  470. TCHAR buf[MAX_PATH];
  471. ZeroMemory(&bi, sizeof(bi));
  472. int drive = PathGetDriveNumber(str);
  473. if (GetDriveType(PathBuildRoot(buf, drive)) == DRIVE_FIXED)
  474. {
  475. StrCpy(buf, str);
  476. }
  477. else
  478. {
  479. buf[0] = 0;
  480. }
  481. bi.hwndOwner = m_hWnd;
  482. bi.pidlRoot = pidl;
  483. bi.pszDisplayName = m_pPathTemp = buf;
  484. bi.lpszTitle = NULL;
  485. bi.ulFlags |= BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS/* | BIF_EDITBOX*/;
  486. bi.lpfn = FileChooserCallback;
  487. bi.lParam = (LPARAM)this;
  488. pidList = SHBrowseForFolder(&bi);
  489. if ( pidList != NULL
  490. && SHGetPathFromIDList(pidList, buf)
  491. )
  492. {
  493. str = buf;
  494. bRes = TRUE;
  495. }
  496. IMalloc * pMalloc;
  497. VERIFY(SUCCEEDED(SHGetMalloc(&pMalloc)));
  498. if (pidl != NULL)
  499. pMalloc->Free(pidl);
  500. pMalloc->Release();
  501. }
  502. CoUninitialize();
  503. }
  504. if (bRes)
  505. {
  506. m_edit_Directory.SetWindowText(str);
  507. OnItemChanged();
  508. }
  509. }
  510. void
  511. CDefWebSitePage::OnChangeEditCompressDirectory()
  512. /*++
  513. Routine Description:
  514. Handle change in compression directory edit box.
  515. Arguments:
  516. None
  517. Return Value:
  518. None
  519. --*/
  520. {
  521. m_fCompressionDirectoryChanged = TRUE;
  522. OnItemChanged();
  523. }
  524. void
  525. CDefWebSitePage::OnRadioLimited()
  526. /*++
  527. Routine Description:
  528. 'Limited' radio button handler
  529. Arguments:
  530. None
  531. Return Value:
  532. None
  533. --*/
  534. {
  535. if (!m_fEnableLimiting)
  536. {
  537. m_nUnlimited = RADIO_LIMITED;
  538. m_fEnableLimiting = TRUE;
  539. OnItemChanged();
  540. m_edit_DirectorySize.SetSel(0, -1);
  541. m_edit_DirectorySize.SetFocus();
  542. }
  543. }
  544. void
  545. CDefWebSitePage::OnRadioUnlimited()
  546. /*++
  547. Routine Description:
  548. 'Unlimited' radio button handler
  549. Arguments:
  550. None
  551. Return Value:
  552. None
  553. --*/
  554. {
  555. if (m_fEnableLimiting)
  556. {
  557. m_nUnlimited = RADIO_UNLIMITED;
  558. m_fEnableLimiting = FALSE;
  559. OnItemChanged();
  560. }
  561. }
  562. void
  563. CDefWebSitePage::OnCheckDynamicCompression()
  564. /*++
  565. Routine Description:
  566. "Enable Dynamic Compression' checkbox handler
  567. Arguments:
  568. None
  569. Return Value:
  570. None
  571. --*/
  572. {
  573. m_fEnableDynamic = !m_fEnableDynamic;
  574. OnItemChanged();
  575. }
  576. void
  577. CDefWebSitePage::OnCheckStaticCompression()
  578. /*++
  579. Routine Description:
  580. "Enable Dynamic Compression' checkbox handler
  581. Arguments:
  582. None
  583. Return Value:
  584. None
  585. --*/
  586. {
  587. m_fEnableStatic = !m_fEnableStatic;
  588. OnItemChanged();
  589. if (m_fEnableStatic)
  590. {
  591. m_edit_Directory.SetSel(0, -1);
  592. m_edit_Directory.SetFocus();
  593. }
  594. }
  595. void
  596. CDefWebSitePage::OnDestroy()
  597. /*++
  598. Routine Description:
  599. WM_DESTROY handler. Clean up internal data
  600. Arguments:
  601. None
  602. Return Value:
  603. None
  604. --*/
  605. {
  606. CInetPropertyPage::OnDestroy();
  607. SAFE_DELETE(m_ppropCompression);
  608. SAFE_DELETE(m_ppropMimeTypes);
  609. }
  610. void
  611. CDefWebSitePage::OnButtonFileTypes()
  612. {
  613. AFX_MANAGE_STATE(::AfxGetStaticModuleState());
  614. CMimeDlg dlg(m_strlMimeTypes, this);
  615. if (dlg.DoModal() == IDOK)
  616. {
  617. OnItemChanged();
  618. }
  619. }
  620. void
  621. CDefWebSitePage::OnCheckCompatMode()
  622. {
  623. OnItemChanged();
  624. }