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.

753 lines
18 KiB

  1. // NewNode.cpp : implementation file
  2. //
  3. //+-------------------------------------------------------------------------
  4. //
  5. // Microsoft Windows
  6. // Copyright (C) Microsoft Corporation, 1992 - 1999
  7. //
  8. // File: NewNode.cpp
  9. //
  10. // Contents: Wizards / Propertysheets for console owned nodes
  11. //
  12. // History: 01-Aug-96 WayneSc Created
  13. //
  14. //--------------------------------------------------------------------------
  15. #include "stdafx.h"
  16. #include <comcat.h> // COM Component Categoories Manager
  17. #include "CompCat.h" // Component Category help functions
  18. #include "guids.h" // AMC Category guids
  19. #include "NewNode.h"
  20. #include "amcmsgid.h"
  21. #include "ndmgrp.h"
  22. #include "fldrsnap.h"
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char THIS_FILE[] = __FILE__;
  26. #endif
  27. // Listview compare function forward
  28. int CALLBACK ListViewCompareFunc(LPARAM lParam1,LPARAM lParam2,LPARAM lParamSort);
  29. void LoadFilterString(CStr &str, int iStrID);
  30. /////////////////////////////////////////////////////////////////////////////
  31. // CHTMLPage1 property page
  32. CHTMLPage1::CHTMLPage1()
  33. {
  34. // SetHelpIDs(g_aHelpIDs_IDD_HTML_WIZPAGE1);
  35. }
  36. CHTMLPage1::~CHTMLPage1()
  37. {
  38. }
  39. LRESULT CHTMLPage1::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  40. {
  41. CWizardPage::OnInitWelcomePage(m_hWnd); // set up the correct title font
  42. HWND const hTarget = ::GetDlgItem( *this, IDC_TARGETTX );
  43. ASSERT( hTarget != NULL );
  44. m_strTarget.Attach( hTarget );
  45. m_strTarget.SetWindowText( _T( "" ) );
  46. m_strTarget.SetLimitText( 128 );
  47. _ValidatePage();
  48. return TRUE;
  49. }
  50. /////////////////////////////////////////////////////////////////////////////
  51. // CHTMLPage1 message handlers
  52. void CHTMLPage1::_ValidatePage(void)
  53. {
  54. TRACE_METHOD(CHTMLPage1, _ValidatePage);
  55. DWORD dwFlags=0;
  56. // Check to see if we have a valid string
  57. TCHAR buff[ 256 ];
  58. int nChars = m_strTarget.GetWindowText( buff, sizeof(buff) / sizeof(TCHAR) );
  59. if( nChars != 0 && _tcslen( buff ) > 0 )
  60. dwFlags|=PSWIZB_NEXT;
  61. HWND hWnd=::GetParent(m_hWnd);
  62. ::SendMessage(hWnd, PSM_SETWIZBUTTONS, 0, dwFlags);
  63. }
  64. BOOL CHTMLPage1::OnSetActive()
  65. {
  66. TRACE_METHOD(CHTMLPage1, OnSetActive);
  67. CWizardPage::OnWelcomeSetActive(m_hWnd);
  68. USES_CONVERSION;
  69. m_strTarget.SetWindowText(GetComponentDataImpl()->GetView());
  70. _ValidatePage();
  71. return TRUE;
  72. }
  73. BOOL CHTMLPage1::OnKillActive()
  74. {
  75. // the line below has been commented because this wizard has only two pages and so we
  76. // want to enable the Finish button, not the Next button.
  77. // CWizardPage::OnWelcomeKillActive(m_hWnd);
  78. TRACE_METHOD(CHTMLPage1, OnKillActive);
  79. USES_CONVERSION;
  80. TCHAR buff[ 256 ];
  81. int nChars = m_strTarget.GetWindowText( buff, sizeof(buff) / sizeof(TCHAR) );
  82. if (nChars == 0)
  83. buff[0] = 0; // initialize to empty if failed
  84. // set the view and the name to be the same intially.
  85. GetComponentDataImpl()->SetView(buff);
  86. GetComponentDataImpl()->SetName(buff);
  87. LPTSTR psz = _tcsrchr(GetComponentDataImpl()->GetView(), TEXT('\\'));
  88. if (psz!=NULL)
  89. {
  90. psz++;
  91. GetComponentDataImpl()->SetName(psz); // use only the string after the last "\". Thus c:\mmc.xml gives mmc.xml as the display name.
  92. }
  93. return TRUE;
  94. }
  95. LRESULT CHTMLPage1::OnUpdateTargetTX( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  96. {
  97. TRACE_METHOD(CHTMLPage1, OnUpdateTargetTX);
  98. _ValidatePage();
  99. return 0;
  100. }
  101. LRESULT CHTMLPage1::OnBrowseBT( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  102. {
  103. TRACE_METHOD(CHTMLPage1, OnBrowseBT);
  104. TCHAR szFile[MAX_PATH] = { 0 };
  105. TCHAR szInitialPath[MAX_PATH];
  106. CStr strFilter;
  107. LoadFilterString(strFilter, IDS_HTML_FILES);
  108. CStr strTitle;
  109. strTitle.LoadString(GetStringModule(), IDS_BROWSE_WEBLINK);
  110. // Copy the current command target value to the file name
  111. m_strTarget.GetWindowText (szInitialPath, sizeof(szInitialPath) / sizeof(TCHAR) );
  112. OPENFILENAME ofn;
  113. ofn.lStructSize = sizeof(ofn);
  114. ofn.hwndOwner = m_hWnd;
  115. ofn.hInstance = NULL;
  116. ofn.lpstrFilter = strFilter;
  117. ofn.lpstrCustomFilter = NULL;
  118. ofn.nMaxCustFilter = 0;
  119. ofn.nFilterIndex = 1; // use 1st filter in lpstrFilter
  120. ofn.lpstrFile = szFile;
  121. ofn.nMaxFile = sizeof(szFile);
  122. ofn.lpstrFileTitle = NULL;
  123. ofn.nMaxFileTitle = 0;
  124. ofn.lpstrTitle = strTitle;
  125. ofn.Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
  126. ofn.nFileOffset = 0;
  127. ofn.nFileExtension = 0;
  128. ofn.lpstrDefExt = _T("htm");
  129. ofn.lCustData = 0;
  130. ofn.lpfnHook = NULL;
  131. ofn.lpTemplateName = NULL;
  132. ofn.lpstrInitialDir = szInitialPath;
  133. if (!GetOpenFileName(&ofn))
  134. {
  135. if (CommDlgExtendedError() != 0)
  136. {
  137. ASSERT(0 && "GetOpenFileName failed");
  138. Dbg(DEB_ERROR, _T("GetOpenFileName failed, 0x%08lx\n"),CommDlgExtendedError());
  139. }
  140. return 0;
  141. }
  142. // lpstrFile has the full path of the file to open
  143. TRACE(_T("Open: %ws\n"), ofn.lpstrFile);
  144. m_strTarget.SetWindowText( ofn.lpstrFile );
  145. return 0;
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. // CHTMLPage2 property page
  149. CHTMLPage2::CHTMLPage2()
  150. {
  151. // SetHelpIDs(g_aHelpIDs_IDD_HTML_WIZPAGE2);
  152. }
  153. CHTMLPage2::~CHTMLPage2()
  154. {
  155. }
  156. LRESULT CHTMLPage2::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  157. {
  158. USES_CONVERSION;
  159. HWND const hDisplay = ::GetDlgItem( *this, IDC_DISPLAYTX );
  160. ASSERT( hDisplay != NULL );
  161. m_strDisplay.Attach( hDisplay );
  162. m_strDisplay.SetWindowText( GetComponentDataImpl()->GetName());
  163. m_strDisplay.SetLimitText( 128 );
  164. _ValidatePage();
  165. return TRUE;
  166. }
  167. void CHTMLPage2::_ValidatePage(void)
  168. {
  169. TRACE_METHOD(CHTMLPage2, _ValidatePage);
  170. DWORD dwFlags=PSWIZB_BACK|PSWIZB_DISABLEDFINISH;
  171. // Check to see if we have a valid string
  172. TCHAR buff[ 256 ];
  173. int nChars = m_strDisplay.GetWindowText( buff, sizeof(buff) / sizeof(TCHAR) );
  174. if( nChars != 0 && _tcslen( buff ) > 0 )
  175. dwFlags|=PSWIZB_FINISH;
  176. HWND hWnd=::GetParent(m_hWnd);
  177. ::SendMessage(hWnd, PSM_SETWIZBUTTONS, 0, dwFlags);
  178. }
  179. BOOL CHTMLPage2::OnSetActive()
  180. {
  181. TRACE_METHOD(CHTMLPage2, OnSetActive);
  182. USES_CONVERSION;
  183. m_strDisplay.SetWindowText( GetComponentDataImpl()->GetName());
  184. _ValidatePage();
  185. return TRUE;
  186. }
  187. BOOL CHTMLPage2::OnKillActive()
  188. {
  189. TRACE_METHOD(CHTMLPage2, OnKillActive);
  190. TCHAR buff[ 256 ];
  191. m_strDisplay.GetWindowText( buff, sizeof(buff) / sizeof(TCHAR) );
  192. GetComponentDataImpl()->SetName(buff);
  193. return TRUE;
  194. }
  195. BOOL CHTMLPage2::OnWizardFinish()
  196. {
  197. TRACE_METHOD(CHTMLPage2, OnWizardFinish);
  198. OnKillActive();
  199. return TRUE;
  200. }
  201. LRESULT CHTMLPage2::OnUpdateDisplayTX( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  202. {
  203. TRACE_METHOD(CHTMLPage2, OnUpdateDisplayTX);
  204. _ValidatePage();
  205. return TRUE;
  206. }
  207. /////////////////////////////////////////////////////////////////////////////
  208. /////////////////////////////////////////////////////////////////////////////
  209. /////////////////////////////////////////////////////////////////////////////
  210. // CActiveXPage0 property page
  211. CActiveXPage0::CActiveXPage0()
  212. {
  213. // SetHelpIDs(g_aHelpIDs_IDD_ACTIVEX_WIZPAGE0);
  214. }
  215. CActiveXPage0::~CActiveXPage0()
  216. {
  217. }
  218. BOOL CActiveXPage0::OnSetActive()
  219. {
  220. CWizardPage::OnWelcomeSetActive(m_hWnd);
  221. return TRUE;
  222. }
  223. BOOL CActiveXPage0::OnKillActive()
  224. {
  225. CWizardPage::OnWelcomeKillActive(m_hWnd);
  226. return TRUE;
  227. }
  228. LRESULT CActiveXPage0::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  229. {
  230. CWizardPage::OnInitWelcomePage(m_hWnd); // set up the correct title font
  231. return TRUE;
  232. }
  233. /////////////////////////////////////////////////////////////////////////////
  234. // CActiveXPage1 property page
  235. CActiveXPage1::CActiveXPage1()
  236. {
  237. m_pListCtrl = NULL;
  238. m_pComponentCategory = NULL;
  239. // SetHelpIDs(g_aHelpIDs_IDD_ACTIVEX_WIZPAGE1);
  240. }
  241. CActiveXPage1::~CActiveXPage1()
  242. {
  243. }
  244. void CActiveXPage1::_ValidatePage(void)
  245. {
  246. DWORD dwFlags = PSWIZB_BACK;
  247. // Check to see if we have a valid string
  248. if (m_pListCtrl != NULL && m_pListCtrl->GetSelectedCount()>0)
  249. dwFlags|=PSWIZB_NEXT;
  250. HWND hWnd=::GetParent(m_hWnd);
  251. ::SendMessage(hWnd, PSM_SETWIZBUTTONS, 0, dwFlags);
  252. }
  253. BOOL CActiveXPage1::OnSetActive()
  254. {
  255. _ValidatePage();
  256. return TRUE;
  257. }
  258. BOOL CActiveXPage1::OnKillActive()
  259. {
  260. LV_ITEM lvi;
  261. memset( &lvi,'\0',sizeof(LV_ITEM) );
  262. lvi.mask = LVIF_PARAM;
  263. lvi.iItem = m_pListCtrl->GetNextItem( -1, LVNI_SELECTED );
  264. if (lvi.iItem != -1)
  265. {
  266. if (m_pListCtrl->GetItem(&lvi))
  267. {
  268. CComponentCategory::COMPONENTINFO* pComponentInfo=(CComponentCategory::COMPONENTINFO*)lvi.lParam;
  269. USES_CONVERSION;
  270. GetComponentDataImpl()->SetName(((LPTSTR)(LPCTSTR)pComponentInfo->m_strName));
  271. LPOLESTR szClsid = NULL;
  272. StringFromCLSID(pComponentInfo->m_clsid, &szClsid);
  273. ASSERT(szClsid != NULL);
  274. if(szClsid != NULL)
  275. {
  276. GetComponentDataImpl()->SetView(OLE2T(szClsid));
  277. CoTaskMemFree(szClsid);
  278. }
  279. }
  280. }
  281. return TRUE;
  282. }
  283. LRESULT CActiveXPage1::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  284. {
  285. /*
  286. * this could take a while - throw up the hourglass
  287. */
  288. // Display hour glass during long initialization
  289. SetCursor (LoadCursor (NULL, IDC_WAIT));
  290. m_nConsoleView = -1;
  291. m_pListCtrl = new WTL::CListViewCtrl;
  292. if ( m_pListCtrl == NULL )
  293. return TRUE;
  294. m_pComboBox = new CComboBoxEx2;
  295. if ( m_pComboBox == NULL )
  296. return TRUE;
  297. m_pComponentCategory = new CComponentCategory;
  298. if ( m_pComponentCategory == NULL )
  299. return TRUE;
  300. // subclass the categories combo box
  301. m_pComboBox->Attach(::GetDlgItem(*this, IDC_CATEGORY_COMBOEX));
  302. // sub class the controls list
  303. m_pListCtrl->Attach(::GetDlgItem( *this, IDC_CONTROLXLS));
  304. // set the imagelist
  305. m_pListCtrl->SetImageList( m_pComponentCategory->m_iml, LVSIL_SMALL );
  306. // create single column in list view
  307. // Reduce column width by width of vertical scroll bar so that we
  308. // don't need a horizontal scroll bar
  309. RECT rc;
  310. m_pListCtrl->GetClientRect(&rc);
  311. LV_COLUMN lvc;
  312. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM;
  313. lvc.fmt = LVCFMT_LEFT;
  314. lvc.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL);
  315. lvc.iSubItem = 0;
  316. m_pListCtrl->InsertColumn(0, &lvc);
  317. // enumerate the categories and add them to the combo box
  318. m_pComponentCategory->EnumComponentCategories();
  319. BuildCategoryList(m_pComponentCategory->m_arpCategoryInfo);
  320. // enumerate all the controls and add them to the list box
  321. m_pComponentCategory->EnumComponents();
  322. m_pComponentCategory->FilterComponents(NULL);
  323. BuildComponentList(m_pComponentCategory->m_arpComponentInfo);
  324. // remove the hourglass
  325. SetCursor (LoadCursor (NULL, IDC_ARROW));
  326. return TRUE;
  327. }
  328. LRESULT CActiveXPage1::OnDestroy( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  329. {
  330. delete m_pComponentCategory;
  331. delete m_pListCtrl;
  332. delete m_pComboBox;
  333. return 0;
  334. }
  335. //
  336. // Populate the category combo box from the category list
  337. //
  338. LRESULT CActiveXPage1::BuildCategoryList(CArray <CATEGORYINFO*, CATEGORYINFO*>& arpCategories)
  339. {
  340. USES_CONVERSION;
  341. COMBOBOXEXITEM ComboItem;
  342. for (int i = 0; i <= arpCategories.GetUpperBound(); i++)
  343. {
  344. CATEGORYINFO* pCatInfo = arpCategories.GetAt(i);
  345. ComboItem.mask = CBEIF_LPARAM | CBEIF_TEXT;
  346. ComboItem.lParam = reinterpret_cast<LPARAM>(pCatInfo);
  347. ComboItem.pszText = OLE2T(pCatInfo->szDescription);
  348. // CComboBoxEx doesn't support CBS_SORT and has no add method, only insert.
  349. // So we need to find the insertion point ourselves. Because it's a short
  350. // list, just do a linear search.
  351. int iInsert;
  352. for (iInsert = 0; iInsert < i; iInsert++)
  353. {
  354. CATEGORYINFO* pCatEntry = reinterpret_cast<CATEGORYINFO*>(m_pComboBox->GetItemData(iInsert));
  355. if (_wcsicmp(pCatInfo->szDescription, pCatEntry->szDescription) < 0)
  356. break;
  357. }
  358. ComboItem.iItem = iInsert;
  359. int iItem = m_pComboBox->InsertItem(&ComboItem);
  360. ASSERT(iItem >= 0);
  361. }
  362. // Add special "All Categories" entry at the top and select it
  363. // Note that this item is recognized by a NULL category info ptr
  364. CStr strAllCat;
  365. strAllCat.LoadString(GetStringModule(), IDS_ALL_CATEGORIES);
  366. ComboItem.mask = CBEIF_LPARAM | CBEIF_TEXT;
  367. ComboItem.lParam = NULL;
  368. ComboItem.pszText = const_cast<LPTSTR>((LPCTSTR)strAllCat);
  369. ComboItem.iItem = 0;
  370. int iItem = m_pComboBox->InsertItem(&ComboItem);
  371. ASSERT(iItem >= 0);
  372. m_pComboBox->SetCurSel(0);
  373. return S_OK;
  374. }
  375. //
  376. // Populate the component listview with the filtered items in the component list
  377. //
  378. LRESULT CActiveXPage1::BuildComponentList(
  379. CArray <CComponentCategory::COMPONENTINFO*,
  380. CComponentCategory::COMPONENTINFO*>& arpComponents )
  381. {
  382. // Get currently selected item data
  383. LPARAM lParamSel = 0;
  384. int iSelect = m_pListCtrl->GetNextItem(-1, LVNI_SELECTED);
  385. if (iSelect != -1)
  386. lParamSel = m_pListCtrl->GetItemData(iSelect);
  387. // clear and reload comp list
  388. m_pListCtrl->DeleteAllItems();
  389. for (int i=0; i <= arpComponents.GetUpperBound(); i++)
  390. {
  391. CComponentCategory::COMPONENTINFO* pCompInfo = arpComponents.GetAt(i);
  392. if (pCompInfo->m_bSelected)
  393. {
  394. LV_ITEM lvi;
  395. lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  396. lvi.iItem = i;
  397. lvi.state = 0;
  398. lvi.stateMask = 0;
  399. lvi.iSubItem = 0;
  400. lvi.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(pCompInfo->m_strName));
  401. lvi.iImage = pCompInfo->m_uiBitmap;
  402. lvi.lParam = (LPARAM)(LPVOID)pCompInfo;
  403. int iRet = m_pListCtrl->InsertItem(&lvi);
  404. ASSERT(iRet != -1);
  405. }
  406. }
  407. // if list isn't empty, select an item
  408. if (m_pListCtrl->GetItemCount() != 0)
  409. {
  410. // first item is the default
  411. iSelect = 0;
  412. // try finding previously selected item
  413. if (lParamSel != NULL)
  414. {
  415. LV_FINDINFO FindInfo;
  416. FindInfo.flags = LVFI_PARAM;
  417. FindInfo.lParam = lParamSel;
  418. iSelect = m_pListCtrl->FindItem(&FindInfo, -1 );
  419. }
  420. LV_ITEM lvi;
  421. lvi.mask = LVIF_STATE;
  422. lvi.iItem = iSelect;
  423. lvi.iSubItem = 0;
  424. lvi.state = LVIS_SELECTED | LVIS_FOCUSED;
  425. lvi.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  426. m_pListCtrl->SetItem(&lvi);
  427. m_pListCtrl->EnsureVisible(iSelect, FALSE);
  428. }
  429. _ValidatePage();
  430. return S_OK;
  431. }
  432. //
  433. // handle component selection change
  434. //
  435. LRESULT CActiveXPage1::OnComponentSelect( int idCtrl, LPNMHDR pnmh, BOOL& bHandled )
  436. {
  437. _ValidatePage();
  438. return 0;
  439. }
  440. //
  441. // Handle category selection change
  442. //
  443. LRESULT CActiveXPage1::OnCategorySelect( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  444. {
  445. int iItem = m_pComboBox->GetCurSel();
  446. ASSERT(iItem >= 0);
  447. if (iItem < 0)
  448. return 0;
  449. // get the category info pointer (item's lparam)
  450. COMBOBOXEXITEM ComboItem;
  451. ComboItem.mask = CBEIF_LPARAM;
  452. ComboItem.iItem = iItem;
  453. BOOL bStat = m_pComboBox->GetItem(&ComboItem);
  454. ASSERT(bStat);
  455. CATEGORYINFO* pCatInfo = reinterpret_cast<CATEGORYINFO*>(ComboItem.lParam);
  456. // filter the component of this category
  457. m_pComponentCategory->FilterComponents(pCatInfo);
  458. // rebuild the component list
  459. BuildComponentList(m_pComponentCategory->m_arpComponentInfo);
  460. return 0;
  461. }
  462. /////////////////////////////////////////////////////////////////////////////
  463. /////////////////////////////////////////////////////////////////////////////
  464. // CActiveXPage2 property page
  465. CActiveXPage2::CActiveXPage2()
  466. {
  467. // SetHelpIDs(g_aHelpIDs_IDD_ACTIVEX_WIZPAGE2);
  468. }
  469. CActiveXPage2::~CActiveXPage2()
  470. {
  471. }
  472. LRESULT CActiveXPage2::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  473. {
  474. HWND const hDisplay = ::GetDlgItem( *this, IDC_DISPLAYTX );
  475. ASSERT( hDisplay != NULL );
  476. m_strDisplay.Attach( hDisplay );
  477. m_strDisplay.SetWindowText( _T( "" ) );
  478. m_strDisplay.SetLimitText( 128 );
  479. _ValidatePage();
  480. return 0;
  481. }
  482. void CActiveXPage2::_ValidatePage(void)
  483. {
  484. DWORD dwFlags=PSWIZB_BACK|PSWIZB_DISABLEDFINISH;
  485. // Check to see if we have a valid string
  486. TCHAR buff[ 256 ];
  487. int nChars = m_strDisplay.GetWindowText( buff, sizeof(buff) / sizeof(TCHAR) );
  488. if( nChars != 0 && _tcslen( buff ) > 0 )
  489. dwFlags|=PSWIZB_FINISH;
  490. HWND hWnd=::GetParent(m_hWnd);
  491. ::SendMessage(hWnd, PSM_SETWIZBUTTONS, 0, dwFlags);
  492. }
  493. BOOL CActiveXPage2::OnSetActive()
  494. {
  495. USES_CONVERSION;
  496. m_strDisplay.SetWindowText(GetComponentDataImpl()->GetName());
  497. _ValidatePage();
  498. return TRUE;
  499. }
  500. BOOL CActiveXPage2::OnKillActive()
  501. {
  502. TCHAR buff[ 256 ];
  503. m_strDisplay.GetWindowText( buff, sizeof(buff) / sizeof(TCHAR) );
  504. GetComponentDataImpl()->SetName(buff);
  505. return TRUE;
  506. }
  507. LRESULT CActiveXPage2::OnUpdateTargetTX( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  508. {
  509. _ValidatePage();
  510. return 0;
  511. }
  512. BOOL CActiveXPage2::OnWizardFinish()
  513. {
  514. OnKillActive();
  515. return TRUE;
  516. }
  517. /////////////////////////////////////////////////////////////////////////////
  518. // CBasePropertyPage
  519. template<class T>
  520. void CBasePropertyPage<T>::OnPropertySheetExit(HWND hWndOwner, int nFlag)
  521. {
  522. m_spComponentData = NULL;
  523. }
  524. // Helper function to reformat filter resource string
  525. // ( resource string uses '\' instead of null to separate strings
  526. // and doesn't terminate in double null. )
  527. void LoadFilterString(CStr &strFilter, int iStrID)
  528. {
  529. // Get resource string
  530. strFilter.LoadString(GetStringModule(), iStrID);
  531. // Append extra NULL to mark end of multi-string
  532. strFilter += _T('\0');
  533. // Change filter separators from '\' to nulls
  534. LPTSTR psz = const_cast<LPTSTR>((LPCTSTR)strFilter);
  535. while (*psz != _T('\0'))
  536. {
  537. if (*psz == _T('\\'))
  538. *psz = _T('\0');
  539. psz++;
  540. }
  541. }