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); return1; }// 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); return1; } 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); return1; } 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("")); return0; }