📄 ieshelltreectrl.cpp
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// You may use this source code, compile or redistribute it as part of your application
// for free. You cannot redistribute it as a part of a software development
// library without the agreement of the author. If the sources are
// distributed along with the application, you should leave the original
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES at your own risk.
//
// For the latest updates to this code, check this site:
// http://www.masmex.com
// after Sept 2000
//
// Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
//*******************************************************************************
// IEShellTreeCtrl.cpp : implementation file
#include "stdafx.h"
#include "IEShellTreeCtrl.h"
#include "cbformats.h"
#include "UIMessages.h"
#include "dirwalk.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CIEShellTreeCtrl
CIEShellTreeCtrl::CIEShellTreeCtrl()
{
m_lptvid = NULL;
m_hListWnd = NULL;
m_hComboWnd = NULL;
m_nThreadCount = 0;
m_bRefreshAllowed = true;
m_bNotifyParent = false;
// Turn off WM_DROPFILES
SetDropFiles(false);
}
CIEShellTreeCtrl::~CIEShellTreeCtrl()
{
}
void CIEShellTreeCtrl::ShellExecute(HTREEITEM hItem,LPCTSTR pszVerb)
{
SHELLEXECUTEINFO si;
ZeroMemory(&si,sizeof(si));
si.cbSize = sizeof(si);
si.hwnd = GetSafeHwnd();
si.nShow = SW_SHOW;
si.lpIDList = (LPVOID)GetPathPidl(hItem);
si.fMask = SEE_MASK_INVOKEIDLIST;
if (pszVerb)
si.lpVerb = pszVerb;
ShellExecuteEx(&si);
}
void CIEShellTreeCtrl::RefreshComboBox(LPTVITEMDATA lptvid)
{
if (m_hComboWnd)
{
::PostMessage(m_hComboWnd,WM_APP_CB_IE_POPULATE,(WPARAM)lptvid->lpifq,0);
}
}
void CIEShellTreeCtrl::SetNotificationObject(bool bNotify)
{
if (bNotify)
CreateFileChangeThreads(GetSafeHwnd());
else
DestroyThreads();
}
void CIEShellTreeCtrl::UpOneLevel(HTREEITEM hItem)
{
if (hItem == NULL)
{
hItem = GetSelectedItem();
}
if (hItem == NULL)
return;
HTREEITEM hParentItem = GetParentItem(hItem);
if (hParentItem)
Select(hParentItem,TVGN_CARET);
}
void CIEShellTreeCtrl::DestroyThreads()
{
if (m_nThreadCount == 0)
return;
for (UINT i=0;i < m_nThreadCount; i++)
m_event[i].SetEvent();
::WaitForMultipleObjects (m_nThreadCount, m_hThreads, TRUE, INFINITE);
for (i=0; i < m_nThreadCount; i++)
delete m_pThreads[i];
m_nThreadCount = 0;
}
void CIEShellTreeCtrl::CreateFileChangeThreads(HWND hwnd)
{
if (m_nThreadCount)
return;
TCHAR szDrives[MAX_PATH];
DWORD dwSize = sizeof(szDrives)/sizeof(TCHAR);
DWORD dwChars = GetLogicalDriveStrings(dwSize,szDrives);
if (dwChars == 0 || dwChars > dwSize)
{
TRACE(_T("Warning: CreateFileChangeThreads failed in GetLogicalDriveStrings\n"));
return;
}
UINT nType;
CString sDrive;
LPCTSTR pszDrives=szDrives;
while (*pszDrives != '\0')
{
sDrive = pszDrives;
nType = ::GetDriveType(sDrive);
if (nType == DRIVE_FIXED || nType == DRIVE_REMOTE || nType == DRIVE_RAMDISK)
{
CreateFileChangeThread(sDrive,hwnd);
}
pszDrives = _tcsninc(pszDrives,sDrive.GetLength()+1);
}
}
void CIEShellTreeCtrl::CreateFileChangeThread(const CString& sPath,HWND hwnd)
{
if (m_nThreadCount >= MAX_THREADS)
return;
PDC_THREADINFO pThreadInfo = new DC_THREADINFO; // Thread will delete
pThreadInfo->sPath = sPath;
pThreadInfo->hEvent = m_event[m_nThreadCount].m_hObject;
pThreadInfo->pTreeCtrl = this;
CWinThread* pThread = AfxBeginThread (ThreadFunc, pThreadInfo,
THREAD_PRIORITY_IDLE);
pThread->m_bAutoDelete = FALSE;
m_hThreads[m_nThreadCount] = pThread->m_hThread;
m_pThreads[m_nThreadCount++] = pThread;
}
HTREEITEM CIEShellTreeCtrl::SearchSiblings(HTREEITEM hItem,LPITEMIDLIST pidlAbs)
{
LPTVITEMDATA pItem = NULL;
HTREEITEM hChildItem = GetChildItem(hItem);
HTREEITEM hFoundItem;
while (hChildItem)
{
pItem = (LPTVITEMDATA)GetItemData(hChildItem);
if (GetShellPidl().ComparePidls(NULL,pItem->lpifq,pidlAbs))
break;
hFoundItem = SearchSiblings(hChildItem,pidlAbs);
if (hFoundItem)
return hFoundItem;
hChildItem = GetNextSiblingItem(hChildItem);
}
return hChildItem;
}
HTREEITEM CIEShellTreeCtrl::ExpandMyComputer(LPITEMIDLIST pidlAbs)
{
HTREEITEM hItem=NULL;
if (pidlAbs == NULL)
return hItem;
LPITEMIDLIST pidlMyComputer=NULL;
LPITEMIDLIST pidlFirst=GetShellPidl().CopyItemID(pidlAbs);
SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlMyComputer);
if (GetShellPidl().ComparePidls(NULL,pidlMyComputer,pidlFirst))
{
hItem = ExpandPidl(pidlMyComputer);
}
if (pidlMyComputer)
GetShellPidl().FreePidl(pidlMyComputer);
if (pidlFirst)
GetShellPidl().FreePidl(pidlFirst);
return hItem;
}
HTREEITEM CIEShellTreeCtrl::ExpandPidl(LPITEMIDLIST pidlAbs)
{
HTREEITEM hItem = SearchSiblings(GetRootItem(),pidlAbs);
if (hItem)
{
Expand(hItem,TVE_EXPAND);
}
return hItem;
}
HTREEITEM CIEShellTreeCtrl::FindPidl(LPITEMIDLIST pidlAbs,BOOL bSelect)
{
HTREEITEM hItem = NULL;
if (pidlAbs == NULL)
hItem = GetRootItem();
else
hItem = SearchSiblings(GetRootItem(),pidlAbs);
if (bSelect && hItem != GetSelectedItem())
{
SelectItem(hItem);
SelectionChanged(hItem,GetItemData(hItem));
}
return hItem;
}
HTREEITEM CIEShellTreeCtrl::FindItem (HTREEITEM hItem, const CString& strTarget)
{
while (hItem != NULL)
{
if (GetItemText (hItem) == strTarget)
break;
hItem = GetNextSiblingItem (hItem);
}
return hItem;
}
UINT CIEShellTreeCtrl::DeleteChildren (HTREEITEM hItem)
{
UINT nCount = 0;
HTREEITEM hChild = GetChildItem (hItem);
while (hChild != NULL)
{
HTREEITEM hNextItem = GetNextSiblingItem (hChild);
DeleteItem (hChild);
hChild = hNextItem;
nCount++;
}
return nCount;
}
void CIEShellTreeCtrl::Init()
{
ModifyStyle(0,TVS_EDITLABELS);
CIEFolderTreeCtrl::Init();
}
void CIEShellTreeCtrl::Refresh()
{
SetRefreshAllowed(false);
CIEFolderTreeCtrl::Refresh();
SetRefreshAllowed(true);
}
bool CIEShellTreeCtrl::DragEnter(CDD_OleDropTargetInfo *pInfo)
{
HTREEITEM hItem = pInfo->GetTreeItem();
if (hItem == NULL)
return false;
LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
ASSERT(ptvid);
if (ptvid == NULL)
return false;
return m_ShellDragDrop.DragEnter(pInfo,ptvid->lpsfParent,ptvid->lpi);
}
bool CIEShellTreeCtrl::DragLeave(CDD_OleDropTargetInfo *pInfo)
{
return m_ShellDragDrop.DragLeave(pInfo);
}
bool CIEShellTreeCtrl::DragOver(CDD_OleDropTargetInfo *pInfo)
{
pInfo->SetDropEffect(DROPEFFECT_NONE);
HTREEITEM hItem = pInfo->GetTreeItem();
if (hItem == NULL)
return false;
LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
ASSERT(ptvid);
if (ptvid == NULL)
return false;
return m_ShellDragDrop.DragOver(pInfo,ptvid->lpsfParent,ptvid->lpi);
}
bool CIEShellTreeCtrl::DragDrop(CDD_OleDropTargetInfo *pInfo)
{
HTREEITEM hItem = pInfo->GetTreeItem();
if (hItem == NULL)
return false;
LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
ASSERT(ptvid);
if (ptvid == NULL)
return false;
return m_ShellDragDrop.DragDrop(pInfo,ptvid->lpsfParent,ptvid->lpi);
}
DROPEFFECT CIEShellTreeCtrl::DoDragDrop(NM_TREEVIEW* pNMTreeView,COleDataSource *pOleDataSource)
{
if (pNMTreeView->itemNew.hItem == GetRootItem())
return DROPEFFECT_NONE;
CCF_ShellIDList sl;
CShellPidl pidl;
HTREEITEM hParentItem = GetParentItem(pNMTreeView->itemNew.hItem);
LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(pNMTreeView->itemNew.hItem);
LPTVITEMDATA ptvid_parent = (LPTVITEMDATA)GetItemData(hParentItem);
ASSERT(ptvid);
ASSERT(ptvid_parent);
if (GetShellPidl().IsDesktopFolder(ptvid->lpsfParent))
sl.AddPidl(GetShellPidl().GetEmptyPidl());
else
sl.AddPidl(ptvid_parent->lpifq);
sl.AddPidl(ptvid->lpi);
CCF_HDROP cf_hdrop;
CCF_String cf_text;
CString sPath;
pidl.SHPidlToPathEx(ptvid->lpifq,sPath);
cf_hdrop.AddDropPoint(CPoint(pNMTreeView->ptDrag),FALSE);
cf_hdrop.AddFileName(sPath);
sPath += _T("\r\n");
cf_text.SetString(sPath);
CWDClipboardData::Instance()->SetData(pOleDataSource,&cf_text,CWDClipboardData::e_cfString);
CWDClipboardData::Instance()->SetData(pOleDataSource,&cf_hdrop,CWDClipboardData::e_cfHDROP);
CWDClipboardData::Instance()->SetData(pOleDataSource,&sl,CWDClipboardData::e_cfShellIDList);
return GetShellPidl().GetDragDropAttributes(ptvid);
}
bool CIEShellTreeCtrl::EndLabelEdit(HTREEITEM hItem,LPCTSTR pszText)
{
LPTVITEMDATA plvit = (LPTVITEMDATA)GetItemData(hItem);
CString sFromPath;
CString sToPath;
GetShellPidl().SHPidlToPathEx(plvit->lpifq,sFromPath);
sToPath = sFromPath;
sToPath.Replace(GetItemText(hItem),pszText);
SHFILEOPSTRUCT shf;
TCHAR szFrom[MAX_PATH+1];
TCHAR szTo[MAX_PATH+1];
ZeroMemory(szFrom,sizeof(szFrom));
lstrcpy(szFrom,sFromPath);
ZeroMemory(szTo,sizeof(szTo));
lstrcpy(szTo,sToPath);
ZeroMemory(&shf,sizeof(shf));
shf.hwnd = GetSafeHwnd();
shf.wFunc = FO_RENAME;
shf.pFrom = szFrom;
shf.pTo = szTo;
#ifdef _DEBUG
CString sMess;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -