|
|
#include "priv.h"
#include <mstask.h>
#include "favorite.h"
#include "iehelpid.h"
#ifdef UNIX
#include "subsmgr.h"
#else
#include "webcheck.h"
#endif
#include "chanmgr.h"
#include "chanmgrp.h"
#include "resource.h"
#include <platform.h>
#include <mobsync.h>
#include <mobsyncp.h>
#include <mluisupp.h>
#ifdef UNIX
#include "unixstuff.h"
#include "shalias.h"
#endif
UINT IE_ErrorMsgBox(IShellBrowser* psb, HWND hwndOwner, HRESULT hrError, LPCWSTR szError, LPCTSTR pszURLparam, UINT idResource, UINT wFlags); void ReplaceTransplacedControls (HWND hDlgMaster, HWND hDlgTemplate);
///////////////////////////////////////////////////////////////////////
// helper function for DoOrganizeFavDlgEx
// the org favs dialog returns a list of null terminated strings containing
// all the urls to update.
void OrgFavSynchronize(HWND hwnd, VARIANT *pvarUrlsToSynch) { #ifndef DISABLE_SUBSCRIPTIONS
ASSERT(pvarUrlsToSynch); //if there are no urls to update, it's an empty string so bail
if ( (pvarUrlsToSynch->vt == VT_BSTR) && (pvarUrlsToSynch->bstrVal) && *(pvarUrlsToSynch->bstrVal) ) { PWSTR pwzUrls = pvarUrlsToSynch->bstrVal;
ISubscriptionMgr *psm;
if (SUCCEEDED(JITCoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&psm, hwnd, FIEF_FLAG_FORCE_JITUI))) { //SysStringLen doesn't look at the string contents, just the cb of the alloc
while (pwzUrls < (pvarUrlsToSynch->bstrVal + SysStringLen(pvarUrlsToSynch->bstrVal))) { psm->UpdateSubscription(pwzUrls); pwzUrls += lstrlenW(pwzUrls) + 1; }
psm->Release(); } } #endif /* !DISABLE_SUBSCRIPTIONS */
}
/*
* DoOrganizeFavDlgEx * * HWND hwnd Owner window for the dialog. * LPWSTR pszInitDir Dir to use as root. if null, the user's favorites dir is used. * * Returns: * BOOL. TRUE if succeeds. FALSE otherwise. * */
BOOL WINAPI DoOrganizeFavDlgEx(HWND hwnd, LPWSTR pszInitDir) { // The easy answer would be to add an about:OrganizeFavorites that
// gets registered in our selfreg.inx file. Unfortunately, multilanguage
// support requires us to generate the URL on the fly.
WCHAR wszUrl[6 + MAX_PATH + 11 + 1]; // "res://MAX_PATH/orgfav.dlg"
StrCpyNW(wszUrl, L"res://", 7);
#ifndef UNIX
GetModuleFileNameWrapW(MLGetHinst(), wszUrl+6, MAX_PATH); #else
// IEUNIX : GetModuleFilename returns /vobs/...../libbrowseui.so
// We need actual dllname here.
StrCpyNW(wszUrl + 6, L"shdocvw.dll" , 12); #endif
StrCatW(wszUrl, L"/orgfav.dlg");
IMoniker *pmk; if (SUCCEEDED(CreateURLMoniker(NULL, wszUrl, &pmk))) { ASSERT(pmk); VARIANT varUrlsToSynch, varInitialDir; BSTR bstrInitDir;
VariantInit(&varUrlsToSynch); VariantInit(&varInitialDir);
if (pszInitDir) { bstrInitDir = SysAllocString(pszInitDir); if (bstrInitDir) { varInitialDir.vt = VT_BSTR; varInitialDir.bstrVal = bstrInitDir; } } ShowHTMLDialog(hwnd, pmk, &varInitialDir, L"Resizable=1", &varUrlsToSynch); OrgFavSynchronize(hwnd, &varUrlsToSynch);
if (pszInitDir && bstrInitDir) SysFreeString(bstrInitDir); VariantClear(&varUrlsToSynch); pmk->Release(); return TRUE; } else return FALSE; }
/*
* DoOrganizeFavDlg * * This API is exported so that it may be called by explorer and mshtml in * addition to being called internally by shdocvw. * * HWND hwndOwner Owner window for the dialog. * LPWSTR pszInitDir Dir to use as root. if null, the user's favorites dir is used. * * Returns: * BOOL. TRUE if succeeds. FALSE otherwise. * */
BOOL WINAPI DoOrganizeFavDlg(HWND hwnd, LPSTR pszInitDir) { BOOL fRet; WCHAR szInitDir[MAX_PATH];
if (pszInitDir) { SHAnsiToUnicode(pszInitDir, szInitDir, ARRAYSIZE(szInitDir)); fRet = DoOrganizeFavDlgEx(hwnd, szInitDir); } else { fRet = DoOrganizeFavDlgEx(hwnd, NULL); }
return fRet; }
BOOL WINAPI DoOrganizeFavDlgW(HWND hwnd, LPWSTR pszInitDir) { return DoOrganizeFavDlgEx(hwnd, pszInitDir); }
#define ADDTOFAVPROP TEXT("SHDOC_ATFPROP")
typedef enum { ATF_FAVORITE, ATF_CHANNEL, ATF_CHANNEL_MODIFY, ATF_CHANNEL_SOFTDIST } FAVDLGTYPE;
typedef struct _ADDTOFAV { PTSTR pszInitDir; UINT cchInitDir; PTSTR pszFile; UINT cchFile; LPITEMIDLIST pidl; LPITEMIDLIST pidlSelected; LPCITEMIDLIST pidlFavorite; FAVDLGTYPE iDlgType; SUBSCRIPTIONINFO siSubsInProg; SUBSCRIPTIONTYPE subsType; BOOL bIsSoftdist; BOOL bStartSubscribed; BOOL bSubscribed; } ADDTOFAV;
BOOL IsSubscribed(ADDTOFAV *patf);
typedef struct _BFFFavSubStruct { WNDPROC lpfnOldWndProc; HWND hwndNew; HWND hwndTV; HWND hwndSave; HWND hTemplateWnd; ADDTOFAV * patf; RECT rcRestored; } BFFFAVSUBSTRUCT;
BOOL_PTR CALLBACK NewFavDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { HWND hwnd; ASSERT(lParam); SetWindowLongPtr(hDlg, DWLP_USER, lParam); EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); // cross-lang platform support
SHSetDefaultDialogFont(hDlg, IDD_NAME); hwnd = GetDlgItem(hDlg, IDD_NAME); #ifndef UNIX
SendMessage(hwnd, EM_LIMITTEXT, MAX_PATH - 1, 0); #else
// IEUNIX : file/dir name on unix is limited to _MAX_FNAME.
SendMessage(hwnd, EM_LIMITTEXT, (WPARAM)(_MAX_FNAME - 1), (LPARAM)0); #endif
EnableOKButtonFromID(hDlg, IDD_NAME); break; } case WM_DESTROY: SHRemoveDefaultDialogFont(hDlg); return FALSE;
case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDD_NAME: { if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_UPDATE) { LPTSTR lpstrName = (LPTSTR) GetWindowLongPtr(hDlg, DWLP_USER); EnableOKButtonFromID(hDlg, IDD_NAME); GetDlgItemText(hDlg, IDD_NAME, lpstrName, MAX_PATH); } break; }
case IDOK: { TCHAR szTmp[MAX_PATH]; StrCpyN(szTmp, (LPTSTR)GetWindowLongPtr(hDlg, DWLP_USER), ARRAYSIZE(szTmp)); if (PathCleanupSpec(NULL,szTmp)) { HWND hwnd;
MLShellMessageBox( hDlg, MAKEINTRESOURCE(IDS_FAVS_INVALIDFN), MAKEINTRESOURCE(IDS_FAVS_ADDTOFAVORITES), MB_OK | MB_ICONHAND); hwnd = GetDlgItem(hDlg, IDD_NAME); SetWindowText(hwnd, TEXT('\0')); EnableWindow(GetDlgItem(hDlg, IDOK), FALSE); SetFocus(hwnd); break; } } // fall through
case IDCANCEL: EndDialog(hDlg, GET_WM_COMMAND_ID(wParam, lParam)); break;
default: return FALSE; } break;
default: return FALSE; }
return TRUE; }
// BOGUS - these id's stolen from SHBrowseForFolder implementation
#define IDD_FOLDERLIST 0x3741
#define IDD_BROWSETITLE 0x3742
#define IDD_BROWSESTATUS 0x3743
const static DWORD aAddToFavHelpIDs[] = { // Context Help IDs
IDC_FAVORITE_DESC, NO_HELP, IDD_BROWSETITLE, NO_HELP, IDD_BROWSESTATUS, NO_HELP, IDC_FAVORITE_ICON, NO_HELP, IDC_NAMESTATIC, IDH_NAMEEDIT, IDC_FOLDERLISTSTATIC, IDH_BROWSELIST, IDC_SUBSCRIBE_FOLDERLIST_PLACEHOLDER, IDH_BROWSELIST, IDC_FAVORITE_NEWFOLDER, IDH_CREATEIN, IDC_SUBSCRIBE_CUSTOMIZE, IDH_CHANNEL_SUBSCR_CUST_BUTTON, IDC_FAVORITE_CREATEIN, IDH_NEWFOLDER, IDC_FAVORITE_NAME, IDH_NAMEEDIT, IDC_MAKE_OFFLINE, IDH_MAKE_AVAIL_OFFLINE, 0, 0 };
const static DWORD aAddToChanHelpIDs[] = { // Context Help IDs
IDC_FAVORITE_DESC, NO_HELP, IDD_BROWSETITLE, NO_HELP, IDD_BROWSESTATUS, NO_HELP, IDC_FAVORITE_ICON, NO_HELP, IDC_NAMESTATIC, IDH_NAMEEDIT, IDC_FOLDERLISTSTATIC, IDH_BROWSELIST, IDC_SUBSCRIBE_FOLDERLIST_PLACEHOLDER, IDH_BROWSELIST, IDC_FAVORITE_NEWFOLDER, IDH_CREATEIN, IDC_SUBSCRIBE_CUSTOMIZE, IDH_CHANNEL_SUBSCR_CUST_BUTTON, IDC_FAVORITE_CREATEIN, IDH_NEWFOLDER, IDC_FAVORITE_NAME, IDH_NAMEEDIT, IDC_MAKE_OFFLINE, IDH_MAKE_AVAIL_OFFLINE, 0, 0 };
/*
* Makes sure the item being added to favorites doesn't already exist. If it does, * puts up a message box to have the user confirm whether they want to overwrite * the old favorite or not. */ BOOL ConfirmAddToFavorites(HWND hwndOwner, ADDTOFAV * patf) { BOOL fRet = FALSE; BOOL fExists; int iPromptString = 0;
if (patf->subsType == SUBSTYPE_CHANNEL) { //patf->pszInitDir now contains the path with a .url on the end; the channel
//will be stored in a directory of that name without .url. Strip it.
TCHAR szPath[MAX_PATH]; StrCpyN(szPath, patf->pszInitDir, ARRAYSIZE(szPath)); PathRemoveExtension (szPath); fExists = PathFileExists(szPath);
iPromptString = IDS_CHANNELS_FILEEXISTS;
} else { fExists = PathFileExists(patf->pszInitDir); iPromptString = IDS_FAVS_FILEEXISTS;
}
fRet = ! fExists || (MLShellMessageBox( hwndOwner, MAKEINTRESOURCE(iPromptString), NULL, //use owner's title
MB_ICONQUESTION | MB_YESNO) == IDYES); return fRet; }
//
// Get the localized date and time
//
typedef HRESULT (*PFVARIANTTIMETOSYSTEMTIME)(DOUBLE, LPSYSTEMTIME);
//
// Subscribe to the current site.
//
HRESULT SubscribeToSite(HWND hwnd, LPCTSTR pszFile, LPCITEMIDLIST pidl, DWORD dwFlags, SUBSCRIPTIONINFO* pSubs, SUBSCRIPTIONTYPE subsType) { #ifndef DISABLE_SUBSCRIPTIONS
TCHAR szURL[MAX_URL_STRING]; ISubscriptionMgr *pISubscriptionMgr;
//
// Get a displayable URL.
//
IEGetDisplayName(pidl, szURL, SHGDN_FORPARSING);
//
// Get a pointer to the subscription manager.
//
HRESULT hr = JITCoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&pISubscriptionMgr, hwnd, FIEF_FLAG_FORCE_JITUI);
if (SUCCEEDED(hr)) { //
// Create a default subscription.
//
BSTR bstrURL = SysAllocStringT(szURL); if (bstrURL) { BSTR bstrName = SysAllocStringT(pszFile); if (bstrName) { hr = pISubscriptionMgr->CreateSubscription(hwnd, bstrURL, bstrName, dwFlags, subsType, pSubs); SysFreeString(bstrName); } SysFreeString(bstrURL); }
//
// Clean up.
//
pISubscriptionMgr->Release(); }
return hr; #else /* !DISABLE_SUBSCRIPTIONS */
return E_FAIL;
#endif /* !DISABLE_SUBSCRIPTIONS */
}
//
// Create in-memory subscription, but only optionally save it to subscription manager
//
BOOL StartSiteSubscription (HWND hwnd, ADDTOFAV* patf, BOOL bFinalize) { #ifndef DISABLE_SUBCRIPTIONS
//update the changes-only flag (radio buttons here are, effectively, direct access to this flag)
if (patf->subsType == SUBSTYPE_CHANNEL || patf->subsType == SUBSTYPE_DESKTOPCHANNEL) { //if set, leave alone; otherwise, put to full download
if (!(patf->siSubsInProg.fChannelFlags & CHANNEL_AGENT_PRECACHE_SOME)) patf->siSubsInProg.fChannelFlags |= CHANNEL_AGENT_PRECACHE_ALL;
patf->siSubsInProg.fUpdateFlags |= SUBSINFO_CHANNELFLAGS | SUBSINFO_SCHEDULE; }
if (S_OK != SubscribeToSite(hwnd, patf->pszFile, patf->pidlFavorite, bFinalize ? CREATESUBS_NOUI | CREATESUBS_FROMFAVORITES : CREATESUBS_NOSAVE, &patf->siSubsInProg, patf->subsType)) { return FALSE; }
return TRUE;
#else /* !DISABLE_SUBSCRIPTIONS */
return FALSE;
#endif /* !DISABLE_SUBSCRIPTIONS */
}
/*
Combines the path and the filename of the favorite and puts it into patf->pszInitDir, so that it has the fully qualified pathname. */ #define SZ_URLEXT TEXT(".url")
#define CCH_URLEXT SIZECHARS(SZ_URLEXT)
BOOL QualifyFileName(ADDTOFAV *patf) { TCHAR szTemp[MAX_PATH]; BOOL fRet = FALSE; LPTSTR pstr;
// Can we safely add the extension to this?
if (lstrlen(patf->pszFile) < (int)(patf->cchFile - CCH_URLEXT)) { //Add extension .url if its not already there
//This is to prevent strings like "com" in "www.microsoft.com" from being interpreted as extensions
pstr = PathFindExtension(patf->pszFile); if (!pstr || (pstr && StrCmpI(pstr, SZ_URLEXT)))// && StrCmpI(pstr, SZ_CDFEXT)))
StrCatBuff(patf->pszFile, SZ_URLEXT, patf->cchFile); // Is there a folder associated with the filename?
if (patf->pidlSelected && SHGetPathFromIDList(patf->pidlSelected, szTemp)) { // Yes
if (PathCombine(szTemp, szTemp, patf->pszFile)) { if ((UINT)lstrlen(szTemp) < patf->cchInitDir) { StrCpyN(patf->pszInitDir, szTemp, patf->cchInitDir); fRet = TRUE; } } } }
return fRet; }
BOOL SubscriptionFailsChannelAuthentication (HWND hDlg, SUBSCRIPTIONINFO* psi) { #ifndef DISABLE_SUBSCRIPTIONS
if (psi->bNeedPassword && !(psi->bstrPassword && psi->bstrPassword[0] && psi->bstrUserName && psi->bstrUserName[0])) { //password would be required
if (IsDlgButtonChecked (hDlg, IDC_MAKE_OFFLINE)) { //they're trying to subscribe... WRONG!
MLShellMessageBox( hDlg, MAKEINTRESOURCE(IDS_NEED_CHANNEL_PASSWORD), NULL, MB_ICONINFORMATION | MB_OK); return TRUE; } }
return FALSE;
#else /* !DISABLE_SUBSCRIPTIONS */
return FALSE;
#endif /* !DISABLE_SUBSCRIPTIONS */
}
LRESULT CALLBACK BFFFavSubclass(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { BFFFAVSUBSTRUCT * pbffFS = (BFFFAVSUBSTRUCT *)GetProp(hwnd, ADDTOFAVPROP); WNDPROC lpfnOldWndProc = pbffFS->lpfnOldWndProc; RECT rc;
switch (uMsg) { case WM_COMMAND: // Intercept the command for the New Folder button we hacked into
// the SHBrowseForFolder dialog.
switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_FAVORITE_NAME: { HWND hwndedit; if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE) EnableOKButtonFromID(hwnd, IDC_FAVORITE_NAME); hwndedit = GetDlgItem(hwnd, IDC_FAVORITE_NAME); SendMessage(hwndedit, EM_LIMITTEXT, MAX_PATH - 1, 0); break; }
#ifndef UNIX
// IEUNIX (OFFLINE) : No offline ability
case IDC_MAKE_OFFLINE: EnableWindow(GetDlgItem(hwnd, IDC_SUBSCRIBE_CUSTOMIZE), IsDlgButtonChecked(hwnd, IDC_MAKE_OFFLINE)); break;
case IDC_SUBSCRIBE_CUSTOMIZE: //need to create -- but not store -- subscription
if (StartSiteSubscription (hwnd, pbffFS->patf, FALSE)) SendMessage (hwnd, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hwnd, IDOK), TRUE); break; #endif
case IDC_FAVORITE_NEWFOLDER: TCHAR szPath[MAX_PATH]; TCHAR szName[MAX_PATH]; HWND hwndTV; TV_ITEM tv_item;
// Bring up the Create New Folder dialog
if ((DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(DLG_NEWFOLDER), hwnd, NewFavDlgProc, (LPARAM)szName) == IDOK) && (SHGetPathFromIDList(pbffFS->patf->pidlSelected, szPath)) && ((lstrlen(szPath) + lstrlen(szName) + 1) < MAX_PATH)) { PathCombine(szPath, szPath, szName);
BOOL bSuccess = FALSE;
#ifdef CREATEFOLDERSINCHANNELSDIR
if (pbffFS->patf->subsType == SUBSTYPE_CHANNEL) { ASSERT(0); //should not be possible in this release
//(I removed this button in the .rc dialogs for channels)
//Note: to make this work in a future release, reenable this code -- it's
//functional. But the folders created here show up ugly in the channel bar
//(just a default folder icon) and if you click on them, you get a shell
//Explorer window instead of a theater-mode browser window. The reason
//for this second happening is that the desktop.ini file created in the new
//folder has no URL=. To remedy this: AddCategory() has to be fixed so it
//doesn't interpret the pszURL argument as a UNC name (I was using a resouce moniker
//pointing into cdfview.dll for the html target), and the OC hosted by the default
//html pages has to learn how to be hosted from a html page without a path -- or we
//actually have to create an html page in the new directory, which is messy.
IChannelMgr* pChanMgr; HRESULT hr;
hr = JITCoCreateInstance(CLSID_ChannelMgr, NULL, CLSCTX_INPROC_SERVER, IID_IChannelMgr, (void**)&pChanMgr, hwnd, FIEF_FLAG_FORCE_JITUI);
if (SUCCEEDED(hr)) { IChannelMgrPriv* pChanMgrPriv; hr = pChanMgr->QueryInterface (IID_IChannelMgrPriv, (void**)&pChanMgrPriv); if (SUCCEEDED(hr)) { char szCFPath[MAX_PATH]; WCHAR wszFolder[MAX_PATH]; IChannelMgrPriv::CHANNELFOLDERLOCATION cflLocation = (pbffFS->patf->iDlgType == ATF_CHANNEL_SOFTDIST ? IChannelMgrPriv::CF_SOFTWAREUPDATE : IChannelMgrPriv::CF_CHANNEL); hr = pChanMgrPriv->GetChannelFolderPath (szCFPath, ARRAYSIZE(szCFPath), cflLocation);
int cchCommon = PathCommonPrefix (szPath, szCFPath, NULL); AnsiToUnicode (szPath + cchCommon, wszFolder, ARRAYSIZE(wszFolder));
CHANNELCATEGORYINFO info = {0}; info.cbSize = sizeof(info); info.pszTitle = wszFolder; bSuccess = SUCCEEDED (pChanMgr->AddCategory (&info));
pChanMgrPriv->Release(); }
pChanMgr->Release(); } } else #endif
{ bSuccess = CreateDirectory(szPath, NULL); }
if (bSuccess) { // This code assumes the layout of SHBrowseForFolder!
// directory successfully created, must notify registered shell components.
SHChangeNotify(SHCNE_MKDIR, SHCNF_PATH, szPath, NULL); // Get the TreeView control
hwndTV = GetDlgItem(hwnd, IDD_FOLDERLIST); if (hwndTV) { HTREEITEM hti = TreeView_GetSelection(hwndTV); // Take the selected item and reset it, then reexpand it so
// that it shows the new directory we just created.
tv_item.mask = TVIF_CHILDREN; tv_item.hItem = hti; tv_item.cChildren = -1; TreeView_SetItem(hwndTV, &tv_item); TreeView_Expand(hwndTV, hti, TVE_COLLAPSE | TVE_COLLAPSERESET); TreeView_Expand(hwndTV, hti, TVE_EXPAND);
// Find the new directory we just created and select it by
// walking the tree from the selected item down.
if (hti = TreeView_GetChild(hwndTV, hti)) { tv_item.mask = TVIF_TEXT; tv_item.pszText = szPath; tv_item.cchTextMax = MAX_PATH; do { tv_item.hItem = hti; TreeView_GetItem(hwndTV, &tv_item); if (StrCmp(szName, szPath) == 0) { TreeView_Select(hwndTV, hti, TVGN_CARET); break; } } while (hti = TreeView_GetNextSibling(hwndTV, hti)); } SetFocus(hwndTV); } } else { LPVOID lpMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, 0, NULL ); MLShellMessageBox( hwnd, (LPCTSTR)lpMsgBuf, MAKEINTRESOURCE(IDS_FAVS_ADDTOFAVORITES), MB_ICONINFORMATION | MB_OK); // Free the buffer.
LocalFree( lpMsgBuf ); lpMsgBuf = NULL; } } break;
case IDOK: // first, make sure they're not trying to subscribe to an authenticated
// channel without entering a password.
if (SubscriptionFailsChannelAuthentication (hwnd, &pbffFS->patf->siSubsInProg)) return FALSE;
// Retrieve the text from the Name edit control.
GetDlgItemText(hwnd, IDC_FAVORITE_NAME, pbffFS->patf->pszFile, pbffFS->patf->cchFile); { // Just a block to declare variables
BOOL fTooBig = TRUE; // assume failure
TCHAR szTmp[MAX_PATH]; if (lstrlen(pbffFS->patf->pszFile) < MAX_PATH) { StrCpyN(szTmp, pbffFS->patf->pszFile, ARRAYSIZE(szTmp));
// PathCleanupSpec deals with MAX_PATH buffers, so we should be fine
if (PathCleanupSpec(NULL, szTmp)) { MLShellMessageBox( hwnd, MAKEINTRESOURCE(IDS_FAVS_INVALIDFN), MAKEINTRESOURCE(IDS_FAVS_ADDTOFAVORITES), MB_OK | MB_ICONHAND); return FALSE; } // Make sure the name is unique and if not, that the user has
// specified that it is OK to override.
if (QualifyFileName(pbffFS->patf)) { if (!ConfirmAddToFavorites(hwnd, pbffFS->patf)) return FALSE;
// Bogus hack since the ATF stuff is only half done
// Depending on which dlg is shown, look for the appropriate
// check.
if (IsDlgButtonChecked (hwnd, IDC_MAKE_OFFLINE)) { //they want to subscribe! save subscription we already have in memory
//trouble is, pbffFS->patf->pszFile ends in a bogus .url
TCHAR* pszTemp = pbffFS->patf->pszFile; TCHAR szNoExt[MAX_PATH]; StrCpyN(szNoExt, pbffFS->patf->pszFile, ARRAYSIZE(szNoExt)); pbffFS->patf->pszFile = szNoExt; PathRemoveExtension (szNoExt); pbffFS->patf->bSubscribed = StartSiteSubscription (hwnd, pbffFS->patf, TRUE); pbffFS->patf->pszFile = pszTemp; } else if (pbffFS->patf->bStartSubscribed) { // If we started subscribed and they unchecked make available
// offline, then delete the subscription.
ISubscriptionMgr* pSubsMgr; if (SUCCEEDED (CoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&pSubsMgr))) { //url is in patf->pidlFavorite
WCHAR wszURL[MAX_URL_STRING]; IEGetDisplayName(pbffFS->patf->pidlFavorite, wszURL, SHGDN_FORPARSING);
pSubsMgr->DeleteSubscription(wszURL, NULL); pSubsMgr->Release(); } }
// Enable and set focus to the tree view so that it is sure to
// be selected so that SHBrowseForFolder will return a pidl.
EnableWindow(pbffFS->hwndTV, TRUE); SetFocus(pbffFS->hwndTV); fTooBig = FALSE; } }
#ifdef UNIX_FEATURE_ALIAS
if( !fTooBig ) { TCHAR alias[MAX_ALIAS_LENGTH]; TCHAR szThisURL[MAX_URL_STRING]; HDPA aliasList = GetGlobalAliasList();
if( aliasList ) { #ifdef UNICODE
// TODO :
#else
// Retrieve the text from the Alias edit control.
GetDlgItemText(hwnd, IDC_ALIAS_NAME, alias, MAX_ALIAS_LENGTH-1); IEGetDisplayName(pbffFS->patf->pidlFavorite, szThisURL, SHGDN_FORPARSING); if(AddAliasToListA( aliasList, alias, szThisURL, hwnd )) SaveAliases(aliasList); #endif
} } #endif /* UNIX_FEATURE_ALIAS */
if (fTooBig) { MLShellMessageBox( hwnd, MAKEINTRESOURCE(IDS_FAVS_FNTOOLONG), MAKEINTRESOURCE(IDS_FAVS_ADDTOFAVORITES), MB_OK | MB_ICONHAND); return FALSE; } } break;
case IDC_FAVORITE_CREATEIN: // The advanced button has been clicked. Enable/disable the tree view
// and New button, set focus to the tree view or ok button, disable the advanced
// button and then resize the dialog.
{ BOOL fExpanding = !IsWindowEnabled(GetDlgItem(hwnd, IDC_SUBSCRIBE_FOLDERLIST_PLACEHOLDER)); //random control that gets enabled when dialog expanded
TCHAR szBuffer[100];
EnableWindow(pbffFS->hwndTV, fExpanding); //don't show New Folder button for channels in the channels folder,
// see code for case IDC_FAVORITE_NEWFOLDER for why
if (fExpanding && pbffFS->patf->subsType == SUBSTYPE_CHANNEL) { LPITEMIDLIST pidlFavs = NULL; TCHAR tzFavsPath[MAX_PATH]; if (SUCCEEDED(SHGetSpecialFolderLocation(hwnd, CSIDL_FAVORITES, &pidlFavs)) && SUCCEEDED(SHGetNameAndFlags(pidlFavs, SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, tzFavsPath, SIZECHARS(tzFavsPath), NULL)) && StrCmpNI(tzFavsPath, pbffFS->patf->pszInitDir, ARRAYSIZE(tzFavsPath))==0) { EnableWindow(pbffFS->hwndNew, TRUE); } if(pidlFavs) ILFree(pidlFavs); } else EnableWindow(pbffFS->hwndNew, fExpanding);
GetWindowRect(hwnd, &rc); if (fExpanding) { int lRet = MLLoadString(IDS_FAVS_ADVANCED_COLLAPSE, szBuffer, ARRAYSIZE(szBuffer)); ASSERT(lRet); SetFocus(pbffFS->hwndTV);
MoveWindow(hwnd, rc.left, rc.top, pbffFS->rcRestored.right - pbffFS->rcRestored.left, pbffFS->rcRestored.bottom - pbffFS->rcRestored.top, TRUE); } else { int lRet = MLLoadString(IDS_FAVS_ADVANCED_EXPAND, szBuffer, ARRAYSIZE(szBuffer)); ASSERT(lRet); SetFocus(GetDlgItem(hwnd, IDC_FAVORITE_NAME));
MoveWindow(hwnd, rc.left, rc.top, pbffFS->rcRestored.right - pbffFS->rcRestored.left, pbffFS->rcRestored.bottom - pbffFS->rcRestored.top, TRUE);
// hide the bottom part of the dialog
int cx, cy; RECT rc; GetWindowRect (GetDlgItem (hwnd, IDC_SUBSCRIBE_FOLDERLIST_PLACEHOLDER), &rc); cy = rc.top; GetWindowRect (hwnd, &rc); cx = rc.right - rc.left; cy = cy /*top of ctrl*/ - rc.top; /*top of window*/ SetWindowPos (hwnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER); } SetWindowText(GetDlgItem(hwnd, IDC_FAVORITE_CREATEIN), szBuffer);
break; } } break;
case WM_DESTROY: { DWORD dwValue = IsWindowEnabled(GetDlgItem(hwnd, IDC_FAVORITE_NEWFOLDER)); //random control that gets enabled when dialog expanded
SHRegSetUSValue(TEXT("Software\\Microsoft\\Internet Explorer\\Main"), TEXT("AddToFavoritesExpanded"), REG_DWORD, &dwValue, 4, SHREGSET_HKCU | SHREGSET_FORCE_HKCU); ReplaceTransplacedControls (hwnd, pbffFS->hTemplateWnd); DestroyWindow (pbffFS->hTemplateWnd); SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR) lpfnOldWndProc); RemoveProp(hwnd, ADDTOFAVPROP); SHRemoveDefaultDialogFont(hwnd); ILFree(pbffFS->patf->pidlSelected); LocalFree((HLOCAL)pbffFS); pbffFS = NULL; break; } case WM_HELP: SHWinHelpOnDemandWrap((HWND)((LPHELPINFO) lParam)->hItemHandle, c_szHelpFile, HELP_WM_HELP, (DWORD_PTR)(LPTSTR) (pbffFS->patf->iDlgType == ATF_FAVORITE ? aAddToFavHelpIDs : aAddToChanHelpIDs)); return TRUE; break;
case WM_CONTEXTMENU: SHWinHelpOnDemandWrap((HWND) wParam, c_szHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) (pbffFS->patf->iDlgType == ATF_FAVORITE ? aAddToFavHelpIDs : aAddToChanHelpIDs)); return TRUE; break;
}
return CallWindowProc(lpfnOldWndProc, hwnd, uMsg, wParam, lParam); }
static const TCHAR szTransplacedProp[] = TEXT("tp"); void ReplaceTransplacedControls (HWND hDlgMaster, HWND hDlgTemplate) { /*
* This function moves the controls that we moved from our temporary * dialog over to SHBrowseForFolder's dialog, back to their original * home, before they get destroyed. This is because otherwise we have * problems when destroying the template dialog -- specifically, we get * a GP fault in user.exe when destroying the edit control, because it * looks to its parent window to figure out where its data segment is. * * Solution: (for safety) -- put everything back where it came from. * Other possibilities: just move the edit control (by ID) back, or * move all edit controls back, or use DS_LOCALEDIT for edit controls * (but this is documented only for use with multiline edits.) * Or modify SHBrowseForFolder to allow other dialog templates... * but that's over in shell32. */ HWND hCtrl = GetWindow (hDlgMaster, GW_CHILD); while (hCtrl) { HWND hNext = GetWindow (hCtrl, GW_HWNDNEXT);
if (GetProp (hCtrl, szTransplacedProp) != NULL) { RemoveProp (hCtrl, szTransplacedProp); SetParent (hCtrl, hDlgTemplate); }
hCtrl = hNext; } }
#define szOriginalWND TEXT("WorkaroundOrigWndProc")
INT_PTR CALLBACK MergeFavoritesDialogControls(HWND hDlgTemplate, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_INITDIALOG: { HWND hDlgMaster = (HWND)lParam; ASSERT (IsWindow (hDlgMaster));
TCHAR szT[200]; RECT rc;
//resize master like us
GetWindowText (hDlgTemplate, szT, ARRAYSIZE(szT)); SetWindowText (hDlgMaster, szT); GetClientRect (hDlgTemplate, &rc); AdjustWindowRect (&rc, GetWindowLong (hDlgMaster, GWL_STYLE), FALSE); SetWindowPos (hDlgMaster, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER); // a-msadek; If the owned window is mirrored, a dialog with specifed
// coordinates, the dialog get moved to the worng direction
HWND hWndOwner = GetWindow(hDlgMaster, GW_OWNER);
if(IS_WINDOW_RTL_MIRRORED(hWndOwner)) { RECT rcOwner, rcDlg; GetWindowRect(hWndOwner, &rcOwner); GetWindowRect(hDlgMaster, &rcDlg); SetWindowPos(hDlgMaster, NULL, rcDlg.left - (rcDlg.right - rcOwner.right), rcDlg.top, 0 ,0, SWP_NOSIZE | SWP_NOZORDER); }
#if 0 //now we do this as part of the "move controls from template to master" process,
//if we notice that a ctrl with that id already exists. This way we pick up the
//tab order too. If someone decides my hack (SetParent) to change tab order is
//broken, then that code can be nuked and this reenabled.
//position already-existing controls in master like us
int ID_PREEXIST_CTRLS[] = { IDOK_PLACEHOLDER, IDCANCEL_PLACEHOLDER, IDC_SUBSCRIBE_FOLDERLIST_PLACEHOLDER };
for (int iCtrl = 0; iCtrl < ARRAYSIZE(ID_PREEXIST_CTRLS); iCtrl++) { GetWindowRect (GetDlgItem (hDlgTemplate, ID_PREEXIST_CTRLS[iCtrl]), &rc); MapWindowPoints (NULL, hDlgTemplate, (LPPOINT)&rc, 2); MoveWindow (GetDlgItem (hDlgMaster, ID_PREEXIST_CTRLS[iCtrl]), rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
DestroyWindow (GetDlgItem (hDlgTemplate, ID_PREEXIST_CTRLS[iCtrl])); } #endif
//copy other controls from us to master
//find last child
HWND hCtrlTemplate = NULL; HWND hNextCtrl = GetWindow (hDlgTemplate, GW_CHILD); if (hNextCtrl) //can't see how this would fail, but...
hCtrlTemplate = GetWindow (hNextCtrl, GW_HWNDLAST);
//have last window in hCtrlTemplate
//now move controls over in reverse order -- they'll end up stacking up in original order from template
while (hCtrlTemplate) { hNextCtrl = GetWindow (hCtrlTemplate, GW_HWNDPREV); DWORD id = GetWindowLong (hCtrlTemplate, GWL_ID); HWND hCtrlExisting; if (id != (USHORT)IDC_STATIC && NULL != (hCtrlExisting = GetDlgItem (hDlgMaster, id))) //it's one of the controls pre-created by SHBrowseForFolder
{ //so don't move this one over -- adjust existing control for size, position, tab order
RECT rc; GetWindowRect (hCtrlTemplate, &rc); MapWindowPoints (NULL, hDlgTemplate, (LPPOINT)&rc, 2); SetWindowPos (hCtrlExisting, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOACTIVATE | SWP_NOZORDER); DestroyWindow (hCtrlTemplate); //REVIEW
//hack -- send control to end of tab order
SetParent (hCtrlExisting, hDlgTemplate); SetParent (hCtrlExisting, hDlgMaster); } else //we should move this control from template to master
{ SetProp (hCtrlTemplate, szTransplacedProp, (HANDLE)TRUE); //anything -- it's the existence of the prop that we check for
SetParent (hCtrlTemplate, hDlgMaster); //to know to move this control back later
} hCtrlTemplate = hNextCtrl; } // Let Template know about the child so that it can forward WM_COMMAND notifications to it
// to work around the fact that edit controls cache their parent pointers and ignore SetParents
// when it comes to sending parent notifications
SetProp(hDlgTemplate, szOriginalWND, hDlgMaster); }
break; case WM_COMMAND: // Workaround for above bug
SendMessage((HWND)GetProp(hDlgTemplate, szOriginalWND), uMsg, wParam, lParam); break; }
return FALSE; }
int CALLBACK BFFFavCallback(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { switch (uMsg) { case BFFM_INITIALIZED: { ADDTOFAV* patf = (ADDTOFAV*)lpData; ASSERT (patf);
HWND hDlgTemp = CreateDialogParam(MLGetHinst(), MAKEINTRESOURCE(IDD_ADDTOFAVORITES_TEMPLATE), NULL, MergeFavoritesDialogControls, (LPARAM)hwnd); //this results in all the controls being copied over
//if successful, make our other modifications
BFFFAVSUBSTRUCT * pbffFavSubStruct; if ((IsWindow(GetDlgItem(hwnd, IDC_SUBSCRIBE_CUSTOMIZE))) //verify existence of randomly-selected control
&& (pbffFavSubStruct = (BFFFAVSUBSTRUCT *) LocalAlloc(LPTR, sizeof(BFFFAVSUBSTRUCT)))) { //done with template, but don't destroy it:
//see MSKB Q84190, owner/owned vs parent/child -- the children
// of template are now children of master, but still OWNED
// by template, and are destroyed when template is destroyed...
// but we'll just keep template around
// invisibly.
//we'll take care of it when we go away
//Do we need to do SetDefaultDialogFont stuff for localization still, since it all comes from the .rc?
//set up window stuff for subclass:
// Get the TreeView control so we can muck with the style bits and move it down
HWND hwndT; if (hwndT = GetDlgItem(hwnd, IDD_FOLDERLIST)) { DWORD dwStyle = GetWindowLong(hwndT, GWL_STYLE); dwStyle |= TVS_SHOWSELALWAYS; dwStyle &= ~TVS_LINESATROOT; SetWindowLong(hwndT, GWL_STYLE, dwStyle); }
// don't allow subscriptions if the URL is not "http:" protocol, or if already subscribed
TCHAR szURL[MAX_URL_STRING];
if (!patf->pidlFavorite || FAILED(IEGetDisplayName(patf->pidlFavorite, szURL, SHGDN_FORPARSING)) || SHRestricted2(REST_NoAddingSubscriptions, szURL, 0) || !IsSubscribable(szURL) || !IsFeaturePotentiallyAvailable(CLSID_SubscriptionMgr) || !IsBrowserFrameOptionsPidlSet(patf->pidlFavorite, BFO_USE_IE_OFFLINE_SUPPORT)) { CheckDlgButton(hwnd, IDC_MAKE_OFFLINE, 0); EnableWindow(GetDlgItem (hwnd, IDC_MAKE_OFFLINE), FALSE); EnableWindow(GetDlgItem (hwnd, IDC_SUBSCRIBE_CUSTOMIZE), FALSE); } else if (IsSubscribed(patf)) { patf->bStartSubscribed = TRUE; CheckDlgButton(hwnd, IDC_MAKE_OFFLINE, 1); } else if (patf->bIsSoftdist) { CheckDlgButton(hwnd, IDC_MAKE_OFFLINE, 1); } EnableWindow(GetDlgItem(hwnd, IDC_SUBSCRIBE_CUSTOMIZE), IsDlgButtonChecked(hwnd, IDC_MAKE_OFFLINE));
//set the name
Edit_LimitText(GetDlgItem(hwnd, IDC_FAVORITE_NAME), MAX_PATH - 1);
// Use URL if title string is not displayable
if (SHIsDisplayable(patf->pszFile, g_fRunOnFE, g_bRunOnNT5)) { SetDlgItemText(hwnd, IDC_FAVORITE_NAME, patf->pszFile); } else { TCHAR szUrlTemp[MAX_URL_STRING]; IEGetDisplayName(patf->pidlFavorite, szUrlTemp, SHGDN_FORPARSING); SetDlgItemText(hwnd, IDC_FAVORITE_NAME, szUrlTemp); }
EnableOKButtonFromID(hwnd, IDC_FAVORITE_NAME);
// hide the (empty) SHBrowseForFolder prompt control
ShowWindow(GetDlgItem (hwnd, IDD_BROWSETITLE), SW_HIDE);
// Fill out the structure and set it as a property so that our subclass
// proc can get to this data.
pbffFavSubStruct->lpfnOldWndProc = (WNDPROC) SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)BFFFavSubclass); pbffFavSubStruct->hwndNew = GetDlgItem(hwnd, IDC_FAVORITE_NEWFOLDER); pbffFavSubStruct->patf = patf; pbffFavSubStruct->hwndTV = GetDlgItem(hwnd, IDC_SUBSCRIBE_FOLDERLIST_PLACEHOLDER); pbffFavSubStruct->hwndSave = GetDlgItem(hwnd, IDC_FAVORITE_CREATEIN); pbffFavSubStruct->hTemplateWnd = hDlgTemp; //save for explicit destruction later
GetWindowRect(hwnd, &(pbffFavSubStruct->rcRestored));
SetProp(hwnd, ADDTOFAVPROP, (HANDLE)pbffFavSubStruct);
patf->pidlSelected = ILClone(patf->pidl);
DWORD dwType, dwValue = 0, dwcData = sizeof(dwValue); TCHAR szBuffer[100]; SHRegGetUSValue(TEXT("Software\\Microsoft\\Internet Explorer\\Main"), TEXT("AddToFavoritesExpanded"), &dwType, &dwValue, &dwcData, 0, NULL, sizeof(dwValue));
if (dwValue == 0) { int lRet = MLLoadString(IDS_FAVS_ADVANCED_EXPAND, szBuffer, ARRAYSIZE(szBuffer)); ASSERT(lRet);
// Disable the tree view and new button so that we can't tab to them.
EnableWindow(GetDlgItem (hwnd, IDC_SUBSCRIBE_FOLDERLIST_PLACEHOLDER), FALSE); EnableWindow(GetDlgItem (hwnd, IDC_FAVORITE_NEWFOLDER), FALSE);
// hide the bottom part of the dialog
int cx, cy; RECT rc; GetWindowRect (GetDlgItem (hwnd, IDC_SUBSCRIBE_FOLDERLIST_PLACEHOLDER), &rc); cy = rc.top; GetWindowRect (hwnd, &rc); cx = rc.right - rc.left; cy = cy /*top of ctrl*/ - rc.top; /*top of window*/ SetWindowPos (hwnd, NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER); } else { //don't show New Folder button for channels in the channels folder,
// see code for case IDC_FAVORITE_NEWFOLDER for why
if (patf->subsType == SUBSTYPE_CHANNEL) { LPITEMIDLIST pidlFavs = NULL; TCHAR tzFavsPath[MAX_PATH]; if (SUCCEEDED(SHGetSpecialFolderLocation(hwnd, CSIDL_FAVORITES, &pidlFavs)) && SUCCEEDED(SHGetNameAndFlags(pidlFavs, SHGDN_FORPARSING | SHGDN_FORADDRESSBAR, tzFavsPath, SIZECHARS(tzFavsPath), NULL)) && 0 == StrCmpNI(tzFavsPath, patf->pszInitDir, ARRAYSIZE(tzFavsPath))) { EnableWindow(pbffFavSubStruct->hwndNew, TRUE); } else EnableWindow(pbffFavSubStruct->hwndNew, FALSE);
if(pidlFavs) ILFree(pidlFavs); } else EnableWindow(pbffFavSubStruct->hwndNew, TRUE); int lRet = MLLoadString(IDS_FAVS_ADVANCED_COLLAPSE, szBuffer, ARRAYSIZE(szBuffer)); ASSERT(lRet); } SetWindowText(GetDlgItem(hwnd, IDC_FAVORITE_CREATEIN), szBuffer); } else { EndDialog(hwnd, IDCANCEL); } break; } case BFFM_SELCHANGED: { //the first of these comes during BFFM_INITIALIZED, so ignore it
if (((ADDTOFAV *)lpData)->pidlSelected != NULL) { ILFree(((ADDTOFAV *)lpData)->pidlSelected); ((ADDTOFAV *)lpData)->pidlSelected = ILClone((LPITEMIDLIST)lParam); } break; } }
return 0; }
// This API is not exported. See below (DoAddToFavDlg) for the exported version
//
// hwnd parent window for the dialog.
// pszInitDir input: initial path
// output: fully qualified path and filename
// chInitDir Length of pszInitDir buffer
// pszFile initial (default) filename for shortcut
// cchFile Length of pszFile buffer
// pidlBrowse associated with pszInitDir
//
// Returns:
// TRUE if a directory and filename were selected by user, and no error
// occurs. In this case pszInitDir contains the new destination directory
// and filename, pszFile contains the new file name.
//
// FALSE if an error occurs or the user selects CANCEL.
STDAPI_(BOOL) DoAddToFavDlgEx(HWND hwnd, TCHAR *pszInitDir, UINT cchInitDir, TCHAR *pszFile, UINT cchFile, LPITEMIDLIST pidlBrowse, LPCITEMIDLIST pidlFavorite, FAVDLGTYPE atfDlgType, SUBSCRIPTIONINFO* pInfo) { ADDTOFAV atf = {pszInitDir, cchInitDir - 1, pszFile, cchFile - 1, pidlBrowse, NULL, pidlFavorite, atfDlgType, {sizeof(SUBSCRIPTIONINFO), 0}, SUBSTYPE_URL }; TCHAR szTemp[1]; //NOTE: we're not using SHBrowseForFolder's prompt string (see below)
TCHAR szDisplayName[MAX_PATH]; BROWSEINFO bi = { hwnd, pidlBrowse, szDisplayName, szTemp, BIF_RETURNONLYFSDIRS, // (BFFCALLBACK)
BFFFavCallback, (LPARAM)&atf, 0 }; LPITEMIDLIST pidl;
if (pInfo) atf.siSubsInProg = *pInfo;
switch (atfDlgType) { case ATF_CHANNEL_SOFTDIST: atf.bIsSoftdist = TRUE; // fall through
case ATF_CHANNEL: atf.subsType = SUBSTYPE_CHANNEL; break;
//default:
// set in initialize to SUBSTYPE_URL
}
//this string is now in the template dialog in the .rc
//REVIEW -- do we want to do it this way (we're hiding SHBrowse...'s control)? then the template dialog looks more like the finished product...
szTemp[0] = 0; //init native font control, otherwise dialog may fail to initialize
{ INITCOMMONCONTROLSEX icc;
icc.dwSize = sizeof(INITCOMMONCONTROLSEX); icc.dwICC = ICC_NATIVEFNTCTL_CLASS; InitCommonControlsEx(&icc); } pidl = SHBrowseForFolder(&bi);
if (pidl) { ILFree(pidl); }
// If the user created a new subscription, start a download.
if (atf.bSubscribed && !atf.bStartSubscribed) { ISubscriptionMgr* pSubsMgr; if (SUCCEEDED (CoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&pSubsMgr))) { WCHAR wszURL[MAX_URL_STRING];
IEGetDisplayName(atf.pidlFavorite, wszURL, SHGDN_FORPARSING);
pSubsMgr->UpdateSubscription(wszURL); pSubsMgr->Release(); } }
return (pidl != NULL); }
STDAPI_(BOOL) DoSafeAddToFavDlgEx(HWND hwnd, TCHAR *pszInitDir, UINT cchInitDir, TCHAR *pszFile, UINT cchFile, LPITEMIDLIST pidlBrowse, LPCITEMIDLIST pidlFavorite, FAVDLGTYPE atfDlgType, SUBSCRIPTIONINFO* pInfo) { BOOL fRet;
if (IEIsLinkSafe(hwnd, pidlFavorite, ILS_ADDTOFAV)) { fRet = DoAddToFavDlgEx(hwnd, pszInitDir, cchInitDir, pszFile, cchFile, pidlBrowse, pidlFavorite, atfDlgType, pInfo); } else { fRet = FALSE; }
return fRet; }
// This API is exported so that it may be called by explorer and mshtml (and MSNVIEWR.EXE)
// in addition to being called internally by shdocvw.
// THEREFORE YOU MUST NOT CHANGE THE SIGNATURE OF THIS API
//
STDAPI_(BOOL) DoAddToFavDlg(HWND hwnd, CHAR *pszInitDir, UINT cchInitDir, CHAR *pszFile, UINT cchFile, LPITEMIDLIST pidlBrowse) { BOOL fRet;
WCHAR szInitDir[MAX_PATH]; WCHAR szFile[MAX_PATH];
SHAnsiToUnicode(pszInitDir, szInitDir, ARRAYSIZE(szInitDir)); SHAnsiToUnicode(pszFile, szFile, ARRAYSIZE(szFile));
fRet = DoSafeAddToFavDlgEx(hwnd, szInitDir, ARRAYSIZE(szInitDir), szFile, ARRAYSIZE(szFile), pidlBrowse, NULL, ATF_FAVORITE, NULL);
SHUnicodeToAnsi(szInitDir, pszInitDir, cchInitDir); SHUnicodeToAnsi(szFile, pszFile, cchFile);
return fRet; }
STDAPI_(BOOL) DoAddToFavDlgW(HWND hwnd, WCHAR *pszInitDir, UINT cchInitDir, WCHAR *pszFile, UINT cchFile, LPITEMIDLIST pidlBrowse) { return DoSafeAddToFavDlgEx(hwnd, pszInitDir, cchInitDir, pszFile, cchFile, pidlBrowse, NULL, ATF_FAVORITE, NULL); }
STDAPI AddToFavoritesEx(HWND hwnd, LPCITEMIDLIST pidlCur, LPCTSTR pszTitle, DWORD dwFlags, SUBSCRIPTIONINFO *pInfo, IOleCommandTarget *pCommandTarget, IHTMLDocument2 *pDoc); STDAPI AddToChannelsEx (HWND hwnd, LPCITEMIDLIST pidlUrl, LPTSTR pszName, LPCWSTR pwszURL, DWORD dwFlags, SUBSCRIPTIONINFO* pInfo); STDAPI SubscribeFromFavorites (HWND hwnd, LPCITEMIDLIST pidlUrl, LPTSTR pszName, DWORD dwFlags, SUBSCRIPTIONTYPE subsType, SUBSCRIPTIONINFO *pInfo);
// This API is exported privately, and is called by ISubscriptionMgr::CreateSubscription.
// shuioc uses it too.
STDAPI SHAddSubscribeFavoriteEx ( HWND hwnd, LPCWSTR pwszURL, LPCWSTR pwszName, DWORD dwFlags, SUBSCRIPTIONTYPE subsType, SUBSCRIPTIONINFO* pInfo, IOleCommandTarget *pcmdt, IHTMLDocument2 *pDoc) { TCHAR szName[MAX_PATH]; LPITEMIDLIST pidl = NULL; HRESULT hr; if (pwszURL==NULL || pwszName == NULL) return E_INVALIDARG; //
// Need to put pwszName into a buffer because it comes in const
// but gets modified in SubscribeFromFavorites.
//
StrCpyN(szName, pwszName, ARRAYSIZE(szName));
hr = IECreateFromPath(pwszURL, &pidl); if (SUCCEEDED(hr)) { ASSERT (pidl);
if (dwFlags & CREATESUBS_FROMFAVORITES) { if (subsType != SUBSTYPE_URL && subsType != SUBSTYPE_CHANNEL) { ASSERT(0); hr = E_INVALIDARG; } else { hr = SubscribeFromFavorites (hwnd, pidl, szName, dwFlags, subsType, pInfo); } } else { if (subsType == SUBSTYPE_URL) { hr = AddToFavoritesEx (hwnd, pidl, szName, dwFlags, pInfo, pcmdt, pDoc); } else if (subsType == SUBSTYPE_CHANNEL && !SHIsRestricted2W(hwnd, REST_NoChannelUI, NULL, 0)) { hr = AddToChannelsEx (hwnd, pidl, szName, pwszURL, dwFlags, pInfo); } else { ASSERT (0); hr = E_INVALIDARG; } }
ILFree(pidl); } return hr; }
STDAPI SHAddSubscribeFavorite (HWND hwnd, LPCWSTR pwszURL, LPCWSTR pwszName, DWORD dwFlags, SUBSCRIPTIONTYPE subsType, SUBSCRIPTIONINFO* pInfo) { return SHAddSubscribeFavoriteEx ( hwnd, pwszURL, pwszName, dwFlags, subsType, pInfo, NULL, NULL); }
// this API is also exported via the .def
// Use for backward compatibility only -- note that it is only for URL's (not channels)
// and doesn't know how to subscribe.
STDAPI AddUrlToFavorites(HWND hwnd, LPWSTR pszUrlW, LPWSTR pszTitleW, BOOL fDisplayUI) { return SHAddSubscribeFavorite (hwnd, pszUrlW, pszTitleW, fDisplayUI ? CREATESUBS_NOUI : 0, SUBSTYPE_URL, NULL); }
// this API is in the .h and is used elsewhere in shdocvw, but is not exported
// Backward compatibility only -- only for URL's (not channels) and can subscribe, but can't
// pass in subscriptioninfo starter.
STDAPI AddToFavorites( HWND hwnd, LPCITEMIDLIST pidlCur, LPCTSTR pszTitle, BOOL fDisplayUI, IOleCommandTarget *pCommandTarget, IHTMLDocument2 *pDoc) { return AddToFavoritesEx (hwnd, pidlCur, pszTitle, fDisplayUI ? 0 : CREATESUBS_NOUI, NULL, pCommandTarget, pDoc); }
//helper function to create one column in a ListView control, add one item to that column,
//size the column to the width of the control, and color the control like a static...
//basically, like SetWindowText for a ListView. Because we use a lot of ListViews to display
//urls that would otherwise be truncated... the ListView gives us automatic ellipsis and ToolTip.
void SetListViewToString (HWND hLV, LPCTSTR pszString) { ASSERT(hLV); LV_COLUMN lvc = {0}; RECT lvRect; GetClientRect (hLV, &lvRect); lvc.mask = LVCF_WIDTH; lvc.cx = lvRect.right - lvRect.left; if (-1 == ListView_InsertColumn(hLV, 0, &lvc)) { ASSERT(0); }
SendMessage(hLV, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_INFOTIP, LVS_EX_INFOTIP);
LV_ITEM lvi = {0}; lvi.iSubItem = 0; lvi.pszText = (LPTSTR)pszString; lvi.mask = LVIF_TEXT; ListView_InsertItem(hLV, &lvi); ListView_EnsureVisible(hLV, 0, TRUE); ListView_SetBkColor(hLV, GetSysColor(COLOR_BTNFACE)); ListView_SetTextBkColor(hLV, GetSysColor(COLOR_BTNFACE)); }
INT_PTR CALLBACK SubscribeFavoriteDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { ADDTOFAV * patf = (ADDTOFAV*)GetProp(hDlg, ADDTOFAVPROP);
switch (uMsg) { case WM_INITDIALOG: { TCHAR szURL[MAX_URL_STRING];
patf = (ADDTOFAV*)lParam; SetProp(hDlg, ADDTOFAVPROP, (HANDLE)patf);
//set up name and url displays
SetDlgItemText (hDlg, IDC_CHANNEL_NAME, patf->pszFile); //url is in patf->pidlFavorite
IEGetDisplayName(patf->pidlFavorite, szURL, SHGDN_FORPARSING); SetListViewToString (GetDlgItem (hDlg, IDC_CHANNEL_URL), szURL);
//now the tricky part... this is for modifying the subscription associated with
//an existing ChannelBar shortcut. We need to find out if they are subscribed --
//if so, load the existing subscription into memory so it can be modified in the
//wizard. If not, leave the information that was passed up because it's got the
//schedule extracted from the CDF. In either case, check the radio button that
//corresponds to their current subscription level.
ISubscriptionMgr* pSubsMgr; BOOL bSubs = FALSE;
HRESULT hr = JITCoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&pSubsMgr, hDlg, FIEF_FLAG_FORCE_JITUI | FIEF_FLAG_PEEK);
if (SUCCEEDED(hr)) { pSubsMgr->IsSubscribed(szURL, &bSubs);
patf->bStartSubscribed = bSubs;
pSubsMgr->Release(); } else if ((E_ACCESSDENIED == hr) || !IsBrowserFrameOptionsPidlSet(patf->pidlFavorite, BFO_USE_IE_OFFLINE_SUPPORT)) { EnableWindow(GetDlgItem(hDlg, IDC_MAKE_OFFLINE), FALSE); }
if (!bSubs && patf->bIsSoftdist) { bSubs = TRUE; }
CheckDlgButton(hDlg, IDC_MAKE_OFFLINE, bSubs ? 1 : 0); EnableWindow(GetDlgItem (hDlg, IDC_SUBSCRIBE_CUSTOMIZE), bSubs); } break;
case WM_DESTROY: RemoveProp (hDlg, ADDTOFAVPROP); break;
case WM_HELP: SHWinHelpOnDemandWrap((HWND)((LPHELPINFO) lParam)->hItemHandle, c_szHelpFile, HELP_WM_HELP, (DWORD_PTR)(LPTSTR) (patf->iDlgType == ATF_FAVORITE ? aAddToFavHelpIDs : aAddToChanHelpIDs)); return TRUE; break;
case WM_CONTEXTMENU: SHWinHelpOnDemandWrap((HWND) wParam, c_szHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPVOID) (patf->iDlgType == ATF_FAVORITE ? aAddToFavHelpIDs : aAddToChanHelpIDs)); return TRUE; break;
case WM_COMMAND: ASSERT (patf); switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDCANCEL: EndDialog(hDlg, IDCANCEL); break;
case IDOK: // first, make sure they're not trying to subscribe to an authenticated
// channel without entering a password.
if (SubscriptionFailsChannelAuthentication (hDlg, &patf->siSubsInProg)) return FALSE;
//find out whether they WERE subscribed, so if they click OK and they
//were already subscribed, we delete that subscription -- and either leave it
//deleted if "No subs" was the choice, or create the new one.
ISubscriptionMgr* pSubsMgr; if (SUCCEEDED (JITCoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&pSubsMgr, hDlg, FIEF_FLAG_FORCE_JITUI))) { //url is in patf->pidlFavorite
TCHAR szURL[MAX_URL_STRING]; IEGetDisplayName(patf->pidlFavorite, szURL, SHGDN_FORPARSING);
BOOL bAlreadySubs; if (SUCCEEDED (pSubsMgr->IsSubscribed (szURL, &bAlreadySubs)) && bAlreadySubs) { pSubsMgr->DeleteSubscription(szURL, NULL); }
pSubsMgr->Release(); }
if (IsDlgButtonChecked (hDlg, IDC_MAKE_OFFLINE)) { //they want to subscribe! save subscription we already have in memory
patf->bSubscribed = StartSiteSubscription (hDlg, patf, TRUE); } EndDialog(hDlg, IDOK); break;
// common code with ATF dialog
case IDC_SUBSCRIBE_CUSTOMIZE: //need to create -- but not store -- subscription
//need to (temporarily) trash patf->pidlFavorite so that we can go through the
//wizard without colliding with an existing subscription. When we actually create
//the subscription, we'll use the real name.
LPCITEMIDLIST pidlSave = patf->pidlFavorite; TCHAR szUrlTemp[MAX_URL_STRING+1]; IEGetDisplayName(patf->pidlFavorite, szUrlTemp, SHGDN_FORPARSING); StrCat (szUrlTemp, TEXT(".")); //just put something nearly invisible on the end
if (SUCCEEDED (IECreateFromPath(szUrlTemp, (LPITEMIDLIST*)&patf->pidlFavorite))) { if (StartSiteSubscription (hDlg, patf, FALSE)) SendMessage (hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, IDOK), TRUE); ILFree ((LPITEMIDLIST)patf->pidlFavorite); } patf->pidlFavorite = pidlSave; break; } break; }
return FALSE; }
static const int CREATESUBS_ACTIVATE = 0x8000; //hidden flag meaning channel is already on system
STDAPI SubscribeFromFavorites (HWND hwnd, LPCITEMIDLIST pidlUrl, LPTSTR pszName, DWORD dwFlags, SUBSCRIPTIONTYPE subsType, SUBSCRIPTIONINFO *pInfo) { //used to subscribe to a channel that's already in the Favorites
//or a URL that's already a Favorite
//flags are same as ISubscriptionMgr::CreateSubscription
//display our part of the fav's dialog -- no need to go through SHBrowseForFolder
//or any of that, just our radio buttons in a fixed-size dialog with our own DlgProc
INT_PTR iDlgResult; HRESULT hr = S_OK; ADDTOFAV atf = {0}; atf.pszFile = pszName; atf.siSubsInProg.cbSize = sizeof(SUBSCRIPTIONINFO); if (pInfo && pInfo->cbSize == sizeof(SUBSCRIPTIONINFO)) atf.siSubsInProg = *pInfo;
atf.subsType = subsType;
//figure out what dialog to use
atf.iDlgType = (subsType == SUBSTYPE_URL ? ATF_FAVORITE : (dwFlags & CREATESUBS_ACTIVATE ? ATF_CHANNEL_MODIFY : ATF_CHANNEL)); // Do we potentially need ANOTHER dialog type for softdist channels?
if (dwFlags & CREATESUBS_SOFTWAREUPDATE) { atf.bIsSoftdist = TRUE; }
atf.pidlFavorite = pidlUrl;
#ifdef OLD_FAVORITES
int iTemplate; switch (atf.iDlgType) { case ATF_CHANNEL_SOFTDIST: // Inappropriate, but it doesn't currently get used
case ATF_CHANNEL: iTemplate = IDD_SUBSCRIBE_FAV_CHANNEL; break; case ATF_CHANNEL_MODIFY: iTemplate = IDD_ACTIVATE_PLATINUM_CHANNEL; break; case ATF_FAVORITE: iTemplate = IDD_SUBSCRIBE_FAVORITE; break; }
iDlgResult = DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(iTemplate), hwnd, SubscribeFavoriteDlgProc, (LPARAM)&atf);
#endif
iDlgResult = DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_ADDTOFAVORITES_TEMPLATE), hwnd, SubscribeFavoriteDlgProc, (LPARAM)&atf);
switch (iDlgResult) { case -1: hr = E_FAIL; break; case IDCANCEL: hr = S_FALSE; break; default: if (pInfo && (pInfo->cbSize == sizeof(SUBSCRIPTIONINFO)) && (dwFlags & CREATESUBS_NOSAVE)) *pInfo = atf.siSubsInProg; hr = S_OK; break; }
return hr; }
STDAPI AddToChannelsEx (HWND hwnd, LPCITEMIDLIST pidlUrl, LPTSTR pszName, LPCWSTR pwszURL, DWORD dwFlags, SUBSCRIPTIONINFO* pInfo) { HRESULT hr = S_OK; IChannelMgrPriv* pIChannelMgrPriv;
hr = JITCoCreateInstance(CLSID_ChannelMgr, NULL, CLSCTX_INPROC_SERVER, IID_IChannelMgrPriv, (void**)&pIChannelMgrPriv, hwnd, FIEF_FLAG_FORCE_JITUI);
if (SUCCEEDED(hr)) { if (S_OK == pIChannelMgrPriv->IsChannelInstalled (pwszURL)) { hr = SubscribeFromFavorites (hwnd, pidlUrl, pszName, dwFlags | CREATESUBS_ACTIVATE, SUBSTYPE_CHANNEL, pInfo); } else { LPITEMIDLIST pidlChannelFolder; TCHAR szPath[MAX_PATH]; TCHAR szCFPath[MAX_PATH];
ASSERT(pIChannelMgrPriv);
IChannelMgrPriv::CHANNELFOLDERLOCATION cflLocation = ((dwFlags & CREATESUBS_SOFTWAREUPDATE) ? IChannelMgrPriv::CF_SOFTWAREUPDATE : IChannelMgrPriv::CF_CHANNEL);
hr = pIChannelMgrPriv->GetChannelFolder(&pidlChannelFolder, cflLocation); if (SUCCEEDED (hr)) { //
// Change IChannelMgrPriv to unicode! This has to get fixed to
// support a unicode "Channels" name. (edwardp)
//
CHAR szBuff[MAX_PATH];
hr = pIChannelMgrPriv->GetChannelFolderPath (szBuff, ARRAYSIZE(szBuff), cflLocation);
if (SUCCEEDED(hr)) SHAnsiToUnicode(szBuff, szCFPath, ARRAYSIZE(szCFPath));
if (SUCCEEDED (hr)) { TCHAR szDspName[MAX_URL_STRING]; DWORD cchDspName = ARRAYSIZE(szDspName);
StrCpyN(szPath, szCFPath, ARRAYSIZE(szPath)); // When we create a short cut for the URL, we have to make sure it's readable for
// the end user. PrepareURLForDisplay() will unescape the string if it's escaped.
if (!UrlIs(pszName, URLIS_URL) || !PrepareURLForDisplay(pszName, szDspName, &cchDspName)) { // Unescaping wasn't wanted or didn't work.
StrCpyN(szDspName, pszName, ARRAYSIZE(szDspName)); } PathCleanupSpec(szPath, szDspName);
FAVDLGTYPE iDlgType = (dwFlags & CREATESUBS_SOFTWAREUPDATE ? ATF_CHANNEL_SOFTDIST : ATF_CHANNEL);
if ((dwFlags & CREATESUBS_NOUI) || DoSafeAddToFavDlgEx(hwnd, szPath, ARRAYSIZE(szPath), szDspName, ARRAYSIZE(szDspName), pidlChannelFolder, pidlUrl, iDlgType, pInfo)) { //we create the channelbar entry here, instead of cdfview, because here
//we know where in the channels folder the user wants it to go.
IChannelMgr* pChannelMgr = NULL; hr = pIChannelMgrPriv->QueryInterface (IID_IChannelMgr, (void**)&pChannelMgr); if (SUCCEEDED (hr)) { //prepare strings
PathRemoveExtension(szPath);
//strip off absolute part of folder path, and convert to Unicode
int cchCommon = PathCommonPrefix (szPath, szCFPath, NULL);
//pack in the info we have
CHANNELSHORTCUTINFO csiChannel = {0}; csiChannel.cbSize = sizeof(csiChannel); csiChannel.pszTitle = szPath + cchCommon; csiChannel.pszURL = (LPWSTR)pwszURL; csiChannel.bIsSoftware = (dwFlags & CREATESUBS_SOFTWAREUPDATE) ? TRUE : FALSE; //and tell the channel mgr to add the channel
hr = pChannelMgr->AddChannelShortcut (&csiChannel); pChannelMgr->Release(); } } else { hr = S_FALSE; //no failure, but no add
} }
ILFree (pidlChannelFolder); } } pIChannelMgrPriv->Release(); }
return hr; }
STDAPI AddToFavoritesEx( HWND hwnd, LPCITEMIDLIST pidlCur, LPCTSTR pszTitle, DWORD dwFlags, SUBSCRIPTIONINFO *pInfo, IOleCommandTarget *pCommandTarget, IHTMLDocument2 *pDoc) { HRESULT hres = S_FALSE; HCURSOR hCursorOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
if (pidlCur) { TCHAR szName[MAX_URL_STRING]; TCHAR szPath[MAX_PATH]; if (pszTitle) { StrCpyN(szName, pszTitle, ARRAYSIZE(szName)); } else { szName[0] = 0;
IEGetNameAndFlags(pidlCur, SHGDN_INFOLDER | SHGDN_NORMAL, szName, SIZECHARS(szName), NULL); }
LPITEMIDLIST pidlFavorites;
if (SHGetSpecialFolderPath(NULL, szPath, CSIDL_FAVORITES, TRUE) && (pidlFavorites = SHCloneSpecialIDList(NULL, CSIDL_FAVORITES, TRUE))) { TCHAR szDspName[MAX_PATH]; DWORD cchDspName = ARRAYSIZE(szDspName); // When we create a short cut for the URL, we have to make sure it's readable for
// the end user. PrepareURLForDisplay() will unescape the string if it's escaped.
if (!UrlIs(szName, URLIS_URL) || !PrepareURLForDisplay(szName, szDspName, &cchDspName)) { // Unescaping wasn't wanted or didn't work.
StrCpyN(szDspName, szName, ARRAYSIZE(szDspName)); }
PathCleanupSpec(szPath, szDspName);
// if left with spaces only, use the filename friendly version of the url instead.
StrTrim(szDspName, L" "); if (szDspName[0] == 0) { if (SUCCEEDED(IEGetNameAndFlags(pidlCur, SHGDN_FORPARSING, szDspName, ARRAYSIZE(szDspName), NULL))) PathCleanupSpec(szPath, szDspName); }
BOOL fDisplayUI = (dwFlags & CREATESUBS_NOUI) ? FALSE : TRUE; if (!fDisplayUI || DoSafeAddToFavDlgEx(hwnd, szPath, ARRAYSIZE(szPath), szDspName, ARRAYSIZE(szDspName), pidlFavorites, pidlCur, ATF_FAVORITE, NULL)) { if (fDisplayUI) PathRemoveFileSpec(szPath); ISHCUT_PARAMS ShCutParams = {0}; PathRemoveExtension(szDspName); ShCutParams.pidlTarget = pidlCur; ShCutParams.pszTitle = PathFindFileName(szDspName); ShCutParams.pszDir = szPath; ShCutParams.pszOut = NULL; ShCutParams.bUpdateProperties = FALSE; ShCutParams.bUniqueName = FALSE; ShCutParams.bUpdateIcon = TRUE; ShCutParams.pCommand = pCommandTarget; ShCutParams.pDoc = pDoc; hres = CreateShortcutInDirEx(&ShCutParams); if (fDisplayUI && FAILED(hres)) { IE_ErrorMsgBox(NULL, hwnd, GetLastError(), NULL, szDspName, IDS_FAV_UNABLETOCREATE, MB_OK| MB_ICONSTOP); } } else { hres = S_FALSE; } ILFree(pidlFavorites); } }
SetCursor(hCursorOld); return hres; }
BOOL IsSubscribed(ADDTOFAV *patf) { BOOL bSubscribed = FALSE;
TCHAR szURL[MAX_URL_STRING]; if (SUCCEEDED(IEGetDisplayName(patf->pidlFavorite, szURL, SHGDN_FORPARSING))) { ISubscriptionMgr *pSubscriptionMgr; if (SUCCEEDED(CoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&pSubscriptionMgr))) { BSTR bstrURL = SysAllocStringT(szURL); if (bstrURL) { if (SUCCEEDED(pSubscriptionMgr->IsSubscribed(bstrURL, &bSubscribed)) && bSubscribed) { patf->siSubsInProg.fUpdateFlags = SUBSINFO_ALLFLAGS; pSubscriptionMgr->GetSubscriptionInfo(bstrURL, &patf->siSubsInProg); } SysFreeString(bstrURL); } pSubscriptionMgr->Release(); } }
return bSubscribed; }
BOOL IsSubscribed(LPCITEMIDLIST pidl) { BOOL bSubscribed = FALSE;
TCHAR szURL[MAX_URL_STRING]; if (FAILED(IEGetNameAndFlags(pidl, SHGDN_FORPARSING, szURL, SIZEOF(szURL), NULL))) return FALSE;
bSubscribed = IsSubscribed(szURL);
return bSubscribed; }
BOOL IsSubscribed(LPWSTR pwzUrl) { #ifndef DISABLE_SUBSCRIPTIONS
BOOL bSubscribed = FALSE;
ISubscriptionMgr * pSubscriptionMgr; if (FAILED(CoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr, (void**)&pSubscriptionMgr))) { return FALSE; }
pSubscriptionMgr->IsSubscribed(pwzUrl, &bSubscribed); pSubscriptionMgr->Release();
return bSubscribed;
#else /* !DISABLE_SUBSCRIPTIONS */
return FALSE;
#endif /* !DISABLE_SUBSCRIPTIONS */
}
|