📄 ieshelltreectrl.cpp
字号:
sMess = szFrom;
sMess += _T("\n");
sMess += szTo;
AfxMessageBox(sMess);
#endif
if (SHFileOperation(&shf) == 0)
return true;
SetRefreshAllowed(false);
return false;
}
bool CIEShellTreeCtrl::SHMoveFile(HTREEITEM hSrcItem,HTREEITEM hDestItem)
{
LPTVITEMDATA plvit_src = (LPTVITEMDATA)GetItemData(hSrcItem);
LPTVITEMDATA plvit_dest = (LPTVITEMDATA)GetItemData(hDestItem);
CString sFromPath;
CString sToPath;
GetShellPidl().SHPidlToPathEx(plvit_src->lpifq,sFromPath);
GetShellPidl().SHPidlToPathEx(plvit_dest->lpifq,sToPath);
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_MOVE;
shf.pFrom = szFrom;
shf.pTo = szTo;
return SHFileOperation(&shf) == 0 ? true : false;
}
BOOL CIEShellTreeCtrl::TransferItem(HTREEITEM hitemDrag, HTREEITEM hitemDrop)
{
return SHMoveFile(hitemDrag,hitemDrop) ? TRUE : FALSE;
}
bool CIEShellTreeCtrl::GetFolderInfo(HTREEITEM hItem,CString &sPath,CString &sName)
{
LPTVITEMDATA lptvid = (LPTVITEMDATA)GetItemData(hItem);
if (lptvid == NULL)
return false;
GetShellPidl().SHPidlToPathEx(lptvid->lpifq,sPath,NULL,SHGDN_NORMAL);
GetShellPidl().GetDisplayName(lptvid->lpi,sName);
return true;
}
bool CIEShellTreeCtrl::LoadFolderItems(LPCTSTR pszPath)
{
return LoadItems(pszPath);
}
CRefresh *CIEShellTreeCtrl::CreateRefreshObject(HTREEITEM hItem,LPARAM lParam)
{
CRefreshShellFolder *pRefresh=NULL;
if (lParam)
{
pRefresh = new CRefreshShellFolder(hItem,lParam);
}
return pRefresh;
}
bool CIEShellTreeCtrl::Expanding(NM_TREEVIEW *nmtvw)
{
if ((nmtvw->itemNew.state & TVIS_EXPANDEDONCE) || nmtvw->itemNew.hItem == GetRootItem())
return false;
LPSHELLFOLDER pFolder=NULL;
CUIListCtrlData *pData = (CUIListCtrlData*)nmtvw->itemNew.lParam;
ASSERT(pData);
ASSERT_KINDOF(CUIListCtrlData,pData);
LPTVITEMDATA lptvid=(LPTVITEMDATA)pData->GetExtData();
if (lptvid)
{
HRESULT hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,
0, IID_IShellFolder,(LPVOID*)&pFolder);
if (SUCCEEDED(hr))
{
if (!AddItems(nmtvw->itemNew.hItem,pFolder))
SetButtonState(nmtvw->itemNew.hItem);
}
return false;
}
// prevent from expanding
return true;
}
BEGIN_MESSAGE_MAP(CIEShellTreeCtrl, CIEFolderTreeCtrl)
//{{AFX_MSG_MAP(CIEShellTreeCtrl)
ON_MESSAGE(WM_SETMESSAGESTRING,OnSetmessagestring)
ON_MESSAGE(WM_APP_CB_IE_HIT_ENTER,OnAppCbIeHitEnter)
// NOTE - the ClassWizard will add and remove mapping macros here.
ON_WM_DESTROY()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_APP_POPULATE_TREE,OnAppPopulateTree)
ON_MESSAGE(WM_APP_CB_IE_SEL_CHANGE,OnCBIESelChange)
ON_MESSAGE(WM_APP_DIR_CHANGE_EVENT,OnAppDirChangeEvent)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIEShellTreeCtrl message handlers
BOOL CIEShellTreeCtrl::OnWndMsg( UINT message, WPARAM wParam, LPARAM lParam, LRESULT* pResult )
{
if ((message == WM_MEASUREITEM || message == WM_DRAWITEM && wParam == 0) || message == WM_INITMENUPOPUP)
{
if (m_lptvid)
{
return GetShellPidl().HandleMenuMsg(m_hWnd,m_lptvid->lpsfParent, m_lptvid->lpi,
message,wParam,lParam);
}
}
return CIEFolderTreeCtrl::OnWndMsg(message, wParam, lParam, pResult );
}
void CIEShellTreeCtrl::PreSubclassWindow()
{
CIEFolderTreeCtrl::PreSubclassWindow();
CreateFileChangeThreads(GetSafeHwnd());
}
/////////////////////////////////////////////////////////////////////////
// Thread function for detecting file system changes
UINT CIEShellTreeCtrl::ThreadFunc (LPVOID pParam)
{
///////////////////////////////
PDC_THREADINFO pThreadInfo = (PDC_THREADINFO) pParam;
HANDLE hEvent = pThreadInfo->hEvent;
CIEShellTreeCtrl *pTreeCtrl = pThreadInfo->pTreeCtrl;
HWND hWnd = pTreeCtrl->GetSafeHwnd();
TCHAR szPath[MAX_PATH];
lstrcpy(szPath,pThreadInfo->sPath);
delete pThreadInfo;
////////////////////////////////////
// Get a handle to a file change notification object.
TRACE(_T("Creating directory thread handler for %s\n"),szPath);
HANDLE hDirChange = ::FindFirstChangeNotification (szPath,TRUE,FILE_NOTIFY_CHANGE_DIR_NAME);
// Return now if ::FindFirstChangeNotification failed.
if (hDirChange == INVALID_HANDLE_VALUE)
return 1;
const int nHandles=2;
HANDLE aHandles[nHandles];
aHandles[0] = hDirChange;
aHandles[1] = hEvent;
BOOL bContinue = TRUE;
// Sleep until a file change notification wakes this thread or
// m_event becomes set indicating it's time for the thread to end.
while (bContinue)
{
TRACE(_T("TreeControl waiting for %u multiple objects\n"),nHandles);
DWORD dw = ::WaitForMultipleObjects (nHandles, aHandles, FALSE, INFINITE);
if (dw - WAIT_OBJECT_0 == 0)
{ // Respond to a change notification.
::FindNextChangeNotification (hDirChange);
TRACE(_T("-- Directory notify event was fired in CIEShellTreeCtrl --\n"));
if (pTreeCtrl->RefreshAllowed())
{
::PostMessage (hWnd, WM_APP_DIR_CHANGE_EVENT,0,0);
}
else
{
TRACE(_T("but not sending as refresh disallowed\n"));
pTreeCtrl->SetRefreshAllowed(true);
TRACE(_T("Refresh is now allowed\n"));
}
}
else if(dw - WAIT_OBJECT_0 == 1)
{
bContinue = FALSE;
TRACE(_T("Directory Notify Thread was signalled to stop\n"));
}
}
// Close the file change notification handle and return.
::FindCloseChangeNotification (hDirChange);
TRACE(_T("Directory Notify Thread is ending\n"));
return 0;
}
void CIEShellTreeCtrl::OnDestroy()
{
DestroyThreads();
CIEFolderTreeCtrl::OnDestroy();
}
LRESULT CIEShellTreeCtrl::OnAppDirChangeEvent(WPARAM wParam, LPARAM lParam)
{
if (!RefreshAllowed())
return 1L;
Refresh();
if (m_bNotifyParent)
GetParent()->SendMessage(WM_APP_UPDATE_ALL_VIEWS,(WPARAM)HINT_SHELL_DIR_CHANGED,(LPARAM)(LPCTSTR)GetRootPath());
return 1L;
}
LRESULT CIEShellTreeCtrl::OnCBIESelChange(WPARAM wParam,LPARAM lParam)
{
LPITEMIDLIST pidl = (LPITEMIDLIST)wParam;
ExpandMyComputer(pidl);
FindPidl(pidl);
GetShellPidl().FreePidl(pidl);
SetFocus();
return 1L;
}
// Selection has changed
void CIEShellTreeCtrl::UpdateEvent(LPARAM lHint,CObject *pHint)
{
// TODO: Add your specialized code here and/or call the base class
// Notify the combo box
const CRefreshShellFolder *pRefresh = static_cast<CRefreshShellFolder*>(pHint);
LPTVITEMDATA lptvid = reinterpret_cast<LPTVITEMDATA>(pRefresh->GetItemData());
ASSERT(lptvid);
// Notify combo box
RefreshComboBox(lptvid);
// Notify list control
if (m_hListWnd)
{
::SendMessage(m_hListWnd,WM_APP_UPDATE_ALL_VIEWS,(WPARAM)lHint,(LPARAM)pHint);
return;
}
// or let base class handle it
CUITreeCtrl::UpdateEvent(lHint,pHint);
}
LRESULT CIEShellTreeCtrl::OnAppPopulateTree(WPARAM wParam, LPARAM lParam)
{
TRACE0("Selecting root item\n");
HTREEITEM hRoot = GetRootItem();
if (hRoot == NULL)
return 1L;
SelectItem(hRoot);
#ifndef _DEBUG
SelectionChanged(hRoot,GetItemData(hRoot));
#else
LPTVITEMDATA lptvid = reinterpret_cast<LPTVITEMDATA>(GetItemData(hRoot));
RefreshComboBox(lptvid);
#endif
return 1;
}
void CIEShellTreeCtrl::DeleteKey(HTREEITEM hItem)
{
// TODO: Add your specialized code here and/or call the base class
SHFILEOPSTRUCT shf;
ZeroMemory(&shf,sizeof(shf));
TCHAR szFrom[MAX_PATH+1];
ZeroMemory(szFrom,sizeof(szFrom)*sizeof(TCHAR));
lstrcpy(szFrom,GetPathName(hItem));
shf.hwnd = GetSafeHwnd();
shf.wFunc = FO_DELETE;
shf.pFrom = szFrom;
shf.fFlags = GetKeyState(VK_SHIFT) < 0 ? 0 : FOF_ALLOWUNDO;
SHFileOperation(&shf);
}
void CIEShellTreeCtrl::DoubleClick(HTREEITEM hItem)
{
// TODO: Add your specialized code here and/or call the base class
ShellExecute(hItem);
}
void CIEShellTreeCtrl::GoBack(HTREEITEM hItem)
{
// TODO: Add your specialized code here and/or call the base class
UpOneLevel(hItem);
}
void CIEShellTreeCtrl::ShowPopupMenu(HTREEITEM hItem,CPoint point)
{
// TODO: Add your specialized code here and/or call the base class
if (m_PopupID)
{
CUITreeCtrl::ShowPopupMenu(hItem,point);
}
// TODO: Add your control notification handler code here
m_lptvid = (LPTVITEMDATA)GetItemData(hItem);
if (m_lptvid)
GetShellPidl().PopupTheMenu(m_hWnd,m_lptvid->lpsfParent, &m_lptvid->lpi, 1, &point);
}
void CIEShellTreeCtrl::ShowProperties(HTREEITEM hItem)
{
// TODO: Add your specialized code here and/or call the base class
ShellExecute(hItem,_T("properties"));
}
LRESULT CIEShellTreeCtrl::OnAppCbIeHitEnter(WPARAM wParam, LPARAM lParam)
{
if (lParam == NULL)
return 0L;
LPCTSTR pszPath = (LPCTSTR)lParam;
LPITEMIDLIST pidl=NULL;
GetShellPidl().SHPathToPidlEx(pszPath,&pidl,NULL);
if (pidl == NULL)
return 0L;
int nCount = GetShellPidl().GetCount(pidl);
LPITEMIDLIST pidlPart=NULL;
LPITEMIDLIST pidlFull=NULL;
HTREEITEM hItem=NULL;
SetRedraw(FALSE);
for(int i=0;i < nCount;i++)
{
pidlPart=GetShellPidl().CopyItemID(pidl,i+1);
if (pidlPart)
{
pidlFull = GetShellPidl().ConcatPidl(pidlFull,pidlPart);
hItem = ExpandPidl(pidlFull);
if (hItem == NULL)
break;
GetShellPidl().FreePidl(pidlPart);
}
}
if (hItem && GetShellPidl().ComparePidls(NULL,pidl,pidlFull))
{
Select(hItem,TVGN_CARET);
}
else
{
CString sMess;
sMess.Format(_T("%s was not found"),pszPath);
AfxMessageBox(sMess,MB_ICONSTOP);
}
if (pidl)
GetShellPidl().FreePidl(pidl);
if (pidlFull)
GetShellPidl().FreePidl(pidlFull);
SetRedraw(TRUE);
return 1;
}
LRESULT CIEShellTreeCtrl::OnSetmessagestring(WPARAM wParam, LPARAM lParam)
{
if (GetParent())
return GetParent()->SendMessage(WM_SETMESSAGESTRING,wParam,lParam);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -