📄 historytree.cpp
字号:
// HistoryTree.cpp : implementation file
//
#include "stdafx.h"
#include "MyIE.h"
#include "HistoryTree.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// 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
LPSTR CHistoryTree::GetTitle()
{
strTitle.LoadString(IDS_TITLE_HIS);
return strTitle.GetBuffer(1);
}
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)
{
// AfxMessageBox("Can't get history folder.");
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);
}
//open today
pEnum->Release();
pUrlHistoryStg2->Release();
}
return FALSE;
}
IShellFolder* psfDesktop;
IShellFolder* psfHistory;
hr = SHGetDesktopFolder(&psfDesktop);
if (NOERROR != hr)
{
AfxMessageBox("Can't get desktop.");
return FALSE;
}
hr = psfDesktop->BindToObject(pidlHistory, NULL, IID_IShellFolder,
(LPVOID*)&psfHistory);
psfDesktop->Release();
if (NOERROR != hr)
{
AfxMessageBox("Can't bind history folder.");
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);
CBitmap bitmap;
CImageList img;
/* img.Create(IDB_BITMAP2, 16, 0, RGB(255, 0, 255));
m_wndHisTree.SetImageList(&img, TVSIL_NORMAL);
img.Detach();
*/
bitmap.LoadBitmap(IDB_BITMAP2);
img.Create(16, 16, ILC_COLORDDB|ILC_MASK, 4, 1);
img.Add(&bitmap, RGB(255,0,255));
m_wndHisTree.SetImageList(&img, TVSIL_NORMAL);
img.Detach();
bitmap.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();
return;
}
//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:")
{
host.LoadString(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);
root.LoadString(IDS_WEEKS_AGO);
root = tw+root;
data = -week-7;
}
else if(week==1)
{
root.LoadString(IDS_LAST_WEEK);
data = -8;
}
else
{
d=filetime.GetDayOfWeek();
if(d==today)
root.LoadString(IDS_TODAY);
else
root.LoadString(IDS_SUNDAY+d-1);
data = -9+d;
if(d==1)
data=-1;
}
HTREEITEM hitem;
hitem = FindAndInsert(NULL, root, 0,0, data);
//open today
// if(d==today)
// m_wndHisTree.Expand( hitem, TVE_EXPAND );
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;
}
//end
BOOL CHistoryTree::Update(int nLevel)
{
if(m_bIE4)
{
HTREEITEM hit, pre=NULL;
BOOL found=FALSE;
int d;
CString text;
text.LoadString(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);
}
//open today
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;
text.LoadString(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;
// STRRET StrRetFile;
LPTSTR lpszName = NULL;
// LPTSTR lpszFileName = NULL;
LPTSTR lpszURL = NULL;
// 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);
// pFolder->GetDisplayNameOf(pidlNext, SHGDN_FORPARSING, &StrRetFile);
StrRetToStr(StrRetName, &lpszName, pidlNext);
// StrRetToStr(StrRetFile, &lpszFileName, 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());
m_pMalloc->Free(lpszURL);
lpszURL = NULL;
}
}
if (lpszName)
m_pMalloc->Free(lpszName);
//if (lpszFileName)
// m_pMalloc->Free(lpszFileName);
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;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -