原文链接:
FavIconizer
class
CDirFileList:
public
CStringArray

{
public:
CDirFileList();


/**//**
*fillsthearraywithallfilesfoundinthegivendirectory.
*/paramdirNamethepathtothedirectoryonwhichthefilesshallbelookedfor
*/paramrecurseTRUEifyouwanttorecurseintosubdirectories
*/paramincludeDirsTRUEifyouwanttoadddirectoriestothearraytoo
*/
voidBuildList(constCStringdirName,constBOOLrecurse,constBOOLincludeDirs);
}
;

CDirFileList::CDirFileList()

{
SetSize(0,50);
}

void
CDirFileList::BuildList(
const
CStringdirName,
const
BOOLrecurse,
const
BOOLincludeDirs)

{
CFileFindfinder;
BOOLworking=finder.FindFile(dirName+_T("//*.*"));
while(working)


{
working=finder.FindNextFile();
//skip"."and".."
if(finder.IsDots())
continue;

//ifitsadirectorythenrecurse
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

{
BYTEbWidth;
BYTEbHeight;
BYTEbColorCount;
BYTEbReserved;
WORDwPlanes;
WORDwBitCount;
DWORDdwBytesInRes;
DWORDdwImageOffset;
}
ICONDIRENTRY;

typedef
struct
ICONHEADER

{
WORDidReserved;
WORDidType;
WORDidCount;
ICONDIRENTRYidEntries[1];
}
ICONHEADER;
BOOLCFavIconizerDlg::IsIconOrBmp(BYTE
*
pBuffer,DWORDdwLen)

{
//Quickanddirtychecktoseeifweactuallygot
//aniconorabitmap
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)
gotocheckifbmp;

returnTRUE;
}

//Notanicon
checkifbmp:

BITMAPFILEHEADER*pBmpFileHeader=(BITMAPFILEHEADER*)pBuffer;
BITMAPINFOHEADER*pBmpInfoHeader=(BITMAPINFOHEADER*)(pBuffer+sizeof(BITMAPFILEHEADER));

if((dwLen<sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER))
||
(pBmpFileHeader->bfType!=BM)
||
(pBmpFileHeader->bfSize!=dwLen))
returnFALSE;

returnTRUE;
}
DWORDCFavIconizerDlg::ThreadMethod()

{
//InitialisetheOLEsubsystem
HRESULThRes=::CoInitialize(NULL);
CStringresult;
intnIcons=0;
if(!SUCCEEDED(hRes))


{
MessageBox(_T("FailedtoinitializeOLE!"),_T("Error"),MB_OK|MB_ICONEXCLAMATION);
return1;
}//if(!SUCCEEDED(hRes))
GetDlgItem(IDOK)->SetWindowText(_T("Abort"));
//firstgetthefavoritesfolderofthecurrentuser
TCHARbuf[MAX_PATH];
//获取“收藏夹”路径
if(!SHGetSpecialFolderPath(this->m_hWnd,buf,CSIDL_FAVORITES,FALSE))


{
//nofavoritesfolder?
MessageBox(_T("couldnotlocateyourfavoritesfolder!"),_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);
return1;
}
CStringsFavPath=CString(buf);
if(!SetCurrentDirectory(sFavPath))


{
MessageBox(_T("couldnotsetthecurrentdirectory!"),_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);
return1;
}
sFavPath+="//";
CStringsFavIconPath=sFavPath+"_icons";
//创建隐藏的图标文件夹保存图标
CreateDirectory(sFavIconPath,NULL);
SetFileAttributes(sFavIconPath,FILE_ATTRIBUTE_HIDDEN);

//gatheralistofalllinksinthefavoritesfolder
CDirFileListfilelist;
filelist.BuildList(sFavPath,TRUE,FALSE);

m_totalProgress.SetRange(0,filelist.GetCount());
m_totalProgress.SetStep(1);
for(inti=0;i<filelist.GetSize();i++)


{
//iteratethroughalllinks
CStringlinkfile=filelist.GetAt(i);
CUrlShellLinklink;
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'sanurltohttp
CStringiconURL;
try


{
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("connecting
"));
CInternetSessionsession;
//尝试连接
CStdioFile*pHtmlFile=session.OpenURL(link.GetPath(),1,INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_NO_COOKIES);
if(pHtmlFile==NULL)
continue;
//nowreadthehtmlfileandsearchfor<LINKREL="SHORTCUTICON"
CStringhtmlline;
CStringhtmlheader;
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("receivingpage
"));
while(pHtmlFile->ReadString(htmlline))


{
htmlheader+=htmlline;
//weassumeherethatthehtmltagforthefaviconisnot
//splitoverseverallinesorhasseveralwhitespacesinit
//thiswon'tworkinallcasesbutarealparserjustfor
//thefaviconsislikekillingflieswitharocket
CStringtemp=htmlheader;
temp.MakeUpper();
if(temp.Find(_T("</HEAD>"))>=0)


{
//endofheaderfound
intpos=temp.Find(_T("<LINKREL=/"SHORTCUTICON/""));
if(pos<0)
pos=temp.Find(_T("<LINKREL=/"ICON/""));
if(pos>=0)


{
//intstartpos=temp.Find(_T("HREF=/""),pos)+6;
//intendpos=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("icontagfound!"));
}//if(pos>=0)
break;
}//if(htmlheader.Find(_T("</HEAD>"))>=0)
}//while(pHtmlFile->ReadString(htmlline))
pHtmlFile->Close();
deletepHtmlFile;
session.Close();
}
catch(CInternetException*pEx)


{
pEx->Delete();
}
if(iconURL.IsEmpty())


{
iconURL=_T("favicon.ico");
DWORDdwService;
CStringstrServer;
CStringstrObject;
INTERNET_PORTnPort;
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)


{
//notafullURLbutarelativeone
if(iconURL.GetAt(0)=='/')


{
DWORDdwService;
CStringstrServer;
CStringstrObject;
INTERNET_PORTnPort;
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'stimetofetchtheicon
try


{
//取图标文件
CInternetSessioniconsession;
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("gettingicon
"));
CStdioFile*pIconFile=iconsession.OpenURL(iconURL,1,INTERNET_FLAG_TRANSFER_BINARY|INTERNET_FLAG_EXISTING_CONNECT);
GetTempPath(sizeof(buf)/sizeof(TCHAR),buf);
TCHARtempfilebuf[MAX_PATH];
GetTempFileName(buf,_T("fav"),0,tempfilebuf);
_tcscat(tempfilebuf,_T(".ico"));
CFileiconfile;
iconfile.Open(tempfilebuf,CFile::modeCreate|CFile::modeReadWrite);
intlen=0;
while(len=pIconFile->Read(buf,sizeof(buf)))


{
iconfile.Write(buf,len);
}
iconfile.Close();
pIconFile->Close();
deletepIconFile;
iconsession.Close();
//nowcheckifit'sreallyaniconwegot
BOOLisIcon=FALSE;
if(iconfile.Open(tempfilebuf,CFile::modeRead|CFile::typeBinary))


{
intnSize=(int)iconfile.GetLength();
BYTE*pBuffer=newBYTE[nSize];

if(iconfile.Read(pBuffer,nSize)>0)


{
if(IsIconOrBmp(pBuffer,nSize))//检查是否是图标
isIcon=TRUE;
}

iconfile.Close();
delete[]pBuffer;
}
if(isIcon)


{
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("storingicon
"));
CStringiconpath=_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("noiconfound!"));
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("%dof%dlinksprocessed.%diconsfound"),i+1,filelist.GetSize(),nIcons);
GetDlgItem(IDC_RESULT)->SetWindowText(result);

}//for(inti=0;i<filelist.GetSize();i++)

//ClosedowntheOLEsubsystem
::CoUninitialize();
GetDlgItem(IDOK)->SetWindowText(_T("OK"));
GetDlgItem(IDC_LINKSTATUS)->SetWindowText(_T("finished!"));
GetDlgItem(IDC_LINKPATH)->SetWindowText(_T(""));

return0;
}


遍历文件夹工具类:



































































判断是否是图标文件:































































刷新IE收藏夹图标:





















































































































































































































































































