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.

1293 lines
37 KiB

  1. #include "shellprv.h"
  2. #include "mshtml.h"
  3. #include "mshtmhst.h"
  4. #include "mshtmdid.h"
  5. #include "htiframe.h"
  6. #include "exdisp.h"
  7. #include "exdispid.h"
  8. #include "dspsprt.h"
  9. #include "cowsite.h"
  10. #include "ids.h"
  11. #include "inetsmgr.h"
  12. #pragma hdrstop
  13. // helper functions
  14. typedef BOOL (*pfnDllRegisterWindowClasses)(const SHDRC * pshdrc);
  15. BOOL SHDOCVW_DllRegisterWindowClasses(const SHDRC * pshdrc)
  16. {
  17. static HINSTANCE _hinstShdocvw = NULL;
  18. static pfnDllRegisterWindowClasses _regfunc = NULL;
  19. BOOL fSuccess = FALSE;
  20. if (!_hinstShdocvw)
  21. {
  22. _hinstShdocvw = LoadLibrary(TEXT("shdocvw.dll"));
  23. _regfunc = (pfnDllRegisterWindowClasses) GetProcAddress(_hinstShdocvw, "DllRegisterWindowClasses");
  24. }
  25. if (_regfunc)
  26. fSuccess = _regfunc(pshdrc);
  27. return fSuccess;
  28. }
  29. // Advise point for DIID_DWebBrowserEvents2
  30. // Just an IDispatch implementation that delegates back to the main class. Allows us to have a separate "Invoke".
  31. class CWebWizardPage;
  32. class CWebEventHandler : public IServiceProvider, DWebBrowserEvents2
  33. {
  34. public:
  35. CWebEventHandler(CWebWizardPage *pswp);
  36. ~CWebEventHandler(); // TODO: Make this virtual or it will never execute.
  37. // IUnknown
  38. STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
  39. STDMETHODIMP_(ULONG) AddRef() {return 2;}
  40. STDMETHODIMP_(ULONG) Release() {return 1;}
  41. // (DwebBrowserEvents)IDispatch
  42. STDMETHODIMP GetTypeInfoCount(/* [out] */ UINT *pctinfo) { return E_NOTIMPL; }
  43. STDMETHODIMP GetTypeInfo(
  44. /* [in] */ UINT iTInfo,
  45. /* [in] */ LCID lcid,
  46. /* [out] */ ITypeInfo **ppTInfo)
  47. { return E_NOTIMPL; }
  48. STDMETHODIMP GetIDsOfNames(
  49. /* [in] */ REFIID riid,
  50. /* [size_is][in] */ LPOLESTR *rgszNames,
  51. /* [in] */ UINT cNames,
  52. /* [in] */ LCID lcid,
  53. /* [size_is][out] */ DISPID *rgDispId)
  54. { return E_NOTIMPL; }
  55. /* [local] */ STDMETHODIMP Invoke(
  56. /* [in] */ DISPID dispIdMember,
  57. /* [in] */ REFIID riid,
  58. /* [in] */ LCID lcid,
  59. /* [in] */ WORD wFlags,
  60. /* [out][in] */ DISPPARAMS *pDispParams,
  61. /* [out] */ VARIANT *pVarResult,
  62. /* [out] */ EXCEPINFO *pExcepInfo,
  63. /* [out] */ UINT *puArgErr);
  64. HRESULT _Advise(BOOL fConnect);
  65. // IServiceProvider
  66. STDMETHODIMP QueryService(REFGUID guidService, REFIID riid, void **ppv);
  67. private:
  68. CWebWizardPage* _pwizPage;
  69. DWORD _dwCPCookie;
  70. IConnectionPoint* _pcpCurrentConnection;
  71. };
  72. #define SHOW_PROGRESS_TIMER 1
  73. #define SHOW_PROGRESS_TIMEOUT 1000 // Start showing the progress indicator after 1 second of dead time.
  74. class CWebWizardPage : public CImpIDispatch,
  75. CObjectWithSite,
  76. IDocHostUIHandler,
  77. IServiceProvider,
  78. IWebWizardExtension,
  79. INewWDEvents
  80. {
  81. public:
  82. CWebWizardPage();
  83. ~CWebWizardPage();
  84. // IUnknown
  85. STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
  86. STDMETHODIMP_(ULONG) AddRef();
  87. STDMETHODIMP_(ULONG) Release();
  88. // IDocHostUIHandler
  89. STDMETHODIMP ShowContextMenu(
  90. /* [in] */ DWORD dwID,
  91. /* [in] */ POINT *ppt,
  92. /* [in] */ IUnknown *pcmdtReserved,
  93. /* [in] */ IDispatch *pdispReserved)
  94. { return E_NOTIMPL; }
  95. STDMETHODIMP GetHostInfo(
  96. /* [out][in] */ DOCHOSTUIINFO *pInfo);
  97. STDMETHODIMP ShowUI(
  98. /* [in] */ DWORD dwID,
  99. /* [in] */ IOleInPlaceActiveObject *pActiveObject,
  100. /* [in] */ IOleCommandTarget *pCommandTarget,
  101. /* [in] */ IOleInPlaceFrame *pFrame,
  102. /* [in] */ IOleInPlaceUIWindow *pDoc)
  103. { return E_NOTIMPL; }
  104. STDMETHODIMP HideUI(void)
  105. { return E_NOTIMPL; }
  106. STDMETHODIMP UpdateUI(void)
  107. { return E_NOTIMPL; }
  108. STDMETHODIMP EnableModeless(
  109. /* [in] */ BOOL fEnable)
  110. { return E_NOTIMPL; }
  111. STDMETHODIMP OnDocWindowActivate(
  112. /* [in] */ BOOL fActivate)
  113. { return E_NOTIMPL; }
  114. STDMETHODIMP OnFrameWindowActivate(
  115. /* [in] */ BOOL fActivate)
  116. { return E_NOTIMPL; }
  117. STDMETHODIMP ResizeBorder(
  118. /* [in] */ LPCRECT prcBorder,
  119. /* [in] */ IOleInPlaceUIWindow *pUIWindow,
  120. /* [in] */ BOOL fRameWindow)
  121. { return E_NOTIMPL; }
  122. STDMETHODIMP TranslateAccelerator(
  123. /* [in] */ LPMSG lpMsg,
  124. /* [in] */ const GUID *pguidCmdGroup,
  125. /* [in] */ DWORD nCmdID)
  126. { return E_NOTIMPL; }
  127. STDMETHODIMP GetOptionKeyPath(
  128. /* [out] */ LPOLESTR *pchKey,
  129. /* [in] */ DWORD dw)
  130. { return E_NOTIMPL; }
  131. STDMETHODIMP GetDropTarget(
  132. /* [in] */ IDropTarget *pDropTarget,
  133. /* [out] */ IDropTarget **ppDropTarget)
  134. { return E_NOTIMPL; }
  135. STDMETHODIMP GetExternal(
  136. /* [out] */ IDispatch **ppDispatch);
  137. STDMETHODIMP TranslateUrl(
  138. /* [in] */ DWORD dwTranslate,
  139. /* [in] */ OLECHAR *pchURLIn,
  140. /* [out] */ OLECHAR **ppchURLOut)
  141. { return E_NOTIMPL; }
  142. STDMETHODIMP FilterDataObject(
  143. /* [in] */ IDataObject *pDO,
  144. /* [out] */ IDataObject **ppDORet)
  145. { return E_NOTIMPL; }
  146. // IServiceProvider
  147. STDMETHODIMP QueryService(
  148. /*[in]*/ REFGUID guidService,
  149. /*[in]*/ REFIID riid,
  150. /*[out]*/ void **ppv);
  151. // INewWDEvents
  152. // (IDispatch)
  153. STDMETHODIMP GetTypeInfoCount(
  154. /* [out] */ UINT *pctinfo)
  155. { return E_NOTIMPL; }
  156. STDMETHODIMP GetTypeInfo(
  157. /* [in] */ UINT iTInfo,
  158. /* [in] */ LCID lcid,
  159. /* [out] */ ITypeInfo **ppTInfo)
  160. {
  161. return CImpIDispatch::GetTypeInfo(iTInfo, lcid, ppTInfo);
  162. }
  163. STDMETHODIMP GetIDsOfNames(
  164. /* [in] */ REFIID riid,
  165. /* [size_is][in] */ LPOLESTR *rgszNames,
  166. /* [in] */ UINT cNames,
  167. /* [in] */ LCID lcid,
  168. /* [size_is][out] */ DISPID *rgDispId)
  169. {
  170. return CImpIDispatch::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgDispId);
  171. }
  172. STDMETHODIMP Invoke(
  173. /* [in] */ DISPID dispIdMember,
  174. /* [in] */ REFIID riid,
  175. /* [in] */ LCID lcid,
  176. /* [in] */ WORD wFlags,
  177. /* [out][in] */ DISPPARAMS *pDispParams,
  178. /* [out] */ VARIANT *pVarResult,
  179. /* [out] */ EXCEPINFO *pExcepInfo,
  180. /* [out] */ UINT *puArgErr)
  181. {
  182. return CImpIDispatch::Invoke(dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
  183. }
  184. STDMETHODIMP FinalBack(void);
  185. STDMETHODIMP FinalNext(void);
  186. STDMETHODIMP Cancel(void);
  187. STDMETHODIMP put_Caption(
  188. /* [in] */ BSTR bstrCaption);
  189. STDMETHODIMP get_Caption(
  190. /* [retval][out] */ BSTR *pbstrCaption);
  191. STDMETHODIMP put_Property(
  192. /* [in] */ BSTR bstrPropertyName,
  193. /* [in] */ VARIANT *pvProperty);
  194. STDMETHODIMP get_Property(
  195. /* [in] */ BSTR bstrPropertyName,
  196. /* [retval][out] */ VARIANT *pvProperty);
  197. STDMETHODIMP SetWizardButtons(
  198. /* [in] */ VARIANT_BOOL vfEnableBack,
  199. /* [in] */ VARIANT_BOOL vfEnableNext,
  200. /* [in] */ VARIANT_BOOL vfLastPage);
  201. STDMETHODIMP SetHeaderText(
  202. /* [in] */ BSTR bstrHeaderTitle,
  203. /* [in] */ BSTR bstrHeaderSubtitle);
  204. STDMETHODIMP PassportAuthenticate(
  205. /* [in] */ BSTR bstrSignInUrl,
  206. /* [retval][out] */ VARIANT_BOOL * pvfAuthenticated);
  207. // IWizardExtension
  208. STDMETHODIMP AddPages(HPROPSHEETPAGE* aPages, UINT cPages, UINT *pnPages);
  209. STDMETHODIMP GetFirstPage(HPROPSHEETPAGE *phPage);
  210. STDMETHODIMP GetLastPage(HPROPSHEETPAGE *phPage)
  211. { return GetFirstPage(phPage); }
  212. // IWebWizardExtension
  213. STDMETHODIMP SetInitialURL(LPCWSTR pszDefaultURL);
  214. STDMETHODIMP SetErrorURL(LPCWSTR pszErrorURL);
  215. protected:
  216. friend class CWebEventHandler;
  217. void _OnDownloadBegin();
  218. void _OnDocumentComplete();
  219. private:
  220. void _InitBrowser();
  221. HRESULT _NavigateBrowser(LPCWSTR pszUrl);
  222. HRESULT _CallScript(IWebBrowser2* pbrowser, LPCWSTR pszFunction);
  223. BOOL _IsScriptFunctionOnPage(IWebBrowser2* pbrowser, LPCWSTR pszFunction);
  224. BOOL _IsBrowserVisible();
  225. void _ShowBrowser(BOOL fShow);
  226. void _SizeProgress();
  227. void _ShowProgress(BOOL fShow);
  228. void _StartShowProgressTimer();
  229. void _SetHeaderText(LPCWSTR pszHeader, LPCWSTR pszSubHeader);
  230. virtual INT_PTR DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  231. static INT_PTR StaticProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
  232. static UINT PropPageProc(HWND hwndDlg, UINT uMsg, PROPSHEETPAGE *ppsp);
  233. BOOL OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam);
  234. BOOL OnDestroy(HWND hwnd);
  235. BOOL OnNotify(HWND hwnd, int idCtrl, LPNMHDR pnmh);
  236. BOOL OnTimer(HWND hwnd, UINT nIDEvent);
  237. LONG _cRef;
  238. CWebEventHandler *_pwebEventHandler;
  239. IWebBrowser2 *_pwebbrowser;
  240. IOleInPlaceActiveObject *_poipao;
  241. HWND _hwndOCHost; // Web browser control window
  242. HWND _hwndFrame; // Wizard frame window
  243. HWND _hwnd; // Dialog window
  244. HPROPSHEETPAGE _hPage;
  245. LPWSTR _pszInitialURL;
  246. LPWSTR _pszErrorURL;
  247. };
  248. INT_PTR CWebWizardPage::StaticProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  249. {
  250. CWebWizardPage* pthis = (CWebWizardPage*) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
  251. PROPSHEETPAGE* ppage;
  252. INT_PTR fProcessed;
  253. if (uMsg == WM_INITDIALOG)
  254. {
  255. ppage = (PROPSHEETPAGE*) lParam;
  256. pthis = (CWebWizardPage*) ppage->lParam;
  257. SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pthis);
  258. }
  259. if (pthis != NULL)
  260. {
  261. fProcessed = pthis->DialogProc(hwndDlg, uMsg, wParam, lParam);
  262. }
  263. else
  264. {
  265. fProcessed = FALSE;
  266. }
  267. return fProcessed;
  268. }
  269. // construction and IUnknown
  270. CWebEventHandler::CWebEventHandler(CWebWizardPage *pwswp) :
  271. _pcpCurrentConnection(NULL),
  272. _pwizPage(pwswp)
  273. {
  274. }
  275. CWebEventHandler::~CWebEventHandler()
  276. {
  277. _Advise(FALSE);
  278. }
  279. HRESULT CWebEventHandler::QueryInterface(REFIID riid, void **ppv)
  280. {
  281. static const QITAB qit[] = {
  282. QITABENTMULTI(CWebEventHandler, IDispatch, DWebBrowserEvents2),
  283. QITABENTMULTI2(CWebEventHandler, DIID_DWebBrowserEvents2, DWebBrowserEvents2),
  284. // QITABENTMULTI2(CWebEventHandler, DIID_DWebBrowserEvents, DWebBrowserEvents),
  285. QITABENT(CWebEventHandler, IServiceProvider),
  286. { 0 },
  287. };
  288. return QISearch(this, qit, riid, ppv);
  289. }
  290. STDMETHODIMP CWebEventHandler::QueryService(REFGUID guidService, REFIID riid, void **ppv)
  291. {
  292. HRESULT hr = E_NOINTERFACE;
  293. *ppv = NULL; // no result yet
  294. // we are a site for the OleControlSite interfaces only
  295. if (guidService == SID_OleControlSite)
  296. {
  297. if (riid == IID_IDispatch)
  298. {
  299. hr = this->QueryInterface(riid, ppv);
  300. }
  301. }
  302. return hr;
  303. }
  304. HRESULT CWebEventHandler_CreateInstance(CWebWizardPage *pwswp, CWebEventHandler **ppweh)
  305. {
  306. *ppweh = new CWebEventHandler(pwswp);
  307. if (!*ppweh)
  308. return E_OUTOFMEMORY;
  309. return S_OK;
  310. }
  311. HRESULT CWebEventHandler::_Advise(BOOL fConnect)
  312. {
  313. HRESULT hr = S_OK;
  314. // If we're already connected, disconnect, since we either want to disconnect or reconnect to
  315. // a different webbrowser.
  316. if (_pcpCurrentConnection)
  317. {
  318. hr = _pcpCurrentConnection->Unadvise(_dwCPCookie);
  319. if (SUCCEEDED(hr))
  320. {
  321. ATOMICRELEASE(_pcpCurrentConnection);
  322. }
  323. }
  324. else
  325. {
  326. // We expect that if _pcpCurrentConnection is NULL, no code earlier would have changed hr, and that it is still S_OK
  327. // The code below expects that if !SUCCEEDED(hr), Unadvise failed above.
  328. ASSERT(SUCCEEDED(hr));
  329. }
  330. if (_pwizPage && _pwizPage->_pwebbrowser)
  331. {
  332. if (SUCCEEDED(hr) && fConnect)
  333. {
  334. IConnectionPointContainer* pcontainer;
  335. hr = _pwizPage->_pwebbrowser->QueryInterface(IID_PPV_ARG(IConnectionPointContainer, &pcontainer));
  336. if (SUCCEEDED(hr))
  337. {
  338. IConnectionPoint* pconnpoint;
  339. hr = pcontainer->FindConnectionPoint(DIID_DWebBrowserEvents2, &pconnpoint);
  340. if (SUCCEEDED(hr))
  341. {
  342. IDispatch* pDisp;
  343. hr = QueryInterface(IID_PPV_ARG(IDispatch, &pDisp));
  344. if (SUCCEEDED(hr))
  345. {
  346. hr = pconnpoint->Advise(pDisp, &_dwCPCookie);
  347. pDisp->Release();
  348. }
  349. if (SUCCEEDED(hr))
  350. {
  351. // TODO: Enable ATOMICRELEASE() to verify we won't leak anything
  352. // ATOMICRELEASE(_pcpCurrentConnection);
  353. _pcpCurrentConnection = pconnpoint;
  354. }
  355. else
  356. {
  357. pconnpoint->Release();
  358. }
  359. }
  360. pcontainer->Release();
  361. }
  362. }
  363. }
  364. return hr;
  365. }
  366. HRESULT CWebEventHandler::Invoke(
  367. /* [in] */ DISPID dispIdMember,
  368. /* [in] */ REFIID riid,
  369. /* [in] */ LCID lcid,
  370. /* [in] */ WORD wFlags,
  371. /* [out][in] */ DISPPARAMS *pDispParams,
  372. /* [out] */ VARIANT *pVarResult,
  373. /* [out] */ EXCEPINFO *pExcepInfo,
  374. /* [out] */ UINT *puArgErr)
  375. {
  376. HRESULT hr = S_OK;
  377. switch (dispIdMember)
  378. {
  379. case DISPID_BEFORENAVIGATE2:
  380. _pwizPage->_OnDownloadBegin();
  381. break;
  382. case DISPID_DOCUMENTCOMPLETE:
  383. _pwizPage->_OnDocumentComplete();
  384. break;
  385. default:
  386. hr = DISP_E_MEMBERNOTFOUND;
  387. break;
  388. }
  389. return hr;
  390. }
  391. // Object for hosting HTML wizard pages
  392. CWebWizardPage::CWebWizardPage() :
  393. CImpIDispatch(LIBID_Shell32, 0, 0, IID_INewWDEvents),
  394. _cRef(1)
  395. {
  396. // Ensure zero-init happened
  397. ASSERT(NULL == _pwebbrowser);
  398. ASSERT(NULL == _pwebEventHandler);
  399. ASSERT(NULL == _pszInitialURL);
  400. ASSERT(NULL == _pszErrorURL);
  401. }
  402. CWebWizardPage::~CWebWizardPage()
  403. {
  404. ATOMICRELEASE(_pwebbrowser);
  405. ATOMICRELEASE(_pwebEventHandler);
  406. ATOMICRELEASE(_punkSite);
  407. ATOMICRELEASE(_poipao);
  408. Str_SetPtr(&_pszInitialURL, NULL);
  409. Str_SetPtr(&_pszErrorURL, NULL);
  410. }
  411. HRESULT CWebWizardPage::QueryInterface(REFIID riid, void **ppv)
  412. {
  413. static const QITAB qit[] =
  414. {
  415. QITABENTMULTI(CWebWizardPage, IWizardExtension, IWebWizardExtension),
  416. QITABENT(CWebWizardPage, IWebWizardExtension),
  417. QITABENT(CWebWizardPage, IDocHostUIHandler),
  418. QITABENT(CWebWizardPage, IServiceProvider),
  419. QITABENT(CWebWizardPage, INewWDEvents),
  420. QITABENT(CWebWizardPage, IDispatch),
  421. QITABENT(CWebWizardPage, IWebWizardExtension),
  422. QITABENT(CWebWizardPage, IObjectWithSite),
  423. { 0 },
  424. };
  425. return QISearch(this, qit, riid, ppv);
  426. }
  427. ULONG CWebWizardPage::AddRef()
  428. {
  429. return InterlockedIncrement(&_cRef);
  430. }
  431. ULONG CWebWizardPage::Release()
  432. {
  433. if (InterlockedDecrement(&_cRef))
  434. return _cRef;
  435. delete this;
  436. return 0;
  437. }
  438. HRESULT CWebWizardPage::QueryService(REFGUID guidService, REFIID riid, void **ppv)
  439. {
  440. HRESULT hr = E_NOINTERFACE;
  441. *ppv = NULL;
  442. if (_punkSite)
  443. hr = IUnknown_QueryService(_punkSite, guidService, riid, ppv);
  444. return hr;
  445. }
  446. void CWebWizardPage::_OnDownloadBegin()
  447. {
  448. _ShowBrowser(FALSE);
  449. _StartShowProgressTimer();
  450. SetWizardButtons(VARIANT_FALSE, VARIANT_FALSE, VARIANT_FALSE);
  451. }
  452. void CWebWizardPage::_OnDocumentComplete()
  453. {
  454. if (!_IsScriptFunctionOnPage(_pwebbrowser, L"OnBack"))
  455. {
  456. // This is an invalid page; navigate to our private error page
  457. BSTR bstrOldUrl;
  458. if (_pwebbrowser && SUCCEEDED(_pwebbrowser->get_LocationURL(&bstrOldUrl)))
  459. {
  460. #ifdef DEBUG
  461. if (IDYES == ::MessageBox(_hwnd, L"A Web Service Error has occured.\n\nDo you want to load the HTML page anyway so you can debug it?\n\n(This only appears in debug builds)", bstrOldUrl, MB_ICONERROR | MB_YESNO))
  462. {
  463. _ShowBrowser(TRUE);
  464. SysFreeString(bstrOldUrl);
  465. return;
  466. }
  467. #endif
  468. BSTR bstrUrl = NULL;
  469. BOOL fUsingCustomError = FALSE;
  470. // If we have a custom error URL and we haven't already failed trying
  471. // to navigate to this custom URL...
  472. if ((NULL != _pszErrorURL) &&
  473. (0 != StrCmpI(_pszErrorURL, bstrOldUrl)))
  474. {
  475. // then use the custom URL.
  476. bstrUrl = SysAllocString(_pszErrorURL);
  477. fUsingCustomError = TRUE;
  478. }
  479. else
  480. {
  481. bstrUrl = SysAllocString(L"res://shell32.dll/WebServiceError.htm");
  482. }
  483. if (bstrUrl)
  484. {
  485. _pwebbrowser->Navigate(bstrUrl, NULL, NULL, NULL, NULL);
  486. SysFreeString(bstrUrl);
  487. // Custom error URL will provide its own header and subheader
  488. if (!fUsingCustomError)
  489. {
  490. WCHAR szTitle[256];
  491. LoadString(g_hinst, IDS_WEBDLG_ERRTITLE, szTitle, ARRAYSIZE(szTitle));
  492. #ifdef DEBUG
  493. _SetHeaderText(szTitle, bstrOldUrl);
  494. #else
  495. _SetHeaderText(szTitle, L"");
  496. #endif
  497. }
  498. }
  499. SysFreeString(bstrOldUrl);
  500. }
  501. // else out of memory - oops.
  502. }
  503. else
  504. {
  505. _ShowBrowser(TRUE);
  506. }
  507. }
  508. HRESULT CWebWizardPage::GetHostInfo(DOCHOSTUIINFO *pInfo)
  509. {
  510. ZeroMemory(pInfo, sizeof(*pInfo));
  511. pInfo->cbSize = sizeof(*pInfo);
  512. pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
  513. pInfo->dwFlags = DOCHOSTUIFLAG_DIALOG | DOCHOSTUIFLAG_NO3DBORDER |
  514. DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE | DOCHOSTUIFLAG_THEME |
  515. DOCHOSTUIFLAG_FLAT_SCROLLBAR;
  516. return S_OK;
  517. }
  518. HRESULT CWebWizardPage::GetExternal(IDispatch** ppDispatch)
  519. {
  520. return QueryInterface(IID_PPV_ARG(IDispatch, ppDispatch));
  521. }
  522. INT_PTR CWebWizardPage::DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  523. {
  524. switch (uMsg)
  525. {
  526. HANDLE_MSG(hwndDlg, WM_INITDIALOG, OnInitDialog);
  527. HANDLE_MSG(hwndDlg, WM_DESTROY, OnDestroy);
  528. HANDLE_MSG(hwndDlg, WM_NOTIFY, OnNotify);
  529. HANDLE_MSG(hwndDlg, WM_TIMER, OnTimer);
  530. }
  531. return FALSE;
  532. }
  533. HRESULT CWebWizardPage::_CallScript(IWebBrowser2* pbrowser, LPCWSTR pszFunction)
  534. {
  535. HRESULT hr = E_INVALIDARG;
  536. if (pbrowser)
  537. {
  538. IDispatch* pdocDispatch;
  539. hr = pbrowser->get_Document(&pdocDispatch);
  540. if ((S_OK == hr) && pdocDispatch)
  541. {
  542. IHTMLDocument* pdoc;
  543. hr = pdocDispatch->QueryInterface(IID_PPV_ARG(IHTMLDocument, &pdoc));
  544. if (SUCCEEDED(hr))
  545. {
  546. IDispatch* pdispScript;
  547. hr = pdoc->get_Script(&pdispScript);
  548. if (S_OK == hr)
  549. {
  550. DISPID dispid;
  551. hr = pdispScript->GetIDsOfNames(IID_NULL, const_cast<LPWSTR*>(&pszFunction), 1, LOCALE_SYSTEM_DEFAULT, &dispid);
  552. if (SUCCEEDED(hr))
  553. {
  554. unsigned int uArgErr;
  555. DISPPARAMS dispparams = {0};
  556. hr = pdispScript->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dispparams, NULL, NULL, &uArgErr);
  557. }
  558. pdispScript->Release();
  559. }
  560. else
  561. {
  562. hr = E_FAIL;
  563. }
  564. pdoc->Release();
  565. }
  566. else
  567. {
  568. hr = E_FAIL;
  569. }
  570. pdocDispatch->Release();
  571. }
  572. }
  573. return hr;
  574. }
  575. BOOL CWebWizardPage::_IsScriptFunctionOnPage(IWebBrowser2* pbrowser, LPCWSTR pszFunction)
  576. {
  577. HRESULT hr = E_INVALIDARG;
  578. if (pbrowser)
  579. {
  580. IDispatch* pdocDispatch;
  581. hr = pbrowser->get_Document(&pdocDispatch);
  582. if (S_OK == hr && pdocDispatch)
  583. {
  584. IHTMLDocument* pdoc;
  585. hr = pdocDispatch->QueryInterface(IID_PPV_ARG(IHTMLDocument, &pdoc));
  586. if (SUCCEEDED(hr))
  587. {
  588. IDispatch* pdispScript;
  589. hr = pdoc->get_Script(&pdispScript);
  590. if (S_OK == hr)
  591. {
  592. DISPID dispid;
  593. hr = pdispScript->GetIDsOfNames(IID_NULL, const_cast<LPWSTR*>(&pszFunction), 1, LOCALE_SYSTEM_DEFAULT, &dispid);
  594. pdispScript->Release();
  595. }
  596. else
  597. {
  598. hr = E_FAIL;
  599. }
  600. pdoc->Release();
  601. }
  602. else
  603. {
  604. hr = E_FAIL;
  605. }
  606. pdocDispatch->Release();
  607. }
  608. }
  609. return (S_OK == hr) ? TRUE : FALSE;
  610. }
  611. // Uncomment this to NOT pass the LCID on the URL query string - for testing only.
  612. BOOL CWebWizardPage::OnNotify(HWND hwnd, int idCtrl, LPNMHDR pnmh)
  613. {
  614. switch (pnmh->code)
  615. {
  616. case PSN_SETACTIVE:
  617. {
  618. _SizeProgress();
  619. _ShowProgress(FALSE);
  620. _ShowBrowser(FALSE);
  621. // fetch the high contrast flag, and set accordingly for the HTML to read
  622. // its OK for us to fail setting this into the property bag.
  623. HIGHCONTRAST hc = {sizeof(hc)};
  624. if (SystemParametersInfo(SPI_GETHIGHCONTRAST, sizeof(hc), &hc, 0))
  625. {
  626. VARIANT var = {VT_BOOL};
  627. var.boolVal = (hc.dwFlags & HCF_HIGHCONTRASTON) ? VARIANT_TRUE:VARIANT_FALSE;
  628. put_Property(L"HighContrast", &var);
  629. }
  630. // Position the OCHost window
  631. RECT rectClient;
  632. GetClientRect(hwnd, &rectClient);
  633. SetWindowPos(_hwndOCHost, NULL, 0, 0, rectClient.right, rectClient.bottom, SWP_NOMOVE | SWP_NOOWNERZORDER);
  634. // set the initial URL
  635. if (_pszInitialURL)
  636. {
  637. WCHAR szURLWithLCID[INTERNET_MAX_URL_LENGTH];
  638. LPCWSTR pszFormat = StrChr(_pszInitialURL, L'?') ? L"%s&lcid=%d&langid=%d":L"%s?lcid=%d&langid=%d";
  639. if (wnsprintf(szURLWithLCID, ARRAYSIZE(szURLWithLCID), pszFormat, _pszInitialURL, GetUserDefaultLCID(), GetUserDefaultUILanguage()) > 0)
  640. {
  641. _NavigateBrowser(szURLWithLCID);
  642. }
  643. }
  644. }
  645. break;
  646. // WIZNEXT and WIZBACK don't actually cause a navigation to occur - they instead forward on the message to the
  647. // hosted web page. Real wizard navigations occur when the hosted web page calls our FinalBack() and FinalNext() methods.
  648. case PSN_WIZNEXT:
  649. _CallScript(_pwebbrowser, L"OnNext");
  650. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1);
  651. return TRUE;
  652. case PSN_WIZBACK:
  653. _CallScript(_pwebbrowser, L"OnBack");
  654. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LONG_PTR) -1);
  655. return TRUE;
  656. // query cancel results in a call to the site to determine if we are going
  657. // to cancel out and if the site wants to provide a page for us to navigate
  658. // to - in some cases, eg. the web publishing wizard this is important
  659. // so that we can cancel the order being processed etc.
  660. case PSN_QUERYCANCEL:
  661. if (_punkSite)
  662. {
  663. IWizardSite *pws;
  664. if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
  665. {
  666. HPROPSHEETPAGE hpage;
  667. if (S_OK == pws->GetCancelledPage(&hpage))
  668. {
  669. PropSheet_SetCurSel(GetParent(hwnd), hpage, -1);
  670. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, (LPARAM)TRUE);
  671. }
  672. pws->Release();
  673. }
  674. }
  675. return TRUE;
  676. case PSN_TRANSLATEACCELERATOR:
  677. {
  678. LPPSHNOTIFY ppsn = (LPPSHNOTIFY)pnmh;
  679. MSG *pmsg = (MSG *)ppsn->lParam;
  680. LONG_PTR lres = PSNRET_NOERROR;
  681. if (_poipao && S_OK == _poipao->TranslateAccelerator(pmsg))
  682. {
  683. lres = PSNRET_MESSAGEHANDLED;
  684. }
  685. SetWindowLongPtr(hwnd, DWLP_MSGRESULT, lres);
  686. }
  687. break;
  688. }
  689. return TRUE;
  690. }
  691. BOOL CWebWizardPage::OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam)
  692. {
  693. _hwnd = hwnd;
  694. _hwndFrame = GetParent(hwnd);
  695. // lets remap some of the text in the dialog if we need to
  696. IResourceMap *prm;
  697. HRESULT hr = IUnknown_QueryService(_punkSite, SID_ResourceMap, IID_PPV_ARG(IResourceMap, &prm));
  698. if (SUCCEEDED(hr))
  699. {
  700. IXMLDOMNode *pdn;
  701. hr = prm->SelectResourceScope(TEXT("dialog"), TEXT("ws:downloading"), &pdn);
  702. if (SUCCEEDED(hr))
  703. {
  704. TCHAR szBuffer[512];
  705. if (SUCCEEDED(prm->LoadString(pdn, TEXT("header"), szBuffer, ARRAYSIZE(szBuffer))))
  706. {
  707. SetDlgItemText(hwnd, IDC_PROGTEXT1, szBuffer);
  708. }
  709. if (SUCCEEDED(prm->LoadString(pdn, TEXT("footer"), szBuffer, ARRAYSIZE(szBuffer))))
  710. {
  711. SetDlgItemText(hwnd, IDC_PROGTEXT2, szBuffer);
  712. }
  713. pdn->Release();
  714. }
  715. prm->Release();
  716. }
  717. // create the web view browser that we will show the providers HTML in
  718. SHDRC shdrc = {0};
  719. shdrc.cbSize = sizeof(shdrc);
  720. shdrc.dwFlags = SHDRCF_OCHOST;
  721. if (SHDOCVW_DllRegisterWindowClasses(&shdrc))
  722. {
  723. RECT rectClient;
  724. GetClientRect(hwnd, &rectClient);
  725. _hwndOCHost = CreateWindow(OCHOST_CLASS, NULL,
  726. WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_TABSTOP,
  727. 0, 0, rectClient.right, rectClient.bottom,
  728. hwnd, NULL, g_hinst, NULL);
  729. if (_hwndOCHost)
  730. {
  731. OCHINITSTRUCT ocs = {0};
  732. ocs.cbSize = sizeof(ocs);
  733. ocs.clsidOC = CLSID_WebBrowser;
  734. ocs.punkOwner = SAFECAST(this, IDocHostUIHandler*);
  735. hr = OCHost_InitOC(_hwndOCHost, (LPARAM)&ocs);
  736. if (SUCCEEDED(hr))
  737. {
  738. _InitBrowser();
  739. OCHost_DoVerb(_hwndOCHost, OLEIVERB_INPLACEACTIVATE, TRUE);
  740. ShowWindow(_hwndOCHost, TRUE);
  741. IServiceProvider* pSP;
  742. hr = _pwebEventHandler->QueryInterface(IID_PPV_ARG(IServiceProvider, &pSP));
  743. if (SUCCEEDED(hr))
  744. {
  745. OCHost_SetServiceProvider(_hwndOCHost, pSP);
  746. pSP->Release();
  747. }
  748. }
  749. }
  750. }
  751. if (FAILED(hr))
  752. EndDialog(hwnd, IDCANCEL);
  753. return TRUE;
  754. }
  755. BOOL CWebWizardPage::OnTimer(HWND hwnd, UINT nIDEvent)
  756. {
  757. if (nIDEvent == SHOW_PROGRESS_TIMER)
  758. {
  759. _ShowProgress(TRUE);
  760. }
  761. return TRUE;
  762. }
  763. BOOL CWebWizardPage::OnDestroy(HWND hwnd)
  764. {
  765. ATOMICRELEASE(_pwebbrowser);
  766. return TRUE;
  767. }
  768. void CWebWizardPage::_InitBrowser(void)
  769. {
  770. ASSERT(IsWindow(_hwndOCHost));
  771. ASSERT(!_pwebbrowser);
  772. HRESULT hr = OCHost_QueryInterface(_hwndOCHost, IID_PPV_ARG(IWebBrowser2, &_pwebbrowser));
  773. if (SUCCEEDED(hr) && _pwebbrowser)
  774. {
  775. ITargetFrame2* ptgf;
  776. if (SUCCEEDED(_pwebbrowser->QueryInterface(IID_PPV_ARG(ITargetFrame2, &ptgf))))
  777. {
  778. DWORD dwOptions;
  779. if (SUCCEEDED(ptgf->GetFrameOptions(&dwOptions)))
  780. {
  781. dwOptions |= FRAMEOPTIONS_BROWSERBAND | FRAMEOPTIONS_SCROLL_AUTO;
  782. ptgf->SetFrameOptions(dwOptions);
  783. }
  784. ptgf->Release();
  785. }
  786. _pwebbrowser->put_RegisterAsDropTarget(VARIANT_FALSE);
  787. // Set up the connection point (including creating the object
  788. if (!_pwebEventHandler)
  789. CWebEventHandler_CreateInstance(this, &_pwebEventHandler);
  790. if (_pwebEventHandler)
  791. _pwebEventHandler->_Advise(TRUE);
  792. OCHost_QueryInterface(_hwndOCHost, IID_PPV_ARG(IOleInPlaceActiveObject, &_poipao));
  793. }
  794. }
  795. HRESULT CWebWizardPage::_NavigateBrowser(LPCWSTR pszUrl)
  796. {
  797. HRESULT hr = E_FAIL;
  798. if (_hwndOCHost && _pwebbrowser)
  799. {
  800. BSTR bstrUrl = SysAllocString(pszUrl);
  801. if (bstrUrl)
  802. {
  803. hr = _pwebbrowser->Navigate(bstrUrl, NULL, NULL, NULL, NULL);
  804. SysFreeString(bstrUrl);
  805. }
  806. }
  807. return hr;
  808. }
  809. HRESULT CWebWizardPage::FinalBack(void)
  810. {
  811. if (_punkSite)
  812. {
  813. IWizardSite *pws;
  814. if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
  815. {
  816. HPROPSHEETPAGE hpage;
  817. HRESULT hr = pws->GetPreviousPage(&hpage);
  818. if (SUCCEEDED(hr))
  819. {
  820. PropSheet_SetCurSel(_hwndFrame, hpage, -1);
  821. }
  822. pws->Release();
  823. }
  824. }
  825. return S_OK;
  826. }
  827. HRESULT CWebWizardPage::FinalNext(void)
  828. {
  829. if (_punkSite)
  830. {
  831. IWizardSite *pws;
  832. if (SUCCEEDED(_punkSite->QueryInterface(IID_PPV_ARG(IWizardSite, &pws))))
  833. {
  834. HPROPSHEETPAGE hpage;
  835. HRESULT hr = pws->GetNextPage(&hpage);
  836. if (SUCCEEDED(hr))
  837. {
  838. PropSheet_SetCurSel(_hwndFrame, hpage, -1);
  839. }
  840. pws->Release();
  841. }
  842. }
  843. return S_OK;
  844. }
  845. HRESULT CWebWizardPage::Cancel(void)
  846. {
  847. PropSheet_PressButton(_hwndFrame, PSBTN_CANCEL); // simulate cancel...
  848. return S_OK;
  849. }
  850. HRESULT CWebWizardPage::put_Caption(
  851. /* [in] */ BSTR bstrCaption)
  852. {
  853. return S_OK;
  854. }
  855. HRESULT CWebWizardPage::get_Caption(
  856. /* [retval][out] */ BSTR *pbstrCaption)
  857. {
  858. WCHAR szCaption[MAX_PATH];
  859. GetWindowText(_hwndFrame, szCaption, ARRAYSIZE(szCaption));
  860. *pbstrCaption = SysAllocString(szCaption);
  861. return S_OK;
  862. }
  863. // fetch and put properties into the frames property bag. this we do
  864. // by a QueryService call and then we can modify the properties accordingly.
  865. HRESULT CWebWizardPage::put_Property(
  866. /* [in] */ BSTR bstrPropertyName,
  867. /* [in] */ VARIANT *pvProperty)
  868. {
  869. IPropertyBag *ppb;
  870. HRESULT hr = IUnknown_QueryService(_punkSite, SID_WebWizardHost, IID_PPV_ARG(IPropertyBag, &ppb));
  871. if (SUCCEEDED(hr))
  872. {
  873. hr = ppb->Write(bstrPropertyName, pvProperty);
  874. ppb->Release();
  875. }
  876. return hr;
  877. }
  878. HRESULT CWebWizardPage::get_Property(
  879. /* [in] */ BSTR bstrPropertyName,
  880. /* [retval][out] */ VARIANT *pvProperty)
  881. {
  882. IPropertyBag *ppb;
  883. HRESULT hr = IUnknown_QueryService(_punkSite, SID_WebWizardHost, IID_PPV_ARG(IPropertyBag, &ppb));
  884. if (SUCCEEDED(hr))
  885. {
  886. hr = ppb->Read(bstrPropertyName, pvProperty, NULL);
  887. if (FAILED(hr))
  888. {
  889. // Return a NULL-variant
  890. VariantInit(pvProperty);
  891. pvProperty->vt = VT_NULL;
  892. hr = S_FALSE;
  893. }
  894. ppb->Release();
  895. }
  896. return hr;
  897. }
  898. HRESULT CWebWizardPage::SetWizardButtons(
  899. /* [in] */ VARIANT_BOOL vfEnableBack,
  900. /* [in] */ VARIANT_BOOL vfEnableNext,
  901. /* [in] */ VARIANT_BOOL vfLastPage)
  902. {
  903. // We ignore vfLastPage because it isn't the last page for us!
  904. DWORD dwButtons = 0;
  905. if (vfEnableBack)
  906. dwButtons |= PSWIZB_BACK;
  907. if (vfEnableNext)
  908. dwButtons |= PSWIZB_NEXT;
  909. PropSheet_SetWizButtons(_hwndFrame, dwButtons);
  910. return S_OK;
  911. }
  912. void CWebWizardPage::_SetHeaderText(LPCWSTR pszHeader, LPCWSTR pszSubHeader)
  913. {
  914. int iPageNumber = PropSheet_HwndToIndex(_hwndFrame, _hwnd);
  915. if (-1 != iPageNumber)
  916. {
  917. PropSheet_SetHeaderTitle(_hwndFrame, iPageNumber, pszHeader);
  918. PropSheet_SetHeaderSubTitle(_hwndFrame, iPageNumber, pszSubHeader);
  919. }
  920. }
  921. HRESULT CWebWizardPage::SetHeaderText(
  922. /* [in] */ BSTR bstrHeaderTitle,
  923. /* [in] */ BSTR bstrHeaderSubtitle)
  924. {
  925. _SetHeaderText(bstrHeaderTitle, bstrHeaderSubtitle);
  926. return S_OK;
  927. }
  928. HRESULT CWebWizardPage::PassportAuthenticate(
  929. /* [in] */ BSTR bstrURL,
  930. /* [retval][out] */ VARIANT_BOOL * pfAuthenticated)
  931. {
  932. *pfAuthenticated = VARIANT_FALSE; // the user isn't authenticated.
  933. IXMLHttpRequest *preq;
  934. HRESULT hr = CoCreateInstance(CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IXMLHttpRequest, &preq));
  935. if (SUCCEEDED(hr))
  936. {
  937. VARIANT varNULL = {0};
  938. VARIANT varAsync = {VT_BOOL};
  939. varAsync.boolVal = VARIANT_FALSE;
  940. // open a post request to the destination that we have
  941. hr = preq->open(L"GET", bstrURL, varAsync, varNULL, varNULL);
  942. if (SUCCEEDED(hr))
  943. {
  944. VARIANT varBody = {0};
  945. hr = preq->send(varBody);
  946. if (SUCCEEDED(hr))
  947. {
  948. long lStatus;
  949. hr = preq->get_status(&lStatus);
  950. if (SUCCEEDED(hr) && (lStatus == HTTP_STATUS_OK))
  951. {
  952. *pfAuthenticated = VARIANT_TRUE;
  953. }
  954. }
  955. }
  956. }
  957. return S_OK;
  958. }
  959. BOOL CWebWizardPage::_IsBrowserVisible()
  960. {
  961. return IsWindowVisible(_hwndOCHost);
  962. }
  963. void CWebWizardPage::_ShowBrowser(BOOL fShow)
  964. {
  965. ShowWindow(_hwndOCHost, fShow ? SW_SHOW : SW_HIDE);
  966. if (fShow)
  967. {
  968. // Can't have these windows overlapping.
  969. _ShowProgress(FALSE);
  970. }
  971. }
  972. void CWebWizardPage::_StartShowProgressTimer()
  973. {
  974. _ShowProgress(FALSE);
  975. if (!SetTimer(_hwnd, SHOW_PROGRESS_TIMER, SHOW_PROGRESS_TIMEOUT, NULL))
  976. {
  977. // Timer failed to set; show progress now;
  978. _ShowProgress(TRUE);
  979. }
  980. }
  981. // Size the progress bar to fit the client area it is in.
  982. void CWebWizardPage::_SizeProgress()
  983. {
  984. HWND hwndProgress = GetDlgItem(_hwnd, IDC_PROGRESS);
  985. RECT rcPage;
  986. GetClientRect(_hwnd, &rcPage);
  987. RECT rcProgress;
  988. GetClientRect(hwndProgress, &rcProgress);
  989. MapWindowPoints(hwndProgress, _hwnd, (LPPOINT) &rcProgress, 2);
  990. rcProgress.right = rcPage.right - rcProgress.left;
  991. SetWindowPos(hwndProgress, NULL, 0, 0, rcProgress.right - rcProgress.left, rcProgress.bottom - rcProgress.top, SWP_NOMOVE | SWP_NOZORDER | SWP_NOREPOSITION);
  992. }
  993. void CWebWizardPage::_ShowProgress(BOOL fShow)
  994. {
  995. HWND hwndProgress = GetDlgItem(_hwnd, IDC_PROGRESS);
  996. ShowWindow(hwndProgress, fShow ? SW_SHOW : SW_HIDE);
  997. ShowWindow(GetDlgItem(_hwnd, IDC_PROGTEXT1), fShow ? SW_SHOW : SW_HIDE);
  998. ShowWindow(GetDlgItem(_hwnd, IDC_PROGTEXT2), fShow ? SW_SHOW : SW_HIDE);
  999. KillTimer(_hwnd, SHOW_PROGRESS_TIMER);
  1000. if (fShow)
  1001. {
  1002. SendMessage(hwndProgress, PBM_SETMARQUEE, (WPARAM) TRUE, 0);
  1003. // Set the header/subheader to a "Connecting to Internet" message.
  1004. WCHAR szTitle[256];
  1005. WCHAR szSubtitle[256];
  1006. LoadString(g_hinst, IDS_WEBDLG_TITLE, szTitle, ARRAYSIZE(szTitle));
  1007. LoadString(g_hinst, IDS_WEBDLG_SUBTITLE, szSubtitle, ARRAYSIZE(szSubtitle));
  1008. _SetHeaderText(szTitle, szSubtitle);
  1009. }
  1010. else
  1011. {
  1012. SendMessage(hwndProgress, PBM_SETMARQUEE, (WPARAM) FALSE, 0);
  1013. }
  1014. }
  1015. // IWizardExtn
  1016. UINT CWebWizardPage::PropPageProc(HWND hwndDlg, UINT uMsg, PROPSHEETPAGE *ppsp)
  1017. {
  1018. CWebWizardPage *pwwp = (CWebWizardPage*)ppsp->lParam;
  1019. switch (uMsg)
  1020. {
  1021. case PSPCB_CREATE:
  1022. return TRUE;
  1023. // we need to release our site in this scenario, we know that we won't be using it
  1024. // anymore, and to ensure that clients down have a circular refernce to us we
  1025. // release it before they call us for our final destruction.
  1026. case PSPCB_RELEASE:
  1027. ATOMICRELEASE(pwwp->_punkSite);
  1028. break;
  1029. }
  1030. return FALSE;
  1031. }
  1032. HRESULT CWebWizardPage::AddPages(HPROPSHEETPAGE* aPages, UINT cPages, UINT *pnPages)
  1033. {
  1034. PROPSHEETPAGE psp = { 0 };
  1035. psp.dwSize = sizeof(psp);
  1036. psp.hInstance = g_hinst;
  1037. psp.dwFlags = PSP_DEFAULT|PSP_USECALLBACK ;
  1038. psp.pszTemplate = MAKEINTRESOURCE(DLG_WEBWIZARD);
  1039. psp.lParam = (LPARAM) this;
  1040. psp.pfnDlgProc = CWebWizardPage::StaticProc;
  1041. psp.pfnCallback = PropPageProc;
  1042. _hPage = CreatePropertySheetPage(&psp);
  1043. if (!_hPage)
  1044. return E_FAIL;
  1045. // return the page we created.
  1046. *aPages = _hPage;
  1047. *pnPages = 1;
  1048. return S_OK;
  1049. }
  1050. STDMETHODIMP CWebWizardPage::GetFirstPage(HPROPSHEETPAGE *phPage)
  1051. {
  1052. *phPage = _hPage;
  1053. return S_OK;
  1054. }
  1055. STDMETHODIMP CWebWizardPage::SetInitialURL(LPCWSTR pszDefaultURL)
  1056. {
  1057. HRESULT hr = E_INVALIDARG;
  1058. if (pszDefaultURL)
  1059. {
  1060. hr = Str_SetPtr(&_pszInitialURL, pszDefaultURL) ? S_OK:E_OUTOFMEMORY;
  1061. }
  1062. return hr;
  1063. }
  1064. STDMETHODIMP CWebWizardPage::SetErrorURL(LPCWSTR pszErrorURL)
  1065. {
  1066. HRESULT hr = E_INVALIDARG;
  1067. if (pszErrorURL)
  1068. {
  1069. hr = Str_SetPtr(&_pszErrorURL, pszErrorURL) ? S_OK:E_OUTOFMEMORY;
  1070. }
  1071. return hr;
  1072. }
  1073. STDAPI CWebWizardPage_CreateInstance(IUnknown* pUnkOuter, REFIID riid, void **ppv)
  1074. {
  1075. if (NULL != pUnkOuter)
  1076. {
  1077. return CLASS_E_NOAGGREGATION;
  1078. }
  1079. CWebWizardPage *pwwp = new CWebWizardPage();
  1080. if (!pwwp)
  1081. {
  1082. return E_OUTOFMEMORY;
  1083. }
  1084. HRESULT hr = pwwp->QueryInterface(riid, ppv);
  1085. pwwp->Release();
  1086. return hr;
  1087. }