⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 historytree.cpp

📁 用VC写的浏览器
💻 CPP
字号:
// HistoryTree.cpp : implementation file
//

#include "stdafx.h"
#include "GreenBrowser.h"
#include "HistoryTree.h"
#include <Wininet.h>
#include "mainfrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//#pragma optimize( "s", on )

/////////////////////////////////////////////////////////////////////////////
// CHistoryTree

CHistoryTree::CHistoryTree()
{
   m_pMalloc = NULL;
   SHGetMalloc(&m_pMalloc);
   m_bIE4 = FALSE;
}

CHistoryTree::~CHistoryTree()
{
	m_wndHisTree.DeleteAllItems();
	m_wndHisTree.m_astrHist.RemoveAll();
    m_pMalloc->Release();
}

/////////////////////////////////////////////////////////////////////////////
// CHistoryTree message handlers

LPCSTR CHistoryTree::GetTitle()
{
	LOADSTR(strTitle ,IDS_TITLE_HIS);
	return (LPCSTR)strTitle;
}

BOOL CHistoryTree::Initialize()
{
	// TODO: Add your command handler code here
	
	m_wndHisTree.DeleteAllItems();
	m_wndHisTree.m_astrHist.RemoveAll();
	
	LPITEMIDLIST pidlHistory = NULL;	
	HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_HISTORY, &pidlHistory);
	if (NOERROR != hr)
	{
	   m_bIE4=TRUE;
	   //for ie4 or win95
	   CWaitCursor wc;
	   
	   IUrlHistoryStg2* pUrlHistoryStg2 = NULL;
	   HRESULT hr = CoCreateInstance(CLSID_CUrlHistory,
		   NULL, CLSCTX_INPROC, IID_IUrlHistoryStg2,
		   (void**)&pUrlHistoryStg2);
	   if (SUCCEEDED(hr))
	   {     
		   IEnumSTATURL* pEnum;
		   hr = pUrlHistoryStg2->EnumUrls(&pEnum);
		   ULONG size;
		   STATURL staturl;
		   int ind=1;
		   hr = pEnum->Next(-1,&staturl, &size);
		   if(SUCCEEDED(hr))
		   {
			   m_wndHisTree.DeleteAllItems();
			   m_wndHisTree.m_astrHist.RemoveAll();
		   }
		   CTime ttime = CTime::GetCurrentTime();
		   today = ttime.GetDayOfWeek();
		   int t;
		   if(today==1)
			   t=8;
		   else
			   t=today;
		   CTimeSpan tt(t-2,0,0,0);
		   ttime =ttime - tt;
		   CTime t2(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
		   montime = t2;
		   while(size>0)
		   {
			   if(insertUrl(&staturl,ind))
			   {
				   m_wndHisTree.m_astrHist.Add(staturl.pwcsUrl);
				   ind++;
			   }
			   pEnum->Next(-1,&staturl, &size);
		   }
		   pEnum->Release();
		   pUrlHistoryStg2->Release();
	   }
	   return FALSE;
   }
   
   IShellFolder* psfDesktop;
   IShellFolder* psfHistory;
   hr = SHGetDesktopFolder(&psfDesktop);
   if (NOERROR != hr)
   {
	   return FALSE;
   }
   hr = psfDesktop->BindToObject(pidlHistory, NULL, IID_IShellFolder,
	   (LPVOID*)&psfHistory);
   psfDesktop->Release();
   if (NOERROR != hr)
   {
	   return FALSE;
   }
   
   AddHistory(psfHistory, NULL);
   m_pMalloc->Free(pidlHistory);
   psfHistory->Release();
   
   return TRUE;
}

BOOL CHistoryTree::Create(CWnd* pParent)
{
	if (!m_wndHisTree.Create(WS_CHILD|WS_VISIBLE|TVS_SHOWSELALWAYS|TVS_LINESATROOT|
		TVS_FULLROWSELECT |TVS_TRACKSELECT ,
		CRect(0,0,0,0), pParent, 100))
	{
		TRACE0("Failed to create instant bar child\n");
		return 0;		// fail to create
	}
	m_wndHisTree.ModifyStyleEx(0, WS_EX_CLIENTEDGE);

	// bring the tooltips to front
	CWnd* pTT = m_wndHisTree.FromHandle((HWND) m_wndHisTree.SendMessage(TVM_GETTOOLTIPS));
    if (pTT != NULL)
		pTT->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0,
			SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);

	CImageList img;
	img.Create(16, 16, ILC_COLORDDB|ILC_MASK, 4, 1);
	HBITMAP hbmp = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_HISTORY));
	ImageList_AddMasked(img.GetSafeHandle(), hbmp, RGB(255,0,255));
	DeleteObject(hbmp);
	m_wndHisTree.SetImageList(&img, TVSIL_NORMAL);
	img.Detach();

	m_wndHisTree.m_pHisTree = this;

	return TRUE;
}

CWnd* CHistoryTree::GetWindow()
{
	return (CWnd*)&m_wndHisTree;
}

void CHistoryTree::Destroy()
{
	m_wndHisTree.DeleteAllItems();
	m_wndHisTree.m_astrHist.RemoveAll();
}

//for ie4 and win95
BOOL CHistoryTree::insertUrl(LPSTATURL pSUrl, int ind)
{
	//get host
	CString url = pSUrl->pwcsUrl;
	CString host;
	CString l = url.Left(5);
	int i;
	if(l=="https")
	{
		host = url.Right(url.GetLength()-8);
		i=host.Find('/');
		if(i>0)
			host=host.Left(i);
	}
	if(l=="http:")
	{
		host = url.Right(url.GetLength()-7);
		i=host.Find('/');
		if(i>0)
			host=host.Left(i);
	}
	else if(l=="ftp:/")
	{
		host = url.Right(url.GetLength()-6);
		i=host.Find('/');
		if(i>0)
			host=host.Left(i);
	}
	else if(l=="file:")
	{
		LOADSTR(host ,IDS_MY_COMPUTER);
	}
	else
		return FALSE;
	//get date
	CTime ttime(pSUrl->ftLastVisited);
	CTime ttime2(pSUrl->ftLastUpdated);
	if( ttime < ttime2)
		ttime=ttime2;

	CTime filetime(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
	int d;
	int week = 0, data;
	CString root;
	CTimeSpan ts = montime-filetime;
	if(filetime < montime)
	{
		week=(ts.GetDays()+6)/7;
	}

	if(week>1)
	{
		char tw[4];
		itoa(week, tw,10);
		LOADSTR(root ,IDS_WEEKS_AGO);
		root = tw+root;
		data = -week-7;
	}
	else if(week==1)
	{
		LOADSTR(root ,IDS_LAST_WEEK);
		data = -8;
	}
	else
	{
		d=filetime.GetDayOfWeek();
		if(d==today)
			{LOADSTR(root ,IDS_TODAY);}
		else
			{LOADSTR(root ,IDS_SUNDAY+d-1);}
		data = -9+d;
		if(d==1)
			data=-1;
	}
	
	HTREEITEM hitem;
	hitem = FindAndInsert(NULL, root, 0,0, data);
	hitem = FindAndInsert(hitem, host, 1,3);

	CString temp;
	temp = pSUrl->pwcsTitle;
	if(temp.IsEmpty())
	{
		temp=pSUrl->pwcsUrl;
		i=temp.ReverseFind('/');
		temp=temp.Right(temp.GetLength()-i-1);
	}
	HTREEITEM hnode = m_wndHisTree.InsertItem(temp, 2, 2, hitem);
	m_wndHisTree.SetItemData(hnode, ind);

	return TRUE;
}

HTREEITEM CHistoryTree::FindAndInsert(HTREEITEM  hRoot, LPCSTR text, int nImg, int nOImg,int data)
{
	HTREEITEM hit, hnode = NULL, pre=TVI_FIRST;
	BOOL found=FALSE;
	hit = m_wndHisTree.GetChildItem(hRoot);
	if(data>=0)
	{
		while(hit!=NULL && !found)
		{
			if(m_wndHisTree.GetItemText(hit).CompareNoCase(text)==1)
			{
				hnode = m_wndHisTree.InsertItem(text, nImg, nOImg, hRoot,TVI_SORT);
				found = TRUE;
			}
			else if(m_wndHisTree.GetItemText(hit).CompareNoCase(text)==0)
			{
				found = TRUE;
				hnode = hit;
			}
			else
				hit = m_wndHisTree.GetNextSiblingItem(hit);
		}
	}
	else //compare with data
	{
		while(hit!=NULL && !found)
		{
			if((signed)m_wndHisTree.GetItemData(hit)>data)
			{
				hnode = m_wndHisTree.InsertItem(text, nImg, nOImg, hRoot,pre);
				found = TRUE;
			}
			else if((signed)m_wndHisTree.GetItemData(hit)==data)
			{
				found = TRUE;
				hnode = hit;
			}
			else
			{
				pre=hit;
				hit = m_wndHisTree.GetNextSiblingItem(hit);
			}
		}
	}

	if(!found)
		hnode = m_wndHisTree.InsertItem(text, nImg, nOImg, hRoot,TVI_LAST);

	m_wndHisTree.SetItemData(hnode, data);

	return hnode;
}

BOOL CHistoryTree::Update(int nLevel)
{
	if(m_bIE4)
	{
		HTREEITEM hit, pre=NULL;
		BOOL found=FALSE;
		int d;
		CString text;
		LOADSTR(text ,IDS_TODAY);
		//now only update today.
		if (nLevel == 0)
		{
			//get today item
			hit = m_wndHisTree.GetChildItem(NULL);
			while(hit!=NULL && !found)
			{
				if(m_wndHisTree.GetItemText(hit).CompareNoCase(text)==0)
				{
					found = TRUE;
				}
				else
				{
					pre = hit;
					hit = m_wndHisTree.GetNextSiblingItem(hit);
				}
			}
			int day;
			if(found)
			{
				d = (int)m_wndHisTree.GetItemData(hit);
				day=d+9;
				if(d==-1)
					day=1;

				//delete today
				m_wndHisTree.DeleteItem(hit);
				m_wndHisTree.Expand(pre, TVE_COLLAPSE);
			}
			else
				day=today;

			//insert history after that day
			CWaitCursor wc;
			IUrlHistoryStg2* pUrlHistoryStg2 = NULL;
			HRESULT hr = CoCreateInstance(CLSID_CUrlHistory,
				NULL, CLSCTX_INPROC, IID_IUrlHistoryStg2,
				(void**)&pUrlHistoryStg2);
			if (SUCCEEDED(hr))
			{     
				IEnumSTATURL* pEnum;
				hr = pUrlHistoryStg2->EnumUrls(&pEnum);
				ULONG size;
				STATURL staturl;
				int ind=m_wndHisTree.m_astrHist.GetUpperBound()+2;
				hr = pEnum->Next(-1,&staturl, &size);
				if(!SUCCEEDED(hr))
				{
					return FALSE;
				}
				CTime ttime = CTime::GetCurrentTime();
				today = ttime.GetDayOfWeek();
				CTime lastday;
				if(today=day)
				{
					CTime t1(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
					lastday = t1;
				}
				else
				{
					CTimeSpan tsp(1,0,0,0);
					ttime = ttime-tsp;
					CTime t1(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
					lastday = t1;
					ttime = ttime +tsp;
				}
				int t;
				if(today==1)
					t=8;
				else
					t=today;
				CTimeSpan tt(t-2,0,0,0);
				ttime =ttime - tt;

				CTime t2(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
				montime = t2;

				while(size>0)
				{
					CTime t3(staturl.ftLastVisited);
					if(t3>=lastday)
					{
						if(insertUrl(&staturl,ind))
						{
							m_wndHisTree.m_astrHist.Add(staturl.pwcsUrl);
							ind++;
						}
					}
					pEnum->Next(-1,&staturl, &size);
				}
				pEnum->Release();
				pUrlHistoryStg2->Release();
			}
			return TRUE;
		}
		return TRUE;
	}

	//following is for ie5 and win98
	//remove the children of Today
	HTREEITEM hit;
	BOOL found=FALSE;
	CString text;
	LOADSTR(text ,IDS_TODAY);
	//get today item
	hit = m_wndHisTree.GetChildItem(NULL);
	while(hit!=NULL && !found)
	{
		if(m_wndHisTree.GetItemText(hit).CompareNoCase(text)==0)
			found = TRUE;
		else
			hit = m_wndHisTree.GetNextSiblingItem(hit);
	}
	if(found)
	{
		//delete today
		m_wndHisTree.DeleteItem(hit);
		//m_wndHisTree.Expand(pre, TVE_COLLAPSE);
	}
	LPITEMIDLIST pidlHistory = NULL;	
	HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_HISTORY, &pidlHistory);
	if (NOERROR != hr)
		return FALSE;
	
	IShellFolder* psfDesktop;
	IShellFolder* psfHistory;	
	hr = SHGetDesktopFolder(&psfDesktop);
	if (NOERROR != hr)
		return FALSE;	
	hr = psfDesktop->BindToObject(pidlHistory, NULL, IID_IShellFolder,
							 (LPVOID*)&psfHistory);
	psfDesktop->Release();	
	if (NOERROR != hr)
		return FALSE;
	
	AddHistory(psfHistory, NULL,0,0,TRUE);	
	m_pMalloc->Free(pidlHistory);	
	psfHistory->Release();
	
	return TRUE;
}

BOOL CHistoryTree::StrRetToStr(STRRET StrRet, LPTSTR *str, LPITEMIDLIST pidl)
{
	HRESULT hr = S_OK;
	int cch;
	LPSTR strOffset;	
	*str = NULL;  // Assume failure
	
	switch (StrRet.uType)
	{
	case STRRET_WSTR: 
		cch = WideCharToMultiByte(CP_OEMCP, 0, StrRet.pOleStr, -1, NULL, 0, NULL, NULL); 
		*str = (LPTSTR)m_pMalloc->Alloc(cch * sizeof(TCHAR));		
		if (*str != NULL)
			WideCharToMultiByte(CP_OEMCP, 0, StrRet.pOleStr, -1, *str, cch, NULL, NULL); 
		else
			hr = E_FAIL;
		break;
		
	case STRRET_OFFSET: 
		strOffset = (((char *) pidl) + StrRet.uOffset);		
		cch = strlen(strOffset) + 1; // NULL terminator
		*str = (LPTSTR)m_pMalloc->Alloc(cch * sizeof(TCHAR));		
		if (*str != NULL)
			strcpy(*str, strOffset);
		else
			hr = E_FAIL;
		break;
		
	case STRRET_CSTR: 
		cch = strlen(StrRet.cStr) + 1; // NULL terminator
		*str = (LPTSTR)m_pMalloc->Alloc(cch * sizeof(TCHAR));		
		if (*str != NULL)
			strcpy(*str, StrRet.cStr);
		else
			hr = E_FAIL;		
		break;
	} 
	
	return TRUE;
}

void CHistoryTree::AddHistory(IShellFolder *pFolder, HTREEITEM root, int nImg, int nOImg, BOOL bNeedCmp)
{
	if(pFolder == NULL)
		return;
	
	//enum history
	IEnumIDList* pItems = NULL;
	LPITEMIDLIST pidlNext = NULL;
	STRRET StrRetName;
	LPTSTR lpszName = NULL;
	LPTSTR lpszURL = NULL;
	DWORD dwEntrySize=0;
	
	// Enumerate all object in the given folder
	HRESULT hr = pFolder->EnumObjects(NULL, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN , &pItems);
	while (NOERROR == hr)
	{
		hr = pItems->Next(1, &pidlNext, NULL);
		if (NOERROR == hr)
		{
			pFolder->GetDisplayNameOf(pidlNext, SHGDN_NORMAL, &StrRetName);
			StrRetToStr(StrRetName, &lpszName, pidlNext);
			//add folder
			BOOL found = FALSE;
			if(bNeedCmp)
			{
				HTREEITEM hit;
				//get today item
				hit = m_wndHisTree.GetChildItem(root);
				while(hit!=NULL && !found)
				{
					if(m_wndHisTree.GetItemText(hit).CompareNoCase(lpszName)==0)
						found = TRUE;
					else
						hit = m_wndHisTree.GetNextSiblingItem(hit);
				}
			}
			if(!found)
			{
				HTREEITEM hItem;
				if(nImg==0)
					hItem = m_wndHisTree.InsertItem(lpszName, nImg, nOImg, root ,TVI_LAST);
				else
					hItem = m_wndHisTree.InsertItem(lpszName, nImg, nOImg, root ,TVI_SORT);
				if(nImg==2)
					ResolveHistory(pFolder, pidlNext, &lpszURL);
				if (lpszURL)
				{
					// Add the URL to the array and free lpszURL
					// since it was created with IMalloc::Alloc
					m_wndHisTree.m_astrHist.Add(lpszURL);
					m_wndHisTree.SetItemData(hItem, m_wndHisTree.m_astrHist.GetSize());
					//is the url cached?
					dwEntrySize = 0;
					if(strncmp(lpszURL, "file:", 5) != 0)
					{
						if (!GetUrlCacheEntryInfoEx(lpszURL,NULL,&dwEntrySize, NULL, NULL, NULL, 0))
						{
							if (GetLastError()==ERROR_FILE_NOT_FOUND)
							{
								m_wndHisTree.SetItemState(hItem, TVIS_CUT, TVIS_CUT);
							}
						}
					}
					m_pMalloc->Free(lpszURL);
					lpszURL = NULL;
				}
			}
			if (lpszName)
				m_pMalloc->Free(lpszName);
			if (pidlNext)
				m_pMalloc->Free(pidlNext);
		}
	}
	if (pItems)
		pItems->Release();
}

BOOL CHistoryTree::ResolveHistory(IShellFolder* pFolder, LPCITEMIDLIST pidl, LPTSTR* lpszURL)
{
	IShellLink* pShellLink;
	*lpszURL = NULL;  // Assume failure
	
	// Get a pointer to the IShellLink interface from the given folder
	HRESULT hr = pFolder->GetUIObjectOf(NULL, 1, &pidl, IID_IShellLink, NULL, (LPVOID*)&pShellLink);
	if (SUCCEEDED(hr))
	{
		WIN32_FIND_DATA wfd;      
		hr = pShellLink->Resolve(AfxGetApp()->m_pMainWnd->m_hWnd, SLR_NO_UI); 
		if (NOERROR == hr)
		{
			// Get the path to the link target. 
			*lpszURL = (LPTSTR)m_pMalloc->Alloc(MAX_PATH);  // Must remember to Free later
			hr = pShellLink->GetPath(*lpszURL, MAX_PATH - 1, (WIN32_FIND_DATA*)&wfd, SLGP_UNCPRIORITY);
		}
		pShellLink->Release();
	}
	
	if(SUCCEEDED(hr))
		return TRUE;
	else
		return FALSE;
}

//#pragma optimize( "s", off)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -