Phinecos(洞庭散人)
光荣在于平淡,艰巨因为漫长
刷新IE收藏夹图标
原文链接:
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;
}