Click here to Skip to main content
Click here to Skip to main content

Easy to use file finding dialog

By , 19 Mar 2001
 
  • Download demo project - 21 Kb
  • Sample Image - FindFileSearching.gif

    Introduction

    Because we couldn't find out how to use the Windows "Find Files or Folders" dialog in our own app, and we needed to be able to retrieve a list of the files that were found in our app (which I don't think the Windows dialog even allows you to do), we wrote our own.

    CFindFileDlg is a simple dialog class that you can use to search hard drives (or floppy, or network, or CDROM drives) for files. It supports wildcards, and recursive folder searching, allows you to end the search after the first file is found, comes standard with a cancel button, simple animated icon and is fully multi-threaded.

    Integrating CFindFileDlg into your own application

    1. Add these files to your project:
      • FileFindDlg.cpp, FileFindDlg.h
      • FileFinder.cpp, FileFinder.h
    2. Copy the IDD_FIND_FILE dialog from the demo resource file to your project
    3. Copy the 12 animation icons (IDI_ICON1 -> IDI_ICON12) from the demo resource to your project
    4. #include "FindFileDlg.h" in the file where you want to use the dialog.

    Using CFindFileDlg

    // declare a search dialog
    CFindFileDlg dlg;
    
    dlg.m_csRootFolder = "C:\\";      // root folder of search
    dlg.m_csFindFile = "file.ext";  // file to search for
    dlg.m_bRecurse = true;          // search subfolders
    
    dlg.m_bFindSingleFile = false;  // find multiple files
    
    // these next three options aren't strictly necessary here, because
    // we've already specified a root folder. if we left the root folder
    // blank (""), the code will search drives A through Z. 
    //
    // the options below allow you to exclude certain types of drives
    
    dlg.m_bSearchNetworkDrives = false;     // ignore network drives
    dlg.m_bSearchRemovableDrives = false;   // ignore removable drives
    dlg.m_bSearchCDROMDrives = false;       // ignore CD-ROM drives
    
    // do it. 
    int nResponse = dlg.DoModal();
    
    // done
    if (nResponse == IDOK)
    {
        // success!!!
        // dlg.m_csaFoundFiles contains the files that matched our search criteria
    }
    else if (nResponse == IDCANCEL)
    {
        // operation failed or was cancelled
    }
    

    History

    20 Mar 2001 - udpated zip

    License

    This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

    A list of licenses authors might use can be found here

    About the Author

    Chris Losinger
    Software Developer
    United States United States
    Member
    Chris Losinger is the president of Smaller Animals Software, Inc..

    Sign Up to vote   Poor Excellent
    Add a reason or comment to your vote: x
    Votes of 3 or less require a comment

    Comments and Discussions

     
    You must Sign In to use this message board.
    Search this forum  
        Spacing  Noise  Layout  Per page   
    QuestionWant to search the root folder and subfolders?memberchris1757 Mar '06 - 5:53 
    Try going into FileFinder.cpp at line 120 and replace the follow code...
    // find tree starting from csSearchFolder 
    if (GET_SAFE(m_pss->m_bRecurse))
    {
    	ok = GetSubDirs(csaSearchFolders, csSearchFolder);
    }
    else
    {
    	csaSearchFolders.Add(csSearchFolder);
    }
    with this...
    >// find tree starting from csSearchFolder 
    csaSearchFolders.Add(csSearchFolder);
    if (GET_SAFE(m_pss->m_bRecurse))
    {
    	ok = GetSubDirs(csaSearchFolders, csSearchFolder);
    }

     
    Chris
    QuestionHow to use this code to find like Filesmemberchris17521 Feb '06 - 8:02 
    In the FileFinder.cpp Line 175 replace the following...
     
    CString searchString = curDir + "\\";
    searchString+=GET_SAFE(m_pss->m_csFindFile);
     
    with the following...
     
    CString searchString = curDir + "\\*";
    searchString+=GET_SAFE(m_pss->m_csFindFile);
    searchString+="*";

     
    Chris
    GeneralBackground threadmembernewkie12 Jan '05 - 23:46 
    First off, great job and thanks for making this available. I would really like to use this as part of an auto-upgrade feature. I have a 150gig HD so this really takes some time to build the folder list and requires quite a few CPU cycles. So I want it to use it in the background and run when the computer is idle. I've tried changing AfxBeginThread to THREAD_PRIORITY_LOWEST and THREAD_PRIORITY_IDLE but it made no difference. Any ideas?
    QuestionC:\RECYCLER folder?memberAngus Comber28 Feb '04 - 4:42 
    Not really a fault of your program I don't suppose, but when I run your program using for example *.doc across all my hard drives I get lots of these:
     
    E:\RECYCLER\S-1-5-21-1715567821-1957994488-1060284298-500\De595.doc
    E:\RECYCLER\S-1-5-21-1715567821-1957994488-1060284298-500\De596.doc
    E:\RECYCLER\S-1-5-21-1715567821-1957994488-1060284298-500\De597.doc
     
    When I look in Explorer at these folders, I see it says eg 988 files - but cannot see any of the files. A bit strange. I suppose that perhaps best bet would be to excluded RECYCLER directory. I am running Windows 2000. I wonder if called RECYCLER on other Windows platforms?
     
    Angus Comber
    ac@NOSPSMiteloffice.com

    AnswerRe: C:\RECYCLER folder?memberDgMv20 Dec '05 - 6:30 
    ok i don't konw too many english, but i try to explain,
     
    first, every logic driver has one X:\RECYCLER, (only hard disk). internally Wondows uses these folders to manage the "deleted files", but before you eliminate it "forever".
     
    second that files should be at the WINDOWS RECYCLER.
     
    third, did you see all files?, did you see hidden and system protected files too? if you want to see these files, go to your EXPLORER > TOOLS and go to the last option, something about "folders options", (i don't have Windows 2000 and i haven't see it in english) then search there in > View options that allows to see the files
     
    DgMv
    QuestionCan it start it a separate thread?memberChristopher Spiteri27 Nov '02 - 0:59 
    I'm developing a similar search dialog but am trying to start it in a separate thread, so that the user can minimize it or move it aside and continue working with the main dialog window while the search goes on. I partially succeeded by creating a CWinThread object in the main window dialog which in turn creates the dialog in a non-modal fashion (otherwise it would still retain the focus); the CWinThread::m_pMainWnd then takes on the address of the search dialog. I'm having a leak in the IMPLEMENT_DYNCREATE macro of the CWinThread object which i can't eliminate...anyone ever encountered a similar problem? Confused | :confused:
    AnswerRe: Can it start it a separate thread?memberChristopher Spiteri27 Nov '02 - 4:57 
    For the interested parties...I managed to find a piece of code that solves the above problem on the MSDN website. The sample name is MTMDI and can be found in the Advanced MFC Samples area.
    Apparently the memleak occurs because the main application terminates before the threaded dialog closes, leaving the dialog object behind. The above sample uses a system of messages to raise an event whenever the application prepares to close, causing the threaded windows to destroy themselves. The main application then uses WaitForSingleObject calls to wait until the threaded windows are closed before exiting.
    GeneralMatching file specs aren't found if they are in the root foldermemberMatthew House12 Apr '02 - 4:14 
    If you search for *.Doc in C:\ with the recursive search ON then ONLY files in subdirs that match *.Doc are found, none in C:\ are found.
    Is this just me ? I would have thought that someone would have picked up on this by now?
     
    I changed the following:
     
    ORIGINAL CODE
    ------------------------------------
    if (GET_SAFE(m_pss->m_bRecurse))
    {
    ok = GetSubDirs(csaSearchFolders, csSearchFolder);
    }
    else
    {
    csaSearchFolders.Add(csSearchFolder);
    }
     
    NEW CODE
    ------------------------------------
    csaSearchFolders.Add(csSearchFolder);
    if (GET_SAFE(m_pss->m_bRecurse))
    ok = GetSubDirs(csaSearchFolders, csSearchFolder);

     
    Matt.
    GeneralToo many backslashes in returned pathmemberMike Eriksson16 Mar '01 - 5:13 
    Hello!
     
    If I set m_csRootFolder = "" then the returned path's will be wrong. There will be an extra \ after the drive, e.g. C:\\TEMP\XYZ.TXT
     
    The error is in the CFileFinder::GetLocalDriveRoots() Where you first put a '\\' in buf and then
    t = buf;
    t += "\\";
     
    To fix it: remove the t += "\\"; line
     
    // Mike

    GeneralRe: Too many backslashes in returned pathmemberChris Losinger16 Mar '01 - 5:15 
    i think it would be better to consider a root folder of "" to be an error - there really is no valid folder called "".
     
    -c
     
    ------------------------------
    Smaller Animals Software, Inc.
    http://www.smalleranimals.com
    GeneralRe: Too many backslashes in returned pathmemberMike Eriksson16 Mar '01 - 5:25 
    Hmmm...
     
    this is from your code
     
    // these next three options aren't strictly necessary here, because
    // we've already specified a root folder. if we left the root folder
    // blank (""), the code will search drives A through Z.
     
    Which I interpret as if I want to search all drives, A to Z, I should set m_csRootFolder = "";
     
    If this isn't the case(?) then you'd better change the comments!
     
    //Mike
    GeneralRe: Too many backslashes in returned pathmemberChris Losinger16 Mar '01 - 5:27 
    Smile | :) ok. you got me.
     
    -c
     
    ------------------------------
    Smaller Animals Software, Inc.
    http://www.smalleranimals.com
    GeneralFindFile doesn't start at all for me :o)sussMichael Kuelshammer12 Oct '00 - 6:25 
    I debugged the sources and found, that there is a small bug in CFileFinder::GetSubDirs(....)
     
    mustn't it be:
     
    CString searchString;
    while (path.GetAt(path.GetLength()-1)=='\\')
    path =path.Left(path.GetLength()-1);
     
    searchString=path+"\\*.*";
     
    I replaced that if-else condition with the while-loop and it's working for me now....
     
    Bye,
    M. K
    GeneralRe: FindFile doesn't start at all for me :o)susschris losinger12 Oct '00 - 6:39 
    wouldn't this only be a problem if you were sending paths in with multiple trailing '\' characters
    GeneralRe: FindFile doesn't start at all for me :o)sussMichael Kuelshammer15 Oct '00 - 23:58 
    I downloaded the sample project, just only pressing the start button after compiling, and nothing happens, only the find file dialog flashes for a short time, so I debugged, I had made no changes in the source code, just only searched for win.ini on disk C:\ and found out, that the variable 'path' is C:\\ for me, my computer is connected to the intranet. So I changed the source code lines as stated above and now it is working for me...., funny, isn't it ??
     
    Bye,
    M. K
    GeneralMemory LeakssussBrigg Thorp10 Jul '00 - 3:28 
    I tried running this demo and I got thousands of string dumps in my output window. What gives??
    GeneralRe: Memory Leakssusschris losinger10 Jul '00 - 3:59 
    i have no idea... it's never leaked on me.
     
    can you give a little more info? (OS, development env. maybe
    GeneralRe: Memory Leaks - are you sure?susschris losinger10 Jul '00 - 4:35 
    are you sure they were memory leaks ?
     
    the demo prints the names of the files that it found to the debug window.
     
    -
    GeneralRe: Memory Leaks - are you sure?sussBrigg Thorp11 Jul '00 - 7:17 
    I am running Windows 2000 and I used Visual C++ 6.0 SP4 to compile the project. These are the errors I get in my debug window when I press Cancel:
     
    --------------
    Found 943 folders
    found 0
    Cancel
    Detected memory leaks!
    Dumping objects ->
    thrdcore.cpp(166) : {74} client block at 0x002F4928, subtype 0, 112 bytes long.
    a CWinThread object at $002F4928, 112 bytes long
    Object dump complete.
    The thread 0x3BC has exited with code 0 (0x0).
    The thread 0x36C has exited with code 0 (0x0).
    The program 'C:\FindFile\Debug\findfile.exe' has exited with code 0 (0x0).
    ------------
     
    Also, when I hit the cancel button, and tried to run it again, I got an unhandled exception in NTDLL.DLL.

    GeneralRe: Memory Leaks - Fixedsusschris losinger11 Jul '00 - 10:55 
    ah... well, it's not really the "thousands" that you mentioned before.
     
    but, it should be fixed in the code that's available now.
     
    -
    GeneralTo Use the Windows Find Files dialog boxsussBrian Hart7 Jul '00 - 20:27 
    Here's code that you can copy and paste into your program right now to use Windows' Find Files dialog box:
     
    #include
    #include
    static BOOL FindAllFilesThenComputers()
    {
    if (!AfxOleInit())
    return FALSE;
     
    HRESULT hResult = ::CoInitialize(NULL);
    IShellDispatch* pShellDisp = NULL;
     
    hResult = ::CoCreateInstance(CLSID_Shell,
    NULL, CLSCTX_SERVER,
    IID_IShellDispatch, (void**)&pShellDisp);
     
    if (FAILED(hResult) || pShellDisp == NULL)
    return FALSE;
     
    // Call the IShellDispatch::FindFiles() method
    // to invoke Windows' Find Files dialog that you
    // get from the Start menu
    pShellDisp->FindFiles();
     
    // Call the IShellDispatch::FindComputer() method
    // to find a computer. This works as if you clicked
    // the Start button, moved to Find, and then clicked
    // Computers...
    pShellDisp->FindComputer();
     
    // When we're done with the IShellDispatch interface,
    // we need to call pShellDisp->Release();
    pShellDisp->Release();
     
    // Cleanup
    ::CoFreeUnusedLibraries();
    ::CoUninitialize();
     
    return TRUE;
    } Smile | :)
     
    And there, we're done. It took a little bit of coding, but at least one doesn't have to re-invent the wheel...
     
    Also, make sure you've downloaded and installed the Platform SDK from Microsoft's site at http://msdn.microsoft.com/downloads/sdks/platform/platform.asp. Download it, and then do a 'Typical' install to get the headers and libs that you need. Smile | :)
     
    Yours,
    Brian Hart

    GeneralRe: To Use the Windows Find Files dialog boxsussBrian Hart7 Jul '00 - 20:32 
    Hey Everybody, a little correction Smile | :)
     
    The #include lines didn't get carried over right by The Code Project's wonderful scripts...
     
    Here they are:
     
    #include < shldisp.h >
    #include < afxdisp.h >
     
    Also, here's a link to the Platform SDK:
     
    http://msdn.microsoft.com/downloads/sdks/platform/platform.asp
     
    Hope this helps!
     
    Brian Har
    GeneralRe: To Use the Windows Find Files dialog boxsussPaul Selormey2 Aug '00 - 10:09 
    Hello Brian,
     
    Why not just call ShellExecute with the verb "find" to get
    the dialog up and running? You love hard work, eh?
     
    Regards,
    Paul.
    GeneralRe: To Use the Windows Find Files dialog boxsussJason16 Oct '00 - 4:15 
    Helpful tips, but how to get the result?
    GeneralRe: To Use the Windows Find Files dialog boxsussChris16 Oct '00 - 4:17 
    :how to get the results?
     
    you can't.
     
    that's why i wrote CFindFileDlg.
     
    -

    General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

    Permalink | Advertise | Privacy | Mobile
    Web01 | 2.6.130523.1 | Last Updated 20 Mar 2001
    Article Copyright 2000 by Chris Losinger
    Everything else Copyright © CodeProject, 1999-2013
    Terms of Use
    Layout: fixed | fluid