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

Windows Kernel

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. //#pragma hdrstop
  3. //#include <shellids.h>
  4. //#include "resource.h"
  5. //#include "deskhtml.h"
  6. //#include "deskstat.h"
  7. //#include "dcomp.h"
  8. //#include "dsubscri.h"
  9. //#include "dutil.h"
  10. //#include "options.h"
  11. //#include "webcheck.h"
  12. //#include <shlwapip.h>
  13. #include <mluisupp.h>
  14. #define _BROWSEUI_      // Make functions exported from browseui as stdapi (as they are delay loaded)
  15. //#include "iethread.h"
  16. //#include "browseui.h"
  17. #ifdef POSTSPLIT
  18. static void EmptyListview(HWND hwndLV, BOOL fDeleteComponents);
  19. static void GetSubscriptionList(HDSA* hdsaSubscriptions);
  20. static void ReplaceSubscriptions(HDSA hdsaOldSubscriptions, HDSA hdsaNewSubscriptions, HWND hwnd);
  21. static void DSA_DestroyWithMembers(HDSA hdsa);
  22. #define DXA_GROWTH_CONST 10
  23.  
  24. #define COMP_CHECKED    0x00002000
  25. #define COMP_UNCHECKED  0x00001000
  26. #define GALRET_NO       0x00000001
  27. #define GALRET_NEVER    0x00000002
  28. #define THISCLASS CCompPropSheetPage
  29. #define c_szHelpFile    TEXT("Update.hlp")
  30. const static DWORD aCompHelpIDs[] = {  // Context Help IDs
  31.     IDC_COMP_CHANNELS,  IDH_LIST_CHANNELS,
  32.     IDC_COMP_ENABLEAD,  IDH_VIEW_AS_WEB_PAGE,
  33.     IDC_COMP_FOLDEROPT, IDH_FOLDER_OPTIONS,
  34.     IDC_COMP_LIST,      IDH_LIST_CHANNELS,
  35.     IDC_COMP_NEW,       IDH_NEW_CHANNEL,
  36.     IDC_COMP_DELETE,    IDH_DELETE_CHANNEL,
  37.     IDC_COMP_PROPERTIES,IDH_CHANNEL_PROPERTIES,
  38.     IDC_COMP_RESET,     IDH_RESET_ALL,
  39.     IDC_COMP_PREVIEW,   IDH_DISPLAY_CHANNELS,
  40.     0, 0
  41. };
  42. typedef struct
  43. {
  44.     WCHAR wszURL[INTERNET_MAX_URL_LENGTH];
  45.     SUBSCRIPTIONINFO si;
  46. } BACKUPSUBSCRIPTION;
  47. static HDSA g_hdsaBackupSubscriptions = NULL;
  48. THISCLASS::CCompPropSheetPage(void)
  49. {
  50.     dwSize = sizeof(THISCLASS);
  51.     dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
  52.     hInstance = HINST_THISDLL;
  53.     pszTemplate = MAKEINTRESOURCE(IDD_COMPONENTS);
  54.     // hIcon = NULL; // unused (PSP_USEICON is not set)
  55.     // pszTitle = NULL; // unused (PSP_USETITLE is not set)
  56.     pfnDlgProc = (DLGPROC)_DlgProc;
  57.     // lParam   = 0;     // unused
  58.     pfnCallback = NULL;
  59.     // pcRefParent = NULL;
  60. }
  61. void THISCLASS::_ConstructLVString(COMPONENTA *pcomp, LPTSTR pszBuf, DWORD cchBuf)
  62. {
  63.     //
  64.     // Use the friendly name if it exists.
  65.     // Otherwise use the source name.
  66.     //
  67.     if (pcomp->szFriendlyName[0])
  68.     {
  69.         lstrcpyn(pszBuf, pcomp->szFriendlyName, cchBuf);
  70.     }
  71.     else
  72.     {
  73.         lstrcpyn(pszBuf, pcomp->szSource, cchBuf);
  74.     }
  75. }
  76. void THISCLASS::_AddComponentToLV(COMPONENTA *pcomp)
  77. {
  78.     TCHAR szBuf[INTERNET_MAX_URL_LENGTH + 40];
  79.     _ConstructLVString(pcomp, szBuf, ARRAYSIZE(szBuf));
  80.     //
  81.     // Construct the listview item.
  82.     //
  83.     LV_ITEM lvi = {0};
  84.     lvi.mask = LVIF_TEXT | LVIF_PARAM;
  85.     lvi.iItem = 0x7FFFFFFF;
  86.     lvi.pszText = szBuf;
  87.     lvi.lParam = pcomp->dwID;
  88.     int index = ListView_InsertItem(_hwndLV, &lvi);
  89.     if (index != -1)
  90.     {
  91.         ListView_SetItemState(_hwndLV, index, pcomp->fChecked ? COMP_CHECKED : COMP_UNCHECKED, LVIS_STATEIMAGEMASK);
  92.         ListView_SetColumnWidth(_hwndLV, 0, LVSCW_AUTOSIZE);
  93.     }
  94. }
  95. void THISCLASS::_SetUIFromDeskState(BOOL fEmpty)
  96. {
  97.     //
  98.     // Disable redraws while we mess repeatedly with the listview contents.
  99.     //
  100.     SendMessage(_hwndLV, WM_SETREDRAW, FALSE, 0);
  101.     if (fEmpty)
  102.     {
  103.         EmptyListview(_hwndLV, FALSE);
  104.     }
  105.     //
  106.     // Add each component to the listview.
  107.     //
  108.     int cComp;
  109.     g_pActiveDesk->GetDesktopItemCount(&cComp, 0);
  110.     for (int i=0; i<cComp; i++)
  111.     {
  112.         COMPONENT comp;
  113.         comp.dwSize = SIZEOF(comp);
  114.         if (SUCCEEDED(g_pActiveDesk->GetDesktopItem(i, &comp, 0)))
  115.         {
  116.             COMPONENTA compA;
  117.             compA.dwSize = sizeof(compA);
  118.             WideCompToMultiComp(&comp, &compA);
  119.             _AddComponentToLV(&compA);
  120.         }
  121.     }
  122.     //
  123.     // Put checkboxes in correct state.
  124.     //
  125.     COMPONENTSOPT co;
  126.     co.dwSize = sizeof(COMPONENTSOPT);
  127.     g_pActiveDesk->GetDesktopItemOptions(&co, 0);
  128.     CheckDlgButton(_hwnd, IDC_COMP_ENABLEAD, co.fActiveDesktop ? BST_CHECKED : BST_UNCHECKED);
  129.     //
  130.     // Reenable redraws.
  131.     //
  132.     SendMessage(_hwndLV, WM_SETREDRAW, TRUE, 0);
  133.     InvalidateRect(_hwndLV, NULL, TRUE);
  134. }
  135. void THISCLASS::_EnableControls(void)
  136. {
  137.     COMPONENTSOPT co;
  138.     co.dwSize = sizeof(COMPONENTSOPT);
  139.     g_pActiveDesk->GetDesktopItemOptions(&co, 0);
  140.     if (co.fActiveDesktop)
  141.     {
  142.         BOOL fEnable;
  143.         COMPONENT comp = { SIZEOF(comp) };
  144.         BOOL fHaveSelection = FALSE;
  145.         //
  146.         // Read in the information about the selected component (if any).
  147.         //
  148.         int iIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_SELECTED);
  149.         if (iIndex > -1)
  150.         {
  151.             LV_ITEM lvi = {0};
  152.             lvi.mask = LVIF_PARAM;
  153.             lvi.iItem = iIndex;
  154.             ListView_GetItem(_hwndLV, &lvi);
  155.             if (SUCCEEDED(g_pActiveDesk->GetDesktopItemByID(lvi.lParam, &comp, 0)))
  156.             {
  157.                 fHaveSelection = TRUE;
  158.             }
  159.         }
  160.         EnableWindow(GetDlgItem(_hwnd, IDC_COMP_NEW), _fAllowAdd);
  161.         //
  162.         // Delete button only enabled when an item is selected.
  163.         //
  164.         fEnable = _fAllowDel && fHaveSelection;
  165.         EnableWindow(GetDlgItem(_hwnd, IDC_COMP_DELETE), fEnable);
  166.         //
  167.         // Properties button only enabled on URL based pictures
  168.         // and websites.
  169.         //
  170.         fEnable = FALSE;
  171.         if (_fAllowEdit && fHaveSelection)
  172.         {
  173.             switch (comp.iComponentType)
  174.             {
  175.             case COMP_TYPE_PICTURE:
  176.             case COMP_TYPE_WEBSITE:
  177.                 LPTSTR  pszSource;
  178. #ifdef UNICODE
  179.                 pszSource = (LPTSTR)comp.wszSource;
  180. #else
  181.                 TCHAR   szCompSource[INTERNET_MAX_URL_LENGTH];
  182.                 SHUnicodeToAnsi(comp.wszSource, szCompSource, ARRAYSIZE(szCompSource));
  183.                 pszSource = szCompSource;
  184. #endif
  185.                 if (PathIsURL(pszSource))
  186.                 {
  187.                     fEnable = TRUE;
  188.                 }
  189.                 break;
  190.             }
  191.         }
  192.         EnableWindow(GetDlgItem(_hwnd, IDC_COMP_PROPERTIES), fEnable);
  193.         EnableWindow(GetDlgItem(_hwnd, IDC_COMP_RESET), _fAllowReset);
  194.         EnableWindow(_hwndLV, TRUE);
  195.     }
  196.     else
  197.     {
  198.         EnableWindow(_hwndLV, FALSE);
  199.         int iSel = ListView_GetNextItem(_hwndLV, -1, LVNI_SELECTED);
  200.         if (iSel > -1)
  201.         {
  202.             ListView_SetItemState(_hwndLV, iSel, 0, LVIS_SELECTED | LVIS_FOCUSED);
  203.         }
  204.         EnableWindow(GetDlgItem(_hwnd, IDC_COMP_NEW), FALSE);
  205.         EnableWindow(GetDlgItem(_hwnd, IDC_COMP_DELETE), FALSE);
  206.         EnableWindow(GetDlgItem(_hwnd, IDC_COMP_PROPERTIES), FALSE);
  207.         EnableWindow(GetDlgItem(_hwnd, IDC_COMP_RESET), FALSE);
  208.     }
  209. }
  210. void THISCLASS::_OnInitDialog(HWND hwnd)
  211. {
  212.     _hwnd = hwnd;
  213.     _hwndLV = GetDlgItem(_hwnd, IDC_COMP_LIST);
  214.     _fLaunchGallery = FALSE;
  215.     _fLaunchFolderOpt = FALSE;
  216.     HWND hWndComp = GetDlgItem(hwnd, IDC_COMP_PREVIEW);
  217.     if (hWndComp) {
  218.         // Turn off mirroring for this control.
  219.         SetWindowBits(hWndComp, GWL_EXSTYLE, RTL_MIRRORED_WINDOW, 0);
  220.     }
  221.     if (!g_pActiveDesk)
  222.     {
  223.         HRESULT  hres;
  224.         IActiveDesktopP * piadp;
  225.         if (SUCCEEDED(hres = CActiveDesktop_InternalCreateInstance((LPUNKNOWN *)&piadp, IID_IActiveDesktopP)))
  226.         {
  227.             WCHAR wszScheme[MAX_PATH];
  228.             DWORD dwcch = ARRAYSIZE(wszScheme);
  229.             // Get the global "edit" scheme and set ourselves us to read from and edit that scheme
  230.             if (SUCCEEDED(piadp->GetScheme(wszScheme, &dwcch, SCHEME_GLOBAL | SCHEME_EDIT)))
  231.             {
  232.                 piadp->SetScheme(wszScheme, SCHEME_LOCAL);
  233.                 
  234.             }
  235.             hres = piadp->QueryInterface(IID_IActiveDesktop, (LPVOID *)&g_pActiveDesk);
  236.             piadp->Release();
  237.         }
  238.         if (FAILED(hres))
  239.         {
  240.             return;
  241.         }
  242.     }
  243.     else
  244.     {
  245.         g_pActiveDesk->AddRef();
  246.     }
  247.     // Save the subscription settings so that we can restore them if Cancel is chosen.
  248.     GetSubscriptionList(&g_hdsaBackupSubscriptions);
  249.     //
  250.     // Read in the restrictions.
  251.     //
  252.     _fAllowAdd = !SHRestricted(REST_NOADDDESKCOMP);
  253.     _fAllowDel = !SHRestricted(REST_NODELDESKCOMP);
  254.     _fAllowEdit = !SHRestricted(REST_NOEDITDESKCOMP);
  255.     _fAllowClose = !SHRestricted(REST_NOCLOSEDESKCOMP);
  256.     _fAllowReset = _fAllowAdd && _fAllowDel && _fAllowEdit &&
  257.                     _fAllowClose && !SHRestricted(REST_NOCHANGINGWALLPAPER);
  258.     EnableWindow(GetDlgItem(_hwnd, IDC_COMP_NEW), _fAllowAdd);
  259.     EnableWindow(GetDlgItem(_hwnd, IDC_COMP_DELETE), _fAllowDel);
  260.     EnableWindow(GetDlgItem(_hwnd, IDC_COMP_PROPERTIES), _fAllowEdit);
  261.     EnableWindow(GetDlgItem(_hwnd, IDC_COMP_RESET), _fAllowReset);
  262.     if (_fAllowClose)
  263.     {
  264.         ListView_SetExtendedListViewStyle(_hwndLV, LVS_EX_CHECKBOXES);
  265.     }
  266.     //
  267.     // Add the single column that we want.
  268.     //
  269.     LV_COLUMN lvc;
  270.     lvc.mask = LVCF_FMT | LVCF_SUBITEM;
  271.     lvc.fmt = LVCFMT_LEFT;
  272.     lvc.iSubItem = 0;
  273.     ListView_InsertColumn(_hwndLV, 0, &lvc);
  274.     //
  275.     // Now make the UI match the g_pActiveDesk object.
  276.     //
  277.     _SetUIFromDeskState(FALSE);
  278.     //
  279.     // Select the first item, if it exists.
  280.     //
  281.     int cComp;
  282.     g_pActiveDesk->GetDesktopItemCount(&cComp, 0);
  283.     if (cComp)
  284.     {
  285.         ListView_SetItemState(_hwndLV, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  286.     }
  287.     _EnableControls();
  288. }
  289. void THISCLASS::_OnNotify(LPNMHDR lpnm)
  290. {
  291.     switch (lpnm->code)
  292.     {
  293.     case PSN_SETACTIVE:
  294.         //
  295.         // Make sure the Disable Active Desktop button is in correct state.
  296.         //
  297.         COMPONENTSOPT co;
  298.         co.dwSize = sizeof(COMPONENTSOPT);
  299.         g_pActiveDesk->GetDesktopItemOptions(&co, 0);
  300.         CheckDlgButton(_hwnd, IDC_COMP_ENABLEAD, co.fActiveDesktop ? BST_CHECKED : BST_UNCHECKED);
  301.         break;
  302.     case PSN_QUERYCANCEL:
  303.         //Just creating a local block to localise the definition of hdsaCurrentSubscriptions
  304.         {
  305.             // Restores subscriptions from the DSA g_hdsaBackupSubscriptions.
  306.             HDSA hdsaCurrentSubscriptions = NULL;
  307.             GetSubscriptionList(&hdsaCurrentSubscriptions);
  308.             ReplaceSubscriptions(hdsaCurrentSubscriptions, g_hdsaBackupSubscriptions, _hwnd);
  309.             DSA_DestroyWithMembers(hdsaCurrentSubscriptions);
  310.         }
  311.         break;
  312.     case PSN_APPLY:
  313.         IActiveDesktopP * piadp;
  314.         DWORD dwApplyFlags;
  315.         dwApplyFlags = AD_APPLY_ALL;
  316.         // Backup subscriptions again
  317.         DSA_DestroyWithMembers(g_hdsaBackupSubscriptions);
  318.         g_hdsaBackupSubscriptions = NULL;
  319.         GetSubscriptionList(&g_hdsaBackupSubscriptions);
  320.         if (SUCCEEDED(g_pActiveDesk->QueryInterface(IID_IActiveDesktopP, (LPVOID *)&piadp)))
  321.         {
  322.             WCHAR wszEdit[MAX_PATH], wszDisplay[MAX_PATH];
  323.             DWORD dwcch = ARRAYSIZE(wszEdit);
  324.             // If the edit scheme and display scheme are different, then we need to make
  325.             // sure we force an update.
  326.             if (SUCCEEDED(piadp->GetScheme(wszEdit, &dwcch, SCHEME_GLOBAL | SCHEME_EDIT)) &&
  327.                 (dwcch = ARRAYSIZE(wszDisplay)) &&
  328.                 SUCCEEDED(piadp->GetScheme(wszDisplay, &dwcch, SCHEME_GLOBAL | SCHEME_DISPLAY)))
  329.             {
  330.                 if (StrCmpW(wszDisplay, wszEdit))
  331.                     dwApplyFlags |= AD_APPLY_FORCE;
  332.                 
  333.             }
  334.             piadp->Release();
  335.         }
  336.         // PSN_APPLY notification message is sent to background prop. tab also. 
  337.         // Inside this function we check to dirty bit to avoid calling this twice.
  338.         EnableADifHtmlWallpaper(_hwnd);
  339.         g_pActiveDesk->ApplyChanges(dwApplyFlags);
  340.         SetSafeMode(SSM_CLEAR);
  341.         SetWindowLong(_hwnd, DWL_MSGRESULT, PSNRET_NOERROR);
  342.         _SetUIFromDeskState(TRUE);
  343.         _EnableControls();
  344.         break;
  345.     case LVN_ITEMCHANGED:
  346.         NM_LISTVIEW *pnmlv = (NM_LISTVIEW *)lpnm;
  347.         if ((pnmlv->uChanged & LVIF_STATE) &&
  348.             ((pnmlv->uNewState ^ pnmlv->uOldState) & COMP_CHECKED))
  349.         {
  350.             LV_ITEM lvi = {0};
  351.             lvi.iItem = pnmlv->iItem;
  352.             lvi.mask = LVIF_PARAM;
  353.             ListView_GetItem(_hwndLV, &lvi);
  354.             COMPONENT comp;
  355.             comp.dwSize = sizeof(COMPONENT);
  356.             if (SUCCEEDED(g_pActiveDesk->GetDesktopItemByID(lvi.lParam, &comp, 0)))
  357.             {
  358.                 comp.fChecked = (pnmlv->uNewState & COMP_CHECKED) != 0;
  359.                 g_pActiveDesk->ModifyDesktopItem(&comp, COMP_ELEM_CHECKED);
  360.             }
  361.             InvalidateRect(GetDlgItem(_hwnd, IDC_COMP_PREVIEW), NULL, FALSE);
  362.             EnableApplyButton(_hwnd);
  363.         }
  364.         if ((pnmlv->uChanged & LVIF_STATE) &&
  365.             ((pnmlv->uNewState ^ pnmlv->uOldState) & LVIS_SELECTED))
  366.         {
  367.             InvalidateRect(GetDlgItem(_hwnd, IDC_COMP_PREVIEW), NULL, FALSE);
  368.             _EnableControls();
  369.         }
  370.         break;
  371.     }
  372. }
  373. //
  374. // Returns TRUE if the string looks like a candidate for
  375. // getting qualified as "file:".
  376. //
  377. BOOL LooksLikeFile(LPCTSTR psz)
  378. {
  379.     BOOL fRet = FALSE;
  380.     if (psz[0] &&
  381.         psz[1] &&
  382. #ifndef UNICODE
  383.         !IsDBCSLeadByte(psz[0]) &&
  384.         !IsDBCSLeadByte(psz[1]) &&
  385. #endif
  386.         ((psz[0] == TEXT('\')) ||
  387.          (psz[1] == TEXT(':')) ||
  388.          (psz[1] == TEXT('|'))))
  389.     {
  390.         fRet = TRUE;
  391.     }
  392.     return fRet;
  393. }
  394. #ifndef SHDOC401_DLL_UI
  395. #define GOTO_GALLERY    (-2)
  396. #endif
  397. #define SetDefaultDialogFont SHSetDefaultDialogFont
  398. #define RemoveDefaultDialogFont SHRemoveDefaultDialogFont
  399. BOOL CALLBACK AddComponentDlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  400. {
  401.     LPTSTR pszSource = (LPTSTR)GetWindowLong(hdlg, DWL_USER);
  402.     TCHAR szBuf[INTERNET_MAX_URL_LENGTH];
  403.     switch (uMsg)
  404.     {
  405.     case WM_INITDIALOG:
  406.         pszSource = (LPTSTR)lParam;
  407.         SetWindowLong(hdlg, DWL_USER, (LONG)pszSource);
  408.         SetDefaultDialogFont(hdlg, IDC_CPROP_SOURCE);
  409.         SetDlgItemText(hdlg, IDC_CPROP_SOURCE, c_szNULL);
  410.         EnableWindow(GetDlgItem(hdlg, IDOK), FALSE);
  411.         SHAutoComplete(GetDlgItem(hdlg, IDC_CPROP_SOURCE), 0);
  412.         return TRUE;
  413.     case WM_DESTROY:
  414.         RemoveDefaultDialogFont(hdlg);
  415.         break;
  416.     case WM_COMMAND:
  417.         switch (GET_WM_COMMAND_ID(wParam, lParam))
  418.         {
  419.         case IDC_CPROP_BROWSE:
  420.             GetDlgItemText(hdlg, IDC_CPROP_SOURCE, szBuf, ARRAYSIZE(szBuf));
  421.             if (!LooksLikeFile(szBuf))
  422.             {
  423.                 //
  424.                 // Open the favorites folder when we aren't
  425.                 // looking at a specific file.
  426.                 //
  427.                 SHGetSpecialFolderPath(hdlg, szBuf, CSIDL_FAVORITES, FALSE);
  428.                 //
  429.                 // Append a slash because GetFileName breaks the
  430.                 // string into a file & dir, and we want to make sure
  431.                 // the entire favorites path is treated as a dir.
  432.                 //
  433.                 lstrcat(szBuf, TEXT("\"));
  434.             }
  435.             if (GetFileName(hdlg, szBuf, ARRAYSIZE(szBuf), IDS_COMP_FILETYPES, GFN_ALL))
  436.             {
  437.                 CheckAndResolveLocalUrlFile(szBuf, ARRAYSIZE(szBuf));
  438.                 SetDlgItemText(hdlg, IDC_CPROP_SOURCE, szBuf);
  439.             }
  440.             break;
  441.         case IDC_CPROP_SOURCE:
  442.             if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  443.             {
  444.                 EnableWindow(GetDlgItem(hdlg, IDOK), GetWindowTextLength(GetDlgItem(hdlg, IDC_CPROP_SOURCE)) > 0);
  445.             }
  446.             break;
  447.         case IDOK:
  448.             GetDlgItemText(hdlg, IDC_CPROP_SOURCE, pszSource, INTERNET_MAX_URL_LENGTH);
  449.             ASSERT(pszSource[0]);
  450.             if (ValidateFileName(hdlg, pszSource, IDS_COMP_TYPE1))
  451.             {
  452.                 CheckAndResolveLocalUrlFile(pszSource, INTERNET_MAX_URL_LENGTH);
  453.                 //
  454.                 // Qualify non file-protocol strings.
  455.                 //
  456.                 if (!LooksLikeFile(pszSource))
  457.                 {
  458.                     DWORD cchSize = INTERNET_MAX_URL_LENGTH;
  459.                     PathRemoveBlanks(pszSource);
  460.                     ParseURLFromOutsideSource(pszSource, pszSource, &cchSize, NULL);
  461.                 }
  462.                 EndDialog(hdlg, 0);
  463.             }
  464.             break;
  465.         case IDCANCEL:
  466.             EndDialog(hdlg, -1);
  467.             break;
  468. #ifndef SHDOC401_DLL_UI
  469.         case IDC_GOTO_GALLERY:
  470.             EndDialog(hdlg, GOTO_GALLERY);
  471.             break;
  472. #endif
  473.         }
  474.         break;
  475.     }
  476.     return FALSE;
  477. }
  478. BOOL IsUrlPicture(LPCTSTR pszUrl)
  479. {
  480.     BOOL fRet = FALSE;
  481.     if(pszUrl[0] == TEXT(''))
  482.     {
  483.         fRet = TRUE;
  484.     }
  485.     else
  486.     {
  487.         LPTSTR pszExt = PathFindExtension(pszUrl);
  488.         if ((lstrcmpi(pszExt, TEXT(".BMP"))  == 0) ||
  489.             (lstrcmpi(pszExt, TEXT(".GIF"))  == 0) ||
  490.             (lstrcmpi(pszExt, TEXT(".JPG"))  == 0) ||
  491.             (lstrcmpi(pszExt, TEXT(".JPE"))  == 0) ||
  492.             (lstrcmpi(pszExt, TEXT(".JPEG")) == 0) ||
  493.             (lstrcmpi(pszExt, TEXT(".DIB"))  == 0) ||
  494.             (lstrcmpi(pszExt, TEXT(".PNG"))  == 0))
  495.         {
  496.             fRet = TRUE;
  497.         }
  498.     }
  499.     return(fRet);
  500. }
  501. int GetComponentType(LPCTSTR pszUrl)
  502. {
  503.     return IsUrlPicture(pszUrl) ? COMP_TYPE_PICTURE : COMP_TYPE_WEBSITE;
  504. }
  505. void CreateComponent(COMPONENTA *pcomp, LPCTSTR pszUrl)
  506. {
  507.     pcomp->dwSize = SIZEOF(*pcomp);
  508.     pcomp->dwID = (DWORD)-1;
  509.     pcomp->iComponentType = GetComponentType(pszUrl);
  510.     pcomp->fChecked = TRUE;
  511.     pcomp->fDirty = FALSE;
  512.     pcomp->fNoScroll = FALSE;
  513.     pcomp->cpPos.dwSize = sizeof(pcomp->cpPos);
  514.     pcomp->cpPos.iLeft = COMPONENT_DEFAULT_LEFT;
  515.     pcomp->cpPos.iTop = COMPONENT_DEFAULT_TOP;
  516.     pcomp->cpPos.dwWidth = COMPONENT_DEFAULT_WIDTH;
  517.     pcomp->cpPos.dwHeight = COMPONENT_DEFAULT_HEIGHT;
  518.     pcomp->cpPos.izIndex = COMPONENT_TOP;
  519.     pcomp->cpPos.fCanResize = TRUE;
  520.     pcomp->cpPos.fCanResizeX = pcomp->cpPos.fCanResizeY = TRUE;
  521.     pcomp->cpPos.iPreferredLeftPercent = pcomp->cpPos.iPreferredTopPercent = 0;
  522.     lstrcpyn(pcomp->szSource, pszUrl, ARRAYSIZE(pcomp->szSource));
  523.     lstrcpyn(pcomp->szSubscribedURL, pszUrl, ARRAYSIZE(pcomp->szSubscribedURL));
  524.     pcomp->szFriendlyName[0] = TEXT('');
  525.     PositionComponent(&pcomp->cpPos, pcomp->iComponentType);
  526. }
  527. BOOL FindComponent(LPCTSTR pszUrl)
  528. {
  529.     BOOL    fRet = FALSE;
  530.     int     i, ccomp;
  531.     LPWSTR  pwszUrl;
  532. #ifndef UNICODE
  533.     WCHAR   wszUrl[INTERNET_MAX_URL_LENGTH];
  534.     SHAnsiToUnicode(pszUrl, wszUrl, ARRAYSIZE(wszUrl));
  535.     pwszUrl = wszUrl;
  536. #else
  537.     pwszUrl = (LPWSTR)pszUrl;
  538. #endif
  539.     g_pActiveDesk->GetDesktopItemCount(&ccomp, 0);
  540.     for (i=0; i<ccomp; i++)
  541.     {
  542.         COMPONENT comp;
  543.         comp.dwSize = sizeof(COMPONENT);
  544.         if (SUCCEEDED(g_pActiveDesk->GetDesktopItem(i, &comp, 0)))
  545.         {
  546.             if (StrCmpIW(pwszUrl, comp.wszSource) == 0)
  547.             {
  548.                 fRet = TRUE;
  549.                 break;
  550.             }
  551.         }
  552.     }
  553.     return fRet;
  554. }
  555. void EmptyListview(HWND hwndLV, BOOL fDeleteComponents)
  556. {
  557.     if (fDeleteComponents)
  558.     {
  559.         SendMessage(hwndLV, WM_SETREDRAW, FALSE, 0);
  560.     }
  561.     //
  562.     // Delete all the old components.
  563.     //
  564.     int cComp;
  565.     g_pActiveDesk->GetDesktopItemCount(&cComp, 0);
  566.     int i;
  567.     COMPONENT comp;
  568.     comp.dwSize = sizeof(COMPONENT);
  569.     for (i=0; i<cComp; i++)
  570.     {
  571.         ListView_DeleteItem(hwndLV, 0);
  572.         if (fDeleteComponents)
  573.         {
  574.             g_pActiveDesk->GetDesktopItem(0, &comp, 0);
  575.             g_pActiveDesk->RemoveDesktopItem(&comp, 0);
  576.             LPTSTR  pszSource;
  577. #ifndef UNICODE
  578.             TCHAR   szCompURL[INTERNET_MAX_URL_LENGTH];
  579.             SHUnicodeToAnsi(comp.wszSubscribedURL, szCompURL, ARRAYSIZE(szCompURL));
  580.             pszSource = szCompURL;
  581. #else
  582.             pszSource = comp.wszSubscribedURL;
  583. #endif
  584.             DeleteFromSubscriptionList(pszSource);
  585.         }
  586.     }
  587.     if (fDeleteComponents)
  588.     {
  589.         SendMessage(hwndLV, WM_SETREDRAW, TRUE, 0);
  590.         InvalidateRect(hwndLV, NULL, TRUE);
  591.     }
  592. }
  593. BOOL THISCLASS::_VisitGallery(void)
  594. {
  595.     TCHAR szTitle[80], szText[1024];
  596.     MLLoadString(IDS_VISITGALLERY_TITLE, szTitle, ARRAYSIZE(szTitle));
  597.     MLLoadString(IDS_VISITGALLERY_TEXT, szText, ARRAYSIZE(szText));
  598.     return (IDYES == SHMessageBoxCheck(_hwnd, szText, szTitle, MB_YESNO | MB_ICONINFORMATION, IDNO, REG_VAL_GENERAL_VISITGALLERY));
  599. }
  600. void THISCLASS::_SelectComponent(LPWSTR pwszUrl)
  601. {
  602.     //
  603.     // Look for the component with our URL.
  604.     //
  605.     int cComp;
  606.     COMPONENT comp = { SIZEOF(comp) };
  607.     g_pActiveDesk->GetDesktopItemCount(&cComp, 0);
  608.     for (int i=0; i<cComp; i++)
  609.     {
  610.         if (SUCCEEDED(g_pActiveDesk->GetDesktopItem(i, &comp, 0)))
  611.         {
  612.             if (StrCmpW(pwszUrl, comp.wszSource) == 0)
  613.             {
  614.                 break;
  615.             }
  616.         }
  617.     }
  618.     //
  619.     // Find the matching listview entry (search for dwID).
  620.     //
  621.     if (i != cComp)
  622.     {
  623.         int nItems = ListView_GetItemCount(_hwndLV);
  624.         for (i=0; i<nItems; i++)
  625.         {
  626.             LV_ITEM lvi = {0};
  627.             lvi.iItem = i;
  628.             lvi.mask = LVIF_PARAM;
  629.             ListView_GetItem(_hwndLV, &lvi);
  630.             if (lvi.lParam == (LPARAM)comp.dwID)
  631.             {
  632.                 //
  633.                 // Found it, select it and exit.
  634.                 //
  635.                 ListView_SetItemState(_hwndLV, i, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  636.                 ListView_EnsureVisible(_hwndLV, i, FALSE);
  637.                 break;
  638.             }
  639.         }
  640.     }
  641. }
  642. void THISCLASS::_NewComponent(void)
  643. {
  644. #ifdef SHDOC401_DLL_UI // old behavior
  645.   //
  646.   // See if the user wants to launch the gallery instead.
  647.   //
  648.   if (_VisitGallery())
  649.   {
  650.       _fLaunchGallery = TRUE;
  651.       PropSheet_PressButton(GetParent(_hwnd), PSBTN_OK);
  652.   }
  653.   else
  654.   {
  655. #endif
  656.     //
  657.     // Get the component name.
  658.     //
  659.     TCHAR szSource[INTERNET_MAX_URL_LENGTH];
  660.     INT_PTR iChoice = DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_ADDCOMPONENT), _hwnd, AddComponentDlgProc, (LPARAM)szSource);
  661. #ifndef SHDOC401_DLL_UI
  662.     if (iChoice == GOTO_GALLERY)   // the user wants to launch the gallery
  663.     {
  664.         _fLaunchGallery = TRUE;
  665.         PropSheet_PressButton(GetParent(_hwnd), PSBTN_OK);
  666.     }
  667.     else
  668. #endif
  669.     if (iChoice >= 0)
  670.     {   // the user has entered a URL address
  671.         BOOL fOkay = TRUE;
  672.         COMPONENT   comp;
  673.         WCHAR szSourceW[INTERNET_MAX_URL_LENGTH];
  674.         
  675.         comp.dwSize = SIZEOF(comp);
  676.         SHTCharToUnicode(szSource, szSourceW, ARRAYSIZE(szSourceW));
  677.         fOkay = SUCCEEDED(g_pActiveDesk->AddUrl(_hwnd, szSourceW, &comp, 0));
  678.      
  679.         if (fOkay)
  680.         {
  681.             // Add component to listview.
  682.             //
  683.             // Need to reload the entire listview so that it is shown in
  684.             // the correct zorder.
  685.             //
  686.             _SetUIFromDeskState(TRUE);
  687.             //
  688.             // Select the newly added component.
  689.             //
  690.             _SelectComponent(comp.wszSource);
  691.             //
  692.             // Redraw preview window.
  693.             //
  694.             InvalidateRect(GetDlgItem(_hwnd, IDC_COMP_PREVIEW), NULL, FALSE);
  695.             //
  696.             // Enable Apply button and any necessary controls.
  697.             //
  698.             _EnableControls();
  699.             EnableApplyButton(_hwnd);
  700.         }
  701.     }
  702. #ifdef SHDOC401_DLL_UI
  703.   }
  704. #endif
  705. }
  706. void THISCLASS::_EditComponent(void)
  707. {
  708.     int iIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_SELECTED);
  709.     if (iIndex > -1)
  710.     {
  711.         LV_ITEM lvi = {0};
  712.         lvi.mask = LVIF_PARAM;
  713.         lvi.iItem = iIndex;
  714.         ListView_GetItem(_hwndLV, &lvi);
  715.         COMPONENT comp = { SIZEOF(comp) };
  716.         if (SUCCEEDED(g_pActiveDesk->GetDesktopItemByID(lvi.lParam, &comp, 0)))
  717.         {
  718.             LPTSTR  pszSubscribedURL;
  719. #ifndef UNICODE
  720.             TCHAR   szSubscribedURL[INTERNET_MAX_URL_LENGTH];
  721.             SHUnicodeToAnsi(comp.wszSubscribedURL, szSubscribedURL, ARRAYSIZE(szSubscribedURL));
  722.             pszSubscribedURL = szSubscribedURL;
  723. #else
  724.             pszSubscribedURL = (LPTSTR)comp.wszSubscribedURL;
  725. #endif
  726.             if (SUCCEEDED(ShowSubscriptionProperties(pszSubscribedURL, _hwnd)))
  727.             {
  728.                 EnableApplyButton(_hwnd);
  729.             }
  730.         }
  731.     }
  732. }
  733. void THISCLASS::_DeleteComponent(void)
  734. {
  735.     int iIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_ALL | LVNI_SELECTED);
  736.     if (iIndex > -1)
  737.     {
  738.         LV_ITEM lvi = {0};
  739.         lvi.mask = LVIF_PARAM;
  740.         lvi.iItem = iIndex;
  741.         ListView_GetItem(_hwndLV, &lvi);
  742.         COMPONENT comp;
  743.         comp.dwSize = sizeof(COMPONENT);
  744.         if (SUCCEEDED(g_pActiveDesk->GetDesktopItemByID(lvi.lParam, &comp, 0)))
  745.         {
  746.             TCHAR szMsg[1024];
  747.             TCHAR szTitle[MAX_PATH];
  748.             MLLoadString(IDS_COMP_CONFIRMDEL, szMsg, ARRAYSIZE(szMsg));
  749.             MLLoadString(IDS_COMP_TITLE, szTitle, ARRAYSIZE(szTitle));
  750.             if (MessageBox(_hwnd, szMsg, szTitle, MB_YESNO | MB_ICONQUESTION) == IDYES)
  751.             {
  752.                 g_pActiveDesk->RemoveDesktopItem(&comp, 0);
  753.                 ListView_DeleteItem(_hwndLV, iIndex);
  754.                 int cComp = ListView_GetItemCount(_hwndLV);
  755.                 if (cComp == 0)
  756.                 {
  757.                     SendMessage(_hwnd, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(_hwnd, IDC_COMP_NEW), TRUE);
  758.                 }
  759.                 else
  760.                 {
  761.                     int iSel = (iIndex > cComp - 1 ? cComp - 1 : iIndex);
  762.                     ListView_SetItemState(_hwndLV, iSel, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  763.                 }
  764.                 LPTSTR  pszSubscribedURL;
  765. #ifndef UNICODE
  766.                 TCHAR   szSubscribedURL[INTERNET_MAX_URL_LENGTH];
  767.                 SHUnicodeToAnsi(comp.wszSubscribedURL, szSubscribedURL, ARRAYSIZE(szSubscribedURL));
  768.                 pszSubscribedURL = szSubscribedURL;
  769. #else
  770.                 pszSubscribedURL = comp.wszSubscribedURL;
  771. #endif
  772.                 DeleteFromSubscriptionList(pszSubscribedURL);
  773.                 InvalidateRect(GetDlgItem(_hwnd, IDC_COMP_PREVIEW), NULL, FALSE);
  774.                 _EnableControls();
  775.                 EnableApplyButton(_hwnd);
  776.             }
  777.         }
  778.     }
  779. }
  780. BOOL THISCLASS::_VerifyFolderOptions(void)
  781. {
  782.     TCHAR szTitle[80], szText[1024];
  783.     MLLoadString(IDS_FOLDEROPT_TITLE, szTitle, ARRAYSIZE(szTitle));
  784.     MLLoadString(IDS_FOLDEROPT_TEXT, szText, ARRAYSIZE(szText));
  785.     return MessageBox(_hwnd, szText, szTitle, MB_YESNO | MB_ICONINFORMATION) == IDYES;
  786. }
  787. void THISCLASS::_OnCommand(WORD wNotifyCode, WORD wID, HWND hwndCtl)
  788. {
  789.     BOOL fFocusToList = FALSE;
  790.     COMPONENTSOPT co;
  791.     switch (wID)
  792.     {
  793.     case IDC_COMP_NEW:
  794.         _NewComponent();
  795.         fFocusToList = TRUE;
  796.         break;
  797.     case IDC_COMP_PROPERTIES:
  798.         _EditComponent();
  799.         fFocusToList = TRUE;
  800.         break;
  801.     case IDC_COMP_DELETE:
  802.         _DeleteComponent();
  803.         fFocusToList = TRUE;
  804.         break;
  805.     
  806.     case IDC_COMP_ENABLEAD:
  807.         co.dwSize = sizeof(COMPONENTSOPT);
  808.         g_pActiveDesk->GetDesktopItemOptions(&co, 0);
  809.         co.fActiveDesktop = IsDlgButtonChecked(_hwnd, wID) == BST_CHECKED;
  810.         g_pActiveDesk->SetDesktopItemOptions(&co, 0);
  811.         _EnableControls();
  812.         InvalidateRect(GetDlgItem(_hwnd, IDC_COMP_PREVIEW), NULL, FALSE);
  813.         EnableApplyButton(_hwnd);
  814.         break;
  815.     case IDC_COMP_FOLDEROPT:
  816.         if (_VerifyFolderOptions())
  817.         {
  818.             _fLaunchFolderOpt = TRUE;
  819.             PropSheet_PressButton(GetParent(_hwnd), PSBTN_OK);
  820.         }
  821.         break;
  822.     case IDC_COMP_RESET:
  823.         TCHAR szMsg[1024];
  824.         TCHAR szTitle[MAX_PATH];
  825.         MLLoadString(IDS_COMP_TITLE, szTitle, ARRAYSIZE(szTitle));
  826.         MLLoadString(IDS_COMP_CONFIRMRESET, szMsg, ARRAYSIZE(szTitle));
  827.         if (MessageBox(_hwnd, szMsg, szTitle, MB_YESNO | MB_ICONQUESTION) != IDYES)
  828.         {
  829.             break;
  830.         }
  831.         //
  832.         // Reset all the check boxes.
  833.         //
  834.         co.dwSize = sizeof(COMPONENTSOPT);
  835.         g_pActiveDesk->GetDesktopItemOptions(&co, 0);
  836.         co.fEnableComponents = TRUE;
  837.         co.fActiveDesktop = TRUE;
  838.         g_pActiveDesk->SetDesktopItemOptions(&co, 0);
  839.         
  840.         //
  841.         // Delete all the old components.
  842.         //
  843.         EmptyListview(_hwndLV, TRUE);
  844.         COMPONENTA compA;
  845.         COMPONENT comp;
  846.         compA.dwSize = sizeof(compA);
  847.         comp.dwSize = sizeof(comp);  //This is needed for MultiCompToWide to work properly.
  848.         //
  849.         // Add the default components.
  850.         //
  851. #ifdef WANT_ORANGE_EGG
  852.         compA.dwID = -1;
  853.         compA.iComponentType = COMP_TYPE_HTMLDOC;
  854.         compA.fChecked = TRUE;
  855.         compA.fDirty = FALSE;
  856.         compA.fNoScroll = FALSE;
  857.         compA.cpPos.dwSize = sizeof(COMPPOS);
  858.         // Find the virtual dimensions.
  859.         EnumMonitorsArea ema;
  860.         GetMonitorSettings(&ema);
  861.         // Position it in the primary monitor.
  862.         compA.cpPos.iLeft = EGG_LEFT + (ema.rcMonitor[0].left - ema.rcVirtualMonitor.left);
  863.         compA.cpPos.iTop = EGG_TOP + (ema.rcMonitor[0].top - ema.rcVirtualMonitor.top);
  864.         compA.cpPos.dwWidth = EGG_WIDTH;
  865.         compA.cpPos.dwHeight = EGG_HEIGHT;
  866.         compA.cpPos.izIndex = COMPONENT_TOP;
  867.         compA.cpPos.fCanResize = compA.cpPos.fCanResizeX = compA.cpPos.fCanResizeY = TRUE;
  868.         compA.cpPos.iPreferredLeftPercent = compA.cpPos.iPreferredTopPercent = 0;
  869.         MLLoadString(IDS_SAMPLE_COMPONENT, compA.szFriendlyName, ARRAYSIZE(compA.szFriendlyName));
  870.         GetWindowsDirectory(compA.szSource, ARRAYSIZE(compA.szSource));
  871.         lstrcat(compA.szSource, COMPON_FILENAME);
  872.         lstrcpy(compA.szSubscribedURL, compA.szSource);
  873.         PositionComponent(&compA.cpPos, compA.iComponentType);
  874.         MultiCompToWideComp(&compA, &comp);
  875.         g_pActiveDesk->AddComponent(&comp);
  876. #endif
  877.         //
  878.         // Don't restore the channel bar on memphis OSR1+.
  879.         //
  880.         if (!IsOS(OS_MEMPHIS) || IsOS(OS_MEMPHIS_GOLD))
  881.         {
  882.             compA.dwID = -1;
  883.             compA.dwSize = SIZEOF(compA);
  884.             compA.iComponentType = COMP_TYPE_CONTROL;
  885.             compA.fChecked = !g_fRunningOnNT;  //On WinNT, the channelbar is turned OFF by default!
  886.             compA.fDirty = FALSE;
  887.             compA.fNoScroll = FALSE;
  888.             compA.cpPos.dwSize = SIZEOF(compA.cpPos);
  889.             GetCBarStartPos(&compA.cpPos.iLeft, &compA.cpPos.iTop, &compA.cpPos.dwWidth, &compA.cpPos.dwHeight);
  890.             compA.cpPos.izIndex = COMPONENT_TOP;
  891.             compA.cpPos.fCanResize = compA.cpPos.fCanResizeX = compA.cpPos.fCanResizeY = TRUE;
  892.             compA.cpPos.iPreferredLeftPercent = compA.cpPos.iPreferredTopPercent = 0;
  893.             MLLoadString(IDS_CHANNEL_BAR, compA.szFriendlyName, ARRAYSIZE(compA.szFriendlyName));
  894.             lstrcpy(compA.szSource, CBAR_SOURCE);
  895.             lstrcpy(compA.szSubscribedURL, CBAR_SOURCE);
  896.             PositionComponent(&compA.cpPos, compA.iComponentType);
  897.             MultiCompToWideComp(&compA, &comp);
  898.             g_pActiveDesk->AddDesktopItem(&comp, 0);
  899.         }
  900.         //
  901.         // Reset the wallpaper settings.
  902.         //
  903.         WALLPAPEROPT wpo;
  904.         wpo.dwSize = sizeof(WALLPAPEROPT);
  905.         g_pActiveDesk->GetWallpaperOptions(&wpo, 0);
  906.         wpo.dwStyle = WPSTYLE_CENTER;
  907.         g_pActiveDesk->SetWallpaperOptions(&wpo, 0);
  908.         //Set the default wallpaper
  909.         TCHAR szWallpaper[INTERNET_MAX_URL_LENGTH];
  910.         WCHAR *pwszWallpaper;
  911.         GetWallpaperDirName(szWallpaper, ARRAYSIZE(szWallpaper));
  912.         lstrcat(szWallpaper, TEXT("\"));
  913.         TCHAR szWP[INTERNET_MAX_URL_LENGTH];
  914.         GetDefaultWallpaper(szWP);
  915.         lstrcat(szWallpaper, szWP);
  916. #ifndef UNICODE
  917.         WCHAR   wszWallpaper[INTERNET_MAX_URL_LENGTH];
  918.         SHAnsiToUnicode(szWallpaper, wszWallpaper, ARRAYSIZE(wszWallpaper));
  919.         pwszWallpaper = wszWallpaper;
  920. #else
  921.         pwszWallpaper = szWallpaper;
  922. #endif
  923.         g_pActiveDesk->SetWallpaper(pwszWallpaper, 0);
  924.         //
  925.         // Get the UI to match the new desk state.
  926.         //
  927.         _SetUIFromDeskState(FALSE);
  928.         //
  929.         // Select the first item, if it exists.
  930.         //
  931.         int cComp;
  932.         g_pActiveDesk->GetDesktopItemCount(&cComp, 0);
  933.         if (cComp)
  934.         {
  935.             ListView_SetItemState(_hwndLV, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  936.         }
  937.         _EnableControls();
  938.         EnableApplyButton(_hwnd);
  939.         fFocusToList = TRUE;
  940.         break;
  941.     }
  942.     //Set the focus back to the components list, if necessary
  943.     if (fFocusToList)
  944.     {
  945.         int iIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_SELECTED);
  946.         if (iIndex > -1)
  947.         {
  948.             SetFocus(GetDlgItem(_hwnd, IDC_COMP_LIST));
  949.         }
  950.     }
  951. }
  952. void THISCLASS::_OnDestroy(void)
  953. {
  954.     if (g_pActiveDesk->Release() == 0)
  955.     {
  956.         g_pActiveDesk = NULL;
  957.     }
  958.     DSA_DestroyWithMembers(g_hdsaBackupSubscriptions);
  959.     g_hdsaBackupSubscriptions = NULL;
  960.     if (_fLaunchGallery)
  961.     {
  962.         WCHAR szGalleryUrl[INTERNET_MAX_URL_LENGTH];
  963.         if (SUCCEEDED(URLSubLoadString(MLGetHinst(), IDS_VISIT_URL, szGalleryUrl, ARRAYSIZE(szGalleryUrl), URLSUB_ALL)))
  964.         {
  965.             NavToUrlUsingIEW(szGalleryUrl, TRUE);
  966.         }
  967.     }
  968.     if (_fLaunchFolderOpt)
  969.     {
  970.         DWORD dwPid;
  971.         if (GetWindowThreadProcessId(GetShellWindow(), &dwPid)) {
  972.             AllowSetForegroundWindow(dwPid);
  973.         }
  974.         PostMessage(GetShellWindow(), CWM_SHOWFOLDEROPT, 0, 0);
  975.     }
  976. }
  977. void THISCLASS::_OnGetCurSel(int *piIndex)
  978. {
  979.     if (_hwndLV)
  980.     {
  981.         *piIndex = ListView_GetNextItem(_hwndLV, -1, LVNI_ALL | LVNI_SELECTED);
  982.     }
  983.     else
  984.     {
  985.         *piIndex = -1;
  986.     }
  987. }
  988. BOOL CALLBACK THISCLASS::_DlgProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  989. {
  990.     CCompPropSheetPage *pcpsp = (CCompPropSheetPage *)GetWindowLong(hdlg, DWL_USER);
  991.     switch(uMsg)
  992.     {
  993.     case WM_INITDIALOG:
  994.         pcpsp = (CCompPropSheetPage *)lParam;
  995.         SetWindowLong(hdlg, DWL_USER, (LPARAM)pcpsp);
  996.         pcpsp->_OnInitDialog(hdlg);
  997.         break;
  998.     case WM_NOTIFY:
  999.         pcpsp->_OnNotify((LPNMHDR)lParam);
  1000.         break;
  1001.     case WM_COMMAND:
  1002.         pcpsp->_OnCommand(HIWORD(wParam), LOWORD(wParam), (HWND)lParam);
  1003.         break;
  1004.     case WM_SYSCOLORCHANGE:
  1005.     case WM_SETTINGCHANGE:
  1006.     case WM_DISPLAYCHANGE:
  1007.         SHPropagateMessage(hdlg, uMsg, wParam, lParam, TRUE);
  1008.         break;
  1009.     case WM_DESTROY:
  1010.         if (pcpsp)
  1011.         {
  1012.             pcpsp->_OnDestroy();
  1013.         }
  1014.         break;
  1015.     case WM_COMP_GETCURSEL:
  1016.         pcpsp->_OnGetCurSel((int *)lParam);
  1017.         break;
  1018.     case WM_HELP:
  1019.         SHWinHelpOnDemandWrap((HWND)((LPHELPINFO) lParam)->hItemHandle, c_szHelpFile,
  1020.                 HELP_WM_HELP, (DWORD)aCompHelpIDs);
  1021.         break;
  1022.     case WM_CONTEXTMENU:
  1023.         SHWinHelpOnDemandWrap((HWND) wParam, c_szHelpFile, HELP_CONTEXTMENU,
  1024.                 (DWORD)(LPVOID) aCompHelpIDs);
  1025.         break;
  1026.     }
  1027.     return FALSE;
  1028. }
  1029. // Backs up subscriptions from the g_pActiveDesk structure.
  1030. void GetSubscriptionList(HDSA* hdsaSubscriptions)
  1031. {
  1032.     if (*hdsaSubscriptions != NULL)    // Just to be sure
  1033.     {
  1034.         TraceMsg(TF_WARNING, "BackupSubscriptions : *hdsaSubscriptions was not Destroyed.");
  1035.         DSA_DestroyWithMembers(*hdsaSubscriptions);
  1036.     }
  1037.     BACKUPSUBSCRIPTION bsi;
  1038.     *hdsaSubscriptions = DSA_Create(SIZEOF(bsi), DXA_GROWTH_CONST);
  1039.     ISubscriptionMgr *psm;
  1040.     if (SUCCEEDED(CoCreateInstance(CLSID_SubscriptionMgr, NULL,
  1041.                 CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&psm)))
  1042.     {
  1043.         int cComp;
  1044.         g_pActiveDesk->GetDesktopItemCount(&cComp, 0);
  1045.         int i;
  1046.         COMPONENT comp;
  1047.         comp.dwSize = sizeof(COMPONENT);
  1048.         for (i=0; i<cComp; i++)
  1049.         {
  1050.             g_pActiveDesk->GetDesktopItem(i, &comp, 0);
  1051.             if(!comp.wszSource)
  1052.                 continue;
  1053.             LPTSTR  pszSource;
  1054. #ifndef UNICODE
  1055.             TCHAR   szSource[INTERNET_MAX_URL_LENGTH];
  1056.             SHUnicodeToAnsi(comp.wszSource, szSource, ARRAYSIZE(szSource));
  1057.             pszSource = szSource;
  1058. #else
  1059.             pszSource = comp.wszSource;
  1060. #endif
  1061.             if(PathIsURL(pszSource) && !UrlIsFileUrl(pszSource))
  1062.             {
  1063.                 LPTSTR  pszSubscribedURL;
  1064. #ifndef UNICODE
  1065.                 TCHAR   szSubscribedURL[INTERNET_MAX_URL_LENGTH];
  1066.                 SHUnicodeToAnsi(comp.wszSubscribedURL, szSubscribedURL, ARRAYSIZE(szSubscribedURL));
  1067.                 pszSubscribedURL = szSubscribedURL;
  1068. #else
  1069.                 pszSubscribedURL = comp.wszSubscribedURL;
  1070. #endif
  1071.                 if(CheckForExistingSubscription(pszSubscribedURL))
  1072.                 {
  1073.                     lstrcpynW(bsi.wszURL, comp.wszSubscribedURL, ARRAYSIZE(bsi.wszURL));
  1074.                     bsi.si.cbSize = sizeof(bsi.si);
  1075.                     bsi.si.fUpdateFlags = SUBSINFO_ALLFLAGS;
  1076.                     HRESULT hr = psm->GetSubscriptionInfo(bsi.wszURL, &bsi.si);
  1077.                     
  1078.                     if(SUCCEEDED(hr))
  1079.                     {
  1080.                         if (DSA_AppendItem(*hdsaSubscriptions, &bsi) == -1)
  1081.                         {
  1082.                             TraceMsg(TF_WARNING, "BackupSubscriptions : Unable to backup subscription info in DSA. Will have problems on clicking Cancel.");
  1083.                         }
  1084.                     }
  1085.                 }
  1086.             }
  1087.         }
  1088.         psm->Release();
  1089.     }
  1090.     else
  1091.     {
  1092.         TraceMsg(TF_WARNING, "BackupSubscriptions : CoCreateInstance for CLSID_SubscriptionMgr failed.");
  1093.     }
  1094. }
  1095. // Restores subscriptions.
  1096. void ReplaceSubscriptions(HDSA hdsaOldSubscriptions, HDSA hdsaNewSubscriptions, HWND hwnd)
  1097. {
  1098.     ISubscriptionMgr *psm;
  1099.     if (SUCCEEDED(CoCreateInstance(CLSID_SubscriptionMgr, NULL,
  1100.                 CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&psm)))
  1101.     {
  1102.         // First, delete subscriptions.
  1103.         BACKUPSUBSCRIPTION bsi;
  1104.         int cSubscriptions = DSA_GetItemCount(hdsaOldSubscriptions);
  1105.         int i;
  1106.         for(i = 0; i < cSubscriptions; i++)
  1107.         {
  1108.             DSA_GetItem(hdsaOldSubscriptions, i, &bsi);
  1109.             psm->DeleteSubscription(bsi.wszURL, NULL);
  1110.         }
  1111.         // Now, restore the subscriptions from hdsaNewSubscriptions
  1112.         cSubscriptions = DSA_GetItemCount(hdsaNewSubscriptions);
  1113.         for(i = 0; i < cSubscriptions; i++)
  1114.         {
  1115.             DSA_GetItem(hdsaNewSubscriptions, i, &bsi);
  1116.             bsi.si.cbSize = sizeof(bsi.si);
  1117.             psm->CreateSubscription(hwnd, bsi.wszURL, bsi.si.bstrFriendlyName, CREATESUBS_NOUI, SUBSTYPE_DESKTOPURL, &bsi.si);
  1118.         }
  1119.         psm->Release();
  1120.     }
  1121.     else
  1122.     {
  1123.         TraceMsg(TF_WARNING, "RestoreSubscriptions : CoCreateInstance for CLSID_SubscriptionMgr failed.");
  1124.     }
  1125. }
  1126. void DSA_DestroyWithMembers(HDSA hdsa)
  1127. {
  1128.     BACKUPSUBSCRIPTION bsi;
  1129.     int cSubscriptions = DSA_GetItemCount(hdsa);
  1130.     int i;
  1131.     for(i = 0; i < cSubscriptions; i++)
  1132.     {
  1133.         DSA_GetItem(hdsa, i, &bsi);
  1134.         if(bsi.si.bstrUserName)
  1135.         {
  1136.             SysFreeString(bsi.si.bstrUserName);
  1137.         }
  1138.         if(bsi.si.bstrPassword)
  1139.         {
  1140.             SysFreeString(bsi.si.bstrPassword);
  1141.         }
  1142.         if(bsi.si.bstrFriendlyName)
  1143.         {
  1144.             SysFreeString(bsi.si.bstrFriendlyName);
  1145.         }
  1146.     }
  1147.     DSA_Destroy(hdsa);
  1148. }
  1149. #endif