proppgs.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 25k
Category:

Windows Kernel

Development Platform:

Visual C++

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