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.

936 lines
24 KiB

  1. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  2. //
  3. // proppgs.cpp
  4. //
  5. // IShellPropSheetExt for channel shortcuts.
  6. //
  7. // History:
  8. //
  9. // 6/12/97 edwardp Created.
  10. //
  11. // Note: The hotkey stuff is comment out, the shell/windows doesn't make it
  12. // possible to persist hotkey settings across sessions and it isn't
  13. // worth kicking off another thread at boot to enable this feature.
  14. //
  15. ////////////////////////////////////////////////////////////////////////////////
  16. //
  17. // Includes
  18. //
  19. #include "stdinc.h"
  20. #include "cdfidl.h"
  21. #include "persist.h"
  22. #include "cdfview.h"
  23. #include "proppgs.h"
  24. #include "xmlutil.h"
  25. #include "dll.h"
  26. #include "iconhand.h"
  27. #include "resource.h"
  28. #include "winineti.h"
  29. #include <iehelpid.h>
  30. #include <mluisupp.h>
  31. #pragma warning(disable:4800)
  32. //
  33. // Constructor and destructor.
  34. //
  35. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  36. //
  37. // *** CPropertyPages::CPropertyPages ***
  38. //
  39. // Constructor for CPropertyPages.
  40. //
  41. ////////////////////////////////////////////////////////////////////////////////
  42. CPropertyPages::CPropertyPages (
  43. void
  44. )
  45. : m_cRef(1)
  46. {
  47. ASSERT(NULL == m_pSubscriptionMgr2);
  48. ASSERT(NULL == m_pInitDataObject);
  49. TraceMsg(TF_OBJECTS, "+ IShellPropSheetExt");
  50. DllAddRef();
  51. return;
  52. }
  53. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  54. //
  55. // *** CPropertyPages::~CPropertyPages ***
  56. //
  57. // Destructor.
  58. //
  59. ////////////////////////////////////////////////////////////////////////////////
  60. CPropertyPages::~CPropertyPages (
  61. void
  62. )
  63. {
  64. if (m_pSubscriptionMgr2)
  65. m_pSubscriptionMgr2->Release();
  66. if (m_pInitDataObject)
  67. m_pInitDataObject->Release();
  68. ASSERT(0 == m_cRef);
  69. //
  70. // Matching Release for the constructor Addref.
  71. //
  72. TraceMsg(TF_OBJECTS, "- IShellPropSheetExt");
  73. DllRelease();
  74. return;
  75. }
  76. //
  77. // IUnknown methods.
  78. //
  79. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  80. //
  81. // *** CPropertyPages::QueryInterface ***
  82. //
  83. // CPropertyPages QI.
  84. //
  85. ////////////////////////////////////////////////////////////////////////////////
  86. STDMETHODIMP
  87. CPropertyPages::QueryInterface (
  88. REFIID riid,
  89. void **ppv
  90. )
  91. {
  92. ASSERT(ppv);
  93. HRESULT hr;
  94. *ppv = NULL;
  95. if (IID_IUnknown == riid || IID_IShellPropSheetExt == riid)
  96. {
  97. *ppv = (IShellPropSheetExt*)this;
  98. }
  99. else if (IID_IShellExtInit == riid)
  100. {
  101. *ppv = (IShellExtInit*)this;
  102. }
  103. if (*ppv)
  104. {
  105. ((IUnknown*)*ppv)->AddRef();
  106. hr = S_OK;
  107. }
  108. else
  109. {
  110. hr = E_NOINTERFACE;
  111. }
  112. ASSERT((SUCCEEDED(hr) && *ppv) || (FAILED(hr) && NULL == *ppv));
  113. return hr;
  114. }
  115. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  116. //
  117. // *** CPropertyPages::AddRef ***
  118. //
  119. // CPropertyPages AddRef.
  120. //
  121. ////////////////////////////////////////////////////////////////////////////////
  122. STDMETHODIMP_(ULONG)
  123. CPropertyPages::AddRef (
  124. void
  125. )
  126. {
  127. ASSERT(m_cRef != 0);
  128. ASSERT(m_cRef < (ULONG)-1);
  129. return ++m_cRef;
  130. }
  131. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  132. //
  133. // *** CPropertyPages::Release ***
  134. //
  135. // CContextMenu Release.
  136. //
  137. ////////////////////////////////////////////////////////////////////////////////
  138. STDMETHODIMP_(ULONG)
  139. CPropertyPages::Release (
  140. void
  141. )
  142. {
  143. ASSERT (m_cRef != 0);
  144. ULONG cRef = --m_cRef;
  145. if (0 == cRef)
  146. delete this;
  147. return cRef;
  148. }
  149. //
  150. // IShellPropSheetExt methods.
  151. //
  152. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  153. //
  154. // *** Name ***
  155. //
  156. //
  157. // Description:
  158. //
  159. //
  160. // Parameters:
  161. //
  162. //
  163. // Return:
  164. //
  165. //
  166. // Comments:
  167. //
  168. //
  169. ////////////////////////////////////////////////////////////////////////////////
  170. STDMETHODIMP
  171. CPropertyPages::AddPages(
  172. LPFNADDPROPSHEETPAGE lpfnAddPage,
  173. LPARAM lParam
  174. )
  175. {
  176. HRESULT hr = S_OK;
  177. PROPSHEETPAGE psp;
  178. psp.dwSize = sizeof(PROPSHEETPAGE);
  179. psp.dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
  180. psp.hInstance = MLGetHinst();
  181. psp.pszTemplate = MAKEINTRESOURCE(IDD_CHANNEL_PROP);
  182. psp.hIcon = NULL;
  183. psp.pszTitle = NULL;
  184. psp.pfnDlgProc = PropSheetDlgProc;
  185. psp.lParam = (LPARAM)(CPropertyPages *)this;
  186. psp.pfnCallback = PropSheetCallback;
  187. HPROPSHEETPAGE hpage = CreatePropertySheetPage(&psp);
  188. if (hpage)
  189. {
  190. // Release() happens in PropSheetCallback.
  191. AddRef();
  192. // Assume the mess below doesn't work, we want the default page to be us.
  193. hr = 1;
  194. // HACKHACK: This code attempts to remove the Folder property pages such as
  195. // General and Sharing (it will also whack any 3rd party pages which were
  196. // unfortunate enough to have been loaded before use :)
  197. PROPSHEETHEADER *ppsh = (PROPSHEETHEADER *)lParam;
  198. // First make sure we can safely access the memory as if it were a
  199. // PROPSHEETHEADER structure.
  200. if (!IsBadReadPtr(ppsh, PROPSHEETHEADER_V1_SIZE) &&
  201. !IsBadWritePtr(ppsh, PROPSHEETHEADER_V1_SIZE))
  202. {
  203. // Now see if the module matches shell32
  204. if (ppsh->hInstance == GetModuleHandle(TEXT("shell32.dll")))
  205. {
  206. // looks good so rip 'em out
  207. for (UINT i = 0; i < ppsh->nPages; i++)
  208. {
  209. // At least be a good citizen and delete their pages so we
  210. // don't leak
  211. DestroyPropertySheetPage(ppsh->phpage[i]);
  212. }
  213. ppsh->nPages = 0;
  214. // Now we shouldn't need to mess with the default page. If someone
  215. // loads after us, we may not win.
  216. hr = 0;
  217. }
  218. }
  219. if (lpfnAddPage(hpage, lParam))
  220. {
  221. WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  222. SHTCharToUnicode(m_szURL, wszURL, ARRAYSIZE(wszURL));
  223. if (SUCCEEDED(InitializeSubsMgr2()))
  224. {
  225. m_pSubscriptionMgr2->IsSubscribed(wszURL, &m_bStartSubscribed);
  226. if (m_bStartSubscribed)
  227. {
  228. IShellPropSheetExt *pspse;
  229. if (SUCCEEDED(m_pSubscriptionMgr2->QueryInterface(IID_IShellPropSheetExt,
  230. (void **)&pspse)))
  231. {
  232. pspse->AddPages(lpfnAddPage, lParam);
  233. pspse->Release();
  234. }
  235. }
  236. }
  237. }
  238. else
  239. {
  240. DestroyPropertySheetPage(hpage);
  241. hr = E_FAIL;
  242. }
  243. }
  244. else
  245. {
  246. hr = E_OUTOFMEMORY;
  247. }
  248. return hr;
  249. }
  250. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  251. //
  252. // *** Name ***
  253. //
  254. //
  255. // Description:
  256. //
  257. //
  258. // Parameters:
  259. //
  260. //
  261. // Return:
  262. //
  263. //
  264. // Comments:
  265. //
  266. //
  267. ////////////////////////////////////////////////////////////////////////////////
  268. STDMETHODIMP
  269. CPropertyPages::ReplacePage(
  270. UINT uPageID,
  271. LPFNADDPROPSHEETPAGE lpfnAddPage,
  272. LPARAM lParam
  273. )
  274. {
  275. return E_NOTIMPL;
  276. }
  277. //
  278. // IShellExtInit methods.
  279. //
  280. //\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\//\\
  281. //
  282. // *** Name ***
  283. //
  284. //
  285. // Description:
  286. //
  287. //
  288. // Parameters:
  289. //
  290. //
  291. // Return:
  292. //
  293. //
  294. // Comments:
  295. //
  296. //
  297. ////////////////////////////////////////////////////////////////////////////////
  298. STDMETHODIMP
  299. CPropertyPages::Initialize(
  300. LPCITEMIDLIST pidl,
  301. LPDATAOBJECT pIDataObject,
  302. HKEY hkey
  303. )
  304. {
  305. HRESULT hr;
  306. STGMEDIUM stgmed;
  307. FORMATETC fmtetc = {CF_HDROP, NULL, DVASPECT_CONTENT, -1,
  308. TYMED_HGLOBAL};
  309. if (m_pInitDataObject)
  310. m_pInitDataObject->Release();
  311. m_pInitDataObject = pIDataObject;
  312. m_pInitDataObject->AddRef();
  313. hr = pIDataObject->GetData(&fmtetc, &stgmed);
  314. if (SUCCEEDED(hr))
  315. {
  316. if (DragQueryFile((HDROP)stgmed.hGlobal, 0, m_szPath,
  317. ARRAYSIZE(m_szPath)))
  318. {
  319. TCHAR szDesktopINI[MAX_PATH];
  320. PathCombine(szDesktopINI, m_szPath, c_szDesktopINI);
  321. GetPrivateProfileString(c_szChannel, c_szCDFURL, TEXT(""), m_szURL,
  322. ARRAYSIZE(m_szURL), szDesktopINI);
  323. //m_wHotkey = GetPrivateProfileInt(c_szChannel, c_szHotkey, 0, szDesktopINI);
  324. }
  325. else
  326. {
  327. hr = E_FAIL;
  328. }
  329. ReleaseStgMedium(&stgmed);
  330. }
  331. return hr;
  332. }
  333. //
  334. // Helper functions
  335. //
  336. HRESULT CPropertyPages::InitializeSubsMgr2()
  337. {
  338. HRESULT hr = E_FAIL;
  339. #ifndef UNIX
  340. if (NULL != m_pSubscriptionMgr2)
  341. {
  342. hr = S_OK;
  343. }
  344. else
  345. {
  346. hr = CoInitialize(NULL);
  347. if (SUCCEEDED(hr))
  348. {
  349. DLL_ForcePreloadDlls(PRELOAD_WEBCHECK);
  350. hr = CoCreateInstance(CLSID_SubscriptionMgr, NULL,
  351. CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr2,
  352. (void**)&m_pSubscriptionMgr2);
  353. if (SUCCEEDED(hr))
  354. {
  355. IShellExtInit* pIShellExtInit;
  356. hr = m_pSubscriptionMgr2->QueryInterface(IID_IShellExtInit,
  357. (void **)&pIShellExtInit);
  358. if (SUCCEEDED(hr))
  359. {
  360. hr = pIShellExtInit->Initialize(NULL, m_pInitDataObject, NULL);
  361. pIShellExtInit->Release();
  362. }
  363. }
  364. }
  365. CoUninitialize();
  366. }
  367. #endif /* !UNIX */
  368. return hr;
  369. }
  370. void CPropertyPages::ShowOfflineSummary(HWND hdlg, BOOL bShow)
  371. {
  372. static const int offSumIDs[] =
  373. {
  374. IDC_SUMMARY,
  375. IDC_LAST_SYNC_TEXT,
  376. IDC_LAST_SYNC,
  377. IDC_DOWNLOAD_SIZE_TEXT,
  378. IDC_DOWNLOAD_SIZE,
  379. IDC_DOWNLOAD_RESULT,
  380. IDC_DOWNLOAD_RESULT_TEXT,
  381. IDC_FREE_SPACE_TEXT
  382. };
  383. if (bShow)
  384. {
  385. TCHAR szLastSync[128];
  386. TCHAR szDownloadSize[128];
  387. TCHAR szDownloadResult[128];
  388. WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  389. MLLoadString(IDS_VALUE_UNKNOWN, szLastSync, ARRAYSIZE(szLastSync));
  390. StrCpyN(szDownloadSize, szLastSync, ARRAYSIZE(szDownloadSize));
  391. StrCpyN(szDownloadResult, szLastSync, ARRAYSIZE(szDownloadResult));
  392. SHTCharToUnicode(m_szURL, wszURL, ARRAYSIZE(wszURL));
  393. ASSERT(NULL != m_pSubscriptionMgr2);
  394. if (NULL != m_pSubscriptionMgr2)
  395. {
  396. ISubscriptionItem *psi;
  397. if (SUCCEEDED(m_pSubscriptionMgr2->GetItemFromURL(wszURL, &psi)))
  398. {
  399. enum { spLastSync, spDownloadSize, spDownloadResult };
  400. static const LPCWSTR pProps[] =
  401. {
  402. c_szPropCompletionTime,
  403. c_szPropCrawlActualSize,
  404. c_szPropStatusString
  405. };
  406. VARIANT vars[ARRAYSIZE(pProps)];
  407. if (SUCCEEDED(psi->ReadProperties(ARRAYSIZE(pProps), pProps, vars)))
  408. {
  409. if (VT_DATE == vars[spLastSync].vt)
  410. {
  411. FILETIME ft, ft2;
  412. DWORD dwFlags = FDTF_DEFAULT;
  413. SYSTEMTIME st;
  414. VariantTimeToSystemTime(vars[spLastSync].date, &st);
  415. SystemTimeToFileTime(&st, &ft);
  416. LocalFileTimeToFileTime(&ft, &ft2);
  417. SHFormatDateTime(&ft2, &dwFlags, szLastSync, ARRAYSIZE(szLastSync));
  418. }
  419. if (VT_I4 == vars[spDownloadSize].vt)
  420. {
  421. StrFormatByteSize(vars[spDownloadSize].lVal * 1024,
  422. szDownloadSize, ARRAYSIZE(szDownloadSize));
  423. }
  424. if (VT_BSTR == vars[spDownloadResult].vt)
  425. {
  426. #ifdef UNICODE
  427. wnsprintf(szDownloadResult, ARRAYSIZE(szDownloadResult),
  428. TEXT("%s"), vars[spDownloadResult].bstrVal);
  429. #else
  430. wnsprintf(szDownloadResult, ARRAYSIZE(szDownloadResult),
  431. TEXT("%S"), vars[spDownloadResult].bstrVal);
  432. #endif
  433. }
  434. for (int i = 0; i < ARRAYSIZE(pProps); i++)
  435. {
  436. VariantClear(&vars[i]);
  437. }
  438. }
  439. psi->Release();
  440. }
  441. }
  442. SetDlgItemText(hdlg, IDC_LAST_SYNC, szLastSync);
  443. SetDlgItemText(hdlg, IDC_DOWNLOAD_SIZE, szDownloadSize);
  444. SetDlgItemText(hdlg, IDC_DOWNLOAD_RESULT, szDownloadResult);
  445. }
  446. for (int i = 0; i < ARRAYSIZE(offSumIDs); i++)
  447. {
  448. ShowWindow(GetDlgItem(hdlg, offSumIDs[i]), bShow ? SW_SHOW : SW_HIDE);
  449. }
  450. }
  451. BOOL CPropertyPages::OnInitDialog(HWND hdlg)
  452. {
  453. TCHAR szName[MAX_PATH];
  454. HICON hicon = NULL;
  455. HRESULT hr;
  456. CIconHandler *pIconHandler = new CIconHandler;
  457. if (pIconHandler)
  458. {
  459. if (SUCCEEDED(pIconHandler->Load(m_szPath, 0)))
  460. {
  461. TCHAR szIconFile[MAX_PATH];
  462. int iIndex;
  463. UINT wFlags;
  464. if (SUCCEEDED(pIconHandler->GetIconLocation(0, szIconFile, ARRAYSIZE(szIconFile),
  465. &iIndex, &wFlags)))
  466. {
  467. HICON hiconScrap = NULL;
  468. hr = pIconHandler->Extract(szIconFile, iIndex, &hicon, &hiconScrap,
  469. MAKELONG(GetSystemMetrics(SM_CXICON),
  470. GetSystemMetrics(SM_CXSMICON)));
  471. if (S_FALSE == hr)
  472. {
  473. // Do it ourselves
  474. hicon = ExtractIcon(g_hinst, szIconFile, iIndex);
  475. }
  476. else if ((NULL != hiconScrap) && (hicon != hiconScrap))
  477. {
  478. // Otherwise cleanup unwanted little icon
  479. DestroyIcon(hiconScrap);
  480. }
  481. }
  482. }
  483. pIconHandler->Release();
  484. }
  485. if (NULL == hicon)
  486. {
  487. hicon = LoadIcon(g_hinst, MAKEINTRESOURCE(IDI_CHANNEL));
  488. }
  489. BOOL bEnableMakeOffline = TRUE;
  490. SendDlgItemMessage(hdlg, IDC_ICONEX2, STM_SETICON, (WPARAM)hicon, 0);
  491. StrCpyN(szName, m_szPath, ARRAYSIZE(szName));
  492. PathStripPath(szName);
  493. SetDlgItemText(hdlg, IDC_NAME, szName);
  494. SetDlgItemText(hdlg, IDC_URL, m_szURL);
  495. TCHAR szVisits[256];
  496. szVisits[0] = 0;
  497. CCdfView* pCCdfView = new CCdfView;
  498. if (pCCdfView)
  499. {
  500. hr = pCCdfView->Load(m_szURL, 0);
  501. if (SUCCEEDED(hr))
  502. {
  503. IXMLDocument* pIXMLDocument;
  504. hr = pCCdfView->ParseCdf(NULL, &pIXMLDocument, PARSE_LOCAL);
  505. if (SUCCEEDED(hr))
  506. {
  507. IXMLElement* pIXMLElement;
  508. LONG nIndex;
  509. hr = XML_GetFirstChannelElement(pIXMLDocument,
  510. &pIXMLElement, &nIndex);
  511. if (SUCCEEDED(hr))
  512. {
  513. BSTR bstrURL = XML_GetAttribute(pIXMLElement, XML_HREF);
  514. if (bstrURL && *bstrURL)
  515. {
  516. BYTE cei[MAX_CACHE_ENTRY_INFO_SIZE];
  517. LPINTERNET_CACHE_ENTRY_INFO pcei = (LPINTERNET_CACHE_ENTRY_INFO)cei;
  518. DWORD cbcei = MAX_CACHE_ENTRY_INFO_SIZE;
  519. if (GetUrlCacheEntryInfoW(bstrURL, pcei, &cbcei))
  520. {
  521. wnsprintf(szVisits, ARRAYSIZE(szVisits), TEXT("%d"),
  522. pcei->dwHitRate);
  523. }
  524. }
  525. SysFreeString(bstrURL);
  526. pIXMLElement->Release();
  527. }
  528. pIXMLDocument->Release();
  529. }
  530. }
  531. pCCdfView->Release();
  532. }
  533. if (0 == szVisits[0])
  534. {
  535. MLLoadString(IDS_VALUE_UNKNOWN, szVisits,
  536. ARRAYSIZE(szVisits));
  537. }
  538. SetDlgItemText(hdlg, IDC_VISITS, szVisits);
  539. /*
  540. SendDlgItemMessage(hdlg, IDC_HOTKEY, HKM_SETRULES,
  541. (HKCOMB_NONE | HKCOMB_A | HKCOMB_C | HKCOMB_S),
  542. (HOTKEYF_CONTROL | HOTKEYF_ALT));
  543. SendDlgItemMessage(hdlg, IDC_HOTKEY, HKM_SETHOTKEY, m_wHotkey, 0);
  544. */
  545. WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  546. SHTCharToUnicode(m_szURL, wszURL, ARRAYSIZE(wszURL));
  547. CheckDlgButton(hdlg, IDC_MAKE_OFFLINE, m_bStartSubscribed ? 1 : 0);
  548. if (m_bStartSubscribed)
  549. {
  550. if (SHRestricted2(REST_NoRemovingSubscriptions, m_szURL, 0))
  551. {
  552. bEnableMakeOffline = FALSE;
  553. }
  554. }
  555. else
  556. {
  557. if (SHRestricted2(REST_NoAddingSubscriptions, m_szURL, 0))
  558. {
  559. bEnableMakeOffline = FALSE;
  560. }
  561. }
  562. if (!CanSubscribe(wszURL))
  563. {
  564. bEnableMakeOffline = FALSE;
  565. }
  566. if (!bEnableMakeOffline)
  567. {
  568. EnableWindow(GetDlgItem(hdlg, IDC_MAKE_OFFLINE), FALSE);
  569. }
  570. ShowOfflineSummary(hdlg, m_bStartSubscribed);
  571. return TRUE;
  572. }
  573. BOOL AddSubsPropsCallback(HPROPSHEETPAGE hpage, LPARAM lParam)
  574. {
  575. return (bool) PropSheet_AddPage((HWND)lParam, hpage);
  576. }
  577. void CPropertyPages::AddRemoveSubsPages(HWND hdlg, BOOL bAdd)
  578. {
  579. ASSERT(NULL != m_pSubscriptionMgr2);
  580. if (NULL != m_pSubscriptionMgr2)
  581. {
  582. if (bAdd)
  583. {
  584. IShellPropSheetExt *pspse;
  585. if (SUCCEEDED(m_pSubscriptionMgr2->QueryInterface(IID_IShellPropSheetExt,
  586. (void **)&pspse)))
  587. {
  588. pspse->AddPages(AddSubsPropsCallback, (LPARAM)GetParent(hdlg));
  589. pspse->Release();
  590. }
  591. }
  592. else
  593. {
  594. ISubscriptionMgrPriv *psmp;
  595. if (SUCCEEDED(m_pSubscriptionMgr2->QueryInterface(IID_ISubscriptionMgrPriv,
  596. (void **)&psmp)))
  597. {
  598. psmp->RemovePages(GetParent(hdlg));
  599. psmp->Release();
  600. }
  601. }
  602. ShowOfflineSummary(hdlg, bAdd);
  603. }
  604. }
  605. BOOL CPropertyPages::OnCommand(HWND hdlg, WORD wNotifyCode, WORD wID, HWND hwndCtl)
  606. {
  607. BOOL bHandled = TRUE;
  608. switch (wID)
  609. {
  610. case IDC_MAKE_OFFLINE:
  611. if (wNotifyCode == BN_CLICKED)
  612. {
  613. AddRemoveSubsPages(hdlg, IsDlgButtonChecked(hdlg, IDC_MAKE_OFFLINE));
  614. PropSheet_Changed(GetParent(hdlg), hdlg);
  615. }
  616. break;
  617. /*
  618. case IDC_HOTKEY:
  619. if (wNotifyCode == EN_CHANGE)
  620. {
  621. PropSheet_Changed(GetParent(hdlg), hdlg);
  622. }
  623. break;
  624. */
  625. default:
  626. bHandled = FALSE;
  627. break;
  628. }
  629. return bHandled;
  630. }
  631. BOOL CPropertyPages::OnNotify(HWND hdlg, WPARAM idCtrl, LPNMHDR pnmh)
  632. {
  633. BOOL bHandled = FALSE;
  634. switch (pnmh->code)
  635. {
  636. case PSN_APPLY:
  637. {
  638. /*
  639. TCHAR szHotkey[32];
  640. TCHAR szDesktopINI[MAX_PATH];
  641. WORD wOldHotkey = m_wHotkey;
  642. m_wHotkey = (WORD)SendDlgItemMessage(hdlg, IDC_HOTKEY, HKM_GETHOTKEY, 0, 0);
  643. wnsprintf(szHotkey, ARRAYSIZE(szHotkey), TEXT("%d"), m_wHotkey);
  644. PathCombine(szDesktopINI, m_szPath, c_szDesktopINI);
  645. WritePrivateProfileString(c_szChannel, c_szHotkey, szHotkey, szDesktopINI);
  646. RegisterGlobalHotkey(wOldHotkey, m_wHotkey, m_szPath);
  647. */
  648. BOOL bIsSubscribed = IsDlgButtonChecked(hdlg, IDC_MAKE_OFFLINE);
  649. if (!bIsSubscribed)
  650. {
  651. WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  652. SHTCharToUnicode(m_szURL, wszURL, ARRAYSIZE(wszURL));
  653. if (NULL != m_pSubscriptionMgr2)
  654. {
  655. m_pSubscriptionMgr2->DeleteSubscription(wszURL, NULL);
  656. }
  657. }
  658. else
  659. {
  660. ISubscriptionMgrPriv *psmp;
  661. if ((NULL != m_pSubscriptionMgr2) &&
  662. SUCCEEDED(m_pSubscriptionMgr2->QueryInterface(IID_ISubscriptionMgrPriv,
  663. (void **)&psmp)))
  664. {
  665. psmp->SaveSubscription();
  666. psmp->Release();
  667. }
  668. }
  669. bHandled = TRUE;
  670. break;
  671. }
  672. }
  673. return bHandled;
  674. }
  675. void CPropertyPages::OnDestroy(HWND hdlg)
  676. {
  677. if (!m_bStartSubscribed &&
  678. IsDlgButtonChecked(hdlg, IDC_MAKE_OFFLINE) &&
  679. (NULL != m_pSubscriptionMgr2))
  680. {
  681. WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  682. SHTCharToUnicode(m_szURL, wszURL, ARRAYSIZE(wszURL));
  683. m_pSubscriptionMgr2->UpdateSubscription(wszURL);
  684. }
  685. // Ensure sys bit is still set
  686. SetFileAttributes(m_szPath, FILE_ATTRIBUTE_SYSTEM);
  687. }
  688. UINT CPropertyPages::PropSheetCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
  689. {
  690. switch (uMsg)
  691. {
  692. case PSPCB_RELEASE:
  693. if (NULL != ppsp->lParam)
  694. {
  695. ((CPropertyPages *)ppsp->lParam)->Release();
  696. }
  697. break;
  698. }
  699. return 1;
  700. }
  701. TCHAR c_szHelpFile[] = TEXT("iexplore.hlp");
  702. DWORD aHelpIDs[] = {
  703. IDC_NAME, IDH_SUBPROPS_SUBTAB_SUBSCRIBED_NAME,
  704. IDC_URL_TEXT, IDH_SUBPROPS_SUBTAB_SUBSCRIBED_URL,
  705. IDC_URL, IDH_SUBPROPS_SUBTAB_SUBSCRIBED_URL,
  706. // IDC_HOTKEY_TEXT, IDH_WEBDOC_HOTKEY,
  707. // IDC_HOTKEY, IDH_WEBDOC_HOTKEY,
  708. IDC_VISITS_TEXT, IDH_WEBDOC_VISITS,
  709. IDC_VISITS, IDH_WEBDOC_VISITS,
  710. IDC_MAKE_OFFLINE, IDH_MAKE_AVAIL_OFFLINE,
  711. IDC_SUMMARY, IDH_GROUPBOX,
  712. IDC_LAST_SYNC_TEXT, IDH_SUBPROPS_SUBTAB_LAST,
  713. IDC_LAST_SYNC, IDH_SUBPROPS_SUBTAB_LAST,
  714. IDC_DOWNLOAD_SIZE_TEXT, IDH_SUBPROPS_DLSIZE,
  715. IDC_DOWNLOAD_SIZE, IDH_SUBPROPS_DLSIZE,
  716. IDC_DOWNLOAD_RESULT_TEXT, IDH_SUBPROPS_SUBTAB_RESULT,
  717. IDC_DOWNLOAD_RESULT, IDH_SUBPROPS_SUBTAB_RESULT,
  718. 0, 0
  719. };
  720. INT_PTR CPropertyPages::PropSheetDlgProc(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
  721. {
  722. INT_PTR lrHandled = FALSE;
  723. CPropertyPages *pThis;
  724. switch (msg)
  725. {
  726. case WM_INITDIALOG:
  727. {
  728. LPPROPSHEETPAGE pPropSheetPage = (LPPROPSHEETPAGE)lParam;
  729. ASSERT(NULL != pPropSheetPage);
  730. if (NULL != pPropSheetPage)
  731. {
  732. SetWindowLongPtr(hdlg, DWLP_USER, pPropSheetPage->lParam);
  733. }
  734. pThis = GetThis(hdlg);
  735. if (NULL != pThis)
  736. {
  737. lrHandled = pThis->OnInitDialog(hdlg);
  738. }
  739. break;
  740. }
  741. case WM_COMMAND:
  742. pThis = GetThis(hdlg);
  743. if (NULL != pThis)
  744. {
  745. lrHandled = pThis->OnCommand(hdlg, HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
  746. }
  747. break;
  748. case WM_NOTIFY:
  749. pThis = GetThis(hdlg);
  750. if (NULL != pThis)
  751. {
  752. lrHandled = pThis->OnNotify(hdlg, wParam, (LPNMHDR)lParam);
  753. }
  754. break;
  755. case WM_DESTROY:
  756. pThis = GetThis(hdlg);
  757. if (NULL != pThis)
  758. {
  759. pThis->OnDestroy(hdlg);
  760. }
  761. break;
  762. case WM_HELP:
  763. SHWinHelpOnDemandWrap((HWND)((LPHELPINFO) lParam)->hItemHandle, c_szHelpFile,
  764. HELP_WM_HELP, (DWORD_PTR) aHelpIDs);
  765. lrHandled = TRUE;
  766. break;
  767. case WM_CONTEXTMENU:
  768. SHWinHelpOnDemandWrap((HWND)wParam, c_szHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)aHelpIDs);
  769. lrHandled = TRUE;
  770. break;
  771. }
  772. return lrHandled;
  773. }