Index: ch/DirTreeCtrl.cpp =================================================================== diff -u -N --- ch/DirTreeCtrl.cpp (revision 6472716fec44f80b223922d89f269e365aeaba60) +++ ch/DirTreeCtrl.cpp (revision 0) @@ -1,1141 +0,0 @@ -/************************************************************************ - Copy Handler 1.x - program for copying data in Microsoft Windows - systems. - Copyright (C) 2001-2004 Ixen Gerthannes (copyhandler@o2.pl) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*************************************************************************/ - -#include "stdafx.h" -#include "DirTreeCtrl.h" -#include "afxtempl.h" -#include "memdc.h" -#include "shlobj.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#undef THIS_FILE -static char THIS_FILE[] = __FILE__; -#endif - -#define WM_INITCONTROL WM_USER+7 - -LPITEMIDLIST Next(LPCITEMIDLIST pidl) -{ - LPSTR lpMem=(LPSTR)pidl; - - lpMem+=pidl->mkid.cb; - - return (LPITEMIDLIST)lpMem; -} - -UINT GetSize(LPCITEMIDLIST pidl) -{ - UINT cbTotal = 0; - if (pidl) - { - cbTotal += sizeof(pidl->mkid.cb); // Null terminator - while (pidl->mkid.cb) - { - cbTotal += pidl->mkid.cb; - pidl = Next(pidl); - } - } - - return cbTotal; -} - -LPITEMIDLIST CreatePidl(UINT cbSize) -{ - LPMALLOC lpMalloc; - HRESULT hr; - LPITEMIDLIST pidl=NULL; - - hr=SHGetMalloc(&lpMalloc); - - if (FAILED(hr)) - return 0; - - pidl=(LPITEMIDLIST)lpMalloc->Alloc(cbSize); - - if (pidl) - memset(pidl, 0, cbSize); // zero-init for external task alloc - - if (lpMalloc) lpMalloc->Release(); - - return pidl; -} - -void FreePidl(LPITEMIDLIST lpiidl) -{ - LPMALLOC lpMalloc; - HRESULT hr; - - hr=SHGetMalloc(&lpMalloc); - - if (FAILED(hr)) - return; - - lpMalloc->Free(lpiidl); - - if (lpMalloc) lpMalloc->Release(); -} - -LPITEMIDLIST ConcatPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2) -{ - LPITEMIDLIST pidlNew; - UINT cb1; - UINT cb2; - - if (pidl1) //May be NULL - cb1 = GetSize(pidl1) - sizeof(pidl1->mkid.cb); - else - cb1 = 0; - - cb2 = GetSize(pidl2); - - pidlNew = CreatePidl(cb1 + cb2); - if (pidlNew) - { - if (pidl1) - memcpy(pidlNew, pidl1, cb1); - memcpy(((LPSTR)pidlNew) + cb1, pidl2, cb2); - } - return pidlNew; -} - -LPITEMIDLIST CopyITEMID(LPMALLOC lpMalloc, LPITEMIDLIST lpi) -{ - LPITEMIDLIST lpiTemp; - - lpiTemp=(LPITEMIDLIST)lpMalloc->Alloc(lpi->mkid.cb+sizeof(lpi->mkid.cb)); - CopyMemory((PVOID)lpiTemp, (CONST VOID *)lpi, lpi->mkid.cb+sizeof(lpi->mkid.cb)); - - return lpiTemp; -} - -BOOL GetName(LPSHELLFOLDER lpsf, - LPITEMIDLIST lpi, - DWORD dwFlags, - LPSTR lpFriendlyName) -{ - BOOL bSuccess=TRUE; - STRRET str; - - if (NOERROR==lpsf->GetDisplayNameOf(lpi,dwFlags, &str)) - { - switch (str.uType) - { - case STRRET_WSTR: - - WideCharToMultiByte(CP_ACP, // CodePage - 0, // dwFlags - str.pOleStr, // lpWideCharStr - -1, // cchWideChar - lpFriendlyName, // lpMultiByteStr - MAX_PATH, - //sizeof(lpFriendlyName), // cchMultiByte, wrong. sizeof on a pointer, psk, psk - NULL, // lpDefaultChar, - NULL); // lpUsedDefaultChar - - break; - - case STRRET_OFFSET: - - lstrcpy(lpFriendlyName, (LPSTR)lpi+str.uOffset); - break; - - case STRRET_CSTR: - - lstrcpy(lpFriendlyName, (LPSTR)str.cStr); - break; - - default: - bSuccess = FALSE; - break; - } - } - else - bSuccess = FALSE; - - return bSuccess; -} - -LPITEMIDLIST GetFullyQualPidl(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi) -{ - char szBuff[MAX_PATH]; - OLECHAR szOleChar[MAX_PATH]; - LPSHELLFOLDER lpsfDeskTop; - LPITEMIDLIST lpifq; - ULONG ulEaten, ulAttribs; - HRESULT hr; - - if (!GetName(lpsf, lpi, SHGDN_FORPARSING, szBuff)) - return NULL; - - hr=SHGetDesktopFolder(&lpsfDeskTop); - - if (FAILED(hr)) - return NULL; - - MultiByteToWideChar(CP_ACP, - MB_PRECOMPOSED, - szBuff, - -1, - (USHORT *)szOleChar, - sizeof(szOleChar)); - - hr=lpsfDeskTop->ParseDisplayName(NULL, - NULL, - szOleChar, - &ulEaten, - &lpifq, - &ulAttribs); - - lpsfDeskTop->Release(); - - if (FAILED(hr)) - return NULL; - - return lpifq; -} - -///////////////////////////////////////////////////////////////////////////// -// CDirTreeCtrl - -CDirTreeCtrl::CDirTreeCtrl() -{ - m_hDrives=NULL; - m_hNetwork=NULL; - m_hImageList=NULL; - m_bIgnore=false; - m_iEditType=0; -// RegisterWindowClass(); -} -/* -bool CDirTreeCtrl::RegisterWindowClass() -{ - WNDCLASS wndcls; - HINSTANCE hInst = AfxGetInstanceHandle(); - - if (!(::GetClassInfo(hInst, DIRTREECTRL_CLASSNAME, &wndcls))) - { - // otherwise we need to register a new class - wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; - wndcls.lpfnWndProc = ::DefWindowProc; - wndcls.cbClsExtra = wndcls.cbWndExtra = 0; - wndcls.hInstance = hInst; - wndcls.hIcon = NULL; - wndcls.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW); - wndcls.hbrBackground = (HBRUSH) (COLOR_3DFACE + 1); - wndcls.lpszMenuName = NULL; - wndcls.lpszClassName = DIRTREECTRL_CLASSNAME; - - if (!AfxRegisterClass(&wndcls)) - { - AfxThrowResourceException(); - return false; - } - } - - return true; -} -*/ -CDirTreeCtrl::~CDirTreeCtrl() -{ -} - - -BEGIN_MESSAGE_MAP(CDirTreeCtrl, CTreeCtrl) - //{{AFX_MSG_MAP(CDirTreeCtrl) - ON_WM_DESTROY() - ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding) - ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteitem) - ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded) - ON_NOTIFY_REFLECT(TVN_ENDLABELEDIT, OnEndlabeledit) - ON_NOTIFY_REFLECT(TVN_BEGINLABELEDIT, OnBeginLabelEdit) - ON_WM_ERASEBKGND() - ON_WM_PAINT() - ON_WM_CREATE() - //}}AFX_MSG_MAP -END_MESSAGE_MAP() - -///////////////////////////////////////////////////////////////////////////// -// CDirTreeCtrl message handlers - -///////////////////////////////////////////////////////////////////////////// -// inicjalizacja -void CDirTreeCtrl::PreSubclassWindow() -{ -// InitControl(); // here's not needed (strange ??) - CTreeCtrl::PreSubclassWindow(); -} - -int CDirTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) -{ - if (CTreeCtrl::OnCreate(lpCreateStruct) == -1) - return -1; - - InitControl(); - - return 0; -} - -void CDirTreeCtrl::InitControl() -{ - // prepare image list - SHFILEINFO sfi; - m_hImageList = (HIMAGELIST)SHGetFileInfo(_T("C:\\"), FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(SHFILEINFO), - SHGFI_SYSICONINDEX | SHGFI_SMALLICON); - - TreeView_SetImageList(this->m_hWnd, m_hImageList, TVSIL_NORMAL); - - // insert desktop icon - InsertDesktopItem(); - - // expanding, ... - PostMessage(WM_INITCONTROL); -} - -///////////////////////////////////////////////////////////////////////////// -// wstawia ikon� pulpitu -HTREEITEM CDirTreeCtrl::InsertDesktopItem() -{ - // clear treectrl - it shouldn't be more than 1 desktop - if (!DeleteAllItems()) - return NULL; - - // clear vars - m_hDrives=NULL; - m_hNetwork=NULL; - - // fill with items - SHFILEINFO sfi; - LPSHELLFOLDER lpsfDesktop; - LPITEMIDLIST lpiidlDesktop; - if (FAILED(SHGetDesktopFolder(&lpsfDesktop))) - return NULL; - if (SHGetSpecialFolderLocation(this->GetSafeHwnd(), CSIDL_DESKTOP, &lpiidlDesktop) != NOERROR) - return NULL; - - // add desktop - TVITEM tvi; - TVINSERTSTRUCT tvis; - TCHAR szText[_MAX_PATH]; - _SHELLITEMDATA *psid=new _SHELLITEMDATA; - psid->lpiidl=lpiidlDesktop; - psid->lpsf=lpsfDesktop; - psid->lpiidlRelative=NULL; - psid->lpsfParent=NULL; - - tvi.mask=TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_PARAM; - if (!GetName(lpsfDesktop, lpiidlDesktop, 0/*SHGDN_INCLUDE_NONFILESYS*/, szText)) - lstrcpy(szText, _T("???")); - tvi.pszText=szText; - sfi.iIcon=-1; - SHGetFileInfo((LPCTSTR)lpiidlDesktop, 0, &sfi, sizeof(SHFILEINFO), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); - tvi.iImage=sfi.iIcon; - sfi.iIcon=-1; - SHGetFileInfo((LPCTSTR)lpiidlDesktop, 0, &sfi, sizeof(SHFILEINFO), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON); - tvi.iSelectedImage=sfi.iIcon; - tvi.cChildren=1; - tvi.lParam=reinterpret_cast(psid); - - tvis.hParent=TVI_ROOT; - tvis.item=tvi; - return InsertItem(&tvis); -} - -////////////////////////////////////////////////////////////////////////////// -// processes WM_INITCONTROL -LRESULT CDirTreeCtrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - switch(message) - { - case WM_INITCONTROL: - ExpandItem(GetRootItem(), TVE_EXPAND); - break; - case WM_SETPATH: - SetPath((LPCTSTR)lParam); - break; - } - - return CTreeCtrl::WindowProc(message, wParam, lParam); -} - -//////////////////////////////////////////////////////////////////////////// -// enables image list, ... -void CDirTreeCtrl::OnDestroy() -{ - SetImageList(NULL, LVSIL_SMALL); - CTreeCtrl::OnDestroy(); -} - -//////////////////////////////////////////////////////////////////////////// -// compares two items -int CALLBACK CompareFunc(LPARAM lParam1, LPARAM lParam2, LPARAM/* lParamSort*/) -{ - // je�li si� nie da - if (lParam1 == NULL || lParam2 == NULL) - return 0; - - // normalne przetwarzanie - SHELLITEMDATA* psidl1=(SHELLITEMDATA*)lParam1, *psidl2=(SHELLITEMDATA*)lParam2; - - LPSHELLFOLDER lpsf; - if (SHGetDesktopFolder(&lpsf) != NOERROR) - return 0; - - HRESULT hRes=lpsf->CompareIDs(0, psidl1->lpiidl, psidl2->lpiidl); - if (!SUCCEEDED(hRes)) - return 0; - - lpsf->Release(); - - return (short)SCODE_CODE(GetScode(hRes)); -} - -///////////////////////////////////////////////////////////////////////////// -// fills a hParent node with items starting with lpsf and lpdil for this item -bool CDirTreeCtrl::FillNode(HTREEITEM hParent, LPSHELLFOLDER lpsf, LPITEMIDLIST lpidl, bool bSilent) -{ - // get the global flag under consideration - if (m_bIgnoreShellDialogs) - bSilent=m_bIgnoreShellDialogs; - - // get the desktop interface and id's of list for net neigh. and my computer - LPSHELLFOLDER lpsfDesktop=NULL; - LPITEMIDLIST lpiidlDrives=NULL, lpiidlNetwork=NULL; - if (hParent == GetRootItem()) - { - SHGetDesktopFolder(&lpsfDesktop); - SHGetSpecialFolderLocation(this->GetSafeHwnd(), CSIDL_DRIVES, &lpiidlDrives); - SHGetSpecialFolderLocation(this->GetSafeHwnd(), CSIDL_NETWORK, &lpiidlNetwork); - } - - LPITEMIDLIST lpiidl; - SHFILEINFO sfi; - ULONG ulAttrib; - TVITEM tvi; - TVINSERTSTRUCT tvis; - _SHELLITEMDATA *psid; - TCHAR szText[_MAX_PATH]; - LPENUMIDLIST lpeid=NULL; - HTREEITEM hCurrent=NULL; - bool bFound=false; - - // shell allocator - LPMALLOC lpm; - if (SHGetMalloc(&lpm) != NOERROR) - return false; - - // enumerate child items for lpsf - if (lpsf->EnumObjects(bSilent ? NULL : GetParent()->GetSafeHwnd(), SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN, &lpeid) != NOERROR) - return false; - - while (lpeid->Next(1, &lpiidl, NULL) == NOERROR) - { - // filer what has been found - ulAttrib=SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM; - lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpiidl, &ulAttrib); - if (ulAttrib & SFGAO_FOLDER && (ulAttrib & SFGAO_FILESYSANCESTOR || ulAttrib & SFGAO_FILESYSTEM) ) - { - // there's something to add so set bFound - bFound=true; - - // it's time to add everything - psid=new _SHELLITEMDATA; - lpsf->BindToObject(lpiidl, NULL, IID_IShellFolder, (void**)&psid->lpsf); - psid->lpiidl=ConcatPidls(lpidl, lpiidl); - psid->lpiidlRelative=CopyITEMID(lpm, lpiidl); - psid->lpsfParent=lpsf; - - tvi.mask=TVIF_CHILDREN | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_PARAM; - if (!GetName(lpsf, lpiidl, SHGDN_INFOLDER/* | SHGDN_INCLUDE_NONFILESYS*/, szText)) - lstrcpy(szText, _T("???")); - tvi.pszText=szText; - sfi.iIcon=-1; - SHGetFileInfo((LPCTSTR)psid->lpiidl, 0, &sfi, sizeof(SHFILEINFO), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON); - tvi.iImage=sfi.iIcon; - sfi.iIcon=-1; - SHGetFileInfo((LPCTSTR)psid->lpiidl, 0, &sfi, sizeof(SHFILEINFO), SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_OPENICON); - tvi.iSelectedImage=sfi.iIcon; - tvi.cChildren=(ulAttrib & SFGAO_HASSUBFOLDER); - tvi.lParam=reinterpret_cast(psid); - - tvis.hParent=hParent; - tvis.item=tvi; - hCurrent=InsertItem(&tvis); - - if (hParent == GetRootItem()) - { - // if this is My computer or net. neigh. - it's better to remember the handles - // compare psid->lpiidl and (lpiidlDrives & lpiidlNetwork) - if (SCODE_CODE(lpsfDesktop->CompareIDs(0, psid->lpiidl, lpiidlDrives)) == 0) - m_hDrives=hCurrent; - else if (SCODE_CODE(lpsfDesktop->CompareIDs(0, psid->lpiidl, lpiidlNetwork)) == 0) - m_hNetwork=hCurrent; - } - - FreePidl(lpiidl); // free found pidl - it was copied already - } - } - - if (lpeid) - lpeid->Release(); - - if (lpsfDesktop) - lpsfDesktop->Release(); - - lpm->Release(); - - // sortuj - if (bFound) - { - TVSORTCB tvscb; - tvscb.hParent=hParent; - tvscb.lpfnCompare=&CompareFunc; - tvscb.lParam=NULL; - if (!SortChildrenCB(&tvscb)) - TRACE("SortChildren failed\n"); - } - else - { - // some items has + and some not - correction - TVITEM tvi; - tvi.mask=TVIF_HANDLE | TVIF_CHILDREN; - tvi.hItem=hParent; - if (GetItem(&tvi) && tvi.cChildren == 1) - { - tvi.cChildren=0; - SetItem(&tvi); - } - } - - return bFound; -} - -//////////////////////////////////////////////////////////////////////////// -// alternate function for Expand(), makes additional processing -bool CDirTreeCtrl::ExpandItem(HTREEITEM hItem, UINT nCode) -{ - switch(nCode) - { - case TVE_EXPAND: - { - // get the item's data - TVITEM tvi; - tvi.mask=TVIF_PARAM | TVIF_STATE; - tvi.hItem=hItem; - tvi.stateMask=TVIS_EXPANDEDONCE | TVIS_SELECTED | TVIS_EXPANDED; - if (!GetItem(&tvi)) - return false; - - if (tvi.state & TVIS_EXPANDED) - return true; - - // Fill node before normal expanding - SHELLITEMDATA* psid; - if (GetItemStruct(hItem, &psid)) - { - if (!FillNode(hItem, psid->lpsf, psid->lpiidl, true)) - TRACE("FillNode in ExpandItem failed...\n"); - - // ignore fillnode in onitemexpanding - m_bIgnore=true; - } - - // normal expand - EnsureVisible(hItem); - SelectItem(hItem); - return Expand(hItem, TVE_EXPAND) != 0; - - break; - } - default: - return Expand(hItem, nCode) != 0; - } -} - -///////////////////////////////////////////////////////////////////////////// -// node expand handling - calls FillNode -void CDirTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) -{ - NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; - _SHELLITEMDATA* psid=reinterpret_cast<_SHELLITEMDATA*>(pNMTreeView->itemNew.lParam); - - switch (pNMTreeView->action) - { - case TVE_EXPAND: - if (!m_bIgnore) - { - // fill - if (!FillNode(pNMTreeView->itemNew.hItem, psid->lpsf, psid->lpiidl)) - TRACE("FillNode failed...\n"); - } - else - { - // now refresh normally - m_bIgnore=false; - } - break; - } - - *pResult = 0; -} - -//////////////////////////////////////////////////////////////////////////// -// deleting items after node collapses -void CDirTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) -{ - NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; - - switch (pNMTreeView->action) - { - case TVE_COLLAPSE: - if (ItemHasChildren(pNMTreeView->itemNew.hItem)) - { - HTREEITEM hItem; - while ((hItem=GetChildItem(pNMTreeView->itemNew.hItem)) != NULL) - DeleteItem(hItem); - } - - break; - } - - *pResult = 0; -} - -////////////////////////////////////////////////////////////////////////////// -// deletes everything what has been allocated for an item -void CDirTreeCtrl::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult) -{ - NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; - _SHELLITEMDATA *psid=reinterpret_cast<_SHELLITEMDATA*>(pNMTreeView->itemOld.lParam); - - if (psid) - { - psid->lpsf->Release(); - FreePidl(psid->lpiidl); - FreePidl(psid->lpiidlRelative); - delete psid; - } - - *pResult = 0; -} - -/////////////////////////////////////////////////////////////////////////// -// returns path associated with an item -bool CDirTreeCtrl::GetPath(HTREEITEM hItem, LPTSTR pszPath) -{ - TVITEM tvi; - tvi.mask=TVIF_HANDLE | TVIF_PARAM; - tvi.hItem=hItem; - - if (GetItem(&tvi)) - { - // item data - _SHELLITEMDATA* psid=reinterpret_cast<_SHELLITEMDATA*>(tvi.lParam); - if (psid == NULL) - return false; - - // desktop interface - LPSHELLFOLDER lpsf; - if (SHGetDesktopFolder(&lpsf) != NOERROR) - return false; - - if (!SHGetPathFromIDList(psid->lpiidl, pszPath)) - { - lpsf->Release(); - return false; - } - - lpsf->Release(); - return true; - } - else - return false; -} - -//////////////////////////////////////////////////////////////////////////// -// finds the item that is nearest to a given path - returns true if find -// even a part of a path -bool CDirTreeCtrl::SetPath(LPCTSTR lpszPath) -{ - ASSERT(lpszPath); - - // if path is empty - if (_tcscmp(lpszPath, _T("")) == 0) - return false; - - // type of path - bool bNetwork=_tcsncmp(lpszPath, _T("\\\\"), 2) == 0; - - if (!bNetwork) - return SetLocalPath(lpszPath); - else - { - // we don't look in net neighbourhood for speed reasons - EnsureVisible(m_hNetwork); -// SelectItem(m_hNetwork); -// ExpandItem(m_hNetwork, TVE_EXPAND); - return true; - } -} - - -/////////////////////////////////////////////////////////////////////////// -// sets the local path - not network -bool CDirTreeCtrl::SetLocalPath(LPCTSTR lpszPath) -{ - // expand desktop and my computer - HTREEITEM hItem=GetRootItem(); - ExpandItem(hItem, TVE_EXPAND); - ExpandItem(m_hDrives, TVE_EXPAND); - - HTREEITEM hFound=RegularSelect(m_hDrives, lpszPath); - if (hFound) - { - EnsureVisible(hFound); - SelectItem(hFound); - ExpandItem(hFound, TVE_EXPAND); - } - - return hFound != NULL; -} - -///////////////////////////////////////////////////////////////////////////// -// sets network path -/* -bool CDirTreeCtrl::SetRemotePath(LPCTSTR lpszPath) -{ - // expand desktop and net neigh - HTREEITEM hItem=GetRootItem(); - ExpandItem(hItem, TVE_EXPAND); - ExpandItem(m_hNetwork, TVE_EXPAND); - - // find root - TCHAR szBuffer[2048]; - NETRESOURCE* pnr; - CArray m_ahRoots; // root's list - bool bSkipRootChecks=false; - HTREEITEM hRoot=GetChildItem(m_hNetwork); - while(hRoot) - { - if (!GetItemShellData(hRoot, SHGDFIL_NETRESOURCE, szBuffer, 2048)) - { - // problem with NETRESOURCE - find next - hRoot=GetNextSiblingItem(hRoot); - continue; - } - - // got NETRESOURCE - pnr=(NETRESOURCE*)szBuffer; - if (pnr->dwDisplayType == RESOURCEDISPLAYTYPE_ROOT) - m_ahRoots.Add(hRoot); - else if (pnr->dwDisplayType == RESOURCEDISPLAYTYPE_SHARE) - { - if (ComparePaths(lpszPath, pnr->lpRemoteName)) - { - bSkipRootChecks=true; // skip II phase - break; // hRoot contains handle to an item from which we need to start searching from - } - } - - // next to check - hRoot=GetNextSiblingItem(hRoot); - } - - // II phase: net neigh tree traversation - if (!bSkipRootChecks) - { - hRoot=NULL; - HTREEITEM hNode; - TCHAR szBuffer[2048]; - for (int i=0;i(tvi.lParam); - - if (SHGetPathFromIDList(psid->lpiidl, szPath)) - { - if (ComparePaths(lpszPath, szPath)) - { - // it's contained - expand - ExpandItem(hItem, TVE_EXPAND); - hLast=hItem; // remember last that matches path - - hItem=GetChildItem(hItem); // another 'zoom' - continue; - } - } - } - - // next folder - hItem=GetNextSiblingItem(hItem); - } - - // return what has been found - return hLast; -} -//////////////////////////////////////////////////////////////////////////// -// helper - finds comp in a network that matches the path. Skips all the -// workgroups, network names, ... -/* -HTREEITEM CDirTreeCtrl::TraverseNetNode(HTREEITEM hItem, LPCTSTR lpszPath, LPTSTR lpszBuffer) -{ - // start with 1st chil item - HTREEITEM hNext=GetChildItem(hItem); - NETRESOURCE *pnet; - - while (hNext) - { - // get NETRESOURCE structure - is this a server ? - if (GetItemShellData(hNext, SHGDFIL_NETRESOURCE, lpszBuffer, 2048)) - { - // got NETRESOURCE - pnet=(NETRESOURCE*)lpszBuffer; - - // is the path contained - if (ComparePaths(lpszPath, pnet->lpRemoteName)) - return hNext; // found what's needed - - if (pnet->dwDisplayType != RESOURCEDISPLAYTYPE_SERVER) - { - // expand - if (!ExpandItem(hNext, TVE_EXPAND)) - return NULL; - - // recurse - HTREEITEM hFound; - if ( (hFound=TraverseNetNode(hNext, lpszPath, lpszBuffer)) != NULL) - return hFound; // if found - return, if not - continue search - } - } - - // next item to check. - hNext=GetNextSiblingItem(hNext); - } - - return NULL; // nothing has been found -} -*/ -//////////////////////////////////////////////////////////////////////////// -// compares two paths - if one is contained in another (to the first '\\' or '/' -bool CDirTreeCtrl::ComparePaths(LPCTSTR lpszFull, LPCTSTR lpszPartial) -{ - CString strSrc=lpszFull, strFnd=lpszPartial; - strFnd.MakeUpper(); - strFnd.TrimRight(_T("\\/")); - - // make uppercas the source string, cut before nearest \\ or / after strFnd.GetLength - strSrc.MakeUpper(); - - // find out the position of a nearest / lub '\\' - int iLen=strFnd.GetLength(), iPos; - if (strSrc.GetLength() >= iLen) - { - iPos=strSrc.Mid(iLen).FindOneOf(_T("\\/")); - if (iPos != -1) - strSrc=strSrc.Left(iPos+iLen); - - return strSrc == strFnd; - } - else - return false; -} - -//////////////////////////////////////////////////////////////////////////// -// returns shell description for an item (like in explorer). -bool CDirTreeCtrl::GetItemInfoTip(HTREEITEM hItem, CString* pTip) -{ - _SHELLITEMDATA* psid=(_SHELLITEMDATA*)GetItemData(hItem); - if (psid == NULL || psid->lpiidlRelative == NULL || psid->lpsfParent == NULL) - return false; - - // get interface - IQueryInfo *pqi; - if (psid->lpsfParent->GetUIObjectOf(this->GetSafeHwnd(), 1, (const struct _ITEMIDLIST**)&psid->lpiidlRelative, IID_IQueryInfo, 0, (void**)&pqi) != NOERROR) - return false; - - // get tip - WCHAR *pszTip; - if (pqi->GetInfoTip(0, &pszTip) != NOERROR) - { - pqi->Release(); - return false; - } - - // copy with a conversion - *pTip=(const WCHAR *)pszTip; - - // uwolnij pami�� skojarzon� z pszTip - LPMALLOC lpm; - if (SHGetMalloc(&lpm) == NOERROR) - { - lpm->Free(pszTip); - lpm->Release(); - } - - pqi->Release(); - - return true; -} - -//////////////////////////////////////////////////////////////////////////// -// better exchange for SHGetDataFromIDList -bool CDirTreeCtrl::GetItemShellData(HTREEITEM hItem, int nFormat, PVOID pBuffer, int iSize) -{ - PSHELLITEMDATA psid; - if (!GetItemStruct(hItem, &psid) || psid->lpsfParent == NULL || psid->lpiidlRelative == NULL) - return false; - - return SHGetDataFromIDList(psid->lpsfParent, psid->lpiidlRelative, nFormat, pBuffer, iSize) == NOERROR; -} - -///////////////////////////////////////////////////////////////////////////// -// returns SHELLITEMDATA associated with an item -bool CDirTreeCtrl::GetItemStruct(HTREEITEM hItem, PSHELLITEMDATA *ppsid) -{ - ASSERT(ppsid); - *ppsid=(PSHELLITEMDATA)GetItemData(hItem); - return *ppsid != NULL; -} - -HTREEITEM CDirTreeCtrl::InsertNewFolder(HTREEITEM hParent, LPCTSTR /*lpszNewFolder*/) -{ - // check if HTREEITEM has an associated path - TCHAR szPath[_MAX_PATH]; - if (!GetPath(hParent, szPath)) - return NULL; - - // focus - SetFocus(); - - // if has child items - enumerate - TVITEM tvi; - tvi.mask=TVIF_HANDLE | TVIF_STATE | TVIF_CHILDREN; - tvi.hItem=hParent; - tvi.stateMask=TVIS_EXPANDED; - if (GetItem(&tvi)) - { - if (!(tvi.state & TVIS_EXPANDED)) - TRACE("InsertNewFolder's expanditem returned %u\n", ExpandItem(hParent, TVE_EXPAND)); - TRACE("%lu child items\n", tvi.cChildren); - } - - // if hParent doesn't have any chilren - add + to make it look like it hastak, aby wydawa�o si�, �e ma - if (!ItemHasChildren(hParent)) - { - tvi.mask=TVIF_HANDLE | TVIF_CHILDREN; - tvi.hItem=hParent; - tvi.cChildren=1; - if (!SetItem(&tvi)) - TRACE("SetItem failed...\n"); - } - - // temp buffer for a name - TCHAR *pszPath=new TCHAR[1]; - pszPath[0]=_T('\0'); - - // insert new item with an empty lParam - TVINSERTSTRUCT tvis; - tvis.hParent=hParent; - tvis.hInsertAfter=TVI_SORT; - tvis.item.mask=TVIF_TEXT | TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE; - tvis.item.iImage=-1; - tvis.item.iSelectedImage=-1; - tvis.item.pszText=pszPath; - tvis.item.cchTextMax=lstrlen(tvis.item.pszText); - tvis.item.lParam=NULL; - - HTREEITEM hRes=InsertItem(&tvis); - - delete [] pszPath; - - // now make sure hParent is expanded - Expand(hParent, TVE_EXPAND); - - // edit an item - if (hRes) - { - m_iEditType=1; - CEdit *pctlEdit=EditLabel(hRes); - if (pctlEdit == NULL) - return NULL; - } - - return hRes; -} - -void CDirTreeCtrl::OnEndlabeledit(NMHDR* pNMHDR, LRESULT* pResult) -{ - NMTVDISPINFO* pdi = (NMTVDISPINFO*)pNMHDR; - - if (m_iEditType == 1) // for a new folder - { - if (pdi->item.pszText && _tcslen(pdi->item.pszText) != 0) - { - // no success at beginning - int iResult=0; - - // item - parent - HTREEITEM hParent=GetParentItem(pdi->item.hItem); - - // get parent folder name - TCHAR szPath[_MAX_PATH]; - if (!GetPath(hParent, szPath)) - { - // there's no path - skip - *pResult=0; - m_iEditType=0; - - // delete item - DeleteItem(pdi->item.hItem); - GetParent()->SendMessage(WM_CREATEFOLDERRESULT, 0, iResult); - return; - } - - // try to create folder - CString strPath=szPath; - if (strPath.Right(1) != _T('\\')) - strPath+=_T('\\'); - - // full path to the new folder - strPath+=pdi->item.pszText; - - // new folder - if (CreateDirectory(strPath, NULL)) - iResult = 1; - - // refresh - delete all from hParent and fill node - HTREEITEM hChild; - while ((hChild=GetChildItem(hParent)) != NULL) - DeleteItem(hChild); - - // now fillnode - SHELLITEMDATA* psid; - if (GetItemStruct(hParent, &psid)) - { - if (!FillNode(hParent, psid->lpsf, psid->lpiidl)) - TRACE("FillNode in EndEditLabel failed...\n"); - } - - hChild=GetChildItem(hParent); - while(hChild) - { - if (!GetPath(hChild, szPath)) - { - hChild=GetNextSiblingItem(hChild); - continue; - } - - if (_tcscmp(strPath, szPath) == 0) - { - // zaznacz - ExpandItem(hChild, TVE_EXPAND); - break; - } - - hChild=GetNextSiblingItem(hChild); - } - - - // another members - *pResult=1; - m_iEditType=0; - - GetParent()->SendMessage(WM_CREATEFOLDERRESULT, 0, iResult); - } - else - { - // no path - skip - *pResult=0; - m_iEditType=0; - - // delete an item - DeleteItem(pdi->item.hItem); - } - } - - *pResult = 0; -} - -void CDirTreeCtrl::OnBeginLabelEdit(NMHDR* /*pNMHDR*/, LRESULT* pResult) -{ - if (m_iEditType == 1) - *pResult=0; - else - *pResult=1; -} - -BOOL CDirTreeCtrl::OnEraseBkgnd(CDC* /*pDC*/) -{ - return FALSE; -} - -void CDirTreeCtrl::OnPaint() -{ - CPaintDC dc(this); // device context for painting - CMemDC memdc(&dc, &dc.m_ps.rcPaint); - - DefWindowProc(WM_PAINT, (WPARAM)memdc.GetSafeHdc(), 0); -} - -void CDirTreeCtrl::SetIgnoreShellDialogs(bool bFlag) -{ - m_bIgnoreShellDialogs=bFlag; -} - -bool CDirTreeCtrl::GetIgnoreShellDialogs() -{ - return m_bIgnoreShellDialogs; -}