HistoryTree.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:13k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // HistoryTree.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "Resource.h"
  5. #include "HistoryTree.h"
  6. #include <Wininet.h>
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CHistoryTree
  14. CHistoryTree::CHistoryTree()
  15. {
  16. m_pMalloc = NULL;
  17. SHGetMalloc(&m_pMalloc);
  18. m_bIE4 = FALSE;
  19. }
  20. CHistoryTree::~CHistoryTree()
  21. {
  22. // m_wndHisTree.DeleteAllItems();
  23. m_wndHisTree.m_astrHist.RemoveAll();
  24.     m_pMalloc->Release();
  25. }
  26. void CHistoryTree::Destroy()
  27. {
  28. }
  29. /////////////////////////////////////////////////////////////////////////////
  30. // CHistoryTree message handlers
  31. LPCTSTR CHistoryTree::GetTitle()
  32. {
  33. strTitle.LoadString(IDS_TITLE_HIS);
  34. return strTitle;
  35. }
  36. BOOL CHistoryTree::Initialize()
  37. {
  38. // TODO: Add your command handler code here
  39. m_wndHisTree.DeleteAllItems();
  40. m_wndHisTree.m_astrHist.RemoveAll();
  41. LPITEMIDLIST pidlHistory = NULL;
  42.    HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_HISTORY, &pidlHistory);
  43.    if (NOERROR != hr)
  44.    {
  45.    // AfxMessageBox("Can't get history folder.");
  46.    m_bIE4=TRUE;
  47.    //for ie4 or win95
  48.    CWaitCursor wc;
  49.    
  50.    IUrlHistoryStg2* pUrlHistoryStg2 = NULL;
  51.    HRESULT hr = CoCreateInstance(CLSID_CUrlHistory,
  52.    NULL, CLSCTX_INPROC, IID_IUrlHistoryStg2,
  53.    (void**)&pUrlHistoryStg2);
  54.    if (SUCCEEDED(hr))
  55.    {     
  56.    IEnumSTATURL* pEnum;
  57.    hr = pUrlHistoryStg2->EnumUrls(&pEnum);
  58.    ULONG size;
  59.    STATURL staturl;
  60.    int ind=1;
  61.    hr = pEnum->Next(1, &staturl, &size);
  62.    if(SUCCEEDED(hr))
  63.    {
  64.    m_wndHisTree.DeleteAllItems();
  65.    m_wndHisTree.m_astrHist.RemoveAll();
  66.    }
  67.    CTime ttime = CTime::GetCurrentTime();
  68.    today = ttime.GetDayOfWeek();
  69.    int t;
  70.    if(today==1)
  71.    t=8;
  72.    else
  73.    t=today;
  74.    CTimeSpan tt(t-2,0,0,0);
  75.    ttime =ttime - tt;
  76.    
  77.    CTime t2(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
  78.    montime = t2;
  79.    
  80.    while(size>0)
  81.    {
  82.    if(insertUrl(&staturl,ind))
  83.    {
  84.    m_wndHisTree.m_astrHist.Add(CString(staturl.pwcsUrl));
  85.    ind++;
  86.    }
  87.    pEnum->Next(1, &staturl, &size);
  88.    }
  89.    //open today
  90.    
  91.    
  92.    pEnum->Release();
  93.    pUrlHistoryStg2->Release();
  94.    }
  95.    
  96.    return FALSE;
  97.    }
  98.    
  99.    IShellFolder* psfDesktop;
  100.    IShellFolder* psfHistory;
  101.    
  102.    hr = SHGetDesktopFolder(&psfDesktop);
  103.    if (NOERROR != hr)
  104.    {
  105.    AfxMessageBox(_T("Can't get desktop."));
  106.    return FALSE;
  107.    }
  108.    
  109.    hr = psfDesktop->BindToObject(pidlHistory, NULL, IID_IShellFolder,
  110.    (LPVOID*)&psfHistory);
  111.    psfDesktop->Release();
  112.    
  113.    if (NOERROR != hr)
  114.    {
  115.    AfxMessageBox(_T("Can't bind history folder."));
  116.    return FALSE;
  117.    }
  118.    
  119.    AddHistory(psfHistory, NULL);
  120.    
  121.    m_pMalloc->Free(pidlHistory);
  122.    
  123.    psfHistory->Release();
  124.    
  125.    return TRUE;
  126. }
  127. BOOL CHistoryTree::Create(CWnd* pParent)
  128. {
  129. if (!m_wndHisTree.Create(WS_BORDER|WS_CHILD|WS_VISIBLE|TVS_SHOWSELALWAYS|TVS_LINESATROOT|
  130. TVS_FULLROWSELECT |TVS_TRACKSELECT ,
  131. CRect(0,0,0,0), pParent, 100))
  132. {
  133. TRACE0("Failed to create instant bar childn");
  134. return 0; // fail to create
  135. }
  136. CWnd* pTT = m_wndHisTree.FromHandle((HWND) m_wndHisTree.SendMessage(TVM_GETTOOLTIPS));
  137.     if (pTT != NULL)
  138. pTT->SetWindowPos(&CWnd::wndTopMost, 0, 0, 0, 0,
  139. SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
  140. CImageList img;
  141. img.Create(16, 16, ILC_COLORDDB|ILC_MASK, 4, 1);
  142. HBITMAP hbmp = ::LoadBitmap(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_TREE));
  143. ImageList_AddMasked(img.GetSafeHandle(), hbmp, RGB(255,0,255));
  144. m_wndHisTree.SetImageList(&img, TVSIL_NORMAL);
  145. img.Detach();
  146. m_wndHisTree.m_pHisTree = this;
  147. return TRUE;
  148. }
  149. CWnd* CHistoryTree::GetWindow()
  150. {
  151. return (CWnd*)&m_wndHisTree;
  152. }
  153. //for ie4 and win95
  154. BOOL CHistoryTree::insertUrl(LPSTATURL pSUrl, int ind)
  155. {
  156. //get host
  157. CString url(pSUrl->pwcsUrl);
  158. CString host;
  159. CString l = url.Left(5);
  160. int i;
  161. if(l == _T("https"))
  162. {
  163. host = url.Right(url.GetLength()-8);
  164. i=host.Find('/');
  165. if(i>0)
  166. host=host.Left(i);
  167. }
  168. if(l == _T("http:"))
  169. {
  170. host = url.Right(url.GetLength()-7);
  171. i=host.Find('/');
  172. if(i>0)
  173. host=host.Left(i);
  174. }
  175. else if(l == _T("ftp:/"))
  176. {
  177. host = url.Right(url.GetLength()-6);
  178. i=host.Find('/');
  179. if(i>0)
  180. host=host.Left(i);
  181. }
  182. else if(l == _T("file:"))
  183. {
  184. host.LoadString(IDS_MY_COMPUTER);
  185. }
  186. else
  187. return FALSE;
  188. //get date
  189. CTime ttime(pSUrl->ftLastVisited);
  190. CTime ttime2(pSUrl->ftLastUpdated);
  191. if( ttime < ttime2)
  192. ttime=ttime2;
  193. CTime filetime(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
  194. int d;
  195. int week = 0, data;
  196. CString root;
  197. CTimeSpan ts = montime-filetime;
  198. if(filetime < montime)
  199. {
  200. week = int(ts.GetDays() + 6)/7;
  201. }
  202. if(week>1)
  203. {
  204. CString tw;
  205. tw.Format(_T("%i"), week);
  206. root.LoadString(IDS_WEEKS_AGO);
  207. root = tw + root;
  208. data = -week-7;
  209. }
  210. else if(week==1)
  211. {
  212. root.LoadString(IDS_LAST_WEEK);
  213. data = -8;
  214. }
  215. else
  216. {
  217. d=filetime.GetDayOfWeek();
  218. if(d==today)
  219. root.LoadString(IDS_TODAY);
  220. else
  221. root.LoadString(IDS_SUNDAY+d-1);
  222. data = -9+d;
  223. if(d==1)
  224. data=-1;
  225. }
  226. HTREEITEM hitem;
  227. hitem = FindAndInsert(NULL, root, 0,0, data);
  228. hitem = FindAndInsert(hitem, host, 1,3);
  229. CString temp;
  230. temp = pSUrl->pwcsTitle;
  231. if(temp.IsEmpty())
  232. {
  233. temp=pSUrl->pwcsUrl;
  234. i=temp.ReverseFind('/');
  235. temp=temp.Right(temp.GetLength()-i-1);
  236. }
  237. HTREEITEM hnode = m_wndHisTree.InsertItem(temp, 2, 2, hitem);
  238. m_wndHisTree.SetItemData(hnode, ind);
  239. return TRUE;
  240. }
  241. HTREEITEM CHistoryTree::FindAndInsert(HTREEITEM  hRoot, LPCTSTR text, int nImg, int nOImg,int data)
  242. {
  243. HTREEITEM hit, hnode = NULL, pre=TVI_FIRST;
  244. BOOL found=FALSE;
  245. hit = m_wndHisTree.GetChildItem(hRoot);
  246. if(data>=0)
  247. while(hit!=NULL && !found)
  248. {
  249. if(m_wndHisTree.GetItemText(hit).CompareNoCase(text)==1)
  250. {
  251. hnode = m_wndHisTree.InsertItem(text, nImg, nOImg, hRoot,TVI_SORT);
  252. found = TRUE;
  253. }
  254. else if(m_wndHisTree.GetItemText(hit).CompareNoCase(text)==0)
  255. {
  256. found = TRUE;
  257. hnode = hit;
  258. }
  259. else
  260. hit = m_wndHisTree.GetNextSiblingItem(hit);
  261. }
  262. else //compare with data
  263. while(hit!=NULL && !found)
  264. {
  265. if((signed)m_wndHisTree.GetItemData(hit)>data)
  266. {
  267. hnode = m_wndHisTree.InsertItem(text, nImg, nOImg, hRoot,pre);
  268. found = TRUE;
  269. }
  270. else if((signed)m_wndHisTree.GetItemData(hit)==data)
  271. {
  272. found = TRUE;
  273. hnode = hit;
  274. }
  275. else
  276. {
  277. pre=hit;
  278. hit = m_wndHisTree.GetNextSiblingItem(hit);
  279. }
  280. }
  281. if(!found)
  282. hnode = m_wndHisTree.InsertItem(text, nImg, nOImg, hRoot,TVI_LAST);
  283. m_wndHisTree.SetItemData(hnode, data);
  284. return hnode;
  285. }
  286. //end
  287. BOOL CHistoryTree::Update(int nLevel)
  288. {
  289. if(m_bIE4)
  290. {
  291. HTREEITEM hit, pre=NULL;
  292. BOOL found=FALSE;
  293. int d;
  294. CString text;
  295. text.LoadString(IDS_TODAY);
  296. //now only update today.
  297. if (nLevel == 0)
  298. {
  299. //get today item
  300. hit = m_wndHisTree.GetChildItem(NULL);
  301. while(hit!=NULL && !found)
  302. {
  303. if(m_wndHisTree.GetItemText(hit).CompareNoCase(text)==0)
  304. {
  305. found = TRUE;
  306. }
  307. else
  308. {
  309. pre = hit;
  310. hit = m_wndHisTree.GetNextSiblingItem(hit);
  311. }
  312. }
  313. int day;
  314. if(found)
  315. {
  316. d = (int)m_wndHisTree.GetItemData(hit);
  317. day=d+9;
  318. if(d==-1)
  319. day=1;
  320. //delete today
  321. m_wndHisTree.DeleteItem(hit);
  322. m_wndHisTree.Expand(pre, TVE_COLLAPSE);
  323. }
  324. else
  325. day=today;
  326. //insert history after that day
  327. CWaitCursor wc;
  328. IUrlHistoryStg2* pUrlHistoryStg2 = NULL;
  329. HRESULT hr = CoCreateInstance(CLSID_CUrlHistory,
  330. NULL, CLSCTX_INPROC, IID_IUrlHistoryStg2,
  331. (void**)&pUrlHistoryStg2);
  332. if (SUCCEEDED(hr))
  333. {     
  334. IEnumSTATURL* pEnum;
  335. hr = pUrlHistoryStg2->EnumUrls(&pEnum);
  336. ULONG size;
  337. STATURL staturl;
  338. int ind = (int)m_wndHisTree.m_astrHist.GetUpperBound() + 2;
  339. hr = pEnum->Next(1,&staturl, &size);
  340. if(!SUCCEEDED(hr))
  341. {
  342. return FALSE;
  343. }
  344. CTime ttime = CTime::GetCurrentTime();
  345. today = ttime.GetDayOfWeek();
  346. CTime lastday;
  347. if(today == day)
  348. {
  349. CTime t1(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
  350. lastday = t1;
  351. }
  352. else
  353. {
  354. CTimeSpan tsp(1,0,0,0);
  355. ttime = ttime-tsp;
  356. CTime t1(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
  357. lastday = t1;
  358. ttime = ttime +tsp;
  359. }
  360. int t;
  361. if (today == 1)
  362. t=8;
  363. else
  364. t = today;
  365. CTimeSpan tt(t-2,0,0,0);
  366. ttime =ttime - tt;
  367. CTime t2(ttime.GetYear(), ttime.GetMonth(), ttime.GetDay(),0,0,0);
  368. montime = t2;
  369. while(size>0)
  370. {
  371. CTime t3(staturl.ftLastVisited);
  372. if(t3>=lastday)
  373. {
  374. if(insertUrl(&staturl,ind))
  375. {
  376. m_wndHisTree.m_astrHist.Add(CString(staturl.pwcsUrl));
  377. ind++;
  378. }
  379. }
  380. pEnum->Next(1,&staturl, &size);
  381. }
  382. //open today
  383. pEnum->Release();
  384. pUrlHistoryStg2->Release();
  385. }
  386. return TRUE;
  387. }
  388. return TRUE;
  389. }
  390. //following is for ie5 and win98
  391. //remove the children of Today
  392. HTREEITEM hit;
  393. BOOL found=FALSE;
  394. CString text;
  395. text.LoadString(IDS_TODAY);
  396. //get today item
  397. hit = m_wndHisTree.GetChildItem(NULL);
  398. while(hit!=NULL && !found)
  399. {
  400. if(m_wndHisTree.GetItemText(hit).CompareNoCase(text)==0)
  401. found = TRUE;
  402. else
  403. hit = m_wndHisTree.GetNextSiblingItem(hit);
  404. }
  405. if(found)
  406. {
  407. //delete today
  408. m_wndHisTree.DeleteItem(hit);
  409. //m_wndHisTree.Expand(pre, TVE_COLLAPSE);
  410. }
  411. LPITEMIDLIST pidlHistory = NULL;
  412.    HRESULT hr = SHGetSpecialFolderLocation(NULL, CSIDL_HISTORY, &pidlHistory);
  413.    if (NOERROR != hr)
  414.    return FALSE;
  415.    
  416.    IShellFolder* psfDesktop;
  417.    IShellFolder* psfHistory;
  418.    
  419.    hr = SHGetDesktopFolder(&psfDesktop);
  420.    if (NOERROR != hr)
  421.    return FALSE;
  422.    
  423.    hr = psfDesktop->BindToObject(pidlHistory, NULL, IID_IShellFolder,
  424.    (LPVOID*)&psfHistory);
  425.    psfDesktop->Release();
  426.    
  427.    if (NOERROR != hr)
  428.    return FALSE;
  429.    
  430.    AddHistory(psfHistory, NULL,0,0,TRUE);
  431.    
  432.    m_pMalloc->Free(pidlHistory);
  433.    
  434.    psfHistory->Release();
  435.    
  436.    return TRUE;
  437. }
  438. void CHistoryTree::AddHistory(IShellFolder *pFolder, HTREEITEM root, int nImg, int nOImg, BOOL bNeedCmp)
  439. {
  440. USES_CONVERSION;
  441. if(pFolder == NULL)
  442. return;
  443. //enum history
  444. IEnumIDList* pItems = NULL;
  445. LPITEMIDLIST pidlNext = NULL;
  446. CString lpszName;
  447. //TCHAR lpszFileName[MAX_PATH];
  448. LPTSTR lpszURL = NULL;
  449. DWORD dwEntrySize=0;
  450. // Enumerate all object in the given folder
  451. HRESULT hr = pFolder->EnumObjects(NULL, SHCONTF_FOLDERS|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN , &pItems);
  452. while (NOERROR == hr)
  453. {
  454. hr = pItems->Next(1, &pidlNext, NULL);
  455. if (NOERROR == hr)
  456. {
  457. GetName(pFolder, pidlNext, SHGDN_NORMAL, lpszName);
  458. //add folder
  459. BOOL found = FALSE;
  460. if(bNeedCmp)
  461. {
  462. HTREEITEM hit;
  463. //get today item
  464. hit = m_wndHisTree.GetChildItem(root);
  465. while(hit!=NULL && !found)
  466. {
  467. if(m_wndHisTree.GetItemText(hit).CompareNoCase(lpszName)==0)
  468. found = TRUE;
  469. else
  470. hit = m_wndHisTree.GetNextSiblingItem(hit);
  471. }
  472. }
  473. if(!found)
  474. {
  475. HTREEITEM hItem;
  476. if(nImg==0)
  477. hItem = m_wndHisTree.InsertItem(lpszName, nImg, nOImg, root ,TVI_LAST);
  478. else
  479. hItem = m_wndHisTree.InsertItem(lpszName, nImg, nOImg, root ,TVI_SORT);
  480. if(nImg==2)
  481. ResolveHistory(pFolder, pidlNext, &lpszURL);
  482. if (lpszURL)
  483. {
  484. // Add the URL to the array and free lpszURL
  485. // since it was created with IMalloc::Alloc
  486. m_wndHisTree.m_astrHist.Add(lpszURL);
  487. m_wndHisTree.SetItemData(hItem, m_wndHisTree.m_astrHist.GetSize());
  488. //is the url cached?
  489. dwEntrySize = 0;
  490. if(_tcsncmp(lpszURL, _T("file:"), 5) != 0)
  491. {
  492. #if _MSC_VER < 1300
  493. if (!GetUrlCacheEntryInfoExA(T2A(lpszURL), NULL, &dwEntrySize, NULL, NULL, NULL, 0))
  494. #else
  495. if (!GetUrlCacheEntryInfoEx(lpszURL, NULL, &dwEntrySize, NULL, NULL, NULL, 0))
  496. #endif
  497. {
  498. if (GetLastError() == ERROR_FILE_NOT_FOUND)
  499. {
  500. m_wndHisTree.SetItemState(hItem, TVIS_CUT, TVIS_CUT);
  501. }
  502. }
  503. }
  504. m_pMalloc->Free(lpszURL);
  505. lpszURL = NULL;
  506. }
  507. }
  508. if (pidlNext)
  509. m_pMalloc->Free(pidlNext);
  510. }
  511. }
  512. if (pItems)
  513. pItems->Release();
  514. }
  515. BOOL CHistoryTree::ResolveHistory(IShellFolder* pFolder, LPCITEMIDLIST pidl, LPTSTR* lpszURL)
  516. {
  517. IShellLink* pShellLink;
  518. *lpszURL = NULL;  // Assume failure
  519. // Get a pointer to the IShellLink interface from the given folder
  520. HRESULT hr = pFolder->GetUIObjectOf(NULL, 1, &pidl, IID_IShellLink, NULL, (LPVOID*)&pShellLink);
  521. if (SUCCEEDED(hr))
  522. {
  523. WIN32_FIND_DATA wfd;      
  524. hr = pShellLink->Resolve(AfxGetApp()->m_pMainWnd->m_hWnd, SLR_NO_UI); 
  525. if (NOERROR == hr)
  526. {
  527. // Get the path to the link target. 
  528. *lpszURL = (LPTSTR)m_pMalloc->Alloc(MAX_PATH);  // Must remember to Free later
  529. hr = pShellLink->GetPath(*lpszURL, MAX_PATH - 1, (WIN32_FIND_DATA*)&wfd, SLGP_UNCPRIORITY);
  530. }
  531. pShellLink->Release();
  532. }
  533. if(SUCCEEDED(hr))
  534. return TRUE;
  535. else
  536. return FALSE;
  537. }