?
Die ist ein System konformer File-Browser,system Konform heißt
das damit nicht entschieden werden kann ob die Datei eine bestimmte Größe oder ein bestimmtes Datum enthalte, dies würde ja dann kein FileBrowser mehr sein.
Wenn Du solche eigenartigen Weisen durchziehen willst, musst Du Dir selber einen Browser bauen, was nicht ganz ohne ist.
Wie das geht kannst Du hier einsehen:
PseudoCode:;
Header:
#pragma once
#include <shlobj.h>
#include "afxcmn.h"
class CShellTree : public CTreeCtrl
{
public:
CShellTree();
virtual ~CShellTree();
typedef struct tagLVID
{
LPSHELLFOLDER lpsfParent;
LPITEMIDLIST lpi;
ULONG ulAttribs;
} LVITEMDATA, *LPLVITEMDATA;
typedef struct tagID
{
LPSHELLFOLDER lpsfParent;
LPITEMIDLIST lpi;
LPITEMIDLIST lpifq;
} TVITEMDATA, *LPTVITEMDATA;
enum FindAttribs{type_drive,type_folder};
void TunnelTree(CString szFindPath);
CString GetLastPath(void);
protected:
CString m_lastpath;
bool SearchTree(HTREEITEM treeNode,CString szSearchName,FindAttribs attr);
BOOL OnFolderSelected(NMHDR* pNMHDR, LRESULT* pResult, CString &szFolderPath);
void OnDeleteShellItem(NMHDR* pNMHDR, LRESULT* pResult);
void FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent);
BOOL GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags,TCHAR *lpFriendlyName);
LPITEMIDLIST ConcatPidls(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
LPSHELLFOLDER SerchFolder(LPSHELLFOLDER lpsf,CString Name);
LPITEMIDLIST CreatePidl(UINT cbSize);
UINT GetSize(LPCITEMIDLIST pidl);
void ProceedSelItem(void);
afx_msg void OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
afx_msg void OnWindowPosChanging(WINDOWPOS FAR* lpwndpos);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()
};
CPP Code:
#include "stdafx.h"
#include "ShellTree.h"
CShellTree::CShellTree()
{
}
CShellTree::~CShellTree()
{
}
BEGIN_MESSAGE_MAP(CShellTree, CTreeCtrl)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
ON_NOTIFY_REFLECT(TVN_DELETEITEM, OnDeleteitem)
ON_WM_SIZE()
ON_WM_SETCURSOR()
ON_WM_WINDOWPOSCHANGING()
ON_WM_CREATE()
END_MESSAGE_MAP()
int CShellTree::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
return -1;
//--- setup icons ----
SHFILEINFO sfi;
HIMAGELIST hImageList = (HIMAGELIST)SHGetFileInfo((LPCSTR)"C:\\",0,&sfi,sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
if (hImageList)
::SendMessage(m_hWnd, TVM_SETIMAGELIST, (WPARAM) TVSIL_NORMAL,(LPARAM)hImageList);
//--- Generate tree ---
LPSHELLFOLDER lpsf=NULL;
HRESULT hr = SHGetDesktopFolder(&lpsf);
if (SUCCEEDED(hr))
{
DeleteAllItems();
FillTreeView(lpsf, NULL, TVI_ROOT);
lpsf->Release();
HTREEITEM RootItem = GetRootItem();
Select(RootItem,TVGN_CARET);
Expand(RootItem,TVE_EXPAND);
EnsureVisible(RootItem);
}
return 0;
}
LPSHELLFOLDER CShellTree::SerchFolder(LPSHELLFOLDER lpsf, CString Name)
{
ULONG ulFetched;
HRESULT hr;
CString Buff;
register LPENUMIDLIST lpe = NULL;
register LPITEMIDLIST lpi = NULL;
register LPSHELLFOLDER lpsf2 = NULL;
//that is essential so not browse in zip Archivs!!!!
if( lpsf->EnumObjects(m_hWnd, SHCONTF_FOLDERS/*|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN*/,&lpe) != S_OK)
return 0;
while(S_OK == lpe->Next(1, &lpi, &ulFetched) )
{
ULONG ulAttrs = SFGAO_FILESYSTEM;//SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs);
if(! (ulAttrs & (SFGAO_FILESYSTEM)) )
continue;
if(GetName(lpsf, lpi, SHGDN_NORMAL, Buff.GetBuffer(MAX_PATH)))
if(Buff.Find(Name) != -1)
{
break;
}
if(lpsf->BindToObject(lpi,0,IID_IShellFolder,(LPVOID *)&lpsf2) == S_OK)
SerchFolder(lpsf2,Name);
}
lpe->Release();
return lpsf;
}
void CShellTree::TunnelTree(CString szFindPath)
{
CString szPathHop;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
char delimiter[]="\\";
WIN32_FIND_DATA fd;
HANDLE hFind = FindFirstFile( szFindPath, &fd );
if ( hFind != INVALID_HANDLE_VALUE )
FindClose( hFind );
if(szFindPath.ReverseFind('\\') != szFindPath.GetLength()-1)
{
szFindPath += "\\";
}
_splitpath(szFindPath,drive,dir,fname,ext);
//search the drive first
szPathHop=drive;
HTREEITEM subNode = GetChildItem(GetRootItem());
if(subNode)
{
if(SearchTree(subNode,szPathHop, CShellTree::type_drive))
{
char *p = strtok(dir,delimiter);
while(p)
{
subNode = GetChildItem(GetSelectedItem());
if(SearchTree(subNode,p,CShellTree::type_folder))
p=strtok(NULL,delimiter);
else
p=NULL;
}
}
}
ProceedSelItem();
}
bool CShellTree::SearchTree(HTREEITEM treeNode,CString szSearchName,FindAttribs attr)
{
LPTVITEMDATA lptvid; //Long pointer to TreeView item data
LPSHELLFOLDER lpsf2=NULL;
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
bool bRet = false;
HRESULT hr;
CString szCompare;
szSearchName.MakeUpper();
while(treeNode && bRet==false)
{
lptvid=(LPTVITEMDATA)GetItemData(treeNode);
if (lptvid && lptvid->lpsfParent && lptvid->lpi)
{
hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,0,IID_IShellFolder,(LPVOID *)&lpsf2);
if (SUCCEEDED(hr))
{
ULONG ulAttrs = SFGAO_FILESYSTEM;
lptvid->lpsfParent->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lptvid->lpi, &ulAttrs);
if (ulAttrs & (SFGAO_FILESYSTEM))
{
if(SHGetPathFromIDList(lptvid->lpifq,szCompare.GetBuffer(MAX_PATH)))
{
switch(attr)
{
case type_drive:
_splitpath(szCompare,drive,dir,fname,ext);
if(strlen(dir) == 1)
szCompare=drive;
break;
case type_folder:
szCompare = GetItemText(treeNode);
break;
}
if(!szCompare.IsEmpty())
{
szCompare.MakeUpper();
if(szCompare == szSearchName)
{
EnsureVisible(treeNode);
SelectItem(treeNode);
Expand(treeNode,TVE_EXPAND);
bRet=true;
}
}
}
}
lpsf2->Release();
}
}
treeNode = GetNextSiblingItem(treeNode);
}
return bRet;
}
void CShellTree::FillTreeView(LPSHELLFOLDER lpsf, LPITEMIDLIST lpifq, HTREEITEM hParent)
{
TV_ITEM tvi; // TreeView Item.
TV_INSERTSTRUCT tvins; // TreeView Insert Struct.
HTREEITEM hPrev = NULL; // Previous Item Added.
ULONG ulFetched;
UINT uCount=0;
HRESULT hr;
TCHAR szBuff[MAX_PATH];
register LPSHELLFOLDER lpsf2=NULL;
register LPENUMIDLIST lpe=NULL;
register LPITEMIDLIST lpi=NULL, lpiTemp=NULL, lpifqThisItem=NULL;
register LPTVITEMDATA lptvid=NULL;
register LPMALLOC lpMalloc=NULL;
//that is essential so not browse in zip Archivs!!!!
if( lpsf->EnumObjects(m_hWnd, SHCONTF_FOLDERS/*|SHCONTF_NONFOLDERS|SHCONTF_INCLUDEHIDDEN*/,&lpe) != S_OK)
return;
if( ::SHGetMalloc(&lpMalloc) != S_OK)
{
lpe->Release();
return;
}
while(S_OK == lpe->Next(1, &lpi, &ulFetched) )
{
ULONG ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
lpsf->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lpi, &ulAttrs);
//browse only Folders :-) if (ulAttrs & (SFGAO_FILESYSTEM))
if( !(ulAttrs & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER)) )
continue;
tvi.mask= TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM;
if( ulAttrs & SFGAO_HASSUBFOLDER )
{
tvi.cChildren = 1;
tvi.mask |= TVIF_CHILDREN;
}
lptvid = (LPTVITEMDATA)lpMalloc->Alloc(sizeof(TVITEMDATA));
if(!lptvid)
{
lpe->Release();
lpMalloc->Free(lpi);
return;
}
if(!GetName(lpsf, lpi, SHGDN_NORMAL, szBuff))
{
lpe->Release();
lpMalloc->Free(lpi);
return;
}
tvi.pszText = szBuff;
tvi.cchTextMax = MAX_PATH;
lpifqThisItem = ConcatPidls(lpifq, lpi);
lptvid->lpi = (LPITEMIDLIST)lpMalloc->Alloc(lpi->mkid.cb+sizeof(lpi->mkid.cb));
CopyMemory((PVOID)lptvid->lpi, (CONST VOID *)lpi, lpi->mkid.cb+sizeof(lpi->mkid.cb));
SHFILEINFO sfi;
SHGetFileInfo((LPCTSTR)lpifqThisItem,0,&sfi,sizeof(SHFILEINFO),SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
tvi.iImage = sfi.iIcon;
SHGetFileInfo((LPCTSTR)lpifqThisItem,0,&sfi,sizeof(SHFILEINFO),SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON|SHGFI_OPENICON);
tvi.iSelectedImage = sfi.iIcon;
lptvid->lpsfParent = lpsf;
lpsf->AddRef();
lptvid->lpifq = ConcatPidls(lpifq, lpi);
tvi.lParam = (LPARAM)lptvid;
tvins.item = tvi;
tvins.hInsertAfter = hPrev;
tvins.hParent = hParent;
hPrev = InsertItem(&tvins);
lpMalloc->Free(lpifqThisItem);lpifqThisItem = 0;
lpMalloc->Free(lpi);lpi=0;
//Expand(hPrev,TVE_EXPAND);//startrecursion+
}
if(lpe) lpe->Release();
if(lpi && lpMalloc) lpMalloc->Free(lpi);
if(lpifqThisItem && lpMalloc) lpMalloc->Free(lpifqThisItem);
if(lpMalloc) lpMalloc->Release();
}
void CShellTree::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
if((pNMTreeView->itemNew.state & TVIS_EXPANDEDONCE))
return;
TCHAR szBuff[MAX_PATH];
LPSHELLFOLDER lpsf2 = NULL;
LPTVITEMDATA lptvid =(LPTVITEMDATA)pNMTreeView->itemNew.lParam;
if(lptvid)
if(lptvid->lpsfParent->BindToObject(lptvid->lpi,0,IID_IShellFolder,(LPVOID *)&lpsf2) == S_OK)
FillTreeView(lpsf2,lptvid->lpifq,pNMTreeView->itemNew.hItem);
*pResult = 0;
}
void CShellTree::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
ProceedSelItem();
*pResult = 0;
}
CString CShellTree::GetLastPath(void)
{
return m_lastpath;
}
void CShellTree::ProceedSelItem(void)
{
LPTVITEMDATA lptvid;
LPSHELLFOLDER lpsf2;
TV_SORTCB tvscb;
TCHAR buffer[MAX_PATH];
lptvid = (LPTVITEMDATA)GetItemData(GetSelectedItem());
if (lptvid && lptvid->lpsfParent && lptvid->lpi)
{
HRESULT hr = lptvid->lpsfParent->BindToObject(lptvid->lpi,0,IID_IShellFolder,(LPVOID *)&lpsf2);
if (SUCCEEDED(hr))
{
ULONG ulAttrs = SFGAO_FILESYSTEM;
lptvid->lpsfParent->GetAttributesOf(1, (const struct _ITEMIDLIST **)&lptvid->lpi, &ulAttrs);
if(ulAttrs & (SFGAO_FILESYSTEM))
if( SHGetPathFromIDList(lptvid->lpifq,&buffer[0]) )
m_lastpath.Format("%s",&buffer[0]);
lpsf2->Release();
}
}
}
void CShellTree::OnDeleteitem(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
LPTVITEMDATA lptvid=NULL;
HRESULT hr;
LPMALLOC lpMalloc;
hr=SHGetMalloc(&lpMalloc);
if(FAILED(hr))
return;
lptvid=(LPTVITEMDATA)pNMTreeView->itemOld.lParam;
lptvid->lpsfParent->Release();
lpMalloc->Free(lptvid->lpi);
lpMalloc->Free(lptvid->lpifq);
lpMalloc->Free(lptvid);
lpMalloc->Release();
*pResult = 0;
}
void CShellTree::OnSize(UINT nType, int cx, int cy)
{
CTreeCtrl::OnSize(nType, cx, cy);
GetParent()->SendMessage(WM_SIZE,nType,cy<<16|cx);
}
BOOL CShellTree::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(nHitTest == HTLEFT || nHitTest == HTBOTTOM || nHitTest == HTTOP || nHitTest == HTTOPRIGHT ||
nHitTest == HTTOPLEFT || nHitTest == HTBOTTOMRIGHT || nHitTest == HTBOTTOMLEFT)
{
SetCursor(::LoadCursor(0,IDC_ARROW) );
return true;
}
return CTreeCtrl::OnSetCursor(pWnd, nHitTest, message);
}
void CShellTree::OnWindowPosChanging(WINDOWPOS FAR* lpwndpos)
{
CTreeCtrl::OnWindowPosChanging(lpwndpos);
if(lpwndpos->cx < 32) lpwndpos->cx = 32;
}
//--------------------------------- Pidl ------------------------------------
UINT CShellTree::GetSize(LPCITEMIDLIST pidl)
{
UINT cbTotal = 0;
if (pidl)
{
LPSTR lpMem;
cbTotal += sizeof(pidl->mkid.cb); // Null terminator
while(pidl->mkid.cb )
{
cbTotal += pidl->mkid.cb;
lpMem = (LPSTR)pidl;
lpMem += pidl->mkid.cb;
pidl = (LPITEMIDLIST)lpMem;
}
}
return cbTotal;
}
LPITEMIDLIST CShellTree::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;
}
LPITEMIDLIST CShellTree::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;
}
BOOL CShellTree::GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST lpi, DWORD dwFlags,TCHAR *lpFriendlyName)
{
STRRET str;
if(lpsf->GetDisplayNameOf(lpi,dwFlags, &str) != S_OK)
return FALSE;
switch (str.uType)
{
case STRRET_WSTR:
WideCharToMultiByte(CP_ACP, // CodePage
0, // dwFlags
str.pOleStr, // lpWideCharStr
-1, // cchWideChar
(TCHAR *)lpFriendlyName,// lpMultiByteStr
MAX_PATH, // sizeof lpFriendlyName
NULL, // lpDefaultChar,
NULL); // lpUsedDefaultChar
break;
case STRRET_OFFSET:
_tcscpy( (TCHAR *)lpFriendlyName,(TCHAR *)(((char*)lpi)+str.uOffset));
break;
case STRRET_CSTR:
_tcscpy( (TCHAR *)lpFriendlyName,(TCHAR *)str.cStr);
break;
}
return TRUE;
}
Viel Spass beim Klabustern ^^
Lass lieber das Konzept der Sichtbaren Dateien bestehen
glaub das mal so.
Grüße und Erfolg
Karsten