原文链接:FavIconizer
遍历文件夹工具类:
复制代码
class CDirFileList : public CStringArray
{
public:
CDirFileList();
/**
* fills the array with all files found in the given directory.
* \param dirName the path to the directory on which the files shall be looked for
* \param recurse TRUE if you want to recurse into subdirectories
* \param includeDirs TRUE if you want to add directories to the array too
*/
void BuildList(const CString dirName, const BOOL recurse, const BOOL includeDirs);
};
CDirFileList::CDirFileList()
{
SetSize(0,50);
}
void CDirFileList::BuildList(const CString dirName, const BOOL recurse, const BOOL includeDirs)
{
CFileFind finder;
BOOL working = finder.FindFile(dirName+_T("\\*.*"));
while (working)
{
working = finder.FindNextFile();
//skip "." and ".."
if (finder.IsDots())
continue;
//if its a directory then recurse
if (finder.IsDirectory())
{//是文件夹
if (includeDirs)
{//若结果要求保存文件夹
Add(finder.GetFilePath());
}
if (recurse)
{//递归下一层
BuildList(finder.GetFilePath(), recurse, includeDirs);
}
} // if (finder.IsDirectory())
else
{//是文件
Add(finder.GetFilePath());
}
} // while (working)
finder.Close();
}
复制代码
判断是否是图标文件:
复制代码
typedef struct tagICONDIRENTRY
{
BYTE bWidth;
BYTE bHeight;
BYTE bColorCount;
BYTE bReserved;
WORD wPlanes;
WORD wBitCount;
DWORD dwBytesInRes;
DWORD dwImageOffset;
} ICONDIRENTRY;
typedef struct ICONHEADER
{
WORD idReserved;
WORD idType;
WORD idCount;
ICONDIRENTRY idEntries[1];
} ICONHEADER;
BOOL CFavIconizerDlg::IsIconOrBmp(BYTE* pBuffer, DWORD dwLen)
{
// Quick and dirty check to see if we actually got
// an icon or a bitmap
ICONHEADER* pIconHeader = (ICONHEADER*) pBuffer;
ICONDIRENTRY* pIconEntry = (ICONDIRENTRY*) (pBuffer + sizeof(WORD) * 3);
BITMAPFILEHEADER* pBmpHeader = (BITMAPFILEHEADER*) pBuffer;
if ((pIconHeader->idType == 1)
&&
(pIconHeader->idReserved == 0)
&&
(dwLen >= sizeof(ICONHEADER) + sizeof(ICONDIRENTRY)) )
{
if (pIconEntry->dwImageOffset >= dwLen)
goto checkifbmp;
return TRUE;
}
// Not an icon
checkifbmp:
BITMAPFILEHEADER* pBmpFileHeader = (BITMAPFILEHEADER*) pBuffer;
BITMAPINFOHEADER* pBmpInfoHeader = (BITMAPINFOHEADER*) (pBuffer + sizeof(BITMAPFILEHEADER));
if ((dwLen < sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER))
||
(pBmpFileHeader->bfType != BM)
||
(pBmpFileHeader->bfSize != dwLen))
return FALSE;
return TRUE;
}
复制代码
刷新IE收藏夹图标:
复制代码
DWORD CFavIconizerDlg::ThreadMethod()
{
//Initialise the OLE subsystem
HRESULT hRes = ::CoInitialize(NULL);
CString result;
int nIcons = 0;
if (!SUCCEEDED(hRes))
{
MessageBox(_T("Failed to initialize OLE!"), _T("Error"), MB_OK | MB_ICONEXCLAMATION);
return 1;
} // if (!SUCCEEDED(hRes))
GetDlgItem(IDOK)->SetWindowText(_T("Abort"));
//first get the favorites folder of the current user
TCHAR buf[MAX_PATH];
//获取“收藏夹”路径
if (!SHGetSpecialFolderPath(this->m_hWnd, buf, CSIDL_FAVORITES, FALSE))
{
//no favorites folder?
MessageBox(_T("could not locate your favorites folder!"), _T("Error"), MB_OK | MB_ICONEXCLAMATION);
::CoUninitialize();
GetDlgItem(IDOK)->SetWindowText(_T("OK"));
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("finished!"));
GetDlgItem(IDC_LINKPATH)->SetWindowText(_T(""));
UpdateData(FALSE);
return 1;
}
CString sFavPath = CString(buf);
if (!SetCurrentDirectory(sFavPath))
{
MessageBox(_T("could not set the current directory!"), _T("Error"), MB_OK | MB_ICONEXCLAMATION);
::CoUninitialize();
GetDlgItem(IDOK)->SetWindowText(_T("OK"));
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("finished!"));
GetDlgItem(IDC_LINKPATH)->SetWindowText(_T(""));
UpdateData(FALSE);
return 1;
}
sFavPath += "\\";
CString sFavIconPath = sFavPath + "_icons";
//创建隐藏的图标文件夹保存图标
CreateDirectory(sFavIconPath, NULL);
SetFileAttributes(sFavIconPath, FILE_ATTRIBUTE_HIDDEN);
//gather a list of all links in the favorites folder
CDirFileList filelist;
filelist.BuildList(sFavPath, TRUE, FALSE);
m_totalProgress.SetRange(0, filelist.GetCount());
m_totalProgress.SetStep(1);
for (int i=0; i<filelist.GetSize(); i++)
{
//iterate through all links
CString linkfile = filelist.GetAt(i);
CUrlShellLink link;
if (!link.Load(linkfile))
continue;
GetDlgItem(IDC_LINKPATH)->SetWindowText(linkfile.Right(linkfile.GetLength() - linkfile.ReverseFind('\\') - 1));
if (link.GetPath().Left(4).CompareNoCase(_T("http"))==0)
{
//yes, it's an url to http
CString iconURL;
try
{
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("connecting"));
CInternetSession session;
//尝试连接
CStdioFile * pHtmlFile = session.OpenURL(link.GetPath(),1, INTERNET_FLAG_TRANSFER_BINARY |INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_NO_COOKIES);
if (pHtmlFile == NULL)
continue;
//now read the html file and search for <LINK REL="SHORTCUT ICON"
CString htmlline;
CString htmlheader;
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("receiving page"));
while (pHtmlFile->ReadString(htmlline))
{
htmlheader += htmlline;
//we assume here that the html tag for the favicon is not
//split over several lines or has several whitespaces in it
//this won't work in all cases but a real parser just for
//the favicons is like killing flies with a rocket
CString temp = htmlheader;
temp.MakeUpper();
if (temp.Find(_T("</HEAD>"))>=0)
{
//end of header found
int pos = temp.Find(_T("<LINK REL=\"SHORTCUT ICON\""));
if (pos < 0)
pos = temp.Find(_T("<LINK REL=\"ICON\""));
if (pos >= 0)
{
//int startpos = temp.Find(_T("HREF=\""), pos)+6;
//int endpos = temp.Find(_T("\""), startpos);
//iconURL = htmlheader.Mid(startpos, endpos);
//iconURL = temp.Mid(pos);
iconURL = htmlheader.Mid(temp.Find(_T("HREF=\""), pos)+6);
iconURL = iconURL.Left(iconURL.Find(_T("\"")));
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("icon tag found!"));
} // if (pos >= 0)
break;
} // if (htmlheader.Find(_T("</HEAD>"))>=0)
} // while (pHtmlFile->ReadString(htmlline))
pHtmlFile->Close();
delete pHtmlFile;
session.Close();
}
catch (CInternetException* pEx)
{
pEx->Delete();
}
if (iconURL.IsEmpty())
{
iconURL = _T("favicon.ico");
DWORD dwService;
CString strServer;
CString strObject;
INTERNET_PORT nPort;
AfxParseURL(link.GetPath(), dwService, strServer, strObject, nPort);
iconURL = _T("http://") + strServer + _T("/") + iconURL;
} // if (iconURL.IsEmpty())
else
{
if (!iconURL.Left(4).CompareNoCase(_T("http"))==0)
{
//not a full URL but a relative one
if (iconURL.GetAt(0) == '/')
{
DWORD dwService;
CString strServer;
CString strObject;
INTERNET_PORT nPort;
AfxParseURL(link.GetPath(), dwService, strServer, strObject, nPort);
iconURL = _T("http://") + strServer + _T("/") + iconURL;
} // if (iconURL.GetAt(0) == '/')
else
{
iconURL = link.GetPath().Left(link.GetPath().ReverseFind('/') + 1) + iconURL;
}
} // if (!iconURL.Left(4).CompareNoCase(_T("http"))==0)
}
if (!m_runthread)
break;
//it's time to fetch the icon
try
{
//取图标文件
CInternetSession iconsession;
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("getting icon"));
CStdioFile * pIconFile = iconsession.OpenURL(iconURL, 1, INTERNET_FLAG_TRANSFER_BINARY |INTERNET_FLAG_EXISTING_CONNECT);
GetTempPath(sizeof(buf)/sizeof(TCHAR), buf);
TCHAR tempfilebuf[MAX_PATH];
GetTempFileName(buf, _T("fav"), 0, tempfilebuf);
_tcscat(tempfilebuf, _T(".ico"));
CFile iconfile;
iconfile.Open(tempfilebuf, CFile::modeCreate | CFile::modeReadWrite);
int len = 0;
while (len = pIconFile->Read(buf, sizeof(buf)))
{
iconfile.Write(buf, len);
}
iconfile.Close();
pIconFile->Close();
delete pIconFile;
iconsession.Close();
//now check if it's really an icon we got
BOOL isIcon = FALSE;
if(iconfile.Open(tempfilebuf, CFile::modeRead | CFile::typeBinary))
{
int nSize = (int)iconfile.GetLength();
BYTE* pBuffer = new BYTE[nSize];
if(iconfile.Read(pBuffer, nSize) > 0)
{
if (IsIconOrBmp(pBuffer, nSize))//检查是否是图标
isIcon = TRUE;
}
iconfile.Close();
delete [] pBuffer;
}
if (isIcon)
{
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("storing icon"));
CString iconpath = _T("_icons\\") + linkfile.Right(linkfile.GetLength() - linkfile.ReverseFind('\\') - 1);
iconpath = iconpath.Left(iconpath.ReverseFind('.')) + _T(".ico");
DeleteFile(iconpath);
MoveFile(tempfilebuf, iconpath);
link.SetIconLocation(iconpath);
link.SetIconLocationIndex(0);
link.Save(linkfile);
nIcons++;
} // if (isIcon)
else
{
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("no icon found!"));
DeleteFile(tempfilebuf);
}
}
catch (CInternetException* pEx)
{
pEx->Delete();
}
catch (CFileException* pEx)
{
pEx->Delete();
}
} // if (link.GetPath().Left(4).CompareNoCase(_T("http"))==0)
if (!m_runthread)
break;
m_totalProgress.StepIt();
result.Format(_T("%d of %d links processed. %d icons found"), i+1, filelist.GetSize(), nIcons);
GetDlgItem(IDC_RESULT)->SetWindowText(result);
} // for (int i=0; i<filelist.GetSize(); i++)
//Closedown the OLE subsystem
::CoUninitialize();
GetDlgItem(IDOK)->SetWindowText(_T("OK"));
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("finished!"));
GetDlgItem(IDC_LINKPATH)->SetWindowText(_T(""));
return 0;
}
复制代码
本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2008/07/06/1236969.html,如需转载请自行联系原作者