CFileDialog::CFileDialog - Filter für Filegröße



  • Hallo,
    ich öffne wie folgt mittels CFileDialog eine Datei:

    CFileDialog dlg(TRUE,"txt",NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);
    
    dlg.m_ofn.lpstrInitialDir = m_path;
    
    if(dlg.DoModal() == IDOK) {
        .....
    }
    

    Jetzt suche ich nach einer Möglichkeit die unter dlg.DoModal() angezeigten Filenamen zuvor nach deren Dateigröße zu filter? 😕
    Ich möchte nur Dateien einer bestimmten Größe zur Auswahl anzeigen.



  • 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


Log in to reply