IEShellTreeCtrl.cpp
上传用户:yatsl7111
上传日期:2007-01-08
资源大小:1433k
文件大小:19k
源码类别:

图形图象

开发平台:

Visual C++

  1. //*******************************************************************************
  2. // COPYRIGHT NOTES
  3. // ---------------
  4. // You may use this source code, compile or redistribute it as part of your application 
  5. // for free. You cannot redistribute it as a part of a software development 
  6. // library without the agreement of the author. If the sources are 
  7. // distributed along with the application, you should leave the original 
  8. // copyright notes in the source code without any changes.
  9. // This code can be used WITHOUT ANY WARRANTIES at your own risk.
  10. // 
  11. // For the latest updates to this code, check this site:
  12. // http://www.masmex.com 
  13. // after Sept 2000
  14. // 
  15. // Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
  16. //*******************************************************************************
  17. // IEShellTreeCtrl.cpp : implementation file
  18. #include "stdafx.h"
  19. #include "IEShellTreeCtrl.h"
  20. #include "cbformats.h"
  21. #include "UIMessages.h"
  22. #include "dirwalk.h"
  23. #ifdef _DEBUG
  24. #define new DEBUG_NEW
  25. #undef THIS_FILE
  26. static char THIS_FILE[] = __FILE__;
  27. #endif
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CIEShellTreeCtrl
  30. CIEShellTreeCtrl::CIEShellTreeCtrl()
  31. {
  32. m_lptvid = NULL;
  33. m_hListWnd = NULL;
  34. m_hComboWnd = NULL;
  35. m_nThreadCount = 0;
  36. m_bRefreshAllowed = true;
  37. m_bNotifyParent = false;
  38. // Turn off WM_DROPFILES
  39. SetDropFiles(false);
  40. }
  41. CIEShellTreeCtrl::~CIEShellTreeCtrl()
  42. {
  43. }
  44. void CIEShellTreeCtrl::ShellExecute(HTREEITEM hItem,LPCTSTR pszVerb)
  45. {
  46. SHELLEXECUTEINFO si;
  47. ZeroMemory(&si,sizeof(si));
  48. si.cbSize = sizeof(si);
  49. si.hwnd = GetSafeHwnd();
  50. si.nShow = SW_SHOW;
  51. si.lpIDList = (LPVOID)GetPathPidl(hItem);
  52. si.fMask  = SEE_MASK_INVOKEIDLIST;
  53. if (pszVerb)
  54. si.lpVerb = pszVerb;
  55. ShellExecuteEx(&si);
  56. }
  57. void CIEShellTreeCtrl::RefreshComboBox(LPTVITEMDATA lptvid)
  58. {
  59. if (m_hComboWnd)
  60. {
  61. ::PostMessage(m_hComboWnd,WM_APP_CB_IE_POPULATE,(WPARAM)lptvid->lpifq,0);
  62. }
  63. }
  64. void CIEShellTreeCtrl::SetNotificationObject(bool bNotify)
  65. {
  66. if (bNotify)
  67. CreateFileChangeThreads(GetSafeHwnd());
  68. else
  69. DestroyThreads();
  70. }
  71. void CIEShellTreeCtrl::UpOneLevel(HTREEITEM hItem)
  72. {
  73. if (hItem == NULL)
  74. {
  75. hItem = GetSelectedItem();
  76. }
  77. if (hItem == NULL)
  78. return;
  79. HTREEITEM hParentItem = GetParentItem(hItem);
  80. if (hParentItem)
  81. Select(hParentItem,TVGN_CARET);
  82. }
  83. void CIEShellTreeCtrl::DestroyThreads()
  84. {
  85.     if (m_nThreadCount == 0) 
  86. return;
  87.     for (UINT i=0;i < m_nThreadCount; i++)
  88.     m_event[i].SetEvent();
  89.     ::WaitForMultipleObjects (m_nThreadCount, m_hThreads, TRUE, INFINITE);
  90.     for (i=0; i < m_nThreadCount; i++)
  91.         delete m_pThreads[i];
  92.     m_nThreadCount = 0;
  93. }
  94. void CIEShellTreeCtrl::CreateFileChangeThreads(HWND hwnd)
  95. {
  96. if (m_nThreadCount)
  97. return;
  98. TCHAR szDrives[MAX_PATH];
  99. DWORD dwSize = sizeof(szDrives)/sizeof(TCHAR);
  100. DWORD dwChars = GetLogicalDriveStrings(dwSize,szDrives);
  101. if (dwChars == 0 || dwChars > dwSize) 
  102. {
  103. TRACE(_T("Warning: CreateFileChangeThreads failed in GetLogicalDriveStringsn"));
  104. return;
  105. }
  106. UINT nType;
  107. CString sDrive;
  108. LPCTSTR pszDrives=szDrives;
  109. while (*pszDrives != '')
  110. {
  111. sDrive = pszDrives;
  112. nType = ::GetDriveType(sDrive);
  113. if (nType == DRIVE_FIXED || nType == DRIVE_REMOTE || nType == DRIVE_RAMDISK)
  114. {
  115. CreateFileChangeThread(sDrive,hwnd);
  116. }
  117. pszDrives = _tcsninc(pszDrives,sDrive.GetLength()+1);
  118. }
  119. }
  120. void CIEShellTreeCtrl::CreateFileChangeThread(const CString& sPath,HWND hwnd)
  121. {
  122. if (m_nThreadCount >= MAX_THREADS)
  123. return;
  124.     PDC_THREADINFO pThreadInfo = new DC_THREADINFO; // Thread will delete
  125.     pThreadInfo->sPath = sPath;
  126.     pThreadInfo->hEvent = m_event[m_nThreadCount].m_hObject;
  127.     pThreadInfo->pTreeCtrl = this;
  128.     CWinThread* pThread = AfxBeginThread (ThreadFunc, pThreadInfo,
  129.         THREAD_PRIORITY_IDLE);
  130.     pThread->m_bAutoDelete = FALSE;
  131.     m_hThreads[m_nThreadCount] = pThread->m_hThread;
  132.     m_pThreads[m_nThreadCount++] = pThread;
  133. }
  134. HTREEITEM CIEShellTreeCtrl::SearchSiblings(HTREEITEM hItem,LPITEMIDLIST pidlAbs)
  135. {
  136. LPTVITEMDATA pItem = NULL;
  137. HTREEITEM hChildItem = GetChildItem(hItem);
  138. HTREEITEM hFoundItem;
  139. while (hChildItem) 
  140. {
  141. pItem = (LPTVITEMDATA)GetItemData(hChildItem);
  142. if (GetShellPidl().ComparePidls(NULL,pItem->lpifq,pidlAbs))
  143.    break;
  144. hFoundItem = SearchSiblings(hChildItem,pidlAbs);
  145. if (hFoundItem)
  146. return hFoundItem;
  147. hChildItem = GetNextSiblingItem(hChildItem);
  148. }
  149. return hChildItem;
  150. }
  151. HTREEITEM CIEShellTreeCtrl::ExpandMyComputer(LPITEMIDLIST pidlAbs)
  152. {
  153. HTREEITEM hItem=NULL;
  154. if (pidlAbs == NULL)
  155. return hItem;
  156. LPITEMIDLIST pidlMyComputer=NULL;
  157. LPITEMIDLIST pidlFirst=GetShellPidl().CopyItemID(pidlAbs);
  158.     SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlMyComputer); 
  159. if (GetShellPidl().ComparePidls(NULL,pidlMyComputer,pidlFirst))
  160. {
  161. hItem = ExpandPidl(pidlMyComputer);
  162. }
  163. if (pidlMyComputer)
  164. GetShellPidl().FreePidl(pidlMyComputer);
  165. if (pidlFirst)
  166. GetShellPidl().FreePidl(pidlFirst);
  167. return hItem;
  168. }
  169. HTREEITEM CIEShellTreeCtrl::ExpandPidl(LPITEMIDLIST pidlAbs)
  170. {
  171. HTREEITEM hItem = SearchSiblings(GetRootItem(),pidlAbs);
  172. if (hItem)
  173. {
  174. Expand(hItem,TVE_EXPAND);
  175. }
  176. return hItem;
  177. }
  178. HTREEITEM CIEShellTreeCtrl::FindPidl(LPITEMIDLIST pidlAbs,BOOL bSelect)
  179. {
  180. HTREEITEM hItem = NULL;
  181. if (pidlAbs == NULL)
  182. hItem = GetRootItem();
  183. else
  184. hItem = SearchSiblings(GetRootItem(),pidlAbs);
  185. if (bSelect && hItem != GetSelectedItem())
  186. {
  187. SelectItem(hItem);
  188. SelectionChanged(hItem,GetItemData(hItem));
  189. }
  190. return hItem;
  191. }
  192. HTREEITEM CIEShellTreeCtrl::FindItem (HTREEITEM hItem, const CString& strTarget)
  193. {
  194.     while (hItem != NULL) 
  195. {
  196.         if (GetItemText (hItem) == strTarget)
  197.             break;
  198.         hItem = GetNextSiblingItem (hItem);
  199.     }
  200.     return hItem;
  201. }
  202. UINT CIEShellTreeCtrl::DeleteChildren (HTREEITEM hItem)
  203. {
  204.     UINT nCount = 0;
  205.     HTREEITEM hChild = GetChildItem (hItem);
  206.     while (hChild != NULL)
  207. {
  208.         HTREEITEM hNextItem = GetNextSiblingItem (hChild);
  209.         DeleteItem (hChild);
  210.         hChild = hNextItem;
  211.         nCount++;
  212.     }
  213.     return nCount;
  214. }
  215. void CIEShellTreeCtrl::Init()
  216. {
  217. ModifyStyle(0,TVS_EDITLABELS);
  218. CIEFolderTreeCtrl::Init();
  219. }
  220. void CIEShellTreeCtrl::Refresh()
  221. {
  222. SetRefreshAllowed(false);
  223. CIEFolderTreeCtrl::Refresh();
  224. SetRefreshAllowed(true);
  225. }
  226. bool CIEShellTreeCtrl::DragEnter(CDD_OleDropTargetInfo *pInfo)
  227. {
  228. HTREEITEM hItem = pInfo->GetTreeItem(); 
  229. if (hItem == NULL)
  230. return false;
  231. LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
  232. ASSERT(ptvid);
  233. if (ptvid == NULL)
  234. return false;
  235. return m_ShellDragDrop.DragEnter(pInfo,ptvid->lpsfParent,ptvid->lpi);
  236. }
  237. bool CIEShellTreeCtrl::DragLeave(CDD_OleDropTargetInfo *pInfo)
  238. {
  239. return m_ShellDragDrop.DragLeave(pInfo);
  240. }
  241. bool CIEShellTreeCtrl::DragOver(CDD_OleDropTargetInfo *pInfo)
  242. {
  243. pInfo->SetDropEffect(DROPEFFECT_NONE);
  244. HTREEITEM hItem = pInfo->GetTreeItem(); 
  245. if (hItem == NULL)
  246. return false;
  247. LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
  248. ASSERT(ptvid);
  249. if (ptvid == NULL)
  250. return false;
  251. return m_ShellDragDrop.DragOver(pInfo,ptvid->lpsfParent,ptvid->lpi);
  252. }
  253. bool CIEShellTreeCtrl::DragDrop(CDD_OleDropTargetInfo *pInfo)
  254. {
  255. HTREEITEM hItem = pInfo->GetTreeItem(); 
  256. if (hItem == NULL)
  257. return false;
  258. LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
  259. ASSERT(ptvid);
  260. if (ptvid == NULL)
  261. return false;
  262. return m_ShellDragDrop.DragDrop(pInfo,ptvid->lpsfParent,ptvid->lpi);
  263. }
  264. DROPEFFECT CIEShellTreeCtrl::DoDragDrop(NM_TREEVIEW* pNMTreeView,COleDataSource *pOleDataSource)
  265. {
  266. if (pNMTreeView->itemNew.hItem == GetRootItem())
  267. return DROPEFFECT_NONE;
  268. CCF_ShellIDList sl;
  269. CShellPidl pidl;
  270. HTREEITEM hParentItem = GetParentItem(pNMTreeView->itemNew.hItem);
  271. LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(pNMTreeView->itemNew.hItem);
  272. LPTVITEMDATA ptvid_parent = (LPTVITEMDATA)GetItemData(hParentItem);
  273. ASSERT(ptvid);
  274. ASSERT(ptvid_parent);
  275. if (GetShellPidl().IsDesktopFolder(ptvid->lpsfParent))
  276. sl.AddPidl(GetShellPidl().GetEmptyPidl());
  277. else
  278. sl.AddPidl(ptvid_parent->lpifq);
  279. sl.AddPidl(ptvid->lpi);
  280. CCF_HDROP cf_hdrop;
  281. CCF_String cf_text;
  282. CString sPath;
  283. pidl.SHPidlToPathEx(ptvid->lpifq,sPath);
  284. cf_hdrop.AddDropPoint(CPoint(pNMTreeView->ptDrag),FALSE);
  285. cf_hdrop.AddFileName(sPath);
  286. sPath += _T("rn");
  287. cf_text.SetString(sPath);
  288. CWDClipboardData::Instance()->SetData(pOleDataSource,&cf_text,CWDClipboardData::e_cfString);
  289. CWDClipboardData::Instance()->SetData(pOleDataSource,&cf_hdrop,CWDClipboardData::e_cfHDROP);
  290. CWDClipboardData::Instance()->SetData(pOleDataSource,&sl,CWDClipboardData::e_cfShellIDList);
  291. return GetShellPidl().GetDragDropAttributes(ptvid);
  292. }
  293. bool CIEShellTreeCtrl::EndLabelEdit(HTREEITEM hItem,LPCTSTR pszText)
  294. {
  295. LPTVITEMDATA plvit = (LPTVITEMDATA)GetItemData(hItem);
  296. CString sFromPath;
  297. CString sToPath;
  298. GetShellPidl().SHPidlToPathEx(plvit->lpifq,sFromPath);
  299. sToPath = sFromPath;
  300. sToPath.Replace(GetItemText(hItem),pszText);
  301. SHFILEOPSTRUCT shf;
  302. TCHAR szFrom[MAX_PATH+1];
  303. TCHAR szTo[MAX_PATH+1];
  304. ZeroMemory(szFrom,sizeof(szFrom));
  305. lstrcpy(szFrom,sFromPath);
  306. ZeroMemory(szTo,sizeof(szTo));
  307. lstrcpy(szTo,sToPath);
  308. ZeroMemory(&shf,sizeof(shf));
  309. shf.hwnd = GetSafeHwnd();
  310. shf.wFunc = FO_RENAME;
  311. shf.pFrom = szFrom;
  312. shf.pTo = szTo;
  313. #ifdef _DEBUG
  314. CString sMess;
  315. sMess = szFrom;
  316. sMess += _T("n");
  317. sMess += szTo;
  318. AfxMessageBox(sMess);
  319. #endif
  320. if (SHFileOperation(&shf) == 0)
  321. return true;
  322. SetRefreshAllowed(false);
  323. return false;
  324. }
  325. bool CIEShellTreeCtrl::SHMoveFile(HTREEITEM hSrcItem,HTREEITEM hDestItem)
  326. {
  327. LPTVITEMDATA plvit_src = (LPTVITEMDATA)GetItemData(hSrcItem);
  328. LPTVITEMDATA plvit_dest = (LPTVITEMDATA)GetItemData(hDestItem);
  329. CString sFromPath;
  330. CString sToPath;
  331. GetShellPidl().SHPidlToPathEx(plvit_src->lpifq,sFromPath);
  332. GetShellPidl().SHPidlToPathEx(plvit_dest->lpifq,sToPath);
  333. SHFILEOPSTRUCT shf;
  334. TCHAR szFrom[MAX_PATH+1];
  335. TCHAR szTo[MAX_PATH+1];
  336. ZeroMemory(szFrom,sizeof(szFrom));
  337. lstrcpy(szFrom,sFromPath);
  338. ZeroMemory(szTo,sizeof(szTo));
  339. lstrcpy(szTo,sToPath);
  340. ZeroMemory(&shf,sizeof(shf));
  341. shf.hwnd = GetSafeHwnd();
  342. shf.wFunc = FO_MOVE;
  343. shf.pFrom = szFrom;
  344. shf.pTo = szTo;
  345. return SHFileOperation(&shf) == 0 ? true : false;
  346. }
  347. BOOL CIEShellTreeCtrl::TransferItem(HTREEITEM hitemDrag, HTREEITEM hitemDrop)
  348. {
  349. return SHMoveFile(hitemDrag,hitemDrop) ? TRUE : FALSE;
  350. }
  351. bool CIEShellTreeCtrl::GetFolderInfo(HTREEITEM hItem,CString &sPath,CString &sName)
  352. {
  353. LPTVITEMDATA lptvid = (LPTVITEMDATA)GetItemData(hItem);
  354. if (lptvid == NULL)
  355. return false;
  356. GetShellPidl().SHPidlToPathEx(lptvid->lpifq,sPath,NULL,SHGDN_NORMAL);
  357. GetShellPidl().GetDisplayName(lptvid->lpi,sName);
  358. return true;
  359. }
  360. bool CIEShellTreeCtrl::LoadFolderItems(LPCTSTR pszPath)
  361. {
  362. return LoadItems(pszPath);
  363. }
  364. CRefresh *CIEShellTreeCtrl::CreateRefreshObject(HTREEITEM hItem,LPARAM lParam)
  365. {
  366. CRefreshShellFolder *pRefresh=NULL;
  367. if (lParam)
  368. {
  369. pRefresh = new CRefreshShellFolder(hItem,lParam);
  370. }
  371. return pRefresh;
  372. }
  373. bool CIEShellTreeCtrl::Expanding(NM_TREEVIEW *nmtvw)
  374. {
  375. if ((nmtvw->itemNew.state & TVIS_EXPANDEDONCE) || nmtvw->itemNew.hItem == GetRootItem())
  376. return false;
  377. LPSHELLFOLDER  pFolder=NULL;
  378. CUIListCtrlData *pData = (CUIListCtrlData*)nmtvw->itemNew.lParam;
  379. ASSERT(pData);
  380. ASSERT_KINDOF(CUIListCtrlData,pData);
  381. LPTVITEMDATA lptvid=(LPTVITEMDATA)pData->GetExtData();
  382. if (lptvid)
  383. {
  384. HRESULT hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
  385. 0, IID_IShellFolder,(LPVOID*)&pFolder);
  386. if (SUCCEEDED(hr))
  387. {
  388. if (!AddItems(nmtvw->itemNew.hItem,pFolder))
  389. SetButtonState(nmtvw->itemNew.hItem);
  390. }
  391. return false;
  392. }
  393. // prevent from expanding
  394. return true;
  395. }
  396. BEGIN_MESSAGE_MAP(CIEShellTreeCtrl, CIEFolderTreeCtrl)
  397. //{{AFX_MSG_MAP(CIEShellTreeCtrl)
  398. ON_MESSAGE(WM_SETMESSAGESTRING,OnSetmessagestring)
  399. ON_MESSAGE(WM_APP_CB_IE_HIT_ENTER,OnAppCbIeHitEnter)
  400. // NOTE - the ClassWizard will add and remove mapping macros here.
  401. ON_WM_DESTROY()
  402. //}}AFX_MSG_MAP
  403. ON_MESSAGE(WM_APP_POPULATE_TREE,OnAppPopulateTree)
  404. ON_MESSAGE(WM_APP_CB_IE_SEL_CHANGE,OnCBIESelChange)
  405. ON_MESSAGE(WM_APP_DIR_CHANGE_EVENT,OnAppDirChangeEvent)
  406. END_MESSAGE_MAP()
  407. /////////////////////////////////////////////////////////////////////////////
  408. // CIEShellTreeCtrl message handlers
  409. BOOL CIEShellTreeCtrl::OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult )
  410. {
  411. if ((message == WM_MEASUREITEM || message == WM_DRAWITEM && wParam == 0) || message == WM_INITMENUPOPUP)
  412. {
  413. if (m_lptvid)
  414. {
  415. return GetShellPidl().HandleMenuMsg(m_hWnd,m_lptvid->lpsfParent, m_lptvid->lpi,
  416. message,wParam,lParam);
  417. }
  418. }
  419. return CIEFolderTreeCtrl::OnWndMsg(message, wParam, lParam, pResult );
  420. }
  421. void CIEShellTreeCtrl::PreSubclassWindow()
  422. {
  423. CIEFolderTreeCtrl::PreSubclassWindow();
  424. CreateFileChangeThreads(GetSafeHwnd());
  425. }
  426. /////////////////////////////////////////////////////////////////////////
  427. // Thread function for detecting file system changes
  428. UINT CIEShellTreeCtrl::ThreadFunc (LPVOID pParam)
  429. {
  430. ///////////////////////////////
  431.     PDC_THREADINFO pThreadInfo = (PDC_THREADINFO) pParam;
  432.     HANDLE hEvent = pThreadInfo->hEvent;
  433. CIEShellTreeCtrl *pTreeCtrl = pThreadInfo->pTreeCtrl;
  434.     HWND hWnd = pTreeCtrl->GetSafeHwnd();
  435. TCHAR szPath[MAX_PATH];
  436. lstrcpy(szPath,pThreadInfo->sPath);
  437.     delete pThreadInfo;
  438.     ////////////////////////////////////
  439.     // Get a handle to a file change notification object.
  440. TRACE(_T("Creating directory thread handler for %sn"),szPath);
  441.     HANDLE hDirChange = ::FindFirstChangeNotification (szPath,TRUE,FILE_NOTIFY_CHANGE_DIR_NAME);
  442.     // Return now if ::FindFirstChangeNotification failed.
  443.     if (hDirChange == INVALID_HANDLE_VALUE)
  444.         return 1;
  445. const int nHandles=2;
  446.     HANDLE aHandles[nHandles];
  447.     aHandles[0] = hDirChange;
  448.     aHandles[1] = hEvent;
  449.     BOOL bContinue = TRUE;
  450.     // Sleep until a file change notification wakes this thread or
  451.     // m_event becomes set indicating it's time for the thread to end.
  452.     while (bContinue)
  453. {
  454. TRACE(_T("TreeControl waiting for %u multiple objectsn"),nHandles);
  455.         DWORD dw = ::WaitForMultipleObjects (nHandles, aHandles, FALSE, INFINITE);
  456.         if (dw - WAIT_OBJECT_0 == 0) 
  457. { // Respond to a change notification.
  458.             ::FindNextChangeNotification (hDirChange);
  459. TRACE(_T("-- Directory notify event was fired in CIEShellTreeCtrl --n"));
  460. if (pTreeCtrl->RefreshAllowed())
  461. {
  462. ::PostMessage (hWnd, WM_APP_DIR_CHANGE_EVENT,0,0);
  463. }
  464. else
  465. {
  466. TRACE(_T("but not sending as refresh disallowedn"));
  467. pTreeCtrl->SetRefreshAllowed(true);
  468. TRACE(_T("Refresh is now allowedn"));
  469. }
  470.         }
  471.         else if(dw - WAIT_OBJECT_0 == 1) 
  472. {
  473.             bContinue = FALSE;
  474. TRACE(_T("Directory Notify Thread was signalled to stopn"));
  475. }
  476.     }
  477.     // Close the file change notification handle and return.
  478.     ::FindCloseChangeNotification (hDirChange);
  479. TRACE(_T("Directory Notify Thread is endingn"));
  480.     return 0;
  481. }
  482. void CIEShellTreeCtrl::OnDestroy()
  483. {
  484. DestroyThreads();
  485. CIEFolderTreeCtrl::OnDestroy();
  486. }
  487. LRESULT CIEShellTreeCtrl::OnAppDirChangeEvent(WPARAM wParam, LPARAM lParam)
  488. {
  489. if (!RefreshAllowed())
  490. return 1L;
  491. Refresh();
  492. if (m_bNotifyParent)
  493. GetParent()->SendMessage(WM_APP_UPDATE_ALL_VIEWS,(WPARAM)HINT_SHELL_DIR_CHANGED,(LPARAM)(LPCTSTR)GetRootPath());
  494. return 1L;
  495. }
  496. LRESULT CIEShellTreeCtrl::OnCBIESelChange(WPARAM wParam,LPARAM lParam)
  497. {
  498. LPITEMIDLIST pidl = (LPITEMIDLIST)wParam;
  499. ExpandMyComputer(pidl);
  500. FindPidl(pidl);
  501. GetShellPidl().FreePidl(pidl);
  502. SetFocus();
  503. return 1L;
  504. }
  505. // Selection has changed
  506. void CIEShellTreeCtrl::UpdateEvent(LPARAM lHint,CObject *pHint)
  507. {
  508. // TODO: Add your specialized code here and/or call the base class
  509. // Notify the combo box
  510. const CRefreshShellFolder *pRefresh = static_cast<CRefreshShellFolder*>(pHint);
  511. LPTVITEMDATA lptvid = reinterpret_cast<LPTVITEMDATA>(pRefresh->GetItemData());
  512. ASSERT(lptvid);
  513. // Notify combo box
  514. RefreshComboBox(lptvid);
  515. // Notify list control
  516. if (m_hListWnd)
  517. {
  518. ::SendMessage(m_hListWnd,WM_APP_UPDATE_ALL_VIEWS,(WPARAM)lHint,(LPARAM)pHint);
  519. return;
  520. }
  521. // or let base class handle it
  522. CUITreeCtrl::UpdateEvent(lHint,pHint);
  523. }
  524. LRESULT CIEShellTreeCtrl::OnAppPopulateTree(WPARAM wParam, LPARAM lParam)
  525. {
  526. TRACE0("Selecting root itemn");
  527. HTREEITEM hRoot = GetRootItem();
  528. if (hRoot == NULL)
  529. return 1L;
  530. SelectItem(hRoot);
  531. //#ifndef _DEBUG
  532. SelectionChanged(hRoot,GetItemData(hRoot));
  533. /*#else
  534. LPTVITEMDATA lptvid = reinterpret_cast<LPTVITEMDATA>(GetItemData(hRoot));
  535. RefreshComboBox(lptvid);
  536. #endif
  537. */
  538. return 1;
  539. }
  540. void CIEShellTreeCtrl::DeleteKey(HTREEITEM hItem)
  541. {
  542. // TODO: Add your specialized code here and/or call the base class
  543. SHFILEOPSTRUCT shf;
  544. ZeroMemory(&shf,sizeof(shf));
  545. TCHAR szFrom[MAX_PATH+1];
  546. ZeroMemory(szFrom,sizeof(szFrom)*sizeof(TCHAR));
  547. lstrcpy(szFrom,GetPathName(hItem));
  548. shf.hwnd = GetSafeHwnd();
  549. shf.wFunc = FO_DELETE;
  550. shf.pFrom = szFrom;
  551. shf.fFlags = GetKeyState(VK_SHIFT) < 0 ? 0 : FOF_ALLOWUNDO;
  552. SHFileOperation(&shf);
  553. }
  554. void CIEShellTreeCtrl::DoubleClick(HTREEITEM hItem)
  555. {
  556. // TODO: Add your specialized code here and/or call the base class
  557. //ShellExecute(hItem);  //comment by 阳光灿烂,i dont need this.
  558. }
  559. void CIEShellTreeCtrl::GoBack(HTREEITEM hItem)
  560. {
  561. // TODO: Add your specialized code here and/or call the base class
  562. UpOneLevel(hItem);
  563. }
  564. void CIEShellTreeCtrl::ShowPopupMenu(HTREEITEM hItem,CPoint point)
  565. {
  566. // TODO: Add your specialized code here and/or call the base class
  567. if (m_PopupID)
  568. {
  569. CUITreeCtrl::ShowPopupMenu(hItem,point);
  570. }
  571. // TODO: Add your control notification handler code here
  572. m_lptvid = (LPTVITEMDATA)GetItemData(hItem);
  573. if (m_lptvid)
  574. GetShellPidl().PopupTheMenu(m_hWnd,m_lptvid->lpsfParent, &m_lptvid->lpi, 1, &point);
  575. }
  576. void CIEShellTreeCtrl::ShowProperties(HTREEITEM hItem)
  577. {
  578. // TODO: Add your specialized code here and/or call the base class
  579. ShellExecute(hItem,_T("properties"));
  580. }
  581. LRESULT CIEShellTreeCtrl::OnAppCbIeHitEnter(WPARAM wParam, LPARAM lParam)
  582. {
  583. if (lParam == NULL)
  584. return 0L;
  585. LPCTSTR pszPath = (LPCTSTR)lParam;
  586. LPITEMIDLIST pidl=NULL;
  587. GetShellPidl().SHPathToPidlEx(pszPath,&pidl,NULL);
  588. if (pidl == NULL)
  589. return 0L;
  590. int nCount = GetShellPidl().GetCount(pidl);
  591. LPITEMIDLIST pidlPart=NULL;
  592. LPITEMIDLIST pidlFull=NULL;
  593. HTREEITEM hItem=NULL;
  594. SetRedraw(FALSE);
  595. for(int i=0;i < nCount;i++)
  596. {
  597. pidlPart=GetShellPidl().CopyItemID(pidl,i+1);
  598. if (pidlPart)
  599. {
  600. pidlFull = GetShellPidl().ConcatPidl(pidlFull,pidlPart);
  601. hItem = ExpandPidl(pidlFull);
  602. if (hItem == NULL)
  603. break;
  604. GetShellPidl().FreePidl(pidlPart);
  605. }
  606. }
  607. if (hItem && GetShellPidl().ComparePidls(NULL,pidl,pidlFull))
  608. {
  609. Select(hItem,TVGN_CARET);
  610. }
  611. else
  612. {
  613. CString sMess;
  614. sMess.Format(_T("%s was not found"),pszPath);
  615. AfxMessageBox(sMess,MB_ICONSTOP);
  616. }
  617. if (pidl)
  618. GetShellPidl().FreePidl(pidl);
  619. if (pidlFull)
  620. GetShellPidl().FreePidl(pidlFull);
  621. SetRedraw(TRUE);
  622. return 1;
  623. }
  624. LRESULT CIEShellTreeCtrl::OnSetmessagestring(WPARAM wParam, LPARAM lParam)
  625. {
  626. if (GetParent())
  627. return GetParent()->SendMessage(WM_SETMESSAGESTRING,wParam,lParam);
  628. return 0;
  629. }