|
|
#include "precomp.h"
#include <olectl.h>
// Implementation helper structures/routines declarations
typedef struct tagFAVLIST { LPFAVSTRUC pfs; int cElements; } FAVLIST, (FAR *LPFAVLIST);
typedef struct tagPERCONTROLDATA { FAVLIST flFavorites; FAVLIST flQuickLinks; } PERCONTROLDATA, (FAR *LPPERCONTROLDATA);
typedef struct tagAEFAVPARAMS { LPFAVSTRUC pfs; BOOL fQL;
HWND hwndErrorParent; HWND htv; HTREEITEM hti; LPCTSTR pszExtractPath; LPCTSTR pszPrevExtractPath;
DWORD dwPlatformID; DWORD dwMode; } AEFAVPARAMS, (FAR *LPAEFAVPARAMS);
static BOOL migrateFavoritesHelper(LPCTSTR pszIns); static void migrateToOldFavoritesHelper(LPCTSTR pszIns); static int importFavoritesHelper(HWND htv, LPCTSTR pszDefInf, LPCTSTR pszIns, LPCTSTR pszFixPath, LPCTSTR pszNewPath, BOOL fIgnoreOffline); static int importQuickLinksHelper(HWND htv, LPCTSTR pszDefInf, LPCTSTR pszIns, LPCTSTR pszFixPath, LPCTSTR pszNewPath, BOOL fIgnoreOffline); static BOOL newUrlHelper(HWND htv, LPCTSTR pszExtractPath, DWORD dwPlatformID, DWORD dwMode); static BOOL modifyFavoriteHelper(HWND htv, HTREEITEM hti, LPCTSTR pszExtractPath, LPCTSTR pszPrevExtractPath, DWORD dwPlatformID, DWORD dwMode); static BOOL deleteFavoriteHelper(HWND htv, HTREEITEM hti, LPCTSTR pszExtractPath); static int importFavoritesCmdHelper(HWND htv, LPCTSTR pszExtractPath); static void exportFavoritesHelper(HWND htv, LPCTSTR pszIns, LPCTSTR pszExtractPath, BOOL fFixUpPath = TRUE); static void exportQuickLinksHelper(HWND htv, LPCTSTR pszIns, LPCTSTR pszExtractPath, BOOL fFixUpPath = TRUE); static void getFavoritesInfoTipHelper(LPNMTVGETINFOTIP pGetInfoTip); static BOOL getFavoriteUrlHelper(HWND htv, HTREEITEM hti, LPTSTR pszUrl);
static int importItems(HWND htv, LPCTSTR pszDefInf, LPCTSTR pszIns, LPCTSTR pszFixPath, LPCTSTR pszNewPath, BOOL fIgnoreOffline, BOOL fQL = FALSE);
static INT_PTR CALLBACK addEditFavoriteDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
static LPFAVSTRUC getItem (HWND htv, HTREEITEM hti); static LPFAVSTRUC getFolderItem (HWND htv, HTREEITEM hti); static LPFAVSTRUC findByName (HWND htv, HTREEITEM hti, LPCTSTR pszName); static LPFAVSTRUC findPath (HWND htv, HTREEITEM hti, LPCTSTR pszFolders); static HRESULT isFavoriteItem(HWND htv, HTREEITEM hti);
static LPFAVSTRUC createFolderItems(HWND htv, HTREEITEM hti, LPCTSTR pszFolders); static BOOL importPath (HWND htv, HTREEITEM htiFrom, HTREEITEM *phtiAfter); static void importPath (HWND htv, HTREEITEM hti, LPCTSTR pszFilesPath, LPCTSTR pszExtractPath, LPCTSTR pszReserved = NULL); static int exportItems(HWND htv, HTREEITEM hti, LPCTSTR pszIns, LPCTSTR pszExtractPath, BOOL fFixUpPath = TRUE);
BOOL extractIcon(LPCTSTR pszIconFile, int iIconIndex, LPCTSTR pszExtractPath, LPTSTR pszResult, UINT cchResult); static LPCTSTR getLinksPath(LPTSTR pszPath, UINT cchPath = 0);
static LPTSTR encodeFavName(LPTSTR pszFavName, LPCTSTR pszIns); static LPTSTR decodeFavName(LPTSTR pszFavName, LPCTSTR pszIns);
/////////////////////////////////////////////////////////////////////////////
// SFav constructors and destructors
SFav::SFav() { wType = FTYPE_UNUSED;
pszName = NULL; pszPath = NULL; pszUrl = NULL; pszIconFile = NULL; fOffline = FALSE;
pTvItem = NULL; }
SFav::~SFav() { Delete(); }
/////////////////////////////////////////////////////////////////////////////
// SFav properties
HRESULT SFav::Load(UINT nIndex, LPCTSTR pszIns, BOOL fQL /*= FALSE*/, LPCTSTR pszFixPath /*= NULL*/, LPCTSTR pszNewPath /*= NULL*/, BOOL fIgnoreOffline /*= FALSE*/) { TCHAR szKey[32]; LPCTSTR pszSection, pszKeyFmt;
if (pszIns == NULL) return E_INVALIDARG;
if (!fQL) { pszSection = IS_FAVORITESEX; pszKeyFmt = IK_TITLE_FMT; } else { pszSection = IS_URL; pszKeyFmt = IK_QUICKLINK_NAME; }
wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); if (InsIsKeyEmpty(pszSection, szKey, pszIns)) return S_FALSE;
wType = FTYPE_URL; if (!Expand()) return E_OUTOFMEMORY;
// Title
pszKeyFmt = (!fQL ? IK_TITLE_FMT : IK_QUICKLINK_NAME); wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); InsGetString(pszSection, szKey, pszName, MAX_PATH, pszIns); if (*pszName == TEXT('\0')) goto Fail;
// URL
pszKeyFmt = (!fQL ? IK_URL_FMT : IK_QUICKLINK_URL); wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); InsGetString(pszSection, szKey, pszUrl, INTERNET_MAX_URL_LENGTH, pszIns); if (*pszUrl == TEXT('\0')) goto Fail;
// Icon file (never required)
pszKeyFmt = (!fQL ? IK_ICON_FMT : IK_QUICKLINK_ICON); wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); InsGetString(pszSection, szKey, pszIconFile, INTERNET_MAX_URL_LENGTH, pszIns);
if (*pszIconFile != TEXT('\0') && !PathIsURL(pszIconFile)) { BOOL fTryToFix;
fTryToFix = FALSE; if (pszFixPath == NULL) fTryToFix = TRUE;
else if (PathIsPrefix(pszFixPath, pszIconFile)) fTryToFix = !PathFileExists(pszIconFile);
if (fTryToFix && pszNewPath != NULL) { TCHAR szNewPath[MAX_PATH];
PathCombine(szNewPath, pszNewPath, PathFindFileName(pszIconFile)); StrCpy(pszIconFile, szNewPath); if (!PathFileExists(pszIconFile)) *pszIconFile = TEXT('\0'); } }
// Make available offline flag
fOffline = FALSE; if (!fIgnoreOffline) { pszKeyFmt = (!fQL ? IK_OFFLINE_FMT : IK_QUICKLINK_OFFLINE); wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); fOffline = InsGetBool(pszSection, szKey, FALSE, pszIns); }
SetTVI(); Shrink(); return S_OK;
Fail: Delete(); return E_FAIL; }
HRESULT SFav::Load(LPCTSTR pszName, LPCTSTR pszFavorite, LPCTSTR pszExtractPath, ISubscriptionMgr2 *psm /*= NULL*/, BOOL fIgnoreOffline /*= FALSE*/) { TCHAR szIconFile[INTERNET_MAX_URL_LENGTH];
USES_CONVERSION;
if (pszFavorite == NULL) return E_INVALIDARG;
wType = FTYPE_URL; if (!Expand()) return E_OUTOFMEMORY;
// Title
if (pszName == NULL) pszName = PathFindFileName(pszFavorite); else ASSERT(StrStrI(pszFavorite, pszName) != NULL); StrCpy(SFav::pszName, pszName); PathRenameExtension(SFav::pszName, DOT_URL);
// URL
InsGetString(IS_INTERNETSHORTCUT, IK_URL, pszUrl, INTERNET_MAX_URL_LENGTH, pszFavorite); if (*pszUrl == TEXT('\0')) goto Fail;
// Icon file
InsGetString(IS_INTERNETSHORTCUT, IK_ICONFILE, szIconFile, countof(szIconFile), pszFavorite); if (szIconFile[0] != TEXT('\0')) { int iIconIndex;
iIconIndex = GetPrivateProfileInt(IS_INTERNETSHORTCUT, IK_ICONINDEX, 1, pszFavorite); ::extractIcon(szIconFile, iIconIndex, pszExtractPath, pszIconFile, INTERNET_MAX_URL_LENGTH); }
// Make available offline flag
fOffline = FALSE; if (!fIgnoreOffline) { HRESULT hr; BOOL fOwnSubMgr;
fOwnSubMgr = FALSE; if (psm == NULL) { hr = CoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr2, (LPVOID *)&psm); if (SUCCEEDED(hr)) fOwnSubMgr = TRUE; }
if (psm != NULL) { hr = psm->IsSubscribed(T2W(pszUrl), &fOffline); if (FAILED(hr)) fOffline = FALSE; }
if (fOwnSubMgr) psm->Release(); }
SetTVI(); Shrink(); return S_OK;
Fail: Delete(); return E_FAIL; }
HRESULT SFav::Add(HWND htv, HTREEITEM hti) { SFav *pfsFolder; TV_INSERTSTRUCT tvins; HTREEITEM htiParent;
if (hti == NULL) hti = TreeView_GetSelection(htv);
pfsFolder = NULL; if (wType == FTYPE_URL) { TCHAR szFolders[MAX_PATH]; LPTSTR pszFile;
pszFile = PathFindFileName(pszName); if (pszFile > pszName) { *(pszFile-1) = TEXT('\0'); StrCpy(szFolders, pszName); StrCpy(pszName, pszFile);
pfsFolder = ::createFolderItems(htv, hti, szFolders); if (pfsFolder == NULL) goto Fail; } }
SetTVI();
if (pfsFolder == NULL) pfsFolder = ::getFolderItem(htv, hti); if (pfsFolder != NULL) { if (pfsFolder->pTvItem == NULL || pfsFolder->pTvItem->hItem == NULL) goto Fail;
htiParent = pfsFolder->pTvItem->hItem; } else htiParent = TVI_ROOT;
ZeroMemory(&tvins, sizeof(tvins)); tvins.hParent = htiParent; tvins.hInsertAfter = TVI_LAST;
CopyMemory(&tvins.item, pTvItem, sizeof(TV_ITEM)); pTvItem->hItem = TreeView_InsertItem(htv, &tvins);
pTvItem->mask = TVIF_HANDLE | TVIF_STATE; TreeView_GetItem(htv, pTvItem);
if (pfsFolder != NULL) TreeView_Expand(htv, htiParent, TVE_EXPAND);
TreeView_SelectItem(htv, pTvItem->hItem);
//----- Increment the number of items -----
LPPERCONTROLDATA ppcd; LPFAVLIST pfl;
ppcd = (LPPERCONTROLDATA)GetWindowLongPtr(htv, GWLP_USERDATA); ASSERT (NULL != ppcd);
pfl = (S_OK == ::isFavoriteItem(htv, pTvItem->hItem)) ? &ppcd->flFavorites : &ppcd->flQuickLinks; pfl->cElements++;
return S_OK;
Fail: Delete(); return FALSE; }
// NOTE: (andrewgu) can also be used to clear the entry in case of quick links
HRESULT SFav::Save(HWND htv, UINT nIndex, LPCTSTR pszIns, LPCTSTR pszExtractPath, BOOL fQL /*= FALSE*/, BOOL fFixUpPath /*= TRUE*/) { TCHAR szAux[INTERNET_MAX_URL_LENGTH], szKey[32]; LPCTSTR pszSection, pszKeyFmt, pszAux;
if (pszIns == NULL) return E_INVALIDARG;
// Name
if (!fQL) { if (wType != FTYPE_URL) return E_UNEXPECTED;
GetPath(htv, szAux); PathAppend(szAux, pszName); if (!PathIsExtension(szAux, DOT_URL)) StrCat(szAux, DOT_URL);
pszAux = szAux; ASSERT(*pszAux != TEXT('\0'));
pszSection = IS_FAVORITESEX; pszKeyFmt = IK_TITLE_FMT; } else { if (pszName != NULL && wType != FTYPE_URL) return E_UNEXPECTED;
pszAux = NULL; if (pszName != NULL) { StrCpy(szAux, pszName);
if (!PathIsExtension(szAux, DOT_URL)) StrCat(szAux, DOT_URL);
pszAux = szAux; ASSERT(*pszAux != TEXT('\0')); }
pszSection = IS_URL; pszKeyFmt = IK_QUICKLINK_NAME; } wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); WritePrivateProfileString(pszSection, szKey, pszAux, pszIns);
// URL
if (!fQL) { ASSERT(pszUrl != NULL && *pszUrl != TEXT('\0'));
pszKeyFmt = IK_URL_FMT; } else { if (pszName != NULL) { ASSERT(pszUrl != NULL && *pszUrl != TEXT('\0')); }
else { ASSERT(pszUrl == NULL); }
pszKeyFmt = IK_QUICKLINK_URL; } wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); WritePrivateProfileString(pszSection, szKey, pszUrl, pszIns);
// Icon file
if (!fQL) { ASSERT(pszIconFile == NULL || *pszIconFile != TEXT('\0'));
pszKeyFmt = IK_ICON_FMT; } else { if (pszName != NULL && pszIconFile != NULL) { ASSERT(*pszIconFile != TEXT('\0')); }
else { ASSERT(pszIconFile == NULL); }
pszKeyFmt = IK_QUICKLINK_ICON; }
pszAux = NULL; if (pszIconFile != NULL) { ::extractIcon(pszIconFile, 1, pszExtractPath, szAux, countof(szAux)); if (szAux[0] != TEXT('\0')) if (PathIsPrefix(pszExtractPath, szAux)) pszAux = szAux;
else { TCHAR szDest[MAX_PATH];
ASSERT(PathFileExists(szAux)); PathCombine(szDest, pszExtractPath, PathFindFileName(szAux)); CopyFile(szAux, szDest, FALSE); SetFileAttributes(szDest, FILE_ATTRIBUTE_NORMAL);
// (pritobla): fFixUpPath should be always TRUE if called by the IEAK
// Wizard or the Profile Manager. The only case when it would
// be FALSE is when called by OPKWIZ. They want to keep the path
// to the icon files what the user entered because they don't use our
// Wizard/ProfMgr logic of temp dirs.
pszAux = fFixUpPath ? szDest : szAux; } } wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); WritePrivateProfileString(pszSection, szKey, pszAux, pszIns);
// Make available offline flag
pszAux = NULL; pszKeyFmt = !fQL ? IK_OFFLINE_FMT : IK_QUICKLINK_OFFLINE; if (!fQL) { if (fOffline) pszAux = TEXT("1"); } else if (pszName != NULL && fOffline) pszAux = TEXT("1"); wnsprintf(szKey, countof(szKey), pszKeyFmt, nIndex); WritePrivateProfileString(pszSection, szKey, pszAux, pszIns);
return S_OK; }
void SFav::SetTVI() { if (!Expand(FF_TVI)) return;
if (wType == FTYPE_URL) wnsprintf(pTvItem->pszText, MAX_PATH + 3 + INTERNET_MAX_URL_LENGTH, TEXT("%s = %s"), pszName, pszUrl); else StrCpy(pTvItem->pszText, pszName);
pTvItem->cchTextMax = StrLen(pTvItem->pszText) + 1; pTvItem->mask = TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_STATE | TVIF_TEXT; pTvItem->lParam = (LPARAM)this; }
/////////////////////////////////////////////////////////////////////////////
// SFav operations
SFav* SFav::CreateNew(HWND htv, BOOL fQL /*= FALSE*/) { SFav* pfsFirst;
pfsFirst = GetFirst(htv, fQL); if (pfsFirst == NULL) return NULL;
for (UINT i = 0; i < SFav::GetMaxNumber(fQL); i++) if ((pfsFirst + i)->wType == FTYPE_UNUSED) break; if (i >= SFav::GetMaxNumber(fQL)) return NULL;
return (pfsFirst + i); }
SFav* SFav::GetFirst(HWND htv, BOOL fQL /*= FALSE*/) { LPPERCONTROLDATA ppcd; LPFAVLIST pfl;
ppcd = (LPPERCONTROLDATA)GetWindowLongPtr(htv, GWLP_USERDATA);
//----- Allocate per-control memory -----
if (NULL == ppcd) { ppcd = (LPPERCONTROLDATA)CoTaskMemAlloc(sizeof(PERCONTROLDATA)); if (NULL == ppcd) return NULL; ZeroMemory(ppcd, sizeof(PERCONTROLDATA));
SetWindowLongPtr(htv, GWLP_USERDATA, (LONG_PTR)ppcd); }
pfl = !fQL ? &ppcd->flFavorites : &ppcd->flQuickLinks; if (NULL == pfl->pfs) { pfl->pfs = (LPFAVSTRUC)CoTaskMemAlloc(sizeof(FAVSTRUC) * SFav::GetMaxNumber(fQL)); if (NULL == pfl->pfs) return NULL; ZeroMemory(pfl->pfs, sizeof(FAVSTRUC) * SFav::GetMaxNumber(fQL)); }
return pfl->pfs; }
SFav* SFav::GetNext(HWND htv, BOOL fQL /*= FALSE*/) const { SFav* pfsFirst; UINT nCur;
pfsFirst = GetFirst(htv, fQL); if (pfsFirst == NULL) return NULL;
for (nCur = (UINT)(this - pfsFirst + 1); nCur < GetMaxNumber(fQL); nCur++) if ((pfsFirst + nCur)->wType != FTYPE_UNUSED) break;
return (nCur < GetMaxNumber(fQL) ? (pfsFirst + nCur) : NULL); }
void SFav::Free(HWND htv, BOOL fQL, LPCTSTR pszExtractPath /*= NULL*/) { if (pszIconFile != NULL && pszExtractPath != NULL) if (PathIsPrefix(pszExtractPath, pszIconFile)) { SetFileAttributes(pszIconFile, FILE_ATTRIBUTE_NORMAL); DeleteFile(pszIconFile); }
if (htv != NULL && pTvItem != NULL && pTvItem->hItem != NULL) TreeView_DeleteItem(htv, pTvItem->hItem); Delete();
//----- Decrement the number of items -----
LPPERCONTROLDATA ppcd; LPFAVLIST pfl;
ppcd = (LPPERCONTROLDATA)GetWindowLongPtr(htv, GWLP_USERDATA); ASSERT (NULL != ppcd);
pfl = !fQL ? &ppcd->flFavorites : &ppcd->flQuickLinks; ASSERT(pfl->cElements > 0); pfl->cElements--;
//----- Free per-control memory -----
if (0 == pfl->cElements) { CoTaskMemFree(pfl->pfs);
// switch to the other one
pfl = fQL ? &ppcd->flFavorites : &ppcd->flQuickLinks; if (0 == pfl->cElements) { CoTaskMemFree(ppcd); SetWindowLongPtr(htv, GWLP_USERDATA, NULL); } } }
UINT SFav::GetNumber(HWND htv, BOOL fQL /*= FALSE*/) { LPPERCONTROLDATA ppcd;
ppcd = (LPPERCONTROLDATA)GetWindowLongPtr(htv, GWLP_USERDATA); if (NULL == ppcd) return 0;
return (!fQL ? ppcd->flFavorites.cElements : ppcd->flQuickLinks.cElements); }
UINT SFav::GetMaxNumber(BOOL fQL /*= FALSE*/) { return (!fQL ? NUM_FAVS : NUM_LINKS) + 1; }
BOOL SFav::Expand(WORD wFlags /*= FF_DEFAULT*/) { BOOL fZeroInit;
if (wFlags == FF_DEFAULT) { if (wType != FTYPE_URL && wType != FTYPE_FOLDER) goto Fail;
wFlags = (wType == FTYPE_URL) ? (WORD)(FF_NAME | FF_URL | FF_ICON) : (WORD)FF_NAME; wFlags |= FF_TVI; }
if (HasFlag(wFlags, FF_NAME)) { fZeroInit = (pszName == NULL || *pszName == TEXT('\0'));
pszName = (LPTSTR)CoTaskMemRealloc(pszName, MAX_PATH*sizeof(TCHAR)); if (pszName == NULL) goto Fail;
if (fZeroInit) ZeroMemory(pszName, MAX_PATH); }
if (HasFlag(wFlags, FF_PATH)) { fZeroInit = (pszPath == NULL || *pszPath == TEXT('\0'));
pszPath = (LPTSTR)CoTaskMemRealloc(pszPath, MAX_PATH*sizeof(TCHAR)); if (pszPath == NULL) goto Fail;
if (fZeroInit) ZeroMemory(pszPath, MAX_PATH); }
if (HasFlag(wFlags, FF_URL)) { fZeroInit = (pszUrl == NULL || *pszUrl == TEXT('\0'));
pszUrl = (LPTSTR)CoTaskMemRealloc(pszUrl, INTERNET_MAX_URL_LENGTH*sizeof(TCHAR)); if (pszUrl == NULL) goto Fail;
if (fZeroInit) ZeroMemory(pszUrl, INTERNET_MAX_URL_LENGTH); } else if (wType == FTYPE_FOLDER) if (pszUrl != NULL) { CoTaskMemFree(pszUrl); pszUrl = NULL; }
if (HasFlag(wFlags, FF_ICON)) { fZeroInit = (pszIconFile == NULL || *pszIconFile == TEXT('\0'));
pszIconFile = (LPTSTR)CoTaskMemRealloc(pszIconFile, INTERNET_MAX_URL_LENGTH*sizeof(TCHAR)); if (pszIconFile == NULL) goto Fail;
if (fZeroInit) ZeroMemory(pszIconFile, INTERNET_MAX_URL_LENGTH); } else if (wType == FTYPE_FOLDER) if (pszIconFile != NULL) { CoTaskMemFree(pszIconFile); pszIconFile = NULL; }
if (HasFlag(wFlags, FF_TVI)) { UINT nTreeViewTextLen;
fZeroInit = TRUE; if (pTvItem == NULL) { pTvItem = (LPTV_ITEM)CoTaskMemAlloc(sizeof(TV_ITEM)); if (pTvItem == NULL) goto Fail; ZeroMemory(pTvItem, sizeof(TV_ITEM)); } else fZeroInit = (pTvItem->pszText == NULL || *pTvItem->pszText == TEXT('\0'));
nTreeViewTextLen = (UINT)((wType == FTYPE_URL) ? (MAX_PATH + 3 + INTERNET_MAX_URL_LENGTH) : MAX_PATH); pTvItem->pszText = (LPTSTR)CoTaskMemRealloc(pTvItem->pszText, nTreeViewTextLen*sizeof(TCHAR)); if (pTvItem->pszText == NULL) goto Fail;
if (fZeroInit) ZeroMemory(pTvItem->pszText, nTreeViewTextLen); }
return TRUE;
Fail: Delete(); return FALSE; }
void SFav::Shrink(WORD wFlags /*= FF_ALL*/) { UINT nLen;
if (HasFlag(wFlags, FF_NAME) && pszName != NULL) { nLen = (*pszName != TEXT('\0')) ? (StrLen(pszName) + 1) : 0; pszName = (LPTSTR)CoTaskMemRealloc(pszName, nLen * sizeof(TCHAR)); ASSERT(pszName != NULL); // should not be empty
}
if (HasFlag(wFlags, FF_PATH) && pszPath != NULL) { nLen = (*pszPath != TEXT('\0')) ? (StrLen(pszPath) + 1) : 0; pszPath = (LPTSTR)CoTaskMemRealloc(pszPath, nLen * sizeof(TCHAR)); ASSERT(pszPath == NULL); // not used
}
if (HasFlag(wFlags, FF_URL) && pszUrl != NULL) { nLen = (*pszUrl != TEXT('\0')) ? (StrLen(pszUrl) + 1) : 0; pszUrl = (LPTSTR)CoTaskMemRealloc(pszUrl, nLen * sizeof(TCHAR)); ASSERT((wType == FTYPE_FOLDER && pszUrl == NULL) || pszUrl != NULL); }
if (HasFlag(wFlags, FF_ICON) && pszIconFile != NULL) { nLen = (*pszIconFile != TEXT('\0')) ? (StrLen(pszIconFile) + 1) : 0; pszIconFile = (LPTSTR)CoTaskMemRealloc(pszIconFile, nLen * sizeof(TCHAR)); }
if (HasFlag(wFlags, FF_TVI) && pTvItem != NULL && pTvItem->pszText != NULL) { pTvItem->pszText = (LPTSTR)CoTaskMemRealloc(pTvItem->pszText, (StrLen(pTvItem->pszText) + 1) * sizeof(TCHAR)); ASSERT(pTvItem->pszText != NULL); } }
void SFav::Delete(WORD wFlags /*= FF_ALL*/) { if (HasFlag(wFlags, FF_NAME) && pszName != NULL) { CoTaskMemFree(pszName); pszName = NULL; }
if (HasFlag(wFlags, FF_PATH) && pszPath != NULL) { CoTaskMemFree(pszPath); pszPath = NULL; }
if (HasFlag(wFlags, FF_URL) && pszUrl != NULL) { CoTaskMemFree(pszUrl); pszUrl = NULL; }
if (HasFlag(wFlags, FF_ICON) && pszIconFile != NULL) { CoTaskMemFree(pszIconFile); pszIconFile = NULL; }
if (HasFlag(wFlags, FF_TVI) && pTvItem != NULL) { if (pTvItem->pszText != NULL) { CoTaskMemFree(pTvItem->pszText); pTvItem->pszText = NULL; }
CoTaskMemFree(pTvItem); pTvItem = NULL; }
if (wFlags == FF_ALL) wType = FTYPE_UNUSED; }
BOOL SFav::GetPath(HWND htv, LPTSTR pszResult, UINT cchResult /*= 0*/) const { SFav *pfs; HTREEITEM htiCur, htiNext; TCHAR szPath[MAX_PATH], szAux [MAX_PATH];
if (pTvItem == NULL || pTvItem->hItem == NULL) return FALSE;
if (pszResult == NULL) return FALSE; *pszResult = TEXT('\0');
if (cchResult == 0) cchResult = MAX_PATH;
szPath[0] = szAux[0] = TEXT('\0'); for (htiCur = TreeView_GetParent(htv, pTvItem->hItem), htiNext = TreeView_GetParent(htv, htiCur); htiNext != NULL; htiCur = htiNext, htiNext = TreeView_GetParent(htv, htiCur)) {
pfs = ::getItem(htv, htiCur); if (pfs == NULL) break;
ASSERT(pfs->wType == FTYPE_FOLDER); PathCombine(szAux, pfs->pszName, szPath); StrCpy(szPath, szAux); } if (htiNext != NULL) return FALSE;
if (cchResult <= (UINT)StrLen(szPath)) return FALSE;
StrCpy(pszResult, szPath); return TRUE; }
/////////////////////////////////////////////////////////////////////////////
// Exported routines
BOOL WINAPI MigrateFavoritesA(LPCSTR pszIns) { USES_CONVERSION;
return migrateFavoritesHelper(A2CT(pszIns)); }
BOOL WINAPI MigrateFavoritesW(LPCWSTR pcwszIns) { USES_CONVERSION;
return migrateFavoritesHelper(W2CT(pcwszIns)); }
void WINAPI MigrateToOldFavoritesA(LPCSTR pszIns) { USES_CONVERSION;
migrateToOldFavoritesHelper(A2CT(pszIns)); }
void WINAPI MigrateToOldFavoritesW(LPCWSTR pcwszIns) { USES_CONVERSION;
migrateToOldFavoritesHelper(W2CT(pcwszIns)); }
int WINAPI ImportFavoritesA(HWND htv, LPCSTR pszDefInf, LPCSTR pszIns, LPCSTR pszFixPath, LPCSTR pszNewPath, BOOL fIgnoreOffline) { USES_CONVERSION;
return importFavoritesHelper(htv, A2CT(pszDefInf), A2CT(pszIns), A2CT(pszFixPath), A2CT(pszNewPath), fIgnoreOffline); }
int WINAPI ImportFavoritesW(HWND htv, LPCWSTR pcwszDefInf, LPCWSTR pcwszIns, LPCWSTR pcwszFixPath, LPCWSTR pcwszNewPath, BOOL fIgnoreOffline) { USES_CONVERSION;
return importFavoritesHelper(htv, W2CT(pcwszDefInf), W2CT(pcwszIns), W2CT(pcwszFixPath), W2CT(pcwszNewPath), fIgnoreOffline); }
int WINAPI ImportQuickLinksA(HWND htv, LPCSTR pszDefInf, LPCSTR pszIns, LPCSTR pszFixPath, LPCSTR pszNewPath, BOOL fIgnoreOffline) { USES_CONVERSION;
return importQuickLinksHelper(htv, A2CT(pszDefInf), A2CT(pszIns), A2CT(pszFixPath), A2CT(pszNewPath), fIgnoreOffline); }
int WINAPI ImportQuickLinksW(HWND htv, LPCWSTR pcwszDefInf, LPCWSTR pcwszIns, LPCWSTR pcwszFixPath, LPCWSTR pcwszNewPath, BOOL fIgnoreOffline) { USES_CONVERSION;
return importQuickLinksHelper(htv, W2CT(pcwszDefInf), W2CT(pcwszIns), W2CT(pcwszFixPath), W2CT(pcwszNewPath), fIgnoreOffline); }
BOOL WINAPI NewUrlA(HWND htv, LPCSTR pszExtractPath, DWORD dwPlatformID, DWORD dwMode) { USES_CONVERSION;
return newUrlHelper(htv, A2CT(pszExtractPath), dwPlatformID, dwMode); }
BOOL WINAPI NewUrlW(HWND htv, LPCWSTR pcwszExtractPath, DWORD dwPlatformID, DWORD dwMode) { USES_CONVERSION;
return newUrlHelper(htv, W2CT(pcwszExtractPath), dwPlatformID, dwMode); }
BOOL WINAPI NewFolder(HWND htv) { LPFAVSTRUC pfsNew; AEFAVPARAMS aefp; int iResult;
ASSERT(isFavoriteItem(htv, TreeView_GetSelection(htv)) == S_OK);
pfsNew = pfsNew->CreateNew(htv); if (pfsNew == NULL) goto Fail;
pfsNew->wType = FTYPE_FOLDER;
ZeroMemory(&aefp, sizeof(aefp)); aefp.pfs = pfsNew; aefp.fQL = FALSE; aefp.hwndErrorParent = GetParent(htv); aefp.htv = htv; aefp.hti = TreeView_GetSelection(htv); aefp.pszExtractPath = NULL; aefp.dwPlatformID = PLATFORM_WIN32; aefp.dwMode = IEM_CORP;
iResult = (int) DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_FAVPOPUP), GetParent(htv), addEditFavoriteDlgProc, (LPARAM)&aefp); if (iResult == IDCANCEL) goto Fail;
pfsNew->Add(htv, NULL); return TRUE;
Fail: if (pfsNew != NULL) pfsNew->Delete();
return FALSE; }
BOOL WINAPI ModifyFavoriteA(HWND htv, HTREEITEM hti, LPCSTR pszExtractPath, LPCSTR pszPrevExtractPath, DWORD dwPlatformID, DWORD dwMode) { USES_CONVERSION;
return modifyFavoriteHelper(htv, hti, A2CT(pszExtractPath), A2CT(pszPrevExtractPath), dwPlatformID, dwMode); }
BOOL WINAPI ModifyFavoriteW(HWND htv, HTREEITEM hti, LPCWSTR pcwszExtractPath, LPCWSTR pcwszPrevExtractPath, DWORD dwPlatformID, DWORD dwMode) { USES_CONVERSION;
return modifyFavoriteHelper(htv, hti, W2CT(pcwszExtractPath), W2CT(pcwszPrevExtractPath), dwPlatformID, dwMode); }
BOOL WINAPI DeleteFavoriteA(HWND htv, HTREEITEM hti, LPCSTR pszExtractPath) { USES_CONVERSION;
return deleteFavoriteHelper(htv, hti, A2CT(pszExtractPath)); }
BOOL WINAPI DeleteFavoriteW(HWND htv, HTREEITEM hti, LPCWSTR pcwszExtractPath) { USES_CONVERSION;
return deleteFavoriteHelper(htv, hti, W2CT(pcwszExtractPath)); }
BOOL WINAPI MoveUpFavorite(HWND htv, HTREEITEM hti) { HTREEITEM htiBrother1, htiBrother2;
htiBrother1 = TreeView_GetPrevSibling(htv, hti); if (htiBrother1 == NULL) return FALSE;
htiBrother2 = TreeView_GetPrevSibling(htv, htiBrother1); if (htiBrother2 == NULL) htiBrother2 = TVI_FIRST;
if (!importPath(htv, hti, &htiBrother2)) return FALSE; ASSERT(htiBrother2 != NULL);
TreeView_SelectItem(htv, htiBrother2); TreeView_DeleteItem(htv, hti); TreeView_EnsureVisible(htv, htiBrother2); return TRUE; }
BOOL WINAPI MoveDownFavorite(HWND htv, HTREEITEM hti) { HTREEITEM htiBrother;
htiBrother = TreeView_GetNextSibling(htv, hti); if (htiBrother == NULL) return FALSE;
if (!importPath(htv, hti, &htiBrother)) return FALSE; ASSERT(htiBrother != NULL);
TreeView_SelectItem(htv, htiBrother); TreeView_DeleteItem(htv, hti); TreeView_EnsureVisible(htv, htiBrother); return TRUE; }
BOOL WINAPI IsFavoriteItem(HWND htv, HTREEITEM hti) { return (isFavoriteItem(htv, hti) == S_OK); }
UINT WINAPI GetFavoritesNumber(HWND htv, BOOL fQL /*= FALSE*/) { return SFav::GetNumber(htv, fQL); }
UINT WINAPI GetFavoritesMaxNumber(BOOL fQL /*= FALSE*/) { return SFav::GetMaxNumber(fQL); }
int WINAPI ImportFavoritesCmdA(HWND htv, LPCSTR pszExtractPath) { USES_CONVERSION;
return importFavoritesCmdHelper(htv, A2CT(pszExtractPath)); }
int WINAPI ImportFavoritesCmdW(HWND htv, LPCWSTR pcwszExtractPath) { USES_CONVERSION;
return importFavoritesCmdHelper(htv, W2CT(pcwszExtractPath)); }
void WINAPI ExportFavoritesA(HWND htv, LPCSTR pszIns, LPCSTR pszExtractPath, BOOL fFixUpPath) { USES_CONVERSION;
exportFavoritesHelper(htv, A2CT(pszIns), A2CT(pszExtractPath), fFixUpPath); }
void WINAPI ExportFavoritesW(HWND htv, LPCWSTR pcwszIns, LPCWSTR pcwszExtractPath, BOOL fFixUpPath) { USES_CONVERSION;
exportFavoritesHelper(htv, W2CT(pcwszIns), W2CT(pcwszExtractPath), fFixUpPath); }
void WINAPI ExportQuickLinksA(HWND htv, LPCSTR pszIns, LPCSTR pszExtractPath, BOOL fFixUpPath) { USES_CONVERSION;
exportQuickLinksHelper(htv, A2CT(pszIns), A2CT(pszExtractPath), fFixUpPath); }
void WINAPI ExportQuickLinksW(HWND htv, LPCWSTR pcwszIns, LPCWSTR pcwszExtractPath, BOOL fFixUpPath) { USES_CONVERSION;
exportQuickLinksHelper(htv, W2CT(pcwszIns), W2CT(pcwszExtractPath), fFixUpPath); }
void WINAPI GetFavoritesInfoTipA(LPNMTVGETINFOTIPA pGetInfoTipA) { NMTVGETINFOTIP GetInfoTip;
ZeroMemory(&GetInfoTip, sizeof(GetInfoTip)); GetInfoTip.pszText = (LPTSTR)LocalAlloc(LPTR, pGetInfoTipA->cchTextMax * sizeof(TCHAR)); if (GetInfoTip.pszText != NULL) { getFavoritesInfoTipHelper(TVInfoTipA2T(pGetInfoTipA, &GetInfoTip)); TVInfoTipT2A(&GetInfoTip, pGetInfoTipA); LocalFree(GetInfoTip.pszText); } }
void WINAPI GetFavoritesInfoTipW(LPNMTVGETINFOTIPW pGetInfoTipW) { NMTVGETINFOTIP GetInfoTip;
ZeroMemory(&GetInfoTip, sizeof(GetInfoTip)); GetInfoTip.pszText = (LPTSTR)LocalAlloc(LPTR, pGetInfoTipW->cchTextMax * sizeof(TCHAR)); if (GetInfoTip.pszText != NULL) { getFavoritesInfoTipHelper(TVInfoTipW2T(pGetInfoTipW, &GetInfoTip)); TVInfoTipT2W(&GetInfoTip, pGetInfoTipW); LocalFree(GetInfoTip.pszText); } }
BOOL WINAPI GetFavoriteUrlA(HWND htv, HTREEITEM hti, LPSTR pszUrl, DWORD cchSize) { LPTSTR pszUrlBuf = (LPTSTR)LocalAlloc(LPTR, cchSize * sizeof(TCHAR)); BOOL fRet;
if (pszUrlBuf == NULL) fRet = FALSE; else { fRet = getFavoriteUrlHelper(htv, hti, pszUrlBuf); if (fRet) T2Abux(pszUrlBuf, pszUrl);
LocalFree(pszUrlBuf); }
return fRet; }
BOOL WINAPI GetFavoriteUrlW(HWND htv, HTREEITEM hti, LPWSTR pwszUrl, DWORD cchSize) { LPTSTR pszUrlBuf = (LPTSTR)LocalAlloc(LPTR, cchSize * sizeof(TCHAR)); BOOL fRet;
if (pszUrlBuf == NULL) fRet = FALSE; else { fRet = getFavoriteUrlHelper(htv, hti, pszUrlBuf); if (fRet) T2Wbux(pszUrlBuf, pwszUrl);
LocalFree(pszUrlBuf); }
return fRet; }
void WINAPI ProcessFavSelChange(HWND hDlg, HWND hTv, LPNMTREEVIEW pnmtv) { LPFAVSTRUC pfs;
if (HasFlag(pnmtv->itemNew.state, TVIS_BOLD)) { int rgids[] = { IDC_MODIFY, IDC_REMOVE, IDC_TESTFAVURL, IDC_FAVUP, IDC_FAVDOWN };
EnsureDialogFocus(hDlg, rgids, countof(rgids), IDC_ADDURL); DisableDlgItems (hDlg, rgids, countof(rgids)); } else { EnableDlgItem(hDlg, IDC_MODIFY); EnableDlgItem(hDlg, IDC_REMOVE);
pfs = (LPFAVSTRUC)pnmtv->itemNew.lParam; if (pfs != NULL) EnableDlgItem2(hDlg, IDC_TESTFAVURL, (pfs->wType == FTYPE_URL));
if (BST_CHECKED == IsDlgButtonChecked(hDlg, IDC_FAVONTOP)) { EnableDlgItem2(hDlg, IDC_FAVUP, (NULL != TreeView_GetPrevSibling(hTv, pnmtv->itemNew.hItem))); EnableDlgItem2(hDlg, IDC_FAVDOWN, (NULL != TreeView_GetNextSibling(hTv, pnmtv->itemNew.hItem))); } }
EnableDlgItem2(hDlg, IDC_ADDFOLDER, IsFavoriteItem(hTv, pnmtv->itemNew.hItem)); }
/////////////////////////////////////////////////////////////////////////////
// Implementation helper routines
static BOOL migrateFavoritesHelper(LPCTSTR pszIns) { TCHAR szTitle[MAX_PATH], szUrl[INTERNET_MAX_URL_LENGTH], szKey[32]; LPCTSTR pszTitle; LPTSTR pszBuffer; HANDLE hIns; DWORD dwInsSize; UINT i;
// figure out if there are any favorites at all
// NOTE: (andrewgu) szUrl serves as a mere buffer in the processing below.
wnsprintf(szKey, countof(szKey), IK_TITLE_FMT, 1); if (InsIsKeyEmpty(IS_FAVORITESEX, szKey, pszIns)) { if (InsIsSectionEmpty(IS_FAVORITES, pszIns)) return TRUE; } else return TRUE;
WritePrivateProfileString(NULL, NULL, NULL, pszIns); hIns = CreateFile(pszIns, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hIns == INVALID_HANDLE_VALUE) return FALSE;
dwInsSize = GetFileSize(hIns, NULL); ASSERT(dwInsSize != 0xFFFFFFFF); CloseHandle(hIns);
pszBuffer = (LPTSTR)CoTaskMemAlloc(dwInsSize*sizeof(TCHAR)); if (pszBuffer == NULL) return FALSE; ZeroMemory(pszBuffer, dwInsSize);
GetPrivateProfileString(IS_FAVORITES, NULL, TEXT(""), pszBuffer, (UINT)dwInsSize, pszIns); ASSERT(*pszBuffer != TEXT('\0'));
for (i = 1, pszTitle = pszBuffer; *pszTitle != TEXT('\0'); pszTitle += StrLen(pszTitle) + 1, i++) { InsGetString(IS_FAVORITES, pszTitle, szUrl, countof(szUrl), pszIns);
wnsprintf(szKey, countof(szKey), IK_TITLE_FMT, i); StrCpy(szTitle, pszTitle); decodeFavName(szTitle, pszIns); WritePrivateProfileString(IS_FAVORITESEX, szKey, szTitle, pszIns);
wnsprintf(szKey, countof(szKey), IK_URL_FMT, i); WritePrivateProfileString(IS_FAVORITESEX, szKey, szUrl, pszIns); }
CoTaskMemFree(pszBuffer); return TRUE; }
static void migrateToOldFavoritesHelper(LPCTSTR pszIns) { TCHAR szTitle[MAX_PATH], szUrl[INTERNET_MAX_URL_LENGTH], szKey[32];
WritePrivateProfileString(IS_FAVORITES, NULL, NULL, pszIns);
for (UINT i = 1; TRUE; i++) { wnsprintf(szKey, countof(szKey), IK_TITLE_FMT, i); InsGetString(IS_FAVORITESEX, szKey, szTitle, countof(szTitle), pszIns); if (szTitle[0] == TEXT('\0')) break;
wnsprintf(szKey, countof(szKey), IK_URL_FMT, i); InsGetString(IS_FAVORITESEX, szKey, szUrl, countof(szUrl), pszIns);
encodeFavName(szTitle, pszIns); WritePrivateProfileString(IS_FAVORITES, szTitle, szUrl, pszIns); }
WritePrivateProfileString(NULL, NULL, NULL, pszIns); }
static int importFavoritesHelper(HWND htv, LPCTSTR pszDefInf, LPCTSTR pszIns, LPCTSTR pszFixPath, LPCTSTR pszNewPath, BOOL fIgnoreOffline) { return importItems(htv, pszDefInf, pszIns, pszFixPath, pszNewPath, fIgnoreOffline); }
static int importQuickLinksHelper(HWND htv, LPCTSTR pszDefInf, LPCTSTR pszIns, LPCTSTR pszFixPath, LPCTSTR pszNewPath, BOOL fIgnoreOffline) { return importItems(htv, pszDefInf, pszIns, pszFixPath, pszNewPath, fIgnoreOffline, TRUE); }
static BOOL newUrlHelper(HWND htv, LPCTSTR pszExtractPath, DWORD dwPlatformID, DWORD dwMode) { LPFAVSTRUC pfsNew; AEFAVPARAMS aefp; HTREEITEM htiSel; int iResult; BOOL fQL;
htiSel = TreeView_GetSelection(htv); fQL = (isFavoriteItem(htv, htiSel) != S_OK);
pfsNew = pfsNew->CreateNew(htv, fQL); if (pfsNew == NULL) goto Fail;
pfsNew->wType = FTYPE_URL;
ZeroMemory(&aefp, sizeof(aefp)); aefp.pfs = pfsNew; aefp.fQL = fQL; aefp.hwndErrorParent = GetParent(htv); aefp.htv = htv; aefp.hti = htiSel; aefp.pszExtractPath = pszExtractPath; aefp.dwPlatformID = dwPlatformID; aefp.dwMode = dwMode;
iResult = (int) DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_FAVPOPUP), GetParent(htv), addEditFavoriteDlgProc, (LPARAM)&aefp);
if (iResult == IDCANCEL) goto Fail;
pfsNew->Add(htv, htiSel); return TRUE;
Fail: if (pfsNew != NULL) pfsNew->Delete();
return FALSE; }
static BOOL modifyFavoriteHelper(HWND htv, HTREEITEM hti, LPCTSTR pszExtractPath, LPCTSTR pszPrevExtractPath, DWORD dwPlatformID, DWORD dwMode) { LPFAVSTRUC pfs; AEFAVPARAMS aefp; int iResult;
pfs = getItem(htv, hti); if (pfs == NULL) return FALSE;
ZeroMemory(&aefp, sizeof(aefp)); aefp.pfs = pfs; aefp.fQL = FALSE; aefp.hwndErrorParent = GetParent(htv); aefp.htv = htv; aefp.hti = TreeView_GetParent(htv, hti); aefp.pszExtractPath = pszExtractPath; aefp.pszPrevExtractPath = pszPrevExtractPath; aefp.dwPlatformID = dwPlatformID; aefp.dwMode = dwMode;
iResult = (int) DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_FAVPOPUP), GetParent(htv), addEditFavoriteDlgProc, (LPARAM)&aefp);
if (iResult == IDCANCEL) return FALSE;
if (pfs->pTvItem != NULL) { TreeView_SetItem(htv, pfs->pTvItem);
if (pfs->pTvItem->hItem != NULL) TreeView_SelectItem(htv, pfs->pTvItem->hItem); }
return TRUE; }
static BOOL deleteFavoriteHelper(HWND htv, HTREEITEM hti, LPCTSTR pszExtractPath) { LPFAVSTRUC pfs; HTREEITEM htiChild;
htiChild = TreeView_GetChild(htv, hti); if (htiChild != NULL) { HTREEITEM htiSibling;
while ((htiSibling = TreeView_GetNextSibling(htv, htiChild)) != NULL) deleteFavoriteHelper(htv, htiSibling, pszExtractPath);
deleteFavoriteHelper(htv, htiChild, pszExtractPath); }
pfs = getItem(htv, hti); if (pfs == NULL) return FALSE;
pfs->Free(htv, (isFavoriteItem(htv, hti) != S_OK), pszExtractPath); return TRUE; }
static int importFavoritesCmdHelper(HWND htv, LPCTSTR pszExtractPath) { LPFAVSTRUC pfsFolder; TCHAR szFolder[MAX_PATH], szTitle[MAX_PATH];
pfsFolder = getFolderItem(htv, TreeView_GetSelection(htv)); if (pfsFolder == NULL || pfsFolder->pTvItem == NULL || pfsFolder->pTvItem->hItem == NULL) return 0;
LoadString(g_hInst, IDS_BROWSEIMPORT, szTitle, countof(szTitle)); if (!BrowseForFolder(htv, szFolder, szTitle)) return 0;
if (szFolder[0] == TEXT('\0')) return 0;
importPath (htv, pfsFolder->pTvItem->hItem, szFolder, pszExtractPath); TreeView_Expand(htv, pfsFolder->pTvItem->hItem, TVE_EXPAND);
return pfsFolder->GetNumber(htv); }
static void exportFavoritesHelper(HWND htv, LPCTSTR pszIns, LPCTSTR pszExtractPath, BOOL fFixUpPath /*= TRUE */) { LPFAVSTRUC pfs; int i;
WritePrivateProfileString(IS_FAVORITESEX, NULL, NULL, pszIns);
pfs = pfs->GetFirst(htv); if (pfs == NULL || pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) return;
i = exportItems(htv, pfs->pTvItem->hItem, pszIns, pszExtractPath, fFixUpPath);
// if no favorites, write out a flag so we don't repopulate with default favorites next time around
InsWriteBool(IS_BRANDING, IK_NOFAVORITES, (i == 1), pszIns); }
static void exportQuickLinksHelper(HWND htv, LPCTSTR pszIns, LPCTSTR pszExtractPath, BOOL fFixUpPath /*= TRUE */) { LPFAVSTRUC pfs; int i;
pfs = pfs->GetFirst(htv, TRUE); if (pfs == NULL || pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) return;
i = exportItems(htv, pfs->pTvItem->hItem, pszIns, pszExtractPath, fFixUpPath);
// if no links, write out a flag so we don't repopulate with default links next time around
InsWriteBool(IS_BRANDING, IK_NOLINKS, (i == 1), pszIns);
// clear out any stuff that might be left over
SFav favEmpty; for (i = (i >= 0) ? i : 1; (UINT)i < pfs->GetMaxNumber(TRUE); i++) favEmpty.Save(NULL, i, pszIns, NULL, TRUE, fFixUpPath); }
static void getFavoritesInfoTipHelper(LPNMTVGETINFOTIP pGetInfoTip) { LPFAVSTRUC pfs; static TCHAR s_szFormat[80], s_szAbsent[30], s_szOfflineOn[30], s_szOfflineOff[30], s_szEllipsis[] = TEXT("...");
TCHAR szBuffer[2 * MAX_PATH], rgszAux [4][30]; LPCTSTR rgpszAux[4];
if (s_szFormat[0] == TEXT('\0')) { LoadString(g_hInst, IDS_FAVS_TOOLTIPFORMAT, s_szFormat, countof(s_szFormat)); LoadString(g_hInst, IDS_FAVS_ABSENT, s_szAbsent, countof(s_szAbsent)); LoadString(g_hInst, IDS_FAVS_OFFLINE, s_szOfflineOn, countof(s_szAbsent)); LoadString(g_hInst, IDS_FAVS_NOOFFLINE, s_szOfflineOff, countof(s_szOfflineOff)); }
ASSERT(pGetInfoTip != NULL);
pfs = (LPFAVSTRUC)pGetInfoTip->lParam; if (pfs == NULL || pfs->wType != FTYPE_URL) { StrCpyN(pGetInfoTip->pszText, pfs != NULL ? pfs->pszName : TEXT(""), pGetInfoTip->cchTextMax); return; }
ASSERT(pfs->pszName != NULL && pfs->pszUrl != NULL); rgpszAux[0] = pfs->pszName; rgpszAux[1] = pfs->pszUrl; rgpszAux[2] = pfs->pszIconFile; rgpszAux[3] = pfs->fOffline ? s_szOfflineOn : s_szOfflineOff;
for (UINT i = 0; i < countof(rgszAux); i++) { if (rgpszAux[i] == NULL) StrCpy(rgszAux[i], s_szAbsent); else { if (StrLen(rgpszAux[i]) < countof(rgszAux[i])) StrCpy(rgszAux[i], rgpszAux[i]); else { StrCpyN(rgszAux[i], rgpszAux[i], countof(rgszAux[i]) - countof(s_szEllipsis) + 1); StrCpy(&rgszAux[i][countof(rgszAux[i]) - countof(s_szEllipsis)], s_szEllipsis); } } } wnsprintf(szBuffer, countof(szBuffer), s_szFormat, rgszAux[0], rgszAux[1], rgszAux[2], rgszAux[3]); StrCpyN(pGetInfoTip->pszText, szBuffer, pGetInfoTip->cchTextMax); }
static BOOL getFavoriteUrlHelper(HWND htv, HTREEITEM hti, LPTSTR pszUrl) { LPFAVSTRUC pfs = getItem(htv, hti); BOOL fRet = FALSE;
if ((pfs != NULL) && (pfs->pszUrl != NULL)) { fRet = TRUE; StrCpy(pszUrl, pfs->pszUrl); }
return fRet; }
int importItems(HWND htv, LPCTSTR pszDefInf, LPCTSTR pszIns, LPCTSTR pszFixPath, LPCTSTR pszNewPath, BOOL fIgnoreOffline, BOOL fQL /*= FALSE */) { LPFAVSTRUC pfs, pfsCur; TCHAR szKey[32]; UINT i;
pfs = pfs->GetFirst(htv, fQL); if (pfs != NULL && pfs->pTvItem != NULL && pfs->pTvItem->hItem != NULL) { DeleteFavorite(htv, pfs->pTvItem->hItem, pszNewPath); ASSERT(pfs->GetNumber(htv, fQL) == 0); }
pfs = pfs->CreateNew(htv, fQL); if (pfs == NULL) return 0; ASSERT(pfs == pfs->GetFirst(htv, fQL));
pfs->wType = FTYPE_FOLDER; if (!pfs->Expand()) return 0;
LoadString(g_hInst, fQL ? IDS_LINKS : IDS_FAVFOLDER, pfs->pszName, MAX_PATH);
pfs->SetTVI(); pfs->pTvItem->stateMask = pfs->pTvItem->state = TVIS_BOLD; pfs->Shrink();
TreeView_SelectItem(htv, NULL); pfs->Add(htv, NULL); ASSERT(pfs->pTvItem != NULL && pfs->pTvItem->hItem != NULL);
for (i = 1; TRUE; i++) { pfsCur = pfs->CreateNew(htv, fQL); if (pfsCur == NULL) break;
if (pfsCur->Load(i, pszIns, fQL, pszFixPath, pszNewPath, fIgnoreOffline) != S_OK) break;
pfsCur->Add(htv, pfs->pTvItem->hItem); }
// NOTE: (andrewgu) this is an ugly special case when there are no quick links in the ins.
// it's a brief version of SFav::Load which only loads name and url fields. there are two
// alternative ways of doing this with SFav::Load. one is to special case the section to
// IS_STRINGS if extension of pszIns is *.inf, another is to make the section an in-parameter
// of SFav::Load.
if (i == 1 && !InsGetBool(IS_BRANDING, fQL ? IK_NOLINKS : IK_NOFAVORITES, FALSE, pszIns)) for (; TRUE; i++) { pfsCur = pfsCur->CreateNew(htv, fQL); if (pfsCur == NULL) break;
pfsCur->wType = FTYPE_URL; if (!pfsCur->Expand()) return pfs->GetNumber(htv, fQL);
*pfsCur->pszIconFile = TEXT('\0');
wnsprintf(szKey, countof(szKey), fQL ? IK_QUICKLINK_NAME : IK_TITLE_FMT, i); InsGetSubstString(fQL ? IS_URL : IS_FAVORITESEX, szKey, pfsCur->pszName, MAX_PATH, pszDefInf); if (*pfsCur->pszName == TEXT('\0')) { pfsCur->Delete(); break; } StrCat(pfsCur->pszName, DOT_URL);
wnsprintf(szKey, countof(szKey), fQL ? IK_QUICKLINK_URL : IK_URL_FMT, i); InsGetSubstString(fQL ? IS_URL : IS_FAVORITESEX, szKey, pfsCur->pszUrl, INTERNET_MAX_URL_LENGTH, pszDefInf); ASSERT(*pfsCur->pszUrl != TEXT('\0'));
pfsCur->SetTVI(); pfsCur->Shrink(); pfsCur->Add(htv, pfs->pTvItem->hItem); }
TreeView_Expand(htv, pfs->pTvItem->hItem, TVE_EXPAND); return pfs->GetNumber(htv, fQL); }
INT_PTR CALLBACK addEditFavoriteDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { LPAEFAVPARAMS paefp; LPFAVSTRUC pfs; TCHAR szName[MAX_PATH], szIconFile[INTERNET_MAX_URL_LENGTH]; HWND hCtrl; BOOL fResult, fEnable, fWasEnabled;
fResult = FALSE; switch (message) { case WM_INITDIALOG: paefp = (LPAEFAVPARAMS)lParam; SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)paefp);
//----- Initialize contols -----
EnableDBCSChars(hDlg, IDE_FAVNAME); EnableDBCSChars(hDlg, IDE_FAVURL); EnableDBCSChars(hDlg, IDE_FAVICON);
Edit_LimitText(GetDlgItem(hDlg, IDE_FAVNAME), _MAX_FNAME); Edit_LimitText(GetDlgItem(hDlg, IDE_FAVURL), INTERNET_MAX_URL_LENGTH-1); Edit_LimitText(GetDlgItem(hDlg, IDE_FAVICON), _MAX_FNAME);
//----- Initialize SFav structure associated with this dialog -----
fResult = (paefp == NULL || (paefp->pfs != NULL ? !paefp->pfs->Expand() : TRUE)); if (fResult) { EndDialog(hDlg, IDCANCEL); break; } pfs = paefp->pfs;
//----- Initialize contols (Part II) -----
if (paefp->dwPlatformID != PLATFORM_WIN32) { EnableWindow(GetDlgItem(hDlg, IDC_FAVICON), FALSE); EnableWindow(GetDlgItem(hDlg, IDE_FAVICON), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_FAVICONBROWSE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_AVAILOFFLINE), FALSE); } else if (!HasFlag(paefp->dwMode, (IEM_CORP | IEM_PROFMGR)) && pfs->wType == FTYPE_URL) EnableWindow(GetDlgItem(hDlg, IDC_AVAILOFFLINE), FALSE);
if (pfs->wType == FTYPE_FOLDER) { EnableWindow(GetDlgItem(hDlg, IDC_FAVURL), FALSE); EnableWindow(GetDlgItem(hDlg, IDE_FAVURL), FALSE);
if (paefp->dwPlatformID == PLATFORM_WIN32) { EnableWindow(GetDlgItem(hDlg, IDC_FAVICON), FALSE); EnableWindow(GetDlgItem(hDlg, IDE_FAVICON), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_FAVICONBROWSE), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_AVAILOFFLINE), FALSE); } else { ASSERT(!IsWindowEnabled(GetDlgItem(hDlg, IDC_FAVICON))); ASSERT(!IsWindowEnabled(GetDlgItem(hDlg, IDE_FAVICON))); ASSERT(!IsWindowEnabled(GetDlgItem(hDlg, IDC_FAVICONBROWSE))); ASSERT(!IsWindowEnabled(GetDlgItem(hDlg, IDC_AVAILOFFLINE))); } }
//----- Populate controls -----
if (pfs->pszName == NULL || *pfs->pszName == TEXT('\0')) { UINT nID;
if (pfs->wType == FTYPE_URL) nID = (!paefp->fQL ? IDS_NEW : IDS_NEWQL);
else { ASSERT(pfs->wType == FTYPE_FOLDER); nID = IDS_NEWFOLDER; }
LoadString(g_hInst, nID, pfs->pszName, MAX_PATH); } SetDlgItemText(hDlg, IDE_FAVNAME, pfs->pszName);
if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_FAVURL))) ; else { if (pfs->pszUrl == NULL || *pfs->pszUrl == TEXT('\0')) StrCpy(pfs->pszUrl, TEXT("http://www."));
SetDlgItemText(hDlg, IDE_FAVURL, pfs->pszUrl); }
if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_FAVICON))) ; else if (pfs->pszIconFile != NULL && *pfs->pszIconFile != TEXT('\0')) SetDlgItemText(hDlg, IDE_FAVICON, pfs->pszIconFile);
if (!IsWindowEnabled(GetDlgItem(hDlg, IDC_AVAILOFFLINE))) ; else if (pfs->fOffline) CheckDlgButton(hDlg, IDC_AVAILOFFLINE, BST_CHECKED);
fResult = TRUE; break;
case WM_COMMAND: switch (LOWORD(wParam)) { case IDE_FAVNAME: case IDE_FAVURL: case IDE_FAVICON: switch (HIWORD(wParam)) { case EN_CHANGE: paefp = (LPAEFAVPARAMS)GetWindowLongPtr(hDlg, DWLP_USER);
hCtrl = GetDlgItem(hDlg, IDOK); fWasEnabled = IsWindowEnabled(hCtrl);
fEnable = (GetWindowTextLength(GetDlgItem(hDlg, IDE_FAVNAME)) > 0); if (paefp->pfs->wType == FTYPE_URL) fEnable &= (GetWindowTextLength(GetDlgItem(hDlg, IDE_FAVURL)) > 0);
if (fEnable != fWasEnabled) EnableWindow(hCtrl, fEnable);
fResult = TRUE; break; } break;
case IDC_FAVICONBROWSE: GetDlgItemText(hDlg, IDE_FAVICON, szIconFile, countof(szIconFile));
if (!BrowseForFile(hDlg, szIconFile, countof(szIconFile), GFN_ICO)) break;
SetDlgItemText(hDlg, IDE_FAVICON, szIconFile); fResult = TRUE; break;
case IDOK: paefp = (LPAEFAVPARAMS)GetWindowLongPtr(hDlg, DWLP_USER);
if (!CheckField(hDlg, IDE_FAVNAME, FC_NONNULL | FC_PATH, PIVP_FILENAME_ONLY)) { fResult = FALSE; break; }
if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_FAVURL))) ; else if (!CheckField(hDlg, IDE_FAVURL, FC_NONNULL | FC_URL)) { fResult = FALSE; break; }
if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_FAVICON))) ; else if (!CheckField(hDlg, IDE_FAVICON, FC_URL | FC_FILE | FC_EXISTS)) { fResult = FALSE; break; }
GetDlgItemText(hDlg, IDE_FAVNAME, szName, countof(szName)); StrRemoveWhitespace(szName); pfs = findByName(paefp->htv, paefp->hti, szName); if (pfs != NULL && pfs != paefp->pfs) { HWND hCtrl;
ErrorMessageBox(paefp->hwndErrorParent, IDS_FAV_ERR_DUPLICATE); hCtrl = GetDlgItem(hDlg, IDE_FAVNAME); Edit_SetSel(hCtrl, 0, -1); SetFocus(hCtrl);
fResult = FALSE; break; }
pfs = paefp->pfs; // reassign pfs back to paefp->pfs
ASSERT(pfs->pszName != NULL); StrCpy(pfs->pszName, szName);
if (pfs->pszUrl != NULL) if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_FAVURL))) *pfs->pszUrl = TEXT('\0');
else { GetDlgItemText(hDlg, IDE_FAVURL, pfs->pszUrl, INTERNET_MAX_URL_LENGTH); StrRemoveWhitespace(pfs->pszUrl); }
if (pfs->pszIconFile != NULL) if (!IsWindowEnabled(GetDlgItem(hDlg, IDE_FAVICON))) *pfs->pszIconFile = TEXT('\0');
else { GetDlgItemText(hDlg, IDE_FAVICON, szIconFile, countof(szIconFile)); StrRemoveWhitespace(szIconFile);
ASSERT(paefp->pszExtractPath != NULL);
if (*pfs->pszIconFile != TEXT('\0') && StrCmpI(szIconFile, pfs->pszIconFile) != 0) { if (PathIsPrefix(paefp->pszPrevExtractPath, pfs->pszIconFile)) DeleteFile(pfs->pszIconFile); else DeleteFileInDir(pfs->pszIconFile, paefp->pszExtractPath); } extractIcon(szIconFile, 1, paefp->pszExtractPath, pfs->pszIconFile, INTERNET_MAX_URL_LENGTH); }
pfs->fOffline = IsWindowEnabled(GetDlgItem(hDlg, IDC_AVAILOFFLINE)) && (IsDlgButtonChecked(hDlg, IDC_AVAILOFFLINE) == BST_CHECKED);
pfs->SetTVI(); EndDialog(hDlg, IDOK); fResult = TRUE; break;
case IDCANCEL: EndDialog(hDlg, IDCANCEL); fResult = TRUE; break; } break;
case WM_DESTROY: paefp = (LPAEFAVPARAMS)GetWindowLongPtr(hDlg, DWLP_USER);
if (paefp != NULL && paefp->pfs != NULL) paefp->pfs->Shrink(); break; }
return fResult; }
LPFAVSTRUC getItem(HWND htv, HTREEITEM hti) { LPFAVSTRUC pfsResult; TV_ITEM tvi;
if (htv == NULL || hti == NULL) return NULL;
ZeroMemory(&tvi, sizeof(tvi)); tvi.mask = TVIF_PARAM; tvi.hItem = hti; TreeView_GetItem(htv, &tvi);
pfsResult = (LPFAVSTRUC)tvi.lParam; if (pfsResult == NULL || pfsResult->pTvItem == NULL || pfsResult->pTvItem->hItem == NULL) return NULL; ASSERT(pfsResult->pTvItem->hItem == hti);
return pfsResult; }
LPFAVSTRUC getFolderItem(HWND htv, HTREEITEM hti) { LPFAVSTRUC pfsResult;
if (htv == NULL || hti == NULL) return NULL;
pfsResult = getItem(htv, hti); if (pfsResult == NULL) return NULL;
if (pfsResult->wType != FTYPE_FOLDER) { pfsResult = getItem(htv, TreeView_GetParent(htv, hti)); if (pfsResult == NULL) return NULL; } ASSERT(pfsResult->wType == FTYPE_FOLDER);
return pfsResult; }
LPFAVSTRUC findByName(HWND htv, HTREEITEM hti, LPCTSTR pszName) { LPFAVSTRUC pfs; HTREEITEM htiCur; TCHAR szFolders[MAX_PATH]; LPTSTR pszFile;
if (pszName == NULL) return NULL;
StrCpy(szFolders, pszName); pszFile = PathFindFileName(szFolders);
if (pszFile == szFolders) pfs = getFolderItem(htv, hti);
else { *(pszFile-1) = TEXT('\0'); pszName = pszFile;
pfs = findPath(htv, hti, szFolders); }
if (pfs == NULL || pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) return NULL;
for (htiCur = TreeView_GetChild(htv, pfs->pTvItem->hItem); htiCur != NULL; htiCur = TreeView_GetNextSibling(htv, htiCur)) {
pfs = getItem(htv, htiCur); if (pfs == NULL || pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) return NULL;
if (StrCmpI(pfs->pszName, pszName) == 0) break; }
return (htiCur != NULL ? pfs : NULL); }
LPFAVSTRUC findPath(HWND htv, HTREEITEM hti, LPCTSTR pszFolders) { LPFAVSTRUC pfsFirst, pfsCur; HTREEITEM htiCur; TCHAR szPathChunk[MAX_PATH]; LPCTSTR pszCur, pszNext;
pfsFirst = pfsFirst->GetFirst(htv); if (pfsFirst == NULL) return NULL;
if (hti != NULL) { pfsCur = getFolderItem(htv, hti); if (pfsCur == NULL) return NULL; } else pfsCur = pfsFirst;
if (pfsCur->pTvItem == NULL || pfsCur->pTvItem->hItem == NULL) return NULL;
if (pszFolders == NULL) return pfsCur;
htiCur = pfsCur->pTvItem->hItem; for (pszCur = pszFolders, pszNext = PathFindNextComponent(pszCur); pszNext != NULL; pszCur = pszNext, pszNext = PathFindNextComponent(pszCur)) {
ASSERT(pszNext-1 > pszCur); StrCpyN(szPathChunk, pszCur, (int)(pszNext-pszCur) + (*pszNext != TEXT('\0') ? 0 : 1));
// determine if there is an object already for this path chunk
pfsCur = findByName(htv, htiCur, szPathChunk); if (pfsCur == NULL || pfsCur->wType != FTYPE_FOLDER || pfsCur->pTvItem == NULL || pfsCur->pTvItem->hItem == NULL) return NULL; }
return (pszNext == NULL ? pfsCur : NULL); }
HRESULT isFavoriteItem(HWND htv, HTREEITEM hti) { LPFAVSTRUC pfs; HTREEITEM htiCur, htiNext;
if (htv == NULL || hti == NULL) return E_INVALIDARG;
for (htiCur = TreeView_GetParent(htv, hti), htiNext = TreeView_GetParent(htv, htiCur); htiNext != NULL; htiCur = htiNext, htiNext = TreeView_GetParent(htv, htiCur)) ;
if (htiCur == NULL) htiCur = hti;
pfs = getItem(htv, htiCur); if (pfs == NULL) return E_FAIL;
return (pfs == pfs->GetFirst(htv) ? S_OK : S_FALSE); }
LPFAVSTRUC createFolderItems(HWND htv, HTREEITEM hti, LPCTSTR pszFolders) { LPFAVSTRUC pfs; HTREEITEM htiCur; TCHAR szPathChunk[MAX_PATH]; LPCTSTR pszCur, pszNext;
if (pszFolders == NULL) return NULL;
pfs = getFolderItem(htv, hti); if (pfs == NULL) return NULL;
if (pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) return NULL;
htiCur = pfs->pTvItem->hItem; for (pszCur = pszFolders, pszNext = PathFindNextComponent(pszCur); pszNext != NULL; pszCur = pszNext, pszNext = PathFindNextComponent(pszCur)) {
ASSERT(pszNext-1 > pszCur); StrCpyN(szPathChunk, pszCur, (int)(pszNext-pszCur) + (*pszNext != TEXT('\0') ? 0 : 1));
// determine if there is an object already for this path chunk
pfs = findByName(htv, htiCur, szPathChunk); if (pfs != NULL) { if (pfs->wType != FTYPE_FOLDER) return NULL;
if (pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) return NULL;
htiCur = pfs->pTvItem->hItem; continue; }
// create this path chunk as SFav object
pfs = pfs->CreateNew(htv); if (pfs == NULL) return NULL;
pfs->wType = FTYPE_FOLDER; if (!pfs->Expand()) return NULL;
StrCpy(pfs->pszName, szPathChunk); pfs->SetTVI(); pfs->Shrink(); pfs->Add(htv, htiCur);
ASSERT(pfs->pTvItem != NULL && pfs->pTvItem->hItem != NULL); htiCur = pfs->pTvItem->hItem; }
return pfs; }
BOOL importPath(HWND htv, HTREEITEM htiFrom, HTREEITEM *phtiAfter) { LPFAVSTRUC pfs; TV_INSERTSTRUCT tvins; TV_ITEM tvi; HTREEITEM htiFromCur, htiToCur, htiParent, htiChild, *phtiQueueFrom, *phtiQueueTo; HRESULT hr; UINT nNumber, nFromHead, nFromTail, nToHead, nToTail; BOOL fQL, fResult;
if (phtiAfter == NULL || *phtiAfter == NULL) return FALSE;
hr = isFavoriteItem(htv, htiFrom); if (FAILED(hr)) return FALSE; fQL = (hr != S_OK);
// REVIEW: (andrewgu) actually, if we are to support this at all there needs to be a better
// default.
pfs = pfs->GetFirst(htv, fQL); if (pfs == NULL || pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) return FALSE;
if (htiFrom == NULL) { htiFrom = pfs->pTvItem->hItem; ASSERT(*phtiAfter != TVI_FIRST); }
fResult = FALSE; nNumber = pfs->GetNumber(htv, fQL); nFromHead = nFromTail = 0; nToHead = nToTail = 0;
// intialize queues
phtiQueueTo = NULL; phtiQueueFrom = new HTREEITEM[nNumber]; if (phtiQueueFrom == NULL) goto Exit; ZeroMemory(phtiQueueFrom, sizeof(HTREEITEM) * nNumber);
phtiQueueTo = new HTREEITEM[nNumber]; if (phtiQueueTo == NULL) goto Exit; ZeroMemory(phtiQueueTo, sizeof(HTREEITEM) * nNumber);
// put first element into the From queue, migrate it over
*(phtiQueueFrom + nFromTail++) = htiFrom;
ZeroMemory(&tvi, sizeof(tvi)); tvi.mask = TVIF_CHILDREN | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_STATE; tvi.hItem = htiFrom; TreeView_GetItem(htv, &tvi);
pfs = (LPFAVSTRUC)tvi.lParam; if (pfs == NULL || pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) goto Exit; tvi.mask |= TVIF_TEXT; tvi.hItem = NULL; tvi.pszText = pfs->pTvItem->pszText; tvi.cchTextMax = StrLen(pfs->pTvItem->pszText) + 1;
if (*phtiAfter == TVI_FIRST || *phtiAfter == TVI_LAST) htiParent = TreeView_GetParent(htv, htiFrom); else htiParent = TreeView_GetParent(htv, *phtiAfter);
ZeroMemory(&tvins, sizeof(tvins)); tvins.hParent = htiParent; tvins.hInsertAfter = *phtiAfter; CopyMemory(&tvins.item, &tvi, sizeof(tvi)); pfs->pTvItem->hItem = TreeView_InsertItem(htv, &tvins);
pfs->pTvItem->mask = TVIF_HANDLE | TVIF_STATE; TreeView_GetItem(htv, pfs->pTvItem);
ZeroMemory(&tvi, sizeof(tvi)); tvi.mask = TVIF_PARAM; tvi.hItem = htiFrom; tvi.lParam = NULL; TreeView_SetItem(htv, &tvi);
*(phtiQueueTo + nToTail++) = pfs->pTvItem->hItem;
// breadth-first graph traversion, non-recursive version
while (nFromHead < nFromTail) { htiFromCur = *(phtiQueueFrom + nFromHead++); htiToCur = *(phtiQueueTo + nToHead++); ASSERT(htiFromCur != NULL && htiToCur != NULL);
for (htiChild = TreeView_GetChild(htv, htiFromCur); htiChild != NULL; htiChild = TreeView_GetNextSibling(htv, htiChild)) {
*(phtiQueueFrom + nFromTail++) = htiChild; ASSERT(nFromTail < nNumber);
ZeroMemory(&tvi, sizeof(tvi)); tvi.mask = TVIF_CHILDREN | TVIF_PARAM | TVIF_SELECTEDIMAGE | TVIF_STATE; tvi.hItem = htiChild; TreeView_GetItem(htv, &tvi);
pfs = (LPFAVSTRUC)tvi.lParam; if (pfs == NULL || pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) goto Exit; tvi.mask |= TVIF_TEXT; tvi.hItem = NULL; tvi.pszText = pfs->pTvItem->pszText; tvi.cchTextMax = StrLen(pfs->pTvItem->pszText) + 1;
ZeroMemory(&tvins, sizeof(tvins)); tvins.hParent = htiToCur; tvins.hInsertAfter = TVI_LAST; CopyMemory(&tvins.item, &tvi, sizeof(tvi)); pfs->pTvItem->hItem = TreeView_InsertItem(htv, &tvins);
pfs->pTvItem->mask = TVIF_HANDLE | TVIF_STATE; TreeView_GetItem(htv, pfs->pTvItem);
ZeroMemory(&tvi, sizeof(tvi)); tvi.mask = TVIF_PARAM; tvi.hItem = htiChild; tvi.lParam = NULL; TreeView_SetItem(htv, &tvi);
*(phtiQueueTo + nToTail++) = pfs->pTvItem->hItem; ASSERT(nToTail < nNumber); } }
ASSERT(nFromHead == nFromTail && nToHead == nFromHead && nToHead == nToTail); fResult = TRUE;
// NOTE: (andrewgu) nFromHead is used is a mere counter here.
for (nFromHead = 0; nFromHead < nNumber; nFromHead++) { if (*(phtiQueueFrom + nFromHead) == NULL) break;
ZeroMemory(&tvi, sizeof(tvi)); tvi.mask = TVIF_STATE; tvi.hItem = *(phtiQueueFrom + nFromHead); TreeView_GetItem(htv, &tvi);
if (HasFlag(tvi.state, TVIS_EXPANDED)) TreeView_Expand(htv, *(phtiQueueTo + nFromHead), TVE_EXPAND); }
Exit: *phtiAfter = fResult ? *phtiQueueTo : NULL;
delete[] phtiQueueFrom; delete[] phtiQueueTo;
return fResult; }
void importPath(HWND htv, HTREEITEM hti, LPCTSTR pszFilesPath, LPCTSTR pszExtractPath, LPCTSTR pszReserved /*= NULL*/) { static LPCTSTR s_pszBasePath; static BOOL s_fMaxReached;
ISubscriptionMgr2 *psm; WIN32_FIND_DATA fd; LPFAVSTRUC pfs; TCHAR szPath[MAX_PATH], szLinksPath[MAX_PATH]; HANDLE hFindFile; HRESULT hr; BOOL fQL, fIgnoreOffline;
//----- Setup globals -----
if (NULL == pszReserved) { s_pszBasePath = pszFilesPath; s_fMaxReached = FALSE; }
if (s_fMaxReached) return;
if (NULL == pszFilesPath) return;
hr = isFavoriteItem(htv, hti); if (FAILED(hr)) return; fQL = (S_OK != hr);
szLinksPath[0] = TEXT('\0'); if (!fQL) getLinksPath(szLinksPath);
fIgnoreOffline = FALSE; psm = NULL;
hr = CoCreateInstance(CLSID_SubscriptionMgr, NULL, CLSCTX_INPROC_SERVER, IID_ISubscriptionMgr2, (LPVOID *)&psm); if (FAILED(hr)) fIgnoreOffline = TRUE;
PathCombine(szPath, pszFilesPath, TEXT("*.*")); hFindFile = FindFirstFile(szPath, &fd); if (INVALID_HANDLE_VALUE == hFindFile) return;
do { PathCombine(szPath, pszFilesPath, fd.cFileName);
if (HasFlag(fd.dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)) { // skip "." and ".." sub-directories
if (0 == StrCmp(fd.cFileName, TEXT(".")) || 0 == StrCmp(fd.cFileName, TEXT(".."))) continue;
// skip folders if importing under quick links
if (fQL) continue;
// magic trick for quick links
if (0 == StrCmpI(szPath, szLinksPath)) { pfs = pfs->GetFirst(htv, TRUE); if (NULL == pfs || NULL == pfs->pTvItem || NULL == pfs->pTvItem->hItem) continue;
importPath(htv, pfs->pTvItem->hItem, szPath, pszExtractPath, szPath); continue; }
importPath(htv, hti, szPath, pszExtractPath, s_pszBasePath); } else { /* it's a file */ // skip all file with extensions other than *.url
if (!PathIsExtension(fd.cFileName, DOT_URL)) continue;
if (NULL == pszReserved) pszReserved = pszFilesPath; ASSERT(StrLen(pszReserved) <= StrLen(pszFilesPath));
// determine if there is an object already for this
pfs = findByName(htv, hti, &szPath[StrLen(pszReserved) + 1]); if (NULL != pfs) { if (FTYPE_URL != pfs->wType || NULL == pfs->pTvItem || NULL == pfs->pTvItem->hItem) break;
pfs->Free(htv, fQL, pszExtractPath); }
pfs = pfs->CreateNew(htv, fQL); if (NULL == pfs) { if (pfs->GetNumber(htv, fQL) == pfs->GetMaxNumber(fQL)) { ErrorMessageBox(GetParent(htv), IDS_FAV_ERR_NOTALL); s_fMaxReached = TRUE; } break; }
hr = pfs->Load(&szPath[StrLen(pszReserved) + (PathHasBackslash(pszReserved) ? 0 : 1)], szPath, pszExtractPath, psm, fIgnoreOffline); if (FAILED(hr)) break;
pfs->Add(htv, hti); } } while (!s_fMaxReached && FindNextFile(hFindFile, &fd)); FindClose(hFindFile); }
int exportItems(HWND htv, HTREEITEM hti, LPCTSTR pszIns, LPCTSTR pszExtractPath, BOOL fFixUpPath /*= TRUE */) { struct SVisited { HTREEITEM hti; BOOL fVisited; } *pVisited;
LPFAVSTRUC pfs; HTREEITEM htiCur, htiChild, *phtiStack; HRESULT hr; UINT i, j, nNumber, nStack; BOOL fQL;
if (pszIns == NULL) return -1;
hr = isFavoriteItem(htv, hti); if (FAILED(hr)) return -1; fQL = (hr != S_OK);
pfs = getFolderItem(htv, hti); if (pfs == NULL || pfs->pTvItem == NULL || pfs->pTvItem->hItem == NULL) return -1;
nNumber = pfs->GetNumber(htv, fQL); nStack = 0;
// intialize stack
phtiStack = new HTREEITEM[nNumber]; if (phtiStack == NULL) return -1; ZeroMemory(phtiStack, sizeof(HTREEITEM) * nNumber);
*phtiStack = pfs->pTvItem->hItem; nStack++;
// initialize visited array
pVisited = new SVisited[nNumber]; if (pVisited == NULL) { delete [] phtiStack; return -1; } for (i = 0; pfs != NULL; i++, pfs = pfs->GetNext(htv, fQL)) { (pVisited + i)->hti = (pfs->pTvItem != NULL && pfs->pTvItem->hItem != NULL) ? pfs->pTvItem->hItem : NULL; (pVisited + i)->fVisited = FALSE; } ASSERT(i == nNumber);
// mark root as visited
for (i = 0; i < nNumber; i++) if ((pVisited + i)->hti == *phtiStack) break; ASSERT(i < nNumber); (pVisited + i)->fVisited = TRUE;
for (j = 1; nStack > 0; ) { htiCur = *(phtiStack + nStack-1);
// determine if there are non-visited children
for (htiChild = TreeView_GetChild(htv, htiCur); htiChild != NULL; htiChild = TreeView_GetNextSibling(htv, htiChild)) {
for (i = 0; i < nNumber; i++) if ((pVisited + i)->hti == htiChild) break; if (i < nNumber && !(pVisited + i)->fVisited) break; }
if (htiChild != NULL) { // add non-visited child to the stack
*(phtiStack + nStack) = htiChild; nStack++;
ASSERT((pVisited + i)->hti == htiChild); (pVisited + i)->fVisited = TRUE;
pfs = getItem(htv, htiChild); if (pfs == NULL || pfs->wType != FTYPE_URL) continue;
pfs->Save(htv, j++, pszIns, pszExtractPath, fQL, fFixUpPath); } else // all visited -> pop
*(phtiStack + --nStack) = NULL; }
delete[] phtiStack; delete[] pVisited;
return j; }
BOOL extractIcon(LPCTSTR pszIconFile, int iIconIndex, LPCTSTR pszExtractPath, LPTSTR pszResult, UINT cchResult) { TCHAR szExtractedFile[MAX_PATH]; HRESULT hr; UINT i; BOOL fURL;
if (pszIconFile == NULL || pszExtractPath == NULL || pszResult == NULL) return FALSE; *pszResult = TEXT('\0');
if (cchResult == 0) cchResult = MAX_PATH;
fURL = PathIsURL(pszIconFile); if (fURL) { PathCombine(szExtractedFile, pszExtractPath, PathFindFileName(pszIconFile));
hr = URLDownloadToFile(NULL, pszIconFile, szExtractedFile, 0L, NULL); if (FAILED(hr)) return FALSE; } else { static LPCTSTR rgpszCopyExt[] = { DOT_ICO, DOT_URL }; static LPCTSTR rgpszExtractExt[] = { DOT_EXE, DOT_DLL };
IStream *pStm; IPicture *pPic; PICTDESC pd; LPCTSTR pszExt; LPVOID pIcon; HANDLE hFile; HGLOBAL hmem; HICON hicon; HRESULT hr; DWORD dwWritten; LONG cbIcon;
// if it's an icon file just copy it
pszExt = PathFindExtension(pszIconFile); for (i = 0; i < countof(rgpszCopyExt); i++) if (StrCmpI(pszExt, rgpszCopyExt[i]) == 0) break; if (i < countof(rgpszCopyExt)) { StrCpy(szExtractedFile, pszIconFile); goto Exit; }
// if it doesn't have extension from which icon can be extracted bail out
for (i = 0; i < countof(rgpszExtractExt); i++) if (StrCmpI(pszExt, rgpszExtractExt[i]) == 0) break; if (i >= countof(rgpszExtractExt)) return FALSE;
// extract icons
ExtractIconEx(pszIconFile, iIconIndex, &hicon, NULL, 1); if (hicon == NULL) return FALSE;
hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm); if (FAILED(hr)) { DestroyIcon(hicon); return FALSE; }
ZeroMemory(&pd, sizeof(pd)); pd.cbSizeofstruct = sizeof(pd); pd.picType = PICTYPE_ICON; pd.icon.hicon = hicon;
hr = OleCreatePictureIndirect(&pd, IID_IPicture, TRUE, (LPVOID *)&pPic); if (FAILED(hr)) { DestroyIcon(hicon); return FALSE; }
hr = pPic->SaveAsFile(pStm, TRUE, &cbIcon); pPic->Release(); if (FAILED(hr)) { pStm->Release(); return FALSE; }
// generate a unique icon name
do { GetTempFileName(pszExtractPath, PREFIX_ICON, 0, szExtractedFile); DeleteFile(szExtractedFile); PathRenameExtension(szExtractedFile, DOT_ICO); } while (PathFileExists(szExtractedFile));
hFile = CreateFile(szExtractedFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { pStm->Release(); return FALSE; }
GetHGlobalFromStream(pStm, &hmem); ASSERT(hmem != NULL); pIcon = GlobalLock(hmem); ASSERT(pIcon != NULL);
WriteFile(hFile, pIcon, cbIcon, &dwWritten, NULL); CloseHandle(hFile);
GlobalUnlock(hmem); pStm->Release(); }
Exit: if (cchResult <= (UINT)StrLen(szExtractedFile)) return FALSE;
StrCpy(pszResult, szExtractedFile); return TRUE; }
LPCTSTR getLinksPath(LPTSTR pszPath, UINT cchPath /*= 0*/) { LPITEMIDLIST pidl; TCHAR szPath[MAX_PATH], szLinks[MAX_PATH]; HRESULT hr;
if (pszPath != NULL) *pszPath = TEXT('\0');
if (cchPath == 0) cchPath = MAX_PATH;
hr = SHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl); if (FAILED(hr)) return NULL;
hr = SHGetPathFromIDList(pidl, szPath) ? S_OK : E_FAIL; CoTaskMemFree(pidl); if (FAILED(hr)) return NULL; ASSERT(szPath[0] != TEXT('\0'));
szLinks[0] = TEXT('\0'); LoadString(g_hInst, IDS_LINKS, szLinks, countof(szLinks)); if (szLinks[0] == TEXT('\0')) return NULL;
PathAppend(szPath, szLinks); if (cchPath <= (UINT)StrLen(szPath)) return NULL;
StrCpy(pszPath, szPath); return pszPath; }
LPTSTR encodeFavName(LPTSTR pszFavName, LPCTSTR pszIns) { TCHAR szWrk[MAX_PATH], chWrk; LPTSTR pszFrom; LPTSTR pszTo; BOOL fEncodeFavs;
StrCpy(szWrk, pszFavName); pszFrom = szWrk; pszTo = pszFavName; fEncodeFavs = FALSE;
while (*pszFrom != TEXT('\0')) { switch(chWrk = *pszFrom++) { case TEXT('['): fEncodeFavs = TRUE; *pszTo++ = TEXT('%'); *pszTo++ = TEXT('('); break;
case TEXT(']'): fEncodeFavs = TRUE; *pszTo++ = TEXT('%'); *pszTo++ = TEXT(')'); break;
case TEXT('='): fEncodeFavs = TRUE; *pszTo++ = TEXT('%'); *pszTo++ = TEXT('-'); break;
case TEXT('%'): fEncodeFavs = TRUE; *pszTo++ = TEXT('%'); *pszTo++ = TEXT('%'); break;
default: *pszTo++ = chWrk; break; } }
*pszTo = TEXT('\0');
InsWriteBool(IS_BRANDING, IK_FAVORITES_ENCODE, fEncodeFavs, pszIns); return pszFavName; }
LPTSTR decodeFavName(LPTSTR pszFavName, LPCTSTR pszIns) { TCHAR szWrk[MAX_PATH], chWrk; LPTSTR pszFrom; LPTSTR pszTo;
if (!InsGetBool(IS_BRANDING, IK_FAVORITES_ENCODE, FALSE, pszIns)) return pszFavName;
StrCpy(szWrk, pszFavName); pszFrom = szWrk; pszTo = pszFavName; while((*pszFrom != TEXT('\0')) && ((chWrk = *pszFrom++) != TEXT('\0'))) { if (chWrk != TEXT('%')) *pszTo++ = chWrk;
else { switch(chWrk = *pszFrom++) { case TEXT('('): *pszTo++ = TEXT('['); break; case TEXT(')'): *pszTo++ = TEXT(']'); break; case TEXT('-'): *pszTo++ = TEXT('='); break; case TEXT('%'): *pszTo++ = TEXT('%'); break;
case TEXT('/'): #ifndef _UNICODE
*pszTo++ = IsDBCSLeadByte(*(pszTo - 1)) ? TEXT('\\') : TEXT('/'); #else
*pszTo++ = TEXT('/'); #endif
break;
default: *pszTo++ = TEXT('%'); *pszTo++ = chWrk; break; } } }
*pszTo = TEXT('\0'); return pszFavName; }
|